lnbits / nostrclient

MIT License
22 stars 9 forks source link

Websocket Not Accessible Behind Nginx Reverse Proxy #15

Open pardus79 opened 1 year ago

pardus79 commented 1 year ago

Nginx setup per https://github.com/lnbits/lnbits/blob/main/docs/guide/installation.md#running-behind-an-nginx-reverse-proxy-over-https appears to block the websocket for this extension so you can't connect to it from an outside Nostr client.

This is the fix that worked for me:

Add the following to the http block in your nginx.conf file:

http {
    upstream website {
        server 127.0.0.1:5000;
    }

    upstream websocket {
        server 127.0.0.1:5000;
    }
}

Then make your vhost file under sites-enabled look like this, substituting your site url:

server {
    listen 80;
    server_name lnbits.org;
    return 301 https://lnbits.org$request_uri;
}

server {
    listen 443 ssl;
    server_name "your site url";

    ssl_certificate /etc/letsencrypt/live/lnbits.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/lnbits.org/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://website;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /nostrclient/api/v1/relay {
        proxy_pass http://websocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Reboot Nginx and you should have access to your wallets, the websocket and nginx will force https.

Perlover commented 1 year ago

I have a following config and I think it's better:

map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
}

server {
        index  index.php index.html index.htm;
        server_name lnbits.YOURDOMAIN.com;

        error_log /var/log/nginx/lnbits.YOURDOMAIN.com_error.log;
        access_log /var/log/nginx/lnbits.YOURDOMAIN.com_access.log;

        location / {
                proxy_pass "http://localhost:5000/";
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_http_version 1.1; # Ensures that replies are re-written to lnbits.yourdomain.com (as opposed to the private IP or .onion)
        }
        location ~ /\.ht {
            deny all;
        }

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/lnbits.YOURDOMAIN.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/lnbits.YOURDOMAIN.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

I have this configuration working with and without a websocket. That is, it is universal. There is no binding to location. If the client requests a websocket, there will be a websocket, if regular HTTP, it will be HTTP 1.1. I would recommend this configuration, because you do not need to prescribe all the potential locations for websocket.