I have installed a Let’s Encrypt certificate in Synology for domain nas.flyingnobita.com (because I couldn’t get Caddy to automatically get a cert for this subdomain for some reason. Caddy gets certs fine for all other subdomains in the Caddyfile)
I’m trying to connect to the NAS web login page with HTTPS but I’m getting the errors below.
4. Error messages and/or full log output:
curl -v https://nas.flyingnobita.com
# shortened for clarity
400 The plain HTTP request was sent to HTTPS port
400 Bad Request
nginx
curl -v https://nas.flyingnobita.com:5001
# or
curl -v http://nas.flyingnobita.com:5000
# shortened for clarity
Sorry, the page you are looking for is not found.
Synology
So it seems that the response from both is coming from Synology which means that it’s at least reaching there somewhat. But obviously, not everything is working.
5. What I already tried:
inside Synology, disable switching HTTP connections to HTTPS
inside Cloudflare tried but none worked:
switching to different SSL/TLS encryption mode
usually is Full(strict)
tried all other modes e.g. Off, Flexible, Full
switching subdomain from Proxied to DNS Only
I have been running this setup with Caddy for >1 year and all other subdomains are working (they have different requirements of course)
What works:
port forward 80/443/5001 to NAS internal IP and in browser connect to NAS login page at https://nas.flyingnobita.com
port forward 5001 to NAS internal IP and in browser connect to <EXTERNAL_IP:5001>
I get a certificate error (expected, as it’s IP and not the domain that the cert is issued for) that I can ignore and login
Okay, so Caddy is properly proxying the request. In that case, that means you’re proxying Caddy to the wrong port. Your NAS must have two ports it’s serving content on, an HTTP and an HTTPS port. Use the HTTP port instead.
Now that I got it to work, I’m curious and would like to ask more questions, if I may:
I thought I configured NAS port 5001 as the HTTPS, and then NAS port 5000 as HTTP. I checked that this seems the case when I connect it locally with the IP address.
Why is it that caddy requires the reverse proxy to use HTTP port?
Caddy isn’t able to automatically retrieve and manage the HTTPS certificate for me for this subdomain, any idea on why this is?
It doesn’t require it, but it’s simplest, and still secure. Since the connection is happening within your network, if you trust all the machines on your network, then it’s safe. See this topic for an explanation:
If you must use HTTPS to proxy, then use https:// in your upstream address to tell Caddy to try to connect with TLS to the upstream.
The issue with proxying over HTTPS is typically trust. If your upstream doesn’t have a trusted certificate (i.e. issued by a well-known public CA) then Caddy can’t trust it and won’t complete the TLS handshake… unless you throw away all security by using tls_insecure_skip_verify transport option, which is “just as secure” as HTTP, as in, not at all. So might as well use HTTP if you don’t want the headache of managing trust internally.
Any logs? I see no evidence of that. If you’re able to connect to https://nas.flyingnobita.com with a successful response from Caddy, then you do have a certificate for that domain.
Thank you for your detailed explanation. It really helps me in understanding how Caddy works and increase my networking understanding, and points me in the right direction for further research!
I was thinking that entering https://nas.flyingnobita.com would be sufficient. Is that what you mean by upstream? And yes I agree that I don’t need https in my own LAN (which is also the case for my other self-hosted services).
The logs don’t mention anything about getting a certificate for this subdomain. But this might be because I already manually installed a certificate in the NAS (which I did to troubleshoot the connection problem that is now solved). I guess a good test would be to remove that certificate and see what Caddy does. Though the NAS is in heavy use now since it is working so I can’t risk it not working, I guess I’ll have to come back to this test.
By “upstream” I’m talking about the first argument to reverse_proxy. The “upstream” is the thing that Caddy sends the request to, when proxying.
So instead of reverse_proxy 192.168.1.13:5001, you might do reverse_proxy https://192.168.1.13:5001. But like I said, this likely wouldn’t work as-is, you’d need to make sure the correct Host header is sent (since the upstream server probably picks the certificate to use based on the Host header or SNI) and then you’d need to deal with the issue of trust, like I wrote earlier.
Caddy probably issued the cert for nas.flyingnobita.com in an earlier run. It won’t log issuance if issuance doesn’t happen. And renewal only happens after 2/3 of the lifetime of the cert, i.e. 90 day lifetime, so after 60 days a renewal is attempted. You could look in Caddy’s storage location to find the certificate/key, i.e. in /home/user/caddy/data, your docker volume for /data.
Yep, you could do that. Don’t delete it too often though cause you could hit Let’s Encrypt rate limits (but it’s pretty hard to hit the rate limits, they’re pretty generous Rate Limits - Let's Encrypt and as an aside ZeroSSL has no rate limits).
I didn’t know this was possible. Thanks for pointing this out. And yes it didn’t work for me as you said.
I did find a setting to customize the server header. I’ll need to investigate more on this to (probably w/ the Synology guys) to see how best to do this.