1. Caddy version (caddy version
):
v2.1.1 h1:X9k1+ehZPYYrSqBvf/ocUgdLSRIuiNiMo7CvyGUQKeA=
2. How I run Caddy:
a. System environment:
CentOS Linux release 7.7.1908 (Core)
b. Command:
systemctl start caddy
c. Service/unit/compose file:
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target
[Service]
User=nginx
Group=nginx
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/caddy.conf
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/caddy.conf
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
d. My complete Caddyfile or JSON config:
{
"apps": {
"http": {
"servers": {
"my_server": {
"listen": [":60000"],
"automatic_https": {
"disable": true
},
"routes": [
{
"handle": [{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "192.168.185.70:80"
}
]
}]
}
],
"tls_connection_policies": [{
"match": {
"sni": ["SUBDOMAIN.DOMAIN.COM"]
}
}]
}
}
},
"tls": {
"certificates": {
"load_files": [{
"certificate": "/etc/caddy/ssl/SUBDOMAIN.DOMAIN.COM/fullchain.pem",
"key": "/etc/caddy/ssl/SUBDOMAIN.DOMAIN.COM/privkey.pem"
}]
}
}
}
}
3. The problem I’m having:
While this seems to work great for transparently adding encryption to my HTTP upstream server, I am having issues with websockets.
My upstream server is running Flask, with flask_socketio, which sets up a websocket between the browser and Flask. When I use caddy without all the SSL stuff (just to proxy HTTP connections), everything works fine. The web socket connects, and I have no issues.
With the caddy setup above, my websocket connects, and almost immediately disconnects. I see this:
From what I understand, the websocket connects, and since my server is configured to send a message to the browser immediately upon connection, that goes through (the Object { status: "SCRIPT_STATUS_COMPLETE"...
line). Then, for some unknown reason, the web socket is dropped almost immediately after that. No idea why.
It then tries to reconnect, reconnects, gets the message from the server, and disconnects again.
4. Error messages and/or full log output:
For errors on the browser, see above.
journalctl -u caddy
shows no errors. Neither does Flask.
Normally the all requests hit nginx on the upstream server before they get to flask, but I removed Nginx from the equation by making gunicorn, which is what runs my flask, bind directly to port 80, rather than a unix socket that talks to Nginx.
5. What I already tried:
I’m at a loss for what I can even look at.
Am I right to assume that in this scenario, the browser tries to establish the web socket using wss (rather than ws) because the web server is being provided as an HTTPS service, which caddy will than translate to an HTTP (ws) request before passing it on to the upstream server? It seems like if this was the problem, I wouldn’t get that initial connection and message from the server at all.