SealSkin

Nginx Proxy Manager

The two proxy hosts SealSkin needs in Nginx Proxy Manager, one for the web app and a wildcard one for the session names.

Run with Nginx Proxy Manager 2.16. Read Behind a reverse proxy first for the settings on the SealSkin side.

The session names, and the wildcard certificate that covers them, are for session isolation; without it the web app's name is all SealSkin needs, and the rule for the session names is harmless and may be left out.

Certificate

Under SSL Certificates, add a Let's Encrypt certificate for sealskin.example.com; with session isolation, one for example.com and *.example.com with Use a DNS Challenge, or upload a wildcard certificate as a custom one.

Two proxy hosts

Web appSessions
Domain Namessealskin.example.com*.example.com
Schemehttpshttps
Forward Hostname / IPsealskinsealskin
Forward Port84438443
Websockets Supportonon
Block Common Exploitsoffoff
SSL Certificatethe wildcard certificatethe wildcard certificate
Force SSLonon

Nginx Proxy Manager does not verify the certificate of an https upstream, so the self-signed one on the session port is fine. For the plain HTTP listener, set SEALSKIN_HTTP_PORT=8080 on SealSkin and use scheme http and port 8080 in both hosts.

The wildcard host takes every name under the domain that no other proxy host names, so your other hosts keep working: nginx prefers an exact name. A name that is neither a session's nor another host's reaches SealSkin too, which answers there as it does on its own name.

The hosts were run with Block Common Exploits off.

SEALSKIN_TRUSTED_PROXIES is the address of the Nginx Proxy Manager container on the network it shares with SealSkin.

Signing users in

To sign users in at SealSkin itself over OpenID Connect or SAML, with any provider of this section, the proxy hosts above need nothing more.

Forward-auth

Nginx Proxy Manager has no forward-auth switch; the web app host's Advanced tab takes the nginx configuration for one. This is Tinyauth's, with Tinyauth itself behind a third proxy host, tinyauth.example.com to http://tinyauth:3000:

location / {
    auth_request /tinyauth;
    error_page 401 = @tinyauth_login;
    auth_request_set $tinyauth_user $upstream_http_remote_user;
    auth_request_set $tinyauth_groups $upstream_http_remote_groups;
    proxy_set_header Remote-User $tinyauth_user;
    proxy_set_header Remote-Groups $tinyauth_groups;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_http_version 1.1;
    include conf.d/include/proxy.conf;
}
location /tinyauth {
    internal;
    proxy_pass http://tinyauth:3000/api/auth/nginx;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Uri $request_uri;
}
location @tinyauth_login {
    return 302 https://tinyauth.example.com/login?redirect_uri=$scheme://$http_host$request_uri;
}

A location / of your own replaces the one Nginx Proxy Manager writes, which is why it repeats the WebSocket lines and the include. The two proxy_set_header Remote- lines keep a visitor's own headers out. Leave the wildcard host for the sessions as it is, and set the sign-in headers on SealSkin as A proxy that signs users in describes.

The browser extension and the mobile app reach the node on raw paths the sign-in must leave alone (why; leave this out for a web-only deployment); add this location to the same Advanced tab, above location /:

# The companion apps, the sessions they open, and public share links: SealSkin signs these in itself.
location ~ "^/(companion/|public/|(ws/)?room/[0-9a-fA-F-]{36}|[0-9a-fA-F-]{36}/)" {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_http_version 1.1;
    include conf.d/include/proxy.conf;
}