-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reject request with IP address as hostname (unless defined in Caddyfile) #2068
Comments
PS: The |
Well, I cannot answer your question directly, but I don't think this can be accomplished at the moment if you are using let's encrypt due to certificate transparency logs. It is pretty easy to use the public logs to find every subdomain of a domain using let's encrypt unless you use the new wildcard certificates (which caddy does not support yet). |
What kind of configuration do you use on other web servers to accomplish this? A "well-behaving" server, in the absence of SNI, will use a "default" certificate (presumably the only one) to serve the connection. And yes, certificate transparency will undermine most of the secrecy you are hoping to gain. (It's still a good thing.) |
I haven't tried this before and don't know how to do it with a different httpd. Can you point me to any standard that specify how a "well-behaving" server is not allowed to reject HTTPS request without SNI? My goal is not to hide my server from someone who is looking for it - that would be enormously difficult. I only wish to hide from someone who is performing a (possibly automated) port scan over an entire IP range. If he gets a response (in form of a certificate for a domain name), he may try something else with that information; if he's rejected right away, he (or the automated scan process) may simply move on. The fact that Let's Encrypt would reveal the domain name is not relevant here. I could simply switch to another CA that doesn't have public logs - problem solved (at least that part of the problem). |
While I personally don't believe this kind of secrecy is important or effective against malicious port scans or crawlers, you could prevent "leakage" of valid domains served at an IP address via certificate names by specifying a site label in Caddy for that IP address as a host and using a self-signed certificate.
A HTTPS request to this site should return something like:
This is alongside another site with a current valid LetsEncrypt certificate. |
@whitestrake Yes, I thought about this, but it won't work if my server has a dynamic external IP. Now, I'm not sure hiding the certificate would be an effective security measure, either. But one of the basic principles of information security is that you shouldn't reveal information unnecessarily. In this case, there is no good reason why a well-intentioned, legitimate client would use the IP address instead of the domain name in its request. Therefore, giving him the certificate is unnecessary, and bad. How bad in practical terms, and how much better it would be not to give him that, does not change the principle nature of the issue. How many security measures have been broken through a combination of seemingly unimportant pieces of information that all should have been kept secret? Keyword "metadata", anyone? |
Haven't tested this one, but I think this would work the same?
Should catch every single HTTPS host that isn't otherwise defined in your Caddyfile. |
@whitestrake Yes, this works for me! |
I wonder if this would also work, if the server is otherwise setup to reject all (unencrypted) HTTP requests:
(I can't test this right now since I have an unrelated problem on my server.) |
Don't forget If you're rejecting HTTP requests, then redirecting to HTTP makes less sense since you're almost guaranteeing a repeat visit (that will only get rejected anyway) and you're sending more bytes (as a location header). Might as well just give them the 403 and end it there. |
We kind of did this in 0.10.11 but it broke quite a few legit reasons for not having valid SNI -- I need to revisit it later, and as you can see, there is a workaround. Thanks for the discussion! |
I'm looking at #2037 (which seems to be the exact opposite of what I want) and wondering: Is it possible (and legitimate) for Caddy to generate (intentional) invalid TLS certificates on the fly, in order to tell the client (by triggering a TLS error) that something is wrong with its request? In other word, in addition to |
Or better still, how about a |
@henrypijames That's possible, I think. Can you open a new issue to discuss it? Just state exactly your situation and what you want to achieve, and if possible how you'd like it to happen. |
@mholt Yes, will do (shortly). |
1. What version of Caddy are you using (
caddy -version
)?0.10.11
2. What are you trying to do?
Serve a HTTPS host that only answers to a specific domain name, while rejecting all other requests and not revealing the very existence of that domain name to anyone who isn't explicitly asking for it
3. What is your entire Caddyfile?
4. How did you run Caddy (give the full command and describe the execution environment)?
/usr/local/bin/caddy -log stdout -agree=true -conf=/etc/caddy/Caddyfile -root=/var/tmp
5. Please paste any relevant HTTP request(s) here.
curl https://1.2.3.4 # literal IP address of domain.example.com
6. What did you expect to see?
Caddy rejecting the request during TLS server hello, since there is no host defined for the literal IP address, and not revealing the domain name of any host it is serving
Preferably, there should be an option to reject any client request for a literal IP address (note that SNI spec does not allow literal IPv4 or IPv6 address to be used in SNI), reject any client request for a domain name but without SNI, and reject any client request for a domain name with SNI but not matching any of the domain names explicitly defined in the Caddyfile
7. What did you see instead (give full error messages and/or log)?
Caddy accepting the request, finishing the TLS server hello and then sending the TLS certificate of domain.example.com to the client, thus revealing that it is serving a host at that domain name
In other words, Caddy is leaking the domain name (which cannot be acquired through reverse DNS from the IP address) to anyone who is scanning the HTTPS port of the server
8. How can someone who is starting from scratch reproduce the bug as minimally as possible?
See above
The text was updated successfully, but these errors were encountered: