I’m currently playing around with client cert based auth on caddy.
But i keep getting 403 Error when i try to connect over the network (localhost somehow works.)
For “Bobs” cert, that is not signd with the correct CA I get the bad certificate response on both (localhost and remote). So I amuse the Alice cert is correctly signed.
When you try https://10.0.60.136:8080, what appears in Caddy’s log?
Edit: Also, try adding the -I flag to get header information which could be useful, i.e.: curl -I --insecure -E caCert/alice.p12 --cert-type p12 https://10.0.60.136:8080
This heavily implies that Caddy isn’t actually receiving this request. Especially if you’re getting a 403 - some web server is responding, but if it were Caddy, there would be an access log entry for this result.
Let us know what you get back from curl -I, it might tell us more about what you’re contacting at that IP address.
The https certificate I get back is the one create by caddy. Also https://10.0.60.136:8080 works without issues if I remove the clients caCert/ca.pem line.
This runs on an frech installation of rasbian on a Pi3. So there should be no other webserver running.
Hmm, that’s interesting. Might be worth investigating as a potential bug. I can’t think of any reason why a client certificate should work on localhost, but fail when accessed by IP address, generate a 403, and then not log it.
Sorry I’m late on this thread. It’s a good thing to ask about, and important to know if you’re using client auth. It should be documented better but sometimes I like to wait and see how it plays out in the wild before assuming I know how people will encounter a certain feature.
And yes, it’s a feature. Everything is working as expected.
When your site is protected with TLS client authentication, Caddy has to take some precautions to ensure it doesn’t expose a site that is protected by client auth to a client that is not authorized. This could happen in older versions of Caddy, but has since been fixed, and the fix is what you’re bumping up into here. Imagine two sites, A and B, both on the same port, where A is protected with client auth but B is not. An attacker simply crafts a TLS connection for B, sending B in the ServerNameIndication (SNI) extension. That handshake succeeds because B’s TLS configuration has no client auth. But then the HTTP request made through that connection sends A in the Host header of the request. That will get routed through A’s middleware chain. That’s bad, because client was not authorized for A; only B.
So, in the presence of client auth, the Host header must match the SNI value exactly.
If it doesn’t, Caddy responds with 403 Forbidden and closes the connection. Your log didn’t pick up that error because the request logger is chained into the middleware stack. The problem is, Caddy was unable to answer the question: “Which middleware stack should we execute?” because of the conflicting SNI and Host values. So it chose none of them as a security precaution, and thus no log was ever invoked. Sorry.
Ready for more fun? Clients don’t (and shouldn’t, according to spec) send IP addresses in SNI, because they are reserved specifically for server names, not addresses. That’s why localhost worked (it matches your site definition), but curl’ing with 10.0.60.136 did not: the SNI value is empty, which is not the same as wildcard server name (*).
It’s subtle, but it’s there for a good reason. Hope this helps.