-
-
Notifications
You must be signed in to change notification settings - Fork 43
Reverse Proxy and Subfolder Deployment
WebSSH uses regular HTTP routes plus Socket.IO/WebSocket traffic. A reverse proxy must preserve the public origin and support connection upgrades.
For one trusted proxy layer:
CORS_ORIGINS=https://ssh.example.com
SESSION_COOKIE_SECURE=true
TRUSTED_PROXIES=1TRUSTED_PROXIES is the number of trusted forwarding layers, not a Boolean.
Keep the WebSSH backend reachable only through those layers.
location / {
proxy_pass http://webssh:5000;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}labels:
- "traefik.enable=true"
- "traefik.http.routers.webssh.rule=Host(`ssh.example.com`)"
- "traefik.http.routers.webssh.tls.certresolver=letsencrypt"
- "traefik.http.services.webssh.loadbalancer.server.port=5000"ssh.example.com {
reverse_proxy webssh:5000
}For a public URL such as https://server.example.com/webssh, configure:
APPLICATION_ROOT=/webssh
TRUSTED_PROXIES=1
CORS_ORIGINS=https://server.example.com
SESSION_COOKIE_SECURE=trueThe reverse proxy must strip /webssh before forwarding the request and send
the original prefix as X-Forwarded-Prefix.
location /webssh/ {
proxy_pass http://webssh:5000/;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /webssh;
}The trailing slash in both location and proxy_pass is intentional.
labels:
- "traefik.enable=true"
- "traefik.http.routers.webssh.rule=Host(`server.example.com`) && PathPrefix(`/webssh`)"
- "traefik.http.middlewares.webssh-strip.stripprefix.prefixes=/webssh"
- "traefik.http.middlewares.webssh-prefix.headers.customrequestheaders.X-Forwarded-Prefix=/webssh"
- "traefik.http.routers.webssh.middlewares=webssh-strip,webssh-prefix"
- "traefik.http.services.webssh.loadbalancer.server.port=5000"server.example.com {
handle_path /webssh/* {
reverse_proxy webssh:5000 {
header_up X-Forwarded-Prefix /webssh
}
}
}When the proxy runs in Docker:
- Attach WebSSH and the proxy to a private shared network.
- Remove public port publishing from WebSSH.
- Proxy to
webssh:5000over the private network. - Set
TRUSTED_PROXIESto the real number of trusted layers.
Do not publish 5000:5000 in parallel with the HTTPS proxy. That would allow
clients to bypass TLS and possibly the trusted-proxy boundary.
If login works but terminal activity disconnects or never starts:
- confirm HTTP/1.1 on the upstream connection;
- confirm
UpgradeandConnectionforwarding; - inspect browser network requests to
/socket.io/; - check that the proxy timeout accommodates long-lived connections;
- verify that the prefix is applied consistently for both HTTP and Socket.IO;
- verify
CORS_ORIGINSexactly matches the browser-visible origin, including the scheme and non-default port.
WebSSH uses forwarded addresses only within the configured proxy trust depth. An incorrect value can either record the proxy address instead of the client or trust attacker-supplied forwarding headers. Prefer a simple topology and keep the backend network private.
curl -I https://ssh.example.com/
curl -fsS https://ssh.example.com/health
curl -fsS https://ssh.example.com/readyFor a subfolder:
curl -I https://server.example.com/webssh/
curl -fsS https://server.example.com/webssh/health
curl -fsS https://server.example.com/webssh/readyComplete the check in a browser by logging in, opening a terminal, resizing it, and transferring a small file.
WebSSH documentation - Project - Issues - Discussions - Security
WebSSH Wiki
Install and operate
- Installation from Source
- Docker and Docker Compose
- Production Deployment
- Reverse Proxy and Subfolder Deployment
- Upgrading, Rollback, and FAQ
Identity and access
- Users and Account Management
- Authentication Overview
- LDAP and Active Directory
- OpenID Connect
- Passkeys and Recovery Codes
SSH and files
- SSH Connections and Host Keys
- Profiles, Jump Hosts, and Commands
- Terminal and Persistent tmux Sessions
- SFTP File Workspace and Transfers
- Tailscale SSH
Reference and administration