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

Closed
opened 2025-11-20 04:19:58 -05:00 by saavagebueno · 13 comments
Owner

Originally created by @eddyg on GitHub (Dec 22, 2020).

Originally assigned to: @qdm12 on GitHub.

  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!

Originally created by @eddyg on GitHub (Dec 22, 2020). Originally assigned to: @qdm12 on GitHub. 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. 2. 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!
Author
Owner

@qdm12 commented on GitHub (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.

@qdm12 commented on GitHub (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.
Author
Owner

@eddyg commented on GitHub (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...)

@eddyg commented on GitHub (Jan 20, 2021): I'm not sure... a quick search found [this page](https://developers.google.com/speed/public-dns/docs/isp) (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...)
Author
Owner

@qdm12 commented on GitHub (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 commented on GitHub (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.
Author
Owner

@qdm12 commented on GitHub (Mar 13, 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.

@qdm12 commented on GitHub (Mar 13, 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.
Author
Owner

@eddyg commented on GitHub (Mar 13, 2021):

Yup, CH is the Chaos class.

@eddyg commented on GitHub (Mar 13, 2021): Yup, `CH` is the [Chaos](https://miek.nl/2009/july/31/dns-classes/) class.
Author
Owner

@qdm12 commented on GitHub (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 https://github.com/miekg/dns/issues/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 commented on GitHub (Mar 14, 2021): Cool thanks for the link. Never thought such thing existed. I asked on [Reddit](https://www.reddit.com/r/golang/comments/m4vjf5/dns_resolver_for_ch_chaosnet_class_records/?utm_medium=android_app&utm_source=share) 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 https://github.com/miekg/dns/issues/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!
Author
Owner

@qdm12 commented on GitHub (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 commented on GitHub (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.
Author
Owner

@qdm12 commented on GitHub (Mar 21, 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! 😄

@qdm12 commented on GitHub (Mar 21, 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! 😄
Author
Owner

@eddyg commented on GitHub (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
@eddyg commented on GitHub (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: ```json { "settings": [] } ``` and I'm only setting these environment variables: ```yaml environment: - LOG_LEVEL=debug - PUBLICIP_FETCHERS=dns ```
Author
Owner

@qdm12 commented on GitHub (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 commented on GitHub (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.
Author
Owner

@qdm12 commented on GitHub (Mar 22, 2021):

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

@qdm12 commented on GitHub (Mar 22, 2021): It's now merged in `:latest`, feel free to continue discussing about it here and I'll get notified. Cheers!
Author
Owner

@eddyg commented on GitHub (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! 🎉

@eddyg commented on GitHub (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! 🎉
Author
Owner

@qdm12 commented on GitHub (Mar 22, 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.

@qdm12 commented on GitHub (Mar 22, 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 in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/ddns-updater#83