0xERR0R / blocky

Fast and lightweight DNS proxy as ad-blocker for local network with many features
https://0xERR0R.github.io/blocky/
Apache License 2.0
4.66k stars 205 forks source link

iOS ignores `customDNS` responses when Extended DNS Errors (EDE) are enabled #1273

Open ouldsmobile opened 10 months ago

ouldsmobile commented 10 months ago

I am testing out Blocky on my home network. Fairly straight forward setup, basically just using default config modified to suit my environment. I do use the customdns feature for local reverse proxy. All is well except on my iphone. When trying to hit my internal web apps. I get a "blocked by null" error using by chrome and safari on the iphone. I tested same sites using PC, Android Phones, and even an ipad(to rule out an iOS issue of some kind). Same sites are all working on any other device except my iphone. I also have technitium setup on my network as I was testing both out to see which I preferred. If I switch the iphone over to technitium the problem seems to go away and I can browse my internal apps without issue. So it's not specifically the iphone or blocky causing the issue, seems to be a combination of the two.

I also tried paring down the config to just the basics i.e. removing the blocking/whitelist section etc. No change.

Here's my block config(redacted my domain name and ip's):

upstreams:
  groups:
    default:
      - tcp-tls:1.1.1.1:853
      - tcp-tls:1.0.0.1:853
  strategy: parallel_best
  timeout: 2s

startVerifyUpstream: true

connectIPVersion: dual

customDNS:
  customTTL: 1h
  filterUnmappedTypes: true
  mapping:
    example.com: 192.168.x.201

blocking:
  blackLists:
    ads:
      - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
      - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
      - http://sysctl.org/cameleon/hosts
      - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
    special:
      - https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
  whiteLists:
    ads:
      - /etc/blocky/whitelist.txt
  clientGroupsBlock:
    default:
      - ads
      - special
  blockType: nxDomain
  blockTTL: 1m
  loading:
    refreshPeriod: 24h
    downloads:
      timeout: 60s
      attempts: 5
      cooldown: 10s
    concurrency: 16
    strategy: failOnError
    maxErrorsPerSource: 5

caching:
  minTime: 5m
  maxTime: 30m
  maxItemsCount: 0
  prefetching: true
  prefetchExpires: 2h
  prefetchThreshold: 5
  prefetchMaxItemsCount: 0
  cacheTimeNegative: 30m

clientLookup:
  upstream: 192.168.x.1
  singleNameOrder:
    - 2
    - 1

prometheus:
  enable: true
  path: /metrics

minTlsServeVersion: 1.3

bootstrapDns:
  - tcp+udp:1.1.1.1
  - https://1.1.1.1/dns-query

ports:
  dns: 53
  tls: 853
  https: 443
  http: 4000

log:
  level: debug
  format: text
  timestamp: true
  privacy: false

ede:
  enable: true

specialUseDomains:
  rfc6762-appendixG: true

Here is what comes in the log, which looks ok:

[2023-11-25 15:24:42] INFO queryLog: query resolved answer= client_ip=192.168.x.143 client_names=192.168.x.143 duration_ms=0 hostname=blocky1 question_name=unifi.example.com. question_type=HTTPS response_code=NOERROR response_reason=CUSTOM DNS response_type=CUSTOMDNS

Here is error message browser shows on iphone:

Safari can't open the page "unifi.example.com" because it was blocked by "(null)"

Hoping someone smarter than me can help me out.

kwitsch commented 10 months ago

iPhones use a HTTPS query for some detection which falls back to A queries if not resolved.

Try setting

filter:
  - HTTPS 

This should avoid incorrect answers and force those devices to use A queries, which should solve your problem.

ouldsmobile commented 10 months ago

iPhones use a HTTPS query for some detection which falls back to A queries if not resolved.

Try setting

filter:
  - HTTPS 

This should avoid incorrect answers and force those devices to use A queries, which should solve your problem.

Thanks for the suggestion. However, "filter" doesn't seem to work as a config option.

Should it be:

filtering:
  queryTypes:
    - HTTPS

If so, that didn't help unfortunately.

kwitsch commented 10 months ago

Yeah sorry about the syntax error. Wrote it out of my head and didn't check first. 🫣

Could you check your log after enabling it and doing a new request?

It should produce a different log message than before.

ouldsmobile commented 10 months ago

Yeah sorry about the syntax error. Wrote it out of my head and didn't check first. 🫣

Could you check your log after enabling it and doing a new request?

It should produce a different log message than before.

No worries, I know the config has changed pretty substantially.

Log with filtering:

[2023-11-25 17:35:39] DEBUG server: new request
[2023-11-25 17:35:39] DEBUG custom_dns_resolver: returning custom dns entry answer=A (192.168.x.201) client_ip=192.168.x.143 client_names=192.168.x.143 domain=example.com question=A (proxmox.example.com)
[2023-11-25 17:35:39] DEBUG server: new request
[2023-11-25 17:35:39]  INFO queryLog: query resolved answer=A (192.168.x.201) client_ip=192.168.x.143 client_names=192.168.x.143 duration_ms=0 hostname=blocky1 question_name=proxmox.example.com. question_type=A response_code=NOERROR response_reason=CUSTOM DNS response_type=CUSTOMDNS

iphone browser still returning same error page.

kwitsch commented 10 months ago

In theory you now get a correct IP(answer=)...

🤔

pg1261 commented 10 months ago

Hello everyone,

are there any new findings on this problem?

br

kwitsch commented 10 months ago

Sorry I can't provide further help since there are no Apple devices in my networks. 😅 In theory filtering the HTTPS queries should solve this issue. 🤷‍♂️

ouldsmobile commented 10 months ago

I haven't had a chance to dig further yet, but last check it was still giving same issue even when filtering HTTPS. Probably just a weird combo of my phone and setup as even with a very basic config it was still not working as expected. If I have time over the weekend I may spin up a fresh install just to make sure it wasn't something funky with the installation.

pg1261 commented 10 months ago

I've had the same problem since iOS 17. If I can help, then I'm happy to do so.

ThinkChaos commented 10 months ago

I use blocky on iOS and don't have any special setup on the blocky side. To configure iOS, I have a provisioning profile with VPN and DNS, amongst other things, so I use Blocky everywhere I go. I'm changing from DoT to DoH (to get HTTP3 automatically in the future) and will update this thread if I notice any weirdness.

But as a first question, how are you configuring iOS' DNS? Maybe using a profile helps?

ouldsmobile commented 10 months ago

I use blocky on iOS and don't have any special setup on the blocky side. To configure iOS, I have a provisioning profile with VPN and DNS, amongst other things, so I use Blocky everywhere I go. I'm changing from DoT to DoH (to get HTTP3 automatically in the future) and will update this thread if I notice any weirdness.

But as a first question, how are you configuring iOS' DNS? Maybe using a profile helps?

For me, I am only seeing the issue when using the "customDNS:" function in conjunction with my iPhone. Otherwise Blocky is working as expected. And again it's only encountering this issue on my iPhone 11, running latest iOS(17.1.2 as of a couple days ago.) Other devices are working fine(Windows, Android phones, even my iPad Air.)

Also, if I switch over to Technitium DNS with a similar config, the iPhone works without issues when hitting my customDNS entries. So, it's definitely some combination of Blocky and iPhone. My blocky config was posted earlier in the thread if needed. I also tried with a super basic Blokcy config and same thing. Lastly I tried multiple browsers(Safari, Chrome and Firefox) on the iPhone just to rule that out as well.

For config on the iPhone, nothing special. Just configuring DNS via DHCP(sometimes it is set manually if I have both Blocky and Technitium running on different ip's, just to do side by side testing, but issue persists either way.) If I am off my home network, I typically am connected back to home over wireguard which is hard coded to use my home DNS as well.

ThinkChaos commented 10 months ago

For me customDNS works fine and I have the exact same iPhone/iOS combo.
I don't use unencrypted DNS though, but did try just to see if I can repro, but even without the HTTPS filtering it works.

So given that, the fact that it works on your iPad, and the message "blocked by null" I'd say try disabling any content blockers and VPNs you might have.
If that's it, I'm not sure why Technitium would work. Either way, could you post logs of Technitium so we can compare?

Also the message saying null is definitely an iOS bug. Hopefully it's just a bug of showing what blocked and you don't have an old content blocker half installed.

ouldsmobile commented 10 months ago

For me customDNS works fine and I have the exact same iPhone/iOS combo. I don't use unencrypted DNS though, but did try just to see if I can repro, but even without the HTTPS filtering it works.

So given that, the fact that it works on your iPad, and the message "blocked by null" I'd say try disabling any content blockers and VPNs you might have. If that's it, I'm not sure why Technitium would work. Either way, could you post logs of Technitium so we can compare?

Also the message saying null is definitely an iOS bug. Hopefully it's just a bug of showing what blocked and you don't have an old content blocker half installed.

I don't have any content blockers that I am aware of on the iPhone, and only use the VPN when outside my network. I am doing my testing while on my local network. I also tried disabling all of Blocky's blocking abilities and was still seeing same error.

This is from Technitium when hitting a customDNS entry from the iphone, it doesn't show much and there doesn't appear to be a setting for anything more verbose:

[2023-12-03 13:05:25 Local] [192.168.x.143:57724] [UDP] QNAME: unifi.exmple.com; QTYPE: HTTPS; QCLASS: IN; RCODE: NoError; ANSWER: []

ThinkChaos commented 10 months ago

I don't have any content blockers that I am aware of on the iPhone

Then I really don't understand why Safari shows that error. Cause AFAIK it's not going to show that when blocky blocks a domain.

Technitium doesn't have any logs for the A query?

@pg1261 could you please provide more details about your setup? Hopefully with both in mind we narrow the issue down.

pg1261 commented 10 months ago
upstreams:
  groups:
    default:
      - tcp-tls:dnsforge.de:853
      - tcp-tls:dns3.digitalcourage.de:853
      - tcp-tls:unicast.uncensoreddns.org:853
      - https://dns.digitale-gesellschaft.ch/dns-query
      - https://dns.cloudflare.com/dns-query
      - https://dns.quad9.net/dns-query
      - https://dnsforge.de/dns-query
      - https://doh.opendns.com/dns-query
      - https://anycast.uncensoreddns.org/dns-query

conditional:
  mapping:
    pg1261.home: 192.168.1.1

blocking:
  blackLists:
    ads:
      - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
      - https://raw.githubusercontent.com/ookangzheng/dbl-oisd-nl/master/dbl.txt
      - https://adaway.org/hosts.txt
      - https://v.firebog.net/hosts/AdguardDNS.txt
      - https://www.github.developerdan.com/hosts/lists/ads-and-tracking-extended.txt
    tracking:
      - https://v.firebog.net/hosts/Easyprivacy.txt
      - https://v.firebog.net/hosts/Prigent-Ads.txt
    malware:
      - https://raw.githubusercontent.com/DandelionSprout/adfilt/master/Alternate%20versions%20Anti-Malware%20List/AntiMalwareHosts.txt
      - https://osint.digitalside.it/Threat-Intel/lists/latestdomains.txt
    special:
      - https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts
      - https://www.github.developerdan.com/hosts/lists/hate-and-junk-extended.txt
      - https://www.github.developerdan.com/hosts/lists/amp-hosts-extended.txt
  whiteLists:
    ads:
      - https://raw.githubusercontent.com/anudeepND/whitelist/master/domains/whitelist.txt
      - https://raw.githubusercontent.com/rahilpathan/pihole-whitelist/main/1.LowWL.txt
  clientGroupsBlock:
    default:
      - ads
      - tracking
      - malware
      - special
  loading:
    downloads:
      timeout: 4m
    concurrency: 100
    strategy: fast

caching:
  minTime: 5m
  maxTime: 30m
  prefetching: true

clientLookup:
  upstream: 192.168.1.1

prometheus:
  enable: true

redis:
  address: pg1261
  database: 2
  required: true
  connectionAttempts: 10
  connectionCooldown: 3s
  sentinelAddresses:
    - 192.168.1.71:5000
    - 192.168.1.81:5000
    - 192.168.1.91:5000

ports:
  http: 4000

ede:
  enable: true
kamelohr commented 9 months ago

EDIT: Nevermind, it just stopped working again and keeps showing the (null) error again - also for domains that worked previously (after the reboot). Back to square one…

Original comment:

As I just started using blocky for my LAN yesterday, I also discovered that weird (null) resolving error on my iPhone (iOS 17.2) for (sub)domains served by customDNS/conditional. I tried with one domain served by a conditional internal DNS server and got the mentioned error in Safari (btw: iOS/Apple only allows using the Safari browser engine for all mobile browsers. AFAIK Firefox, Chrome etc. all are nothing but Safari under the hood on iOS).

Before trying with other custom/conditional domains I updated my blocky config with both the mentioned HTTPS-filter and also certificates for the 443 port (the port is also enabled by default):

certFile: /<path>/tls.crt
keyFile: /<path>/tls.key
filtering:
  queryTypes:
    - HTTPS   

Rebooting the blocky container and my iPhone then did the trick for domains of that custom/conditional group that I haven't tried before on my phone. However the one domain I tried before reconfiguring and rebooting still delivered the (null) error.

So, I assume it's local caching on the iPhone which keeps displaying that error and hopefully it will sort itself out once iPhone's caches are flushed.

I'm also not quite sure if it really helped to provide those TLS cert files as they are provided and signed by letsencrypt and thus only connected to a DNS. Maybe somebody knows more about that matter.

ouldsmobile commented 9 months ago

Rebooting the blocky container and my iPhone then did the trick for domains of that custom/conditional group that I haven't tried before on my phone. However the one domain I tried before reconfiguring and rebooting still delivered the (null) error. So, I assume it's local caching on the iPhone which keeps displaying that error and hopefully it will sort itself out once iPhone's caches are flushed.

Interesting, thanks for chiming in. Weird thing on my end, if I simply switch DNS to my Technitium setup, the pages in question come right up so I am thinking it's not a caching issue on the phone. It is indeed a bit of an odd issue. I may try spinning up a fresh Blocky install to see it if changes anything. Just gotta carve out some time to do it. :-)

Edit: Spun up a new instance, no change still getting the "null" error screen

pg1261 commented 9 months ago

Is this a mDNS/Bonjour behavior?

I don't use a ".local" Domain, but the airplaine mode solves the issue temporarily.

https://alwayswithyouwhatcannotbedone.wordpress.com/2019/03/10/temporary-fix-for-an-iphone-that-cannot-access-local-addresses/

h3mmy commented 9 months ago

Is this a mDNS/Bonjour behavior?

I don't use a ".local" Domain, but the airplaine mode solves the issue temporarily.

https://alwayswithyouwhatcannotbedone.wordpress.com/2019/03/10/temporary-fix-for-an-iphone-that-cannot-access-local-addresses/

For me this issue comes up when I try to access a local network IP via a domain name, but I don't use .local

My setup uses a split-horizon DNS, and there is a conditional block that forwards requests for my domain name to k8s-gateway. With an iPad, this will work occasionally but a lot of the time I will get the blocked by "(null)" error since iOS 16+ which is frustrating. Cycling airplane mode resolves the issue half of the time.

This happens regardless of whether I am filtering HTTPS types. I experimented with using a pihole with a custom DNS entry but that didn't actually change anything.

I have firewall rules to block outgoing DNS including to external DoH servers. Even though I don't use iCloud relay, and have manual DNS set in my iPad, I still see blocked outgoing requests to Apple's DoH servers.

I do intend to experiment to see if it may be DNSSEC related but the fact that it's inconsistent about the error makes it difficult to reach any conclusions

h3mmy commented 9 months ago

Update: After further investigation, it's definitely not DNSSEC related. I ran tests with external IPs with and without DNSSEC and it made no difference.

The iPad actually fetches the DNS records from blocky successfully. Using Network Tools, I can get the DNS records just fine. Also with the attempt that was "blocked by null", the blocky logs still show a successful query.

Sometimes when using a domain that returns an internal IP works, It's immediately after I turn on WiFi after it's been off for a bit (at least 30s). Any longer and it will fail. My domain ends with .xyz and not .local so I wouldn't expect it to be an mDNS issue.

When I am getting the blocked by "(null)" error in Safari, if I try using Firefox (still the WebKit engine), what I get is NSURLErrorDomain (https://developer.apple.com/documentation/foundation/nsurlerrordomain) with no error code. I'm working on figuring out how to get debug logs without a Mac because I'm hoping that can provide more information.

h3mmy commented 9 months ago

Update: After further investigation, it's definitely not DNSSEC related. I ran tests with external IPs with and without DNSSEC and it made no difference.

The iPad actually fetches the DNS records from blocky successfully. Using Network Tools, I can get the DNS records just fine.

Sometimes when using a domain that returns an internal IP works, It's immediately after I turn on WiFi after it's been off for a bit (at least 30s). Any longer and it will fail. My domain ends with .xyz and not .local so I wouldn't expect it to be an mDNS issue.

When I am getting the blocked by "(null)" error in Safari, if I try using Firefox (still the WebKit engine), what I get is NSURLErrorDomain (https://developer.apple.com/documentation/foundation/nsurlerrordomain) with no error code. I'm working on figuring out how to get debug logs without a Mac because I'm hoping that can provide more information.

Update 2: I figured out something that works! Instead of using mydomain.xyz in the address bar, if I use mydomain.xyz/. it works flawlessly. I still don't know the root cause, but I can say it's not really a blocky issue, and definitely a bug in iOS somewhere. They make it too difficult to get to system logs without a Mac so I gave up on that as it wasn't worth the frustration I was feeling.

TL;DR: Append a /. to your url when using iOS trying to resolve a URL that is on your local network.

@ouldsmobile I'm curious if this workaround also works for your setup?

pg1261 commented 9 months ago

The log is not easy for me to read. Is this part helpful?

08:51:55.481328+0100 mDNSResponder [Q51232] DetermineUnicastQuerySuppression: Query suppressed for <mask.hash: 'F8ziU6wnTxUCQRTwtr41Hw=='> AAAA (AAAA records are unusable)

08:51:55.481358+0100 mDNSResponder [R241475->Q36423] Question for <mask.hash: 'F8ziU6wnTxUCQRTwtr41Hw=='> (Addr) assigned DNS service 834

08:51:55.481386+0100 mDNSResponder [R241475->Q51232] GenerateNegativeResponse: Generating negative response for question <mask.hash: 'F8ziU6wnTxUCQRTwtr41Hw=='> (AAAA)

h3mmy commented 9 months ago

The log is not easy for me to read. Is this part helpful?

08:51:55.481328+0100 mDNSResponder [Q51232] DetermineUnicastQuerySuppression: Query suppressed for <mask.hash: 'F8ziU6wnTxUCQRTwtr41Hw=='> AAAA (AAAA records are unusable)

08:51:55.481358+0100 mDNSResponder [R241475->Q36423] Question for <mask.hash: 'F8ziU6wnTxUCQRTwtr41Hw=='> (Addr) assigned DNS service 834

08:51:55.481386+0100 mDNSResponder [R241475->Q51232] GenerateNegativeResponse: Generating negative response for question <mask.hash: 'F8ziU6wnTxUCQRTwtr41Hw=='> (AAAA)

Without any context I'm not sure that is meant to represent. It could simply be normal mDNS chatter with flood control?

Could you provide some more context for this snippet? What actions did you take (if any) to create these logs?

pg1261 commented 9 months ago

That is quite difficult. Messages rush through in milliseconds and URLs are masked.

ThinkChaos commented 9 months ago

Update 2: I figured out something that works! Instead of using mydomain.xyz in the address bar, if I use mydomain.xyz/. it works flawlessly

Nice find! Does mydomain.xyz/ (without the period) work @h3mmy?

h3mmy commented 9 months ago

Update 2: I figured out something that works! Instead of using mydomain.xyz in the address bar, if I use mydomain.xyz/. it works flawlessly

Nice find! Does mydomain.xyz/ (without the period) work @h3mmy?

Only after getting the site to load with a dot first. All subsequent access is fine until some time has passed.

kamelohr commented 8 months ago

Any news on this issue? So far, for me the issue remains and applies for different Apple devices (iPhone 15 Pro/iOS 17.3, iPhone 13 Mini/iOS 17.2.1, and iPad Mini 6/iPadOS 17.0).

I discovered that there is a short moment directly after rebooting the device when it successfully resolves local domains. Then the used domain remains to work for some time until it goes back to the (null) error page.

The mentioned hacks with adding dots or slashes to the domain didn't work for me, unfortunately.

As I'm running blocky in k3s, I cut off http/s access to the pods via the service to try if it could be related to iOS's DNS Type 65 behaviour - no luck here either.

ouldsmobile commented 8 months ago

Any news on this issue? So far, for me the issue remains and applies for different Apple devices (iPhone 15 Pro/iOS 17.3, iPhone 13 Mini/iOS 17.2.1, and iPad Mini 6/iPadOS 17.0).

I discovered that there is a short moment directly after rebooting the device when it successfully resolves local domains. Then the used domain remains to work for some time until it goes back to the (null) error page.

The mentioned hacks with adding dots or slashes to the domain didn't work for me, unfortunately.

As I'm running blocky in k3s, I cut off http/s access to the pods via the service to try if it could be related to iOS's DNS Type 65 behaviour - no luck here either.

Still same for me. None of the "tricks" worked in my case either. Always get the (null) error on my iPhone.

I did run a DNS utility on my iphone to compare the differences when running Blocky vs Technitium DNS(which is working on iphone.) The only difference I noticed was the "flags" here's a couple screenshots, both hitting the same internal domain.

This is running blocky:

image

This is running technitium:

image

Not sure if it is helpful but definitely a difference.

Here is a description of the flags:

Flags: AA = Authoritative Answer TC = Truncation RD = Recursion Desired (set in a query and copied into the response if recursion is supported) RA = Recursion Available (if set, denotes recursive query support is available) AD = Authenticated Data (for DNSSEC only; indicates that the data was authenticated) CD = Checking Disabled (DNSSEC only; disables checking at the receiving server)

The difference is the AA flag which appears on Blocky but not Technitium. Not sure whether that would make a difference though.

h3mmy commented 8 months ago

Any news on this issue? So far, for me the issue remains and applies for different Apple devices (iPhone 15 Pro/iOS 17.3, iPhone 13 Mini/iOS 17.2.1, and iPad Mini 6/iPadOS 17.0). I discovered that there is a short moment directly after rebooting the device when it successfully resolves local domains. Then the used domain remains to work for some time until it goes back to the (null) error page. The mentioned hacks with adding dots or slashes to the domain didn't work for me, unfortunately. As I'm running blocky in k3s, I cut off http/s access to the pods via the service to try if it could be related to iOS's DNS Type 65 behaviour - no luck here either.

Still same for me. None of the "tricks" worked in my case either. Always get the (null) error on my iPhone.

I did run a DNS utility on my iphone to compare the differences when running Blocky vs Technitium DNS(which is working on iphone.) The only difference I noticed was the "flags" here's a couple screenshots, both hitting the same internal domain.

This is running technitium:

image

This is with Blocky:

image

Not sure if it is helpful but definitely a difference.

Here is a description of the flags:

Flags: AA = Authoritative Answer TC = Truncation RD = Recursion Desired (set in a query and copied into the response if recursion is supported) RA = Recursion Available (if set, denotes recursive query support is available) AD = Authenticated Data (for DNSSEC only; indicates that the data was authenticated) CD = Checking Disabled (DNSSEC only; disables checking at the receiving server)

The difference is the AA flag which appears on Blocky but not Technitium. Not sure whether that would make a difference though.

For your Technitium setup: Is it only an IP change in your iOS network settings? Or are you using their iOS app to manage the configuration?

Secondly does the Technitium DNS server use NXDomain or zeroIP for it's blocking? Does it have any extra records like PTR or SOA for the domain that blocky is missing?

ouldsmobile commented 8 months ago

For your Technitium setup: Is it only an IP change in your iOS network settings? Or are you using their iOS app to manage the configuration?

Just an IP change for DNS server on the iphone. I have both Technitium and Blocky up and running on different IP's. Currently using Technitium and was testing out Blocky when I came across this issue. My dhcp is handing out the Technitium IP as the DNS server, so when I want to test Blocky I just change it from automatic to manual on the iphone(or any other device I want to do some testing.)

Secondly does the Technitium DNS server use NXDomain or zeroIP for it's blocking? Does it have any extra records like PTR or SOA for the domain that blocky is missing?

I currently have it set to use NXDomain for blocking but there are a couple other options as well. Like so:

image

Technitium uses "zones" for configuration, so when setting up a zone you can add whatever types of records(including PTR and SOA) you want for that particular zone, in my case for my local domain I only have it setup with an A record. Is that what you meant?

h3mmy commented 8 months ago

For your Technitium setup: Is it only an IP change in your iOS network settings? Or are you using their iOS app to manage the configuration?

Just an IP change for DNS server on the iphone. I have both Technitium and Blocky up and running on different IP's. Currently using Technitium and was testing out Blocky when I came across this issue. My dhcp is handing out the Technitium IP as the DNS server, so when I want to test Blocky I just change it from automatic to manual on the iphone(or any other device I want to do some testing.)

Secondly does the Technitium DNS server use NXDomain or zeroIP for it's blocking? Does it have any extra records like PTR or SOA for the domain that blocky is missing?

I currently have it set to use NXDomain for blocking but there are a couple other options as well. Like so:

image

Technitium uses "zones" for configuration, so when setting up a zone you can add whatever types of records(including PTR and SOA) you want for that particular zone, in my case for my local domain I only have it setup with an A record. Is that what you meant?

Thanks, that's good to know. If you use your DNS utility to get ALL DNS records, do you get any other records with your A record? I'm wondering if technitium adds any extra records by default.

ouldsmobile commented 8 months ago

Thanks, that's good to know. If you use your DNS utility to get ALL DNS records, do you get any other records with your A record? I'm wondering if technitium adds any extra records by default.

It sends an MX and TXT record along with the A record.

ThinkChaos commented 8 months ago

I did run a DNS utility on my iphone to compare the differences when running Blocky vs Technitium DNS(which is working on iphone.) The only difference I noticed was the "flags" here's a couple screenshots, both hitting the same internal domain.

That seems worth looking into just in case, though it's not guaranteed it's the same request that iOS is doing.
Is the blocky response from customDNS? I don't see anywhere in the code where that flag is set. And testing with dig, the flags I see are qr rd ra.
Did you maybe invert the two screenshots? Because the flags I got match the ones from the Technitium screenshot.

Here's a custom blocky build: v0.23 with a patch to set the authoritative flag for customDNS responses.
Please try it out to see if blocky and technitium now match, and more importantly if the issue is fixed :) blocky.gz

EDIT: here's the commit I used if you're curious or would like to build it yourself https://github.com/ThinkChaos/blocky/commit/aeb47d95067f77c2536f3e80d36c1c43a00cdcdf

ouldsmobile commented 8 months ago

Did you maybe invert the two screenshots? Because the flags I got match the ones from the Technitium screenshot.

Yeah woops I did reverse the descriptions somehow. Good catch. Sorry bout that. I fixed it for future inquiries.

Here's a custom blocky build: v0.23 with a patch to set the authoritative flag for customDNS responses. Please try it out to see if blocky and technitium now match, and more importantly if the issue is fixed :) blocky.gz

EDIT: here's the commit I used if your curious or would like to build it yourself ThinkChaos@aeb47d9

Great. I will give it a try when I have a moment. Thanks!!

ouldsmobile commented 8 months ago

So I built a copy of blocky using @ThinkChaos commit. It unfortunately doesn't fix the issue on the iphone, still getting the (null) error. However, the output in the dns utility looks the same for Technitium and Blocky now. Flags are the same and they are both returning MX and TXT records. But still something that doesn't jive with the iphone. :-/

pg1261 commented 8 months ago

Since blocky 0.23 or iOS 17.3, the problem no longer exists in my environment.

I had forgotten to check it after the blocky 0.23 update. But after the iOS 17.3 update and with both on the latest version, I checked the behavior again.

kamelohr commented 8 months ago

@pg1261 Are you using customDNS, because I cannot see such entries in the config you posted above? I only see the conditional setting. Did you have issues with that one, because I only had them with the customDNS setting, not the conditionals.


However, I just tinkered around with my blocky config and changed this:

    # optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists.
    # accepted: dual, v4, v6
    # default: dual
    connectIPVersion: v4  
    #### PREVIOUS SETTING > connectIPVersion: dual

    # optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma
    # example: query "printer.lan" or "my.printer.lan" will return 192.168.178.3
    # optional: drop all queries with following query types. Default: empty
    filtering:
      queryTypes:
       ####    - HTTPS < PREVIOUS SETTING: https filter was not commented/disabled

    # optional: if path defined, use this file for query resolution (A, AAAA and rDNS). Default: empty
    # hostsFile:
    # optional: add EDE error codes to dns response
    ede:
      # enabled if true, Default: false
      #### PREVIOUS SETTING > enable: true
      enable: false

I don't think the IP version for connections should be related to the issue, but feel free to correct me, if you think otherwise. I disabled IPv6 at my router since I'm just starting to learn it and doesn't want to have possible attack vectors open.

Probably it is related to https and/or the error code setting, because now, with those new settings customDNS seems to work on my Apple devices (finally). 🥂

Maybe that helps finding the cause of the error.

h3mmy commented 8 months ago

@pg1261 Are you using customDNS, because I cannot see such entries in the config you posted above? I only see the conditional setting. Did you have issues with that one, because I only had them with the customDNS setting, not the conditionals.

However, I just tinkered around with my blocky config and changed this:

    # optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists.
    # accepted: dual, v4, v6
    # default: dual
    connectIPVersion: v4  
    #### PREVIOUS SETTING > connectIPVersion: dual

    # optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma
    # example: query "printer.lan" or "my.printer.lan" will return 192.168.178.3
    # optional: drop all queries with following query types. Default: empty
    filtering:
      queryTypes:
       ####    - HTTPS < PREVIOUS SETTING: https filter was not commented/disabled

    # optional: if path defined, use this file for query resolution (A, AAAA and rDNS). Default: empty
    # hostsFile:
    # optional: add EDE error codes to dns response
    ede:
      # enabled if true, Default: false
      #### PREVIOUS SETTING > enable: true
      enable: false

I don't think the IP version for connections should be related to the issue, but feel free to correct me, if you think otherwise. I disabled IPv6 at my router since I'm just starting to learn it and doesn't want to have possible attack vectors open.

Probably it is related to https and/or the error code setting, because now, with those new settings customDNS seems to work on my Apple devices (finally). 🥂

Maybe that helps finding the cause of the error.

What version of iOS are you testing with?

kamelohr commented 8 months ago

What version of iOS are you testing with?

On iPhone it's iOS 17.3 (21D50) (stable). The last days I used the beta but the issue persisted after updating to the stable 17.3 release (and prior to the config change). Additionally, prior to the conf. change I had the (null) issue on iPadOS 17.2. Now, after the change its gone. Although, initial loading on the iPad takes quite some time. Might be related to Apple's way of resolving on i-Devices (https vs. UDP query).

h3mmy commented 8 months ago

Thanks! That's helpful to me, so I can test. I'll try the config options independently. The HTTPS filter didn't change anything for me when I tried it with version 16 and 17.2 of iOS

ThinkChaos commented 8 months ago

FWIW my config had filtering.queryTypes: [ "AAAA" ] but no connectIPVersion and was working.
I tried disabling the filtering and it still worked. And now I've got filtering re-enabled and connectIPVersion: v4 and it also works.
So basically messing with those didn't help me repro.

h3mmy commented 8 months ago

Tested with iOS 17.2 Blocky v0.23

To test, clear the blocky cache. Clear the iPad cache (toggle airplane mode off and on with a 10s gap) Then use a domain that points to an rfc1918 address without a trailing slashdot

HTTPS/SVCB filtered vs not filtered - no difference Single stack vs dual stack - no difference (tested with both ipv4 and ipv6) ede enabled vs ede disabled - Bingo! This was it.

It's a little disappointing that I can't use ede error codes if I want to be able to fully use my iPad, at least for now. But it's nice to pin down a cause.

ThinkChaos commented 8 months ago

I can reproduce with ede: enable: true!
Thanks for persisting and finding that. I'm sorry I missed that originally because it's in the config posted in the issue...

Looking into actually fixing this :)

ThinkChaos commented 8 months ago

Found the bug!

The EDE resolver adds the extra information even if the query was a success, but EDE is Extended DNS Errors. And iOS assumes that the response is an error, even though the rest of the data says it's not, which is fair enough.
I'm not sure what the by (null) thing is, but still leaning towards it being an iOS bug.

Please give my fix/ios branch a shot and let me know if that works for you. It's based on v0.23 with two minor changes. The one of interest here is https://github.com/ThinkChaos/blocky/commit/71993086d401f2924fde2ff3afa8b0dd7aceffb4.

kwitsch commented 8 months ago

Since there is an EDE code for forged answers in my opinion the iOS behavior is somewhat faulty. 🫤

We could enhance the config setting to an enum like [disabled/enabled for all/enabled for blocks & errors only] 🤔

ThinkChaos commented 8 months ago

Yeah looks like you're right. RFC-8914 Section 3 says:

Receivers MUST be able to accept EDE codes and EXTRA-TEXT in all messages, including those with a NOERROR RCODE but need not act on them. Applications MUST continue to follow requirements from applicable specifications on how to process RCODEs no matter what EDE values are also received.

So the bug is more on iOS' side. If anyone has access to report a bug there that would be welcome, but let's just say I'm not holding my breath on it being fixed.
I like the idea of an enum. Paired with a not in the docs that should be enough since EDE is disabled by default for now, so users are likely to see the note/other enum value.

EDIT: I'll wait for someone else to confirm the branch fixes the issue before making a PR.

kwitsch commented 8 months ago

Since it's most likely not a bug in blocky a workaround to compensate for a bug in a different software should be considered an enhancement.

larivierec commented 8 months ago

I can reproduce with ede: enable: true! Thanks for persisting and finding that. I'm sorry I missed that originally because it's in the config posted in the issue...

Looking into actually fixing this :)

Wow. i've been looking around for months for this 😮‍💨 i thought it was something wrong with my setup and wanted extra info via ede.

turns out it was the culprit for iOS. Thanks for the workaround

buroa commented 8 months ago

I have noticed the ede: enabled in my setup as well. The DNS queries work for a moment and then just stop. That's why I disabled it in my network for now.

kamelohr commented 8 months ago

EDIT: I'll wait for someone else to confirm the branch fixes the issue before making a PR.

@ThinkChaos Thanks for the fix! I built a docker image based on your branch and was successfully able to resolve the customDNS domains in question on my Apple devices while having ede: enabled: true (although there were some strange hiccups first on my iPad. But they went away after a another restart of the blocky containers, perhaps a caching issue; seems to be stable now).

So the bug is more on iOS' side. If anyone has access to report a bug there that would be welcome, but let's just say I'm not holding my breath on it being fixed.

Apple has a "Feedback" tool on all their platforms that's pretty much a bug tracker. I've logged a bug there, but I'm not confident they'll even notice or fix it. There's a bunch of threads on the Apple Dev Forums where people complain about Apple ignoring bug reports for years. If somebody lucks out and finds an email for an Apple Engineer, especially one on the iOS/iPadOS core team (probably dealing with networking stuff), that might be a quicker way to get things sorted.