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.154.15:80"
}
]
}]
}
],
"tls_connection_policies": [{
"match": {
"sni": ["subdomain.domain.com"]
}
}]
}
}
},
"tls": {
"certificates": {
"load_files": [{
"certificate": "/etc/ssl/subdomain.domain.com/fullchain.pem",
"key": "/etc/ssl/subdomain.domain.com/privkey.pem"
}]
}
}
}
}
3. The problem I’m having:
I run a Django server on the same system that Caddy is running on.
When users connect to my server, and login, they have a list of remote systems they have access to. When they select a remote system and want to connect to its web interface, my Django:
- Uses the Caddy API to setup a reverse proxy to that system’s web interface on an unused port (ex port 4000)
- Tells the user’s browser to go to subdomain.domain.com:4000.
This works, and lets the user interact with the remote system’s web interface through my Django website. It does have a few disadvantages though:
- I need a unique port for every remote system actively in use
- This is not ideal, but my Django website does not currently, nor will it ever have enough simultaneous users for me to run out of ports
- Security
- If a user sees that they are connecting to subdomain.domain.com:PORT, and simply guesses a different PORT number, they’ll connect to a system they don’t own
Is there a better way to do this?
I’m thinking that:
- If Caddy has something similar to Nginx’s concept of Internal paths, where it won’t load a resource for a user unless Django specifically allows it, this would solve my security issue
- I could use domain names instead of ports to match on, and a wildcard SSL cert, which would solve my first problem of using one port per remote system
- Unfortunately our DNS provier (Network Solutions) does not appear to be supported by DNS challenge, which is the only way to get a wildcard cert (as far as I can tell). I can’t write Go to make a module to support them, and even if I could, they don’t have an API to update TXT records (I asked them)
Does Caddy have a concept of internal resources like Nginx does? Anything else I can do? Any suggestions would be appreciated.