NGINX to reverse proxy websockets AND enable SSL (wss://)?
Have no fear, because a brave group of Ops Programmers have solved the situation with a brand spanking new nginx_tcp_proxy_module
Written in August 2012, so if you are from the future you should do your homework.
Prerequisites
Assumes you are using CentOS:
- Remove current instance of NGINX (suggest using dev server for this)
- If possible, save your old NGINX config files so you can re-use them (that includes your
init.d/nginx
script) yum install pcre pcre-devel openssl openssl-devel
and any other necessary libs for building NGINX- Get the nginx_tcp_proxy_module from GitHub here https://github.com/yaoweibin/nginx_tcp_proxy_module and remember the folder where you placed it (make sure it is not zipped)
Build Your New NGINX
Again, assumes CentOS:
cd /usr/local/
wget 'http://nginx.org/download/nginx-1.2.1.tar.gz'
tar -xzvf nginx-1.2.1.tar.gz
cd nginx-1.2.1/
patch -p1 < /path/to/nginx_tcp_proxy_module/tcp.patch
./configure --add-module=/path/to/nginx_tcp_proxy_module --with-http_ssl_module
(you can add more modules if you need them)make
make install
Optional:
sudo /sbin/chkconfig nginx on
Set Up Nginx
Remember to copy over your old configuration files first if you want to re-use them.
Important: you will need to create a tcp {}
directive at the highest level in your conf. Make sure it is not inside your http {}
directive.
The example config below shows a single upstream websocket server, and two proxies for both SSL and Non-SSL.
tcp {
upstream websockets {
## webbit websocket server in background
server 127.0.0.1:5501;
## server 127.0.0.1:5502; ## add another server if you like!
check interval=3000 rise=2 fall=5 timeout=1000;
}
server {
server_name _;
listen 7070;
timeout 43200000;
websocket_connect_timeout 43200000;
proxy_connect_timeout 43200000;
so_keepalive on;
tcp_nodelay on;
websocket_pass websockets;
websocket_buffer 1k;
}
server {
server_name _;
listen 7080;
ssl on;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.key;
timeout 43200000;
websocket_connect_timeout 43200000;
proxy_connect_timeout 43200000;
so_keepalive on;
tcp_nodelay on;
websocket_pass websockets;
websocket_buffer 1k;
}
}
Just to note that nginx has now support for Websockets on the release 1.3.13. Example of use:
location /websocket/ {
proxy_pass http://backend_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
You can also check the nginx changelog and the WebSocket proxying documentation.
This worked for me:
location / {
# redirect all HTTP traffic to localhost:8080
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
-- borrowed from: https://github.com/nicokaiser/nginx-websocket-proxy/blob/df67cd92f71bfcb513b343beaa89cb33ab09fb05/simple-wss.conf