Reverse Proxy Proxmox VNC With Nginx

The noVNC console in the Proxmox Web GUI transfers it’s data through a technology called Websockets. Websockets often work in tandem with normal HTTP traffic and therefore often use the same end point (IP and port). Proxmox uses port 8006 by default for all web traffic; this includes the Web GUI you see and a websockets stream for the VNC console.

If you use Nginx to reverse proxy your Proxmox Web GUI already, making it websocket compatible is very easy. In fact, it’s as easy as adding three additional lines to your Nginx config file for the location tag that serves your Proxmox Web GUI.

Open up your sites-available config file for your Proxmox site with a text editor:

Enabling web content compression is one of the simplest ways to save bandwidth and, for some users, speed up the time it takes to serve a page. All modern browsers support content compression and the CPU overhead for clients is a thing of the past.

Compressing content on your server however, can be CPU intensive and something you may have to plan for. Generally, compressing anything is a trade off between size of the content and the CPU cycles required in compressing it. With Nginx, content that has compression enabled has to be sent through a gzip algorithm to compress it before it’s sent to the client.

Some content does not lend itself to compression in this manner. such as images and zip archives. This is because this content has already been compressed and compressing further will have little or no result. In fact, certain types of content can even end up larger after compression. Due to this, we only tend to compress content such as HTML, CSS, JS, XML and other text based content.

The below steps will enable gzip compression for the entire Nginx server – that includes all server{} tags listed in the sites-enabled config.

Create a new file called compression.conf in the Nginx conf.d directory. If this directory doesn’t exist on your Nginx installation, you can add this to the bottom of nginx.conf.

I won’t detail each line in the file, but two of the interesting attributes are:

gzip_comp_level – this is the compression level that gzip will apply to the content, between 1 and 9 where 1 is the lowest compression and 9 is the highest. Again, this is a trade of between CPU (and therefore time to compress the content) and the resulting file size. 5 – 7 is usually considered a sensible range for this value.

gzip_types – this is the MIME type of content that may be compressed. As you can see, each entry here is text based with no images/ zip files listed.

Installing Nginx on Debian or Ubuntu is as easy as a single apt-get command, however it does not install the latest version of Nginx. In fact, the latest stable Nginx version is 1.8 and the latest package in Debian’s standard repository is 1.2

To get the latest stable version we need to add a new source to our package manager. Before doing so, add the Nginx PGP key which is used to sign all packages. Run the below commands to download the key from Nginx.com, add it to our package manager and clean up the local downloaded file.

1

2

3

wget http://nginx.org/keys/nginx_signing.key

apt-key add nginx_signing.key

rmnginx_signing.key

We can now create the new source file with the Nginx repository location.

1

vi/etc/apt/sources.list.d/nginx.list

Add one of the following depending on your Linux distribution. You will need to change wheezy or trusty to the codename of your distribution version.

The error is presented because a request being sent to the server contains more data than Nginx allows by default. You can increase the allowed maximum with the client_max_body_size attribute.

You can add the client_max_body_size attribute to your configuration files in multiple places to control what sites or locations the attribute affects. For example, you can add it to your main config file to ensure than any site can upload the value you set. The below example sets a global value of 50MB for all sites.

1

vi/etc/nginx/nginx.conf

1

2

3

4

5

http{

client_max_body_size50M;

...

...

}

You could also add it inside the server { tags of an individual site, or even the location { tags of a specific location.

Once you have made your change remember to reload the configuration and the changes will take effect.

The Proxmox web GUI is served by Proxmox’s new event driven API server called PVE Proxy. The default settings for the Proxmox web GUI is to listen on port 8006 for incoming HTTPS connections.

The following tutorial will show you how to use Nginx to reverse proxy the PVE Proxy application to do the following:

Redirect HTTP requests to use the HTTPS protocol.

Add your own certificate to use for HTTPS.

Listen on the standard HTTPS port (port 443).

The following steps show how to use Nginx to reverse Proxy Proxmox’s web GUI. If you would prefer to use Apache, please see my other blog post.

The first step is to make sure you have Nginx installed on the machine, or virtual instance, that you are going to use. You can install Nginx directly on the Proxmox host however, I prefer to keep the host software as standard as possible and run all additional applications in OpenVZ containers.

Create a shell session on the machine you would like to use and use apt-get to install Nginx.

We now need to specify the configuration for Nginx. Remove the existing site configuration and create a new configuration file called proxmox-gui. You can call this file whatever you wish, but you will also need to use the same name in the below steps.

1

2

rm-f/etc/nginx/sites-enabled/default

vi/etc/nginx/sites-enabled/proxmox-gui

Add the below text to your proxmox-gui file. You will need to substitute some of the settings with your own values:

ssl_certificate – this should point to your SSL certificate to use for signing the SSL traffic.

ssl_certificate_key – is this key which matches the above certificate.

server – this is the IP and port of your Proxmox server. If you have installed Nginx on the same host as the Proxmox web GUI then you could use https://localhost:8006 here.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

upstreamproxmox{

server10.10.10.10:8006;

}

server{

listen80default_server;

rewrite^(.*)https://$host$1 permanent;

}

server{

listen443;

server_name_;

ssl on;

ssl_certificate/etc/nginx/ssl/cert.pem;

ssl_certificate_key/etc/nginx/ssl/key.pem;

proxy_redirect off;

location/{

proxy_pass https://proxmox;

}

}

If you have multiple Proxmox servers in a cluster, it would make sense to use load balancing in Nginx. We don’t really want to use this feature to spread the load, because usually the traffic will be very light – we want to use it so that if one node in the cluster is down, Nginx will automatically try a different node in the cluster.

I previously wrote in this blog post about how to fix an error with Gitlab. The error was presented when using the git push command with a remote repository that uses the Gitlabs HTTP protocol and not the SSH protocol.

The following error was presented in the Git client when using the git push command:

1

2

3

4

5

6

7

8

9

10

git push-uorigin master

Counting objects:556,done.

Delta compression using up to8threads.

Compressing objects:100%(539/539),done.

efrror:RPC failed;result=22,HTTP code=413367.00KiB/s

atal:The remote endhung up unexpectedly

Writing objects:100%(556/556),1.45MiB|367.00KiB/s,done.

Total556(delta282),reused0(delta0)

fatal:The remote endhung up unexpectedly

Everything up-to-date

It seems that the issue is Nginx, Gitlab’s HTTP server, is not configured to receive large amounts of data. We need to specify the attribute client_max_body_size in Gitlab’s Nginx configuration file and specify the maximum amount of data Nginx will accept.

Open the configuration file and find the line location @gitlab.

1

vi/etc/nginx/sites-available/gitlab

Add the client_max_body_size attribute and specify the size value to use.

1

client_max_body_size20M

The M stands for megabyte – you can also use G for gigabytes.

If the size of your git push ever exceeds the above value, you will have to either increase the size further or reduce your git commit sizes.

Your completed /etc/nginx/sites-available/gitlab file should look like the below example which has a 20MB upload limit.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

upstreamgitlab{

serverunix:/home/git/gitlab/tmp/sockets/gitlab.socket;

}

server{

listen*:80default_server;# e.g., listen 192.168.1.1:80; In most cases *:80 is a good idea

server_nameYOUR_SERVER_FQDN;# e.g., server_name source.example.com;

server_tokensoff;# don't show the version number, a security best practice