In order to use XMPP with websocket, and take advantage of nginx capabilities to proxy to 443 and to serve multiple domains, I've configured nginx as follows:
server {
listen 443 ssl http2 default_server;
server_name grasp.deals www.grasp.deals;
ssl_certificate /etc/letsencrypt/live/grasp.deals/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/grasp.deals/privkey.pem; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-
draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
access_log /var/log/nginx/graspdeals-access.log combined;
add_header Strict-Transport-Security "max-age=31536000";
location = /favicon.ico { access_log off; log_not_found off; }
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /weights {
root /home/raphy/www;
try_files $uri $uri/ =404;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Following is necessary for Websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /http-bind {
proxy_pass http://127.0.0.1:5280/http-bind;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
tcp_nodelay on;
}
location /xmpp-websocket {
proxy_pass http://127.0.0.1:5280/xmpp-websocket;
proxy_http_version 1.1;
proxy_set_header Connection "Upgrade";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900s;
}
}
server {
listen 81;
server_name grasp.deals www.grasp.deals;
location ~ ^/(websocket|websocket\/socket-io) {
proxy_pass http://127.0.0.1:4201;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwared-For $remote_addr;
proxy_set_header Host $host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
}
# https://prosody.im/doc/setting_up_bosh
location /http-bind {
proxy_pass http://127.0.0.1:5280/http-bind;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
tcp_nodelay on;
}
# https://prosody.im/doc/websocket#nginx
location /xmpp-websocket {
proxy_pass http://127.0.0.1:5280/xmpp-websocket;
proxy_http_version 1.1;
proxy_set_header Connection "Upgrade";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900s;
}
}
upstream golang-webserver {
ip_hash;
server 127.0.0.1:2000;
}
server {
root /puser/add;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-
draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
location / {
proxy_pass http://golang-webserver;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
server {
if ($host = grasp.deals) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = www.grasp.deals) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = conference.grasp.deals) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name grasp.deals www.grasp.deals conference.grasp.deals;
listen 80 default_server;
return 404; # managed by Certbot
}
server {
listen 443 ssl http2 ;
server_name conference.grasp.deals; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/grasp.deals/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/grasp.deals/privkey.pem; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-
draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
access_log /var/log/nginx/graspdeals-access.log combined;
add_header Strict-Transport-Security "max-age=31536000";
location = /favicon.ico { access_log off; log_not_found off; }
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /weights {
root /home/raphy/www;
try_files $uri $uri/ =404;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Following is necessary for Websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# https://prosody.im/doc/setting_up_bosh
location /http-bind {
proxy_pass http://127.0.0.1:5280/http-bind;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
tcp_nodelay on;
}
# https://prosody.im/doc/websocket#nginx
location /xmpp-websocket {
proxy_pass http://127.0.0.1:5280/xmpp-websocket;
proxy_http_version 1.1;
proxy_set_header Connection "Upgrade";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900s;
}
}
In the app I'm developing, when I switch from BOSH (http-bind), which works fine:
let [conn, setConn] = React.useState(new Strophe.Connection("https://grasp.deals/http-bind"));
to websocket:
let [conn, setConn] = React.useState(new Strophe.Connection("wss://grasp.deals/xmpp-websocket"));
I get this error:
WebSocket connection to 'wss://grasp.deals/xmpp-websocket' failed: Error during WebSocket handshake:
Unexpected response code: 403
I asked in the prosody XMM server chat, and I got this answer:
"take time to understand what nginx is doing in your setup, and what a reverse proxy is, and understand what service is listening on what ports"
So... I'm here to understand more about nginx configuration for websocket, and how to solve this problem "Error during WebWocket handshake".
Looking forward to your kind help and suggestions.