Nginx Configuration for websocket: Error during WebSocket handshake: Unexpected response code: 403

raphy nginx-forum at forum.nginx.org
Thu Jun 10 10:14:03 UTC 2021


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.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,291828,291828#msg-291828



More information about the nginx mailing list