Dealing with nginx reverse proxy

My setup is pretty simple, so read the forum and also looked on the web and this is what I have so far

salas.dominio.edu.ar (Reverse proxy)

server_names_hash_bucket_size 64;

types {
        application/wasm     wasm;
}

server {
        listen 80;
        server_name salas.dominio.edu.ar;
        return 301 https://salas.dominio.edu.ar$request_uri;
}

server {
        listen 443 ssl http2;

        server_name salas.dominio.edu.ar;

        ssl_certificate /etc/letsencrypt/live/salas.dominio.edu.ar/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/salas.dominio.edu.ar/privkey.pem;

	ssl_session_cache builtin:1000 shared:SSL:10m;                        
	# Defining option to share SSL Connection with Passed Proxy
   
	# Mozilla Guideline v5.4, nginx 1.17.7, OpenSSL 1.1.1d, intermediate configuration
	ssl_protocols TLSv1.2 TLSv1.3;
	ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
	ssl_prefer_server_ciphers off;

	ssl_session_timeout 1d;
	ssl_session_cache shared:SSL:10m;  # about 40000 sessions
	ssl_session_tickets off;

	add_header Strict-Transport-Security "max-age=63072000" always;
	set $prefix "";

   
        ssl_dhparam /etc/ssl/dhparams.pem;

        #ssl_stapling on;
        #ssl_stapling_verify on;

        add_header Strict-Transport-Security "max-age=63072000" always;

        location /.well-known/acme-challenge {
                alias /var/www/html/.well-known/acme-challenge;
        }

        location / {
                proxy_set_header Host $host;		
		proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

		proxy_ssl_server_name on;

                proxy_pass https://INTERNAL-IP:443;

                # WebSocket support
		proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }

}

Jitsy server

server_names_hash_bucket_size 64;

types {
# nginx's default mime.types doesn't include a mapping for wasm
    application/wasm     wasm;
}

server {
#    listen 80;
    listen 443 ssl;
    server_name salas.dominio.edu.ar;

    set_real_ip_from SERVER-IP;
    real_ip_header X-Real-IP;

    set $prefix "";

    root /usr/share/jitsi-meet;

    # ssi on with javascript for multidomain variables in config.js
    ssi on;
    ssi_types application/x-javascript application/javascript;

    index index.html index.htm;
    error_page 404 /static/404.html;

    gzip on;
    gzip_types text/plain text/css application/javascript application/json image/x-icon application/octet-stream application/wasm;
    gzip_vary on;
    gzip_proxied no-cache no-store private expired auth;
    gzip_min_length 512;

    location = /config.js {
        alias /etc/jitsi/meet/salas.dominio.edu.ar-config.js;
    }

    location = /external_api.js {
        alias /usr/share/jitsi-meet/libs/external_api.min.js;
    }

    # ensure all static content can always be found first
    location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
    {
        add_header 'Access-Control-Allow-Origin' '*';
        alias /usr/share/jitsi-meet/$1/$2;

        # cache all versioned files
        if ($arg_v) {
            expires 1y;
        }
    }

    # load test minimal client, uncomment when used
    #location ~ ^/_load-test/([^/?&:'"]+)$ {
    #    rewrite ^/_load-test/(.*)$ /load-test/index.html break;
    #}
    #location ~ ^/_load-test/libs/(.*)$ {
    #    add_header 'Access-Control-Allow-Origin' '*';
    #    alias /usr/share/jitsi-meet/load-test/libs/$1;
    #}

    location ~ ^/([^/?&:'"]+)$ {
        try_files $uri @root_path;
    }

    location @root_path {
        rewrite ^/(.*)$ / break;
    }

    # Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
    location ~ ^/([^/?&:'"]+)/(.*)$ {
        set $subdomain "$1.";
        set $subdir "$1/";
        rewrite ^/([^/?&:'"]+)/(.*)$ /$2;
    }
}

But accesing internally I have a certificate error, and from the outside a 502 bad gateway. }

Any hint will be much appreciated.-

There are many mistakes

  • Lets Encrypt updates will not work if you redirect all TCP/80 requests to https

  • The certificate is not valid for INTERNAL-IP (I guess). So, the reverse proxy cannot communicate with the upstream

  • You should not redirect all requests like websockets

Here’s my updated conf. I can log in, start a room, but when someone joins the room it closes.

JITSI CONF

server_names_hash_bucket_size 64;

types {
application/wasm wasm;
}

server {
listen 80;
server_name DOMAIN;

set_real_ip_from RP-IP;
real_ip_header X-Real-IP;

set $prefix "";

root /usr/share/jitsi-meet;

ssi on;
ssi_types application/x-javascript application/javascript;

index index.html index.htm;
error_page 404 /static/404.html;

gzip on;
gzip_types text/plain text/css application/javascript application/json image/x-icon application/octet-stream application/wasm;
gzip_vary on;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 512;

location = /config.js {
    alias /etc/jitsi/meet/DOMAIN-config.js;
}

location = /external_api.js {
    alias /usr/share/jitsi-meet/libs/external_api.min.js;
}

location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
{
    add_header 'Access-Control-Allow-Origin' '*';
    alias /usr/share/jitsi-meet/$1/$2;

    if ($arg_v) {
        expires 1y;
    }
}

location ~ ^/([^/?&:'"]+)$ {
    try_files $uri @root_path;
}

location @root_path {
    rewrite ^/(.*)$ / break;
}

location ~ ^/([^/?&:'"]+)/(.*)$ {
    set $subdomain "$1.";
    set $subdir "$1/";
    rewrite ^/([^/?&:'"]+)/(.*)$ /$2;
}

}

RP CONF

server_names_hash_bucket_size 64;

types {
        application/wasm     wasm;
}

server {
        listen 80;
        server_name DOMAIN;
        server_tokens off; ## Don't show the nginx version number, a security best practice
        return 301 https://DOMAIN$request_uri;
}

server {
        listen 443 ssl http2;

        server_name DOMAIN;
        server_tokens off; ## Don't show the nginx version number, a security best practice

        ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem;

        ssl_session_cache builtin:1000 shared:SSL:10m;                        
   
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_prefer_server_ciphers off;

        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:10m;  # about 40000 sessions
        ssl_session_tickets off;

        add_header Strict-Transport-Security "max-age=63072000" always;
        set $prefix "";
   
        ssl_dhparam /etc/ssl/dhparams.pem;
        ssl_ecdh_curve secp384r1;

        location /.well-known/acme-challenge {
                alias /var/www/html/.well-known/acme-challenge;
        }

        location / {
                ssi on;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;

                proxy_pass http://JITSI-SERVER-IP/;

                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
        }

        location ~ ^/(?!(http-bind|external_api\.|xmpp-websocket))([a-zA-Z0-9=_äÄöÖüÜß\?\-]+)$ {
                rewrite ^/(.*)$ / break;
        }
        # BOSH
        location /http-bind {
                proxy_pass      http://JITSI-SERVER-IP:5280/http-bind;
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_set_header Host $http_host;
        }
        # xmpp websockets
        location /xmpp-websocket {
                proxy_pass http://JITSI-SERVER-IP:5280/xmpp-websocket;
                proxy_http_version      1.1;
                proxy_set_header        Upgrade $http_upgrade;
                proxy_set_header        Connection "upgrade";
                proxy_set_header        Host $host;
                tcp_nodelay             on;
        }

}

/etc/jitsi/videobridge/sip-communicator.properties :

#org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER=true
#org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=meet-jit-si-turnrelay.jitsi.net:443
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=JITSI-SERVER-IP
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=PUBLIC-IP
org.jitsi.videobridge.ENABLE_STATISTICS=true
org.jitsi.videobridge.STATISTICS_TRANSPORT=muc
org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=DOMAIN
org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.DOMAIN
org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb
org.jitsi.videobridge.xmpp.user.shard.PASSWORD=BhvR8YDg
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.auth.DOMAIN

Firewall stuff

Redirect LAN & WAN 443 to RP-IP
Redirect LAN UDP 10000 to JITSI-SERVER-IP

Created a pad with the logs

After restart all services could connect 4 users to test, everything was fine but the video quality was very low

Did you check you browser console for errors?

think you should check whether your foo.com is pointing to the right ip address or not first by removing the reverse proxy config. E.g.

http {
    server {
        listen 80;
        server_name foo.com;

        location / {
        }
    }
}

Then, if your ip address already has a service running on port 80 you should specify the server_name for each service like in my example. Nginx can only distinguish which service to respond to which domain by server_name .

*My guess is that you forgot the server_name option.