Skip to content
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

Feature request: use DNS queries instead of HTTPS requests to determine IP address #136

Closed
eddyg opened this issue Dec 22, 2020 · 13 comments
Assignees

Comments

@eddyg
Copy link

eddyg commented Dec 22, 2020

  1. What's the feature?

Instead of making HTTP(S) requests to various "services", it would be nice to just be able to query special DNS addresses that return your V4/V6 address.

  1. Extra information?

For example, these queries return your current IPv[46] address by just making a quick, UDP DNS query to Google. No TCP connection setup, no TLS negotiation, etc.:

dig -4 TXT +short o-o.myaddr.l.google.com @ns1.google.com
dig -6 TXT +short o-o.myaddr.l.google.com @ns2.google.com

This uses CloudFlare:

dig -4 TXT CH +short whoami.cloudflare @one.one.one.one
dig -6 TXT CH +short whoami.cloudflare @one.one.one.one

OpenDNS has one as well (but it doesn't seem to work with -6 for V6 queries):

dig -4 +short myip.opendns.com @resolver1.opendns.com

There may be other providers that respond similarly.

I'd prefer using this DNS-based approach to determine my address instead of relying on some HTTP-based service.

Thanks!

@qdm12
Copy link
Owner

qdm12 commented Jan 20, 2021

Will do that very soon, would you by any chance know if these are rate limited? If not, that would allow for sub-second checks and we wouldn't need the PERIOD setting anymore.

@eddyg
Copy link
Author

eddyg commented Jan 20, 2021

I'm not sure... a quick search found this page (which is about ISPs that want to use Google's DNS service) and it says:

Your per-IP address QPS rate is less than 1000 QPS
You can configure Google Public DNS however you like; you do not need to request a rate limit increase.

(Even so, sub-second queries seem very aggressive to me. Abusing a free resource is a good way to have it limited at some point in the future. Checking it even once a minute seems plenty fast for DDNS purposes, IMO...)

@qdm12
Copy link
Owner

qdm12 commented Jan 20, 2021

Oh yes for home users (and me) this is enough. You're right leaving the PERIOD is a good idea. I had one user who needed high uptime and was looking for something checking every few seconds. But thanks for the research, I'll try to do it tonight.

@qdm12
Copy link
Owner

qdm12 commented Mar 14, 2021

It works for Google but not for Cloudflare, my guess being because of the CH in dig -4 TXT CH +short whoami.cloudflare @one.one.one.one. Do you have any idea what that CH is for?

EDIT: Seems to be the Q Class of the record, I'll check out if Go supports such CH q class instead of the default IN class.

@eddyg
Copy link
Author

eddyg commented Mar 14, 2021

Yup, CH is the Chaos class.

@qdm12
Copy link
Owner

qdm12 commented Mar 14, 2021

Cool thanks for the link. Never thought such thing existed. I asked on Reddit as I'm struggling to implement that. We might have to only support Google for now.

EDIT: Some progress, trying to use miekg/dns but I'm waiting on miekg/dns#1240 as I need to be able to use their DNS client over both udp4 and upd6 for dual stack (ipv4+ipv6) systems.

EDIT 2: Found the solution to that issue, using miekg/dns now. Cloudflare should be working soon as well!

@qdm12
Copy link
Owner

qdm12 commented Mar 14, 2021

Alright it's working for both Google and Cloudflare 👍 I'll let it be for a few days for a reviewer to review, it should finally be done around next weekend. Thanks for the suggestion again, it's a nice addition. Maybe that can also allow for faster detection of IP address changes, since it takes around ~20ms (and a higher or no rate limiting I suppose) compared to HTTP which takes ~200ms or more and is rate limited / a paid service depending on the website.

@qdm12
Copy link
Owner

qdm12 commented Mar 22, 2021

Hey @eddyg it's finally alive!!

Can you please try the image ddns-updater:publicip-options? You can set the environment variable PUBLICIP_FETCHERS=dns to only use DNS. By default it cycles between the DNS ip echo providers Cloudflare and Google.

If you don't pass any environment variables, it should cycle between each fetcher (http and dns) and between each provider for each fetcher.

Note: It's late and I'm tired, please forgive if it doesn't work the first try! 😄

@eddyg
Copy link
Author

eddyg commented Mar 22, 2021

Thanks so much for working on this! 👍 I think this is a much better solution than establishing a new TLS connection to a web site every few minutes!

Do I need to have a dynamic DNS provider configured to just periodically query my IPs? When I start the container, I get:

2021/03/22 12:50:27 DEBUG configured to fetch IP: v4 or v6: false, v4: false, v6: false
2021/03/22 12:50:27 DEBUG your public IP address are: v4 or v6: <nil>, v4: <nil>, v6: <nil>
2021/03/22 12:55:27 DEBUG configured to fetch IP: v4 or v6: false, v4: false, v6: false
2021/03/22 12:55:27 DEBUG your public IP address are: v4 or v6: <nil>, v4: <nil>, v6: <nil>

every 5 minutes. 🤔

My config.json is simply:

{
    "settings": []
}

and I'm only setting these environment variables:

    environment:
      - LOG_LEVEL=debug
      - PUBLICIP_FETCHERS=dns

@qdm12
Copy link
Owner

qdm12 commented Mar 22, 2021

Ah that's an interesting bug 😉 Which is also a feature I guess?

Because you have no settings configured, the program sees you don't need to update any ipv4 or ipv6 or ipv4/ipv6 records so it doesn't fetch your public IP address at all. So every period (5m by default), it checks the settings it has and see there is no public IP address to go fetch for the purpose.

God this is some nice feature actually 😄
Anyway, try with a record? You can try by creating a free record on duckdns.org for example if you want.

EDIT: I ran it on my container during the night and no errors so far, I think this is good to go! Just need to add a bit of documentation before merging.

@qdm12 qdm12 closed this as completed in 8b2e83a Mar 22, 2021
@qdm12
Copy link
Owner

qdm12 commented Mar 22, 2021

It's now merged in :latest, feel free to continue discussing about it here and I'll get notified. Cheers!

@eddyg
Copy link
Author

eddyg commented Mar 22, 2021

Ah, I see. I thought that might be the case.

It's kind of unfortunate, though. It would be really nice to be able to run this without a provider but still log (and get notifications) when your IP changes. In some cases, IPs change infrequently enough that updating them manually isn't a huge deal, and then you don't need to deal with/depend on a separate dynamic DNS provider.

Thanks again for implementing this feature! 🎉

@qdm12
Copy link
Owner

qdm12 commented Mar 23, 2021

I'll see what I can do. Anyway the mechanism should be reworked for #184 so you wouldn't have to specify the ip version you want. In that case, I think it would get your public IP address on every period if you have no record.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants