Jul 172021
 

HEADS UP: this is still under review. Until this notice is removed, I recommend not using this.

I have a Dell R720 at an ISP. The iDRAC connection is filtered, by the ISP, and is accessible only from a small number of IP addresses.

Sure, this talks about a web proxy. It works. So does the ssh forwarding shown at the bottom of this post.

NOTE: I should start monitoring that IP addr ess to ensure it is not publicly accessible.

My goal is to configure an Nginx reverse proxy at one of those IP addresses. Access to the proxy will be via VPN only. Configuration of the VPN is outside the scope of this post.

When I first tweeted about this back in May, I asked for suggestions and ideas. In this post, I’ll elaborate more upon my use case, which was not well explained in the tweet, and show a solution I’ve implemented. I will also consider how secure is the connection to port 5900.

My use case

The server in question (the one with the iDRAC) will be at a datacenter where I have no control.

The datacenter will firewall off the iDRAC IP address and restrict access to pre-determined IP addresses.

This is iDRAC 7 with an HTML console access.

My laptop can connect to the VPN. From there, I access the Nginx proxy via my web browser.

The Nginx proxy is not accessible unless on the VPN.

The iDRAC proxy

I was able to get a basic proxy up and running. I could login, and it worked.

R720 iDRAC login

R720 iDRAC login

But the main page did not load completely.

R720 iDRAC post login via proxy

R720 iDRAC post login via proxy

Searching for “nginx reverse proxy dell r720 idrac 7”, I found this reddit post. The various location /*.jsesp directives got it working for me.

R720 main screen after login

R720 main screen after login

The virtual console

Next, opening the virtual console showed me I needed another virtual host.

Console window failed - this was behind the following screen shot

Console window failed – this was behind the following screen shot

This was the window just in front of the above.

Cannot connect to port 5900

Cannot connect to port 5900

That prompted me to create the second virtual host. Once in place, the virtual console worked:

Virtual console connected

Virtual console connected

The configuration

This is the configuration I first used. I’m going to split it into three different files to remove duplication. See the next section for that solution.

[dan@[redacated]:/usr/local/etc/nginx/includes] $ cat r720-02-idrac.conf
server {
    listen [redacted]:443 ssl http2;

    server_name r720-02-ipmi.int.unixathome.org;

    access_log  /var/log/nginx/r720-02-idrac-acceess.log;
    error_log   /var/log/nginx/r720-02-idrac-error.log;

    location / {
        proxy_pass https://[IP ADDRESS OF IDRAC];
#        proxy_redirect     off;
#        proxy_set_header   Host               $host;
#        proxy_set_header   X-Real-IP          $remote_addr;
#        proxy_set_header   X-Forwarded-For    $proxy_add_x_forwarded_for;
#        proxy_set_header   X-Forwarded-Proto  http;
#        proxy_set_header   X-NginX-Proxy true;

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass_request_headers on;
        proxy_set_header Connection "keep-alive";
        proxy_store off;
    }

    location  /userpriv.jsesp {
        add_header Content-Type application/javascript;
        proxy_pass https://[IP ADDRESS OF IDRAC]/userpriv.jsesp;
        expires 1y;
        add_header Cache-Control "public";
    }
    location  /functions.jsesp {
        add_header Content-Type application/javascript;
        proxy_pass https://[IP ADDRESS OF IDRAC]/functions.jsesp;
        expires 1y;
        add_header Cache-Control "public";
    }
    location  /sysSummary.jsesp {
        add_header Content-Type application/javascript;
        proxy_pass https://[IP ADDRESS OF IDRAC]/sysSummary.jsesp;
        expires 1y;
        add_header Cache-Control "public";
    }
    location  /sensors.jsesp {
        add_header Content-Type application/javascript;
        proxy_pass https://[IP ADDRESS OF IDRAC]/sensors.jsesp;
        expires 1y;
        add_header Cache-Control "public";
    }



  ssl_protocols TLSv1.2 TLSv1;

  ssl_prefer_server_ciphers on; 
  
  ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
  ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
  ssl_session_timeout  10m;
  ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off; # Requires nginx >= 1.5.9
  resolver_timeout 5s; 
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
  add_header X-XSS-Protection "1; mode=block";

  ssl_certificate     /usr/local/etc/ssl/r720-02-ipmi.int.unixathome.org.fullchain.cer;
  ssl_certificate_key /usr/local/etc/ssl/r720-02-ipmi.int.unixathome.org.key;
}

server {
    listen [redacted]:5900 ssl http2;

    server_name r720-02-ipmi.int.unixathome.org;

    access_log  /var/log/nginx/r720-02-idrac-acceess.log;
    error_log   /var/log/nginx/r720-02-idrac-error.log;

    location / {
        proxy_pass https://[IP ADDRESS OF IDRAC]:5900;

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass_request_headers on;
        proxy_set_header Connection "keep-alive";
        proxy_store off;
    }

  ssl_protocols TLSv1.2 TLSv1;

  # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
  ssl_dhparam /usr/local/etc/ssl/dhparams.pem;

  ssl_prefer_server_ciphers on; 
  
  ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
  ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
  ssl_session_timeout  10m;
  ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off; # Requires nginx >= 1.5.9
  resolver_timeout 5s; 
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
  add_header X-XSS-Protection "1; mode=block";

  ssl_certificate     /usr/local/etc/ssl/r720-02-ipmi.int.unixathome.org.fullchain.cer;
  ssl_certificate_key /usr/local/etc/ssl/r720-02-ipmi.int.unixathome.org.key;
}

The three file solution

These are the three files I’m using. You want to use either the above or the below, not both.

[dan@[redacted]:/usr/local/etc/nginx/includes] $ cat r720-02-idrac.conf
server {
    listen [redacted]:443 ssl http2;

    include /usr/local/etc/nginx/includes/r720-02-idrac.common.inc;

    location / {
        proxy_pass https://[IP ADDRESS OF IDRAC];

        include /usr/local/etc/nginx/includes/r720-02-idrac.common-proxy.inc;
    }

    location  /userpriv.jsesp {
        add_header Content-Type application/javascript;
        proxy_pass https://[IP ADDRESS OF IDRAC]/userpriv.jsesp;
        expires 1y;
        add_header Cache-Control "public";
    }
    location  /functions.jsesp {
        add_header Content-Type application/javascript;
        proxy_pass https://[IP ADDRESS OF IDRAC]/functions.jsesp;
        expires 1y;
        add_header Cache-Control "public";
    }
    location  /sysSummary.jsesp {
        add_header Content-Type application/javascript;
        proxy_pass https://[IP ADDRESS OF IDRAC]/sysSummary.jsesp;
        expires 1y;
        add_header Cache-Control "public";
    }
    location  /sensors.jsesp {
        add_header Content-Type application/javascript;
        proxy_pass https://[IP ADDRESS OF IDRAC]/sensors.jsesp;
        expires 1y;
        add_header Cache-Control "public";
    }
}

server {
    listen [redacted]:5900 ssl http2;

    include /usr/local/etc/nginx/includes/r720-02-idrac.common.inc;

    location / {
        proxy_pass https://[IP ADDRESS OF IDRAC]:5900;

        include /usr/local/etc/nginx/includes/r720-02-idrac.common-proxy.inc;
    }
}
[dan@[redacted]:/usr/local/etc/nginx/includes] $ cat r720-02-idrac.common.inc
  server_name r720-02-ipmi.int.unixathome.org;

  access_log  /var/log/nginx/r720-02-idrac-acceess.log;
  error_log   /var/log/nginx/r720-02-idrac-error.log;

  ssl_protocols TLSv1.2 TLSv1;

  ssl_prefer_server_ciphers on; 
  
  ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA512:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:ECDH+AESGCM:ECDH+AES256:DH+AESGCM:DH+AES256:RSA+AESGCM:!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
  ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
  ssl_session_timeout  10m;
  ssl_session_cache shared:SSL:10m;
  ssl_session_tickets off; # Requires nginx >= 1.5.9
  resolver_timeout 5s; 
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
  add_header X-XSS-Protection "1; mode=block";

  ssl_certificate     /usr/local/etc/ssl/r720-02-ipmi.int.unixathome.org.fullchain.cer;
  ssl_certificate_key /usr/local/etc/ssl/r720-02-ipmi.int.unixathome.org.key;
[dan@[redacted]:/usr/local/etc/nginx/includes] $ cat r720-02-idrac.common-proxy.inc

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass_request_headers on;
        proxy_set_header Connection "keep-alive";
        proxy_store off;
[dan@[redacted]:/usr/local/etc/nginx/includes] $ 

How secure is that port 5900?

From my web browser to the proxy port 443: https

From the proxy, to the iDRAC port 443: https

From my web browser to the proxy port 5900: https

From the proxy to the iDRAC port 5900: also https

How do I do know the traffic from the proxy to the iDRAC is protected?

I know the iDRAC on port 443 is fine, but I’ll test it anyway.

I tested it like this:

$ openssl s_client -connect [IP ADDRESS OF IDRAC]:443
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 C = US, ST = Texas, L = Round Rock, O = Dell Inc., OU = Remote Access Group, CN = idrac, emailAddress = support@dell.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = US, ST = Texas, L = Round Rock, O = Dell Inc., OU = Remote Access Group, CN = idrac, emailAddress = support@dell.com
verify return:1
---
Certificate chain
 0 s:C = US, ST = Texas, L = Round Rock, O = Dell Inc., OU = Remote Access Group, CN = idrac, emailAddress = support@dell.com
   i:C = US, ST = Texas, L = Round Rock, O = Dell Inc., OU = Remote Access Group, CN = idrac, emailAddress = support@dell.com
---
Server certificate
-----BEGIN CERTIFICATE-----
[redacted]
-----END CERTIFICATE-----
subject=C = US, ST = Texas, L = Round Rock, O = Dell Inc., OU = Remote Access Group, CN = idrac, emailAddress = support@dell.com

issuer=C = US, ST = Texas, L = Round Rock, O = Dell Inc., OU = Remote Access Group, CN = idrac, emailAddress = support@dell.com

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 1701 bytes and written 421 bytes
Verification error: self signed certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: F0EF3BA3E9318EEB32557129359941BBB24E1DBE70CBB76D539827AFF396D771
    Session-ID-ctx: 
    Master-Key: [redacted]
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 97 b3 3b f0 38 41 ba 63-b9 ab f7 dd cf fd ad 1a   ..;.8A.c........
[redacted]
    00a0 - c0 bb 14 ee f3 ea a9 10-3c f7 24 62 4b cb b6 59   ........<.$bK..Y

    Start Time: 1626547934
    Timeout   : 7200 (sec)
    Verify return code: 18 (self signed certificate)
    Extended master secret: no
---
DONE

And with port 5900, I say similar output. My conclusion, I'm OK with the traffic between the proxy and the iDRAC at the ISP.

ssh port forwarding

This also works:

ssh -2 -L 127.0.0.1:8443:[IP ADDRESS OF IDRAC]:443 -L127.0.0.1:5900:[IP ADDRESS OF IDRAC]:5900 myproxy.example.org

With this, you don't need the web proxy.

Deploy

I could deploy this to each of the trusted IP addresses which are allowed access. So far, it's just one location.

I'm going to ask around about this solution and look for suggestions.

Hope this helps.

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive