Skip to content

Configure NGINX as a reverse proxy for vSphere

Introduction

For various reasons, it can be useful to hide vSphere behind a reverse proxy. For example, if you want to prevent the direct access to vsphere, or if you want to simplify the deployment of HTTPS, hiding behind a proxy such as NGINX can be interesting.

In my case, I have a small vsphere infrastructure that I use as a homelab, which I use to test experimental things that helps me to increase my understanding how what can be done with such infrastructures. Sometimes, I can have an idea while being out of reach of my homelab. Setting up a reverse proxy enabled me to access the homelab from any computer.

In this article, I will show what is the reverse proxy configuration that I used. Please note that this configuration is suitable for testing, and should not be used as is for production. In a second article I will show how I added some security via the use of authelia, an open source authentication and authorization server.

A first draft of vsphere behind an HTTP reverse proxy (nginx)

Let assume that vsphere is available at https://192.168.1.25, and that we want to hide vsphere behind the http://cloud.homelab.lan domain, you add the following entry in the /etc/nginx/sites-enabled/default:

server {
    server_name cloud.homelab.lan

    location / {
        proxy_set_header Host "192.168.1.25";
        proxy_set_header Origin "192.168.1.25";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_ssl_verify off;
        proxy_pass https://192.168.1.25;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
        client_max_body_size 0;
        proxy_read_timeout 36000s;
        proxy_redirect https://192.168.1.25/ https://cloud.homelab.lan/;
    }

    location /websso/SAML2 {
        sub_filter "://192.168.1.25" "://cloud.homelab.lan";
        proxy_set_header Host 192.168.1.25;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_ssl_verify off;
        proxy_pass https://192.168.1.25;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
        client_max_body_size 0;
        proxy_read_timeout 36000s;
        proxy_ssl_session_reuse on;
        proxy_redirect https://192.168.1.25/ https://cloud.homelab.lan/;
    }

    location /ui/app-fabric/fabric {
        proxy_pass https://192.168.1.25/ui/app-fabric/fabric;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        access_log  /var/log/nginx/server.log;
    }

    location /ui/actionsService/actions/evaluations {
        proxy_pass https://192.168.1.25/ui/actionsService/actions/evaluations;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        access_log  /var/log/nginx/server.log;
    }

    location /ui/webconsole/authd {
        proxy_pass https://192.168.1.25/ui/webconsole/authd;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        access_log  /var/log/nginx/server.log;
    }

    listen 80;
}

A second draft of vsphere behind an HTTPs reverse proxy (nginx)

You can go further and hide vsphere behind an HTTPs reverse proxy. Let assume that you have a working SSL certificate (generated via Lets encrypt) with the following files:

File Usual location (using certbot)
certificate /etc/letsencrypt/live/homelab/fullchain.pem
private key /etc/letsencrypt/live/homelab/privkey.pem
Nginx Let's encrypt configuration /etc/letsencrypt/options-ssl-nginx.conf

To enable HTTPs, first modify the existing configuration:

listen 80;

by:

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/homelab/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/homelab/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;

and add this configuration to redirect HTTP traffic to HTTPs:

server {
    listen 80;
    server_name cloud.homelab.lan;

    return 301 https://$server_name$request_uri;
}

Here is the complete configuration:

server {
    server_name cloud.homelab.lan

    location / {
        proxy_set_header Host "192.168.1.25";
        proxy_set_header Origin "192.168.1.25";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_ssl_verify off;
        proxy_pass https://192.168.1.25;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
        client_max_body_size 0;
        proxy_read_timeout 36000s;
        proxy_redirect https://192.168.1.25/ https://cloud.homelab.lan/;
    }

    location /websso/SAML2 {
        sub_filter "://192.168.1.25" "://cloud.homelab.lan";
        proxy_set_header Host 192.168.1.25;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_ssl_verify off;
        proxy_pass https://192.168.1.25;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
        client_max_body_size 0;
        proxy_read_timeout 36000s;
        proxy_ssl_session_reuse on;
        proxy_redirect https://192.168.1.25/ https://cloud.homelab.lan/;
    }

    location /ui/app-fabric/fabric {
        proxy_pass https://192.168.1.25/ui/app-fabric/fabric;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        access_log  /var/log/nginx/server.log;
    }

    location /ui/actionsService/actions/evaluations {
        proxy_pass https://192.168.1.25/ui/actionsService/actions/evaluations;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        access_log  /var/log/nginx/server.log;
    }

    location /ui/webconsole/authd {
        proxy_pass https://192.168.1.25/ui/webconsole/authd;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        access_log  /var/log/nginx/server.log;
    }

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/homelab/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/homelab/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
}

server {
    listen 80;
    server_name cloud.homelab.lan;

    return 301 https://$server_name$request_uri;
}

Security considerations

You have to be aware that your infrastructure should not be accessible directly on internet. Doing so would expose you infrastructure to hackers that will try to gain the control of your vpshere. You can add a security layer by using an authentication and authorization server, such as authelia.

References

To sucessfully set up the reverse proxy, I used several sources as inspiration:

Comments