-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Standalone mode does not bind to ipv6 #1466
Comments
At the moment the server won't connect over IPv6 to perform validation, either. So this feature request is blocked (or at least not useful) until this boulder ticket is resolved. |
Subticket of #180 |
While I do see where you are coming from, I have to disagree with you. Having the client listen on ipv6 is relevant right now because of NAT64. What is NAT64, you may ask? At the very least, I do appreciate that you guys may look at this eventually. |
Have you tried running the client under your setup? I don't think there is anything in the code that stops us from "binding" to IPv6. If there is, then please paste the traceback. |
There is no error, it's just not binding/listening on ipv6. Basically, it seems to be listening on 0.0.0.0 but not :: (aka, it's listening on all ipv4 ips, but not all ipv6 ips) (I gathered this information with netstat). Now, from taking a cursory glance at the code I can spot why it does this. As an example, here is my modified version of the python SimpleHTTPServer command manual mode has you run (I added some spacing for clarity):
Interestingly enough, it does seem that python implements "accepting ipv4 over ipv6". What does this mean? Well, if you run this and then check netstat you'll find it's listening on :::80 (port 80 on ::), which means that technically it's only listening on ipv6. BUT ipv6 has this neat socket option called IPV6_V6ONLY (yes, I'm diving a little into the python internals here). Basically, turning this option off (which python does) allows an ipv6 socket that binds to :: (all ips/the ipv6 equivalent to 0.0.0.0) to accept both ipv6 and ipv4 connections. The only real difference here is that the ips in use are ipv6 and that ipv4 ips are "mapped" to ipv6 ips in a way similar to what NAT64 does. Although it uses ::ffff: as the prefix rather than 64:ff9b:: So both
Both calls returned the expected data. (For reference to people who've never seen ipv6 before, ::1 is the ipv6 equivalent of 127.0.0.1. Also, I need a shirt that says "No place like ::1".) I hope this clarifies things a bit/helps. |
I don't get why this is an "enhancement" since it can lead to all sorts of problems and weird failures on IPv6 enabled machines, like for my setup (which has perfectly working IPv4 connectivity, by the way):
Boom, broken. Would easily work if it had bound to ::0 instead of 0.0.0.0 which should be a one line change.. Edit: .. and while I could replace "localhost" with "127.0.0.1" in my proxy config, this is also a bad workaround in the long term because once let's encrypt actually supports IPv6 and uses that to reach out from the ACME server to me, I would assume it can trigger new obscure problems - so I'm basically setting myself up for future problems. Therefore, this really should be fixed in the standalone mode as soon as feasible before everyone is forced to bork their configs to work around this. Edit 2: treat example above with care, since I just found out silly me also broke something else in my setup which is possibly the culprit. However, "localhost" does indeed resolve to "::1" on my machine. And listening to IPv6/IPv4 is pretty easy: just choosing ::0 will usually get you a dualstack socket that listens to both |
With IPv6 support in Let's Encrypt, we should try to get this issue resolved quickly. |
I confirmed that
does not end up listening on IPv6 interfaces. Following the comment above at #1466 (comment), apparently it might be sufficient to add
at line 28 of |
Perhaps we could do something like
The theory is that if the system is unable to create |
To see the plausibility that this solution will work, note the error from something like |
Confirms the solution works! Without the patch my ipv6-only site cannot be reached by letscrypt server and it reports a TLS-SNI-01 error; with it everything works OK. |
Is there already a way to create or renew a certificate for the IPv6 address of a dualstack machine only even if there are A and AAAA records?
|
Does someone want to open a pull request containing the reported solution here? |
Made one PR in #3369 |
Added support for using IPv6 sockets if possible. As part of this, I also had to fix crypto_util.probe_sni() to use ('', 0) as the default source address, instructing python to use the system default source. The previous value ('0', 0) was interpreted as the IPv4 address 0.0.0.0. Closes certbot#1466
Assuming no outside contributor picks this up, this issue probably won't make our 0.11.0 release, but I'm planning on working on this myself for 0.12.0. As of right now, those two releases are scheduled for February 1st and March 1st respectively. |
There have been two PRs attempting this: #3369 and #3687. #3369 was a very small fix, which set, in the server classes:
It had two problems: It was failing unittests, and it wouldn't work on (a) OS's that don't support IPv6 (note: different from instances that lack an IPv6 interface), and (b) Python versions compiled without IPv6. I am still hopeful that such an approach could work. For instance, could we wrap the assignment to address_family in a |
Currently the best approach we're aware of is attempting to get both an IPv4 and an IPv6 socket, configuring the IPv6 socket to only get IPv6 traffic. There is some discussion of this in #3687. |
Aha, I had missed this specific comment: #3687 (comment) seems to indicate an additional reason #3369's small fix wouldn't work: It would break on FreeBSD and OpenBSD based on this stackexchange answer. |
FYI, we recently had an issue with Let's Encrypt where IPv6 validation was failing some of the time. Since we use Certbot for an end-to-end testing / monitoring tool, we might have caught this earlier if Certbot was able to handle IPv6 in standalone. So consider this a friendly request to bump priority a bit. :-) |
Maybe a intermittent solution could be to have a parameter that tells the program to bind to IPv6, for example -6? |
I think in general we should require a pretty high bar for adding new flags. In most cases, just binding to both is enough, and we have a plan for how to do that. So I think that's a better approach than adding a new flag. BTW, I talked to @ohemorange offline and she's committed to implementing this soon. |
Changing this to standalone because there's a separate PR out there for manual |
As far as I can tell, the letsencrypt client does not bind to ipv6 in standalone mode nor do the commands given in manual mode. While this may not seem too significant, but for people with ipv6 only machines (like me) this is quite a big problem. My suggestion would be to somehow bind to both ipv4 and ipv6 at the same time.
Either way, what you're doing is a great service to the global internet community, keep on rocking!
The text was updated successfully, but these errors were encountered: