Sometimes you want to build a service using WebSocket (WS) transport and then you want to terminate the Secure WebSocket (WSS) in the Nginx. Or you want to terminate your WebSocket in Nginx to enable load balancing. These scenarios are very common for Nginx.
In this tutorial, we will help you build your Nginx as Websocket reverse proxy as well as offloading the SSL in the Nginx.
Check Prerequisite
- Nginx Installed, if not installed yet, you can just use
apt install nginx
to install it. - Sudo privileges, you need to have sudo privileges to edit the Nginx configuration. To make sure that we don’t have a permission issue, execute
sudo su
command before starting this tutorial.
Use Case
To demonstrate the WebSocket reverse proxy, will use this use case:
___________ ____________
wss | | ws | |
user -----------> | Nginx |----------> | App |
|___________| |____________|
For example, this will be the spesification of each node:
- Nginx:
- port: 443
- ip: 10.1.0.10/24
- App:
- port: 3000
- ip: 10.2.0.20/24
Your App
is using a plain WebSocket (ws), while Nginx
will use a secure WebSocket (wss), and terminate the SSL
. In this example, we will use my.websocket.app
domain.
Nginx Configuration
First, you need an Nginx that already running. Move our work directory to the Nginx configuration folder
cd /etc/nginx
Backup the default nginx configuration file
mv nginx.conf nginx.conf.old
Create a new configuration file
nano nginx.conf
Add this configuration to the configuration file
user www-data; worker_processes auto; worker_rlimit_nofile 8192; pid /run/nginx.pid; events { worker_connections 4096; } http { include mime.types; default_type application/octet-stream; # Sending fille Optimization sendfile on; tcp_nopush on; tcp_nodelay on; # Keepalive Connection keepalive_timeout 65; server { listen 443 ssl http2; server_name my.websocket.app # Security and SSL ssl_protocols TLSv1.3 TLSv1.2; ssl_certificate /etc/ssl/cert_file.crt; ssl_certificate_key /etc/ssl/key_file.key; location / { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_http_version 1.1; proxy_set_header Host $host; proxy_pass http://10.2.0.20:3000; } } }
proxy_set_header Upgrade $http_upgrade
and proxy_set_header Connection "Upgrade"
directives is needed when we want to use WS protocol instead of HTTP protocol for the upstream connection. And it is the core difference between the HTTP reverse proxy and WS reverse proxy.
WSS and WS protocol is only supported on HTTP version 1.1
, so you must use the proxy_http_version 1.1
directive to make sure the Nginx works properly.
proxy_set_header Host $host
is another mandatory directive if you want to use WSS and WS protocol. It takes the Host
header on the request and passes it to the upstream server.
Lastly, We use the proxy_pass
directive to tell the Nginx the upstream ws server, in this case, we will proxy the WSS request to our WS app in 10.2.0.20:3000
.
If your domain is using plain WS then you can comment out ssl_protocols
, ssl_certificate
, and ssl_certificate_key
directives, and also change the listen
directive to 80
or whatever port that you want to use.
After the configuration is done, make sure that there is no error in the configuration by running this command
nginx -t
Reload the nginx so it uses the new configuration file
service nginx reload
You can check the nginx status by running this command
service nginx status
That’s it! Congratulation, now you can build your Nginx as WebSocket Reverse Proxy.