[GH-ISSUE #440] Add DNS caching time parameter for multiple servers #158

Closed
opened 2026-02-26 04:34:13 +03:00 by kerem · 21 comments
Owner

Originally created by @rayout on GitHub (Apr 25, 2024).
Original GitHub issue: https://github.com/mageddo/dns-proxy-server/issues/440

I would like to suggest adding the ability to configure the caching time parameter when multiple DNS servers are available. For example, in my configuration, I have two DNS servers: 10.0.0.10 and 8.8.8.8. The first DNS (10.0.0.10) is used via VPN, and if it does not respond, the request will be sent to the second DNS (8.8.8.8). Currently, all subsequent requests go to the second DNS. However, I would like the system to switch back to resolving requests from the first DNS after a specified time.

Perhaps these 20 seconds should be made a configurable parameter:
github.com/mageddo/dns-proxy-server@17b0c0043d/src/main/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverRemote.java (L174)

This change would allow for more flexible management of DNS request caching and ensure more efficient operation with multiple DNS servers. I would appreciate your consideration of this proposal. Thank you!

Originally created by @rayout on GitHub (Apr 25, 2024). Original GitHub issue: https://github.com/mageddo/dns-proxy-server/issues/440 I would like to suggest adding the ability to configure the caching time parameter when multiple DNS servers are available. For example, in my configuration, I have two DNS servers: 10.0.0.10 and 8.8.8.8. The first DNS (10.0.0.10) is used via VPN, and if it does not respond, the request will be sent to the second DNS (8.8.8.8). Currently, all subsequent requests go to the second DNS. However, I would like the system to switch back to resolving requests from the first DNS after a specified time. Perhaps these 20 seconds should be made a configurable parameter: https://github.com/mageddo/dns-proxy-server/blob/17b0c0043d883cf9f902075739183c7938c808b2/src/main/java/com/mageddo/dnsproxyserver/server/dns/solver/SolverRemote.java#L174 This change would allow for more flexible management of DNS request caching and ensure more efficient operation with multiple DNS servers. I would appreciate your consideration of this proposal. Thank you!
kerem 2026-02-26 04:34:13 +03:00
Author
Owner

@mageddo commented on GitHub (May 4, 2024):

Alright, so by some reason 10.0.0.10 is failing, circuit is opening for that server and you would want to customize the circuitbreaker parameters, right?

Just for curiosity do you know what is the 10.0.0.10 failing reason?

<!-- gh-comment-id:2094477228 --> @mageddo commented on GitHub (May 4, 2024): Alright, so by some reason `10.0.0.10` is failing, circuit is opening for that server and you would want to customize the circuitbreaker parameters, right? Just for curiosity do you know what is the `10.0.0.10` failing reason?
Author
Owner

@rayout commented on GitHub (May 5, 2024):

Yes, you are right.
10.0.0.10 is the DNS for VPN network. For corporate network resources.
When i turn on computer, VPN is not yet connected. At this case DNS will excluded.
That`s why i have to restart docker container after connection to the VPN.

<!-- gh-comment-id:2094781382 --> @rayout commented on GitHub (May 5, 2024): Yes, you are right. 10.0.0.10 is the DNS for VPN network. For corporate network resources. When i turn on computer, VPN is not yet connected. At this case DNS will excluded. That`s why i have to restart docker container after connection to the VPN.
Author
Owner

@mageddo commented on GitHub (May 23, 2024):

Hey, I'm releasing 3.18.1 right now, can you check it solves your usecase after the release finish? Check the jSON config docs of how to use it.

<!-- gh-comment-id:2127813933 --> @mageddo commented on GitHub (May 23, 2024): Hey, I'm releasing 3.18.1 right now, can you check it solves your usecase after the release finish? Check the [jSON config docs][1] of how to use it. [1]: https://mageddo.github.io/dns-proxy-server/latest/en/3-configuration/#example-json-configuration
Author
Owner

@mageddo commented on GitHub (May 23, 2024):

@rayout

<!-- gh-comment-id:2127814051 --> @mageddo commented on GitHub (May 23, 2024): @rayout
Author
Owner

@rayout commented on GitHub (May 24, 2024):

Hello! Thank you for your help!
I tried to check, but an error occurs during the launch (I tried both with my own config and by replacing the config with the one from the documentation).

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.mageddo.dnsproxyserver.config.dataprovider.vo.ConfigJsonV2$SolverRemote$CircuitBreaker: cannot deserialize from Object value (no delegate- or property-based Creator): this appears to be a native image, in which case you may need to configure reflection for the class that is to be deserialized at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: com.mageddo.dnsproxyserver.config.dataprovider.vo.ConfigJsonV2["solverRemote"]->com.mageddo.dnsproxyserver.config.dataprovider.vo.ConfigJsonV2$SolverRemote["circuitBreaker"])

<!-- gh-comment-id:2129025373 --> @rayout commented on GitHub (May 24, 2024): Hello! Thank you for your help! I tried to check, but an error occurs during the launch (I tried both with my own config and by replacing the config with the one from the documentation). > Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.mageddo.dnsproxyserver.config.dataprovider.vo.ConfigJsonV2$SolverRemote$CircuitBreaker`: cannot deserialize from Object value (no delegate- or property-based Creator): this appears to be a native image, in which case you may need to configure reflection for the class that is to be deserialized at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: com.mageddo.dnsproxyserver.config.dataprovider.vo.ConfigJsonV2["solverRemote"]->com.mageddo.dnsproxyserver.config.dataprovider.vo.ConfigJsonV2$SolverRemote["circuitBreaker"])
Author
Owner

@mageddo commented on GitHub (May 24, 2024):

Hello! Thank you for your help! I tried to check, but an error occurs during the launch (I tried both with my own config and by replacing the config with the one from the documentation).

Thanks for the feedback, fixing that on #454 and releasing 3.18.2-snapshot

<!-- gh-comment-id:2129846469 --> @mageddo commented on GitHub (May 24, 2024): > Hello! Thank you for your help! I tried to check, but an error occurs during the launch (I tried both with my own config and by replacing the config with the one from the documentation). > Thanks for the feedback, fixing that on #454 and releasing `3.18.2-snapshot`
Author
Owner

@rayout commented on GitHub (May 28, 2024):

I tested it. I specified two addresses as DNS - 10.0.0.10 and 8.8.8.8. The 10.0.0.10 DNS is only accessible via VPN.

I connected to the VPN and used the dig command to query an address that has an IP within the 10.0.0.10 range. The command was: dig @172.17.0.1 (this is the IP of the Docker where the DNS is listening). There were no issues, and the response was the address 10.0.0.169.

Next, I disconnected from the VPN and tried the dig command again multiple times. I still received the internal IP 10.0.0.169, even though the site has an external IP address on 8.8.8.8. I waited 10 minutes to check the cache, but I still received the internal address.

What could I have done wrong? If I run dig

@10.0.0.10, it results in an error because I am disconnected from the VPN. Therefore, it should have switched to 8.8.8.8 after some time, but it didn't work.

<!-- gh-comment-id:2135070799 --> @rayout commented on GitHub (May 28, 2024): I tested it. I specified two addresses as DNS - 10.0.0.10 and 8.8.8.8. The 10.0.0.10 DNS is only accessible via VPN. I connected to the VPN and used the dig command to query an address that has an IP within the 10.0.0.10 range. The command was: dig <site address> @172.17.0.1 (this is the IP of the Docker where the DNS is listening). There were no issues, and the response was the address 10.0.0.169. Next, I disconnected from the VPN and tried the dig command again multiple times. I still received the internal IP 10.0.0.169, even though the site has an external IP address on 8.8.8.8. I waited 10 minutes to check the cache, but I still received the internal address. What could I have done wrong? If I run dig <address> @10.0.0.10, it results in an error because I am disconnected from the VPN. Therefore, it should have switched to 8.8.8.8 after some time, but it didn't work.
Author
Owner

@mageddo commented on GitHub (May 29, 2024):

I still received the internal IP 10.0.0.169, even though the site has an external IP address on 8.8.8.8. I waited 10 minutes to check the cache

I suppose this scenario it's related to the response entries cache, so it's a second scenario, not related to the circuitbreaker. Once query has a successful response then DPS will cache it for the time the remote server specifies, (10.0.0.10 in your case).

In the bellow example, 107 is the TTL in seconds.

$ dig +noall +nocmd +answer google.com
google.com.		107	IN	A	142.251.129.238

You can make the same test and manage the cache with the APIs bellow:

See how's the cache

$ curl localhost:5385/v1/caches/

Clear a cache

$ curl -X DELETE localhost:5385/v1/caches?name=REMOTE

@rayout

<!-- gh-comment-id:2137218079 --> @mageddo commented on GitHub (May 29, 2024): > I still received the internal IP 10.0.0.169, even though the site has an external IP address on 8.8.8.8. I waited 10 minutes to check the cache I suppose this scenario it's related to the response entries cache, so it's a second scenario, not related to the circuitbreaker. Once query has a successful response then DPS will cache it for the time the remote server specifies, (10.0.0.10 in your case). In the bellow example, 107 is the TTL in seconds. ```shell $ dig +noall +nocmd +answer google.com google.com. 107 IN A 142.251.129.238 ``` You can make the same test and manage the cache with the APIs bellow: See how's the cache ```bash $ curl localhost:5385/v1/caches/ ``` Clear a cache ```bash $ curl -X DELETE localhost:5385/v1/caches?name=REMOTE ``` @rayout
Author
Owner

@mageddo commented on GitHub (May 29, 2024):

I'm thinking about what can be done in this scenario.

<!-- gh-comment-id:2137220731 --> @mageddo commented on GitHub (May 29, 2024): I'm thinking about what can be done in this scenario.
Author
Owner

@mageddo commented on GitHub (May 29, 2024):

Please confirm if it really is the scenario

<!-- gh-comment-id:2137221726 --> @mageddo commented on GitHub (May 29, 2024): Please confirm if it really is the scenario
Author
Owner

@mageddo commented on GitHub (May 29, 2024):

Enable trace debug level and post the output when you test the same scenario again plus the cache clear scenario will help me.

<!-- gh-comment-id:2137242826 --> @mageddo commented on GitHub (May 29, 2024): Enable trace debug level and post the output when you test the same scenario again plus the cache clear scenario will help me.
Author
Owner

@rayout commented on GitHub (May 29, 2024):

Yes, the problem is indeed with the cache. When looking at /v1/caches/ (thanks, very useful), I can see two entries for the domain I need:

global: ttl": "PT20S"
remote: "ttl": "PT1H"
With the VPN disconnected, I run dig +noall +nocmd +answer @172.17.0.1 and get "nothing" because 8.8.8.8 does not have a record for this domain. Then I connect to the VPN, run the same command, and no matter how long I wait (more than 20 seconds), I do not get an IP or a TTL.

Here is what I see in the console during debugging:

  1. VPN disconnected:

image

  1. VPN connected:

image

  1. Cache cleared:

image

<!-- gh-comment-id:2137361912 --> @rayout commented on GitHub (May 29, 2024): Yes, the problem is indeed with the cache. When looking at /v1/caches/ (thanks, very useful), I can see two entries for the domain I need: global: ttl": "PT20S" remote: "ttl": "PT1H" With the VPN disconnected, I run dig +noall +nocmd +answer <domain> @172.17.0.1 and get "nothing" because 8.8.8.8 does not have a record for this domain. Then I connect to the VPN, run the same command, and no matter how long I wait (more than 20 seconds), I do not get an IP or a TTL. Here is what I see in the console during debugging: 1. VPN disconnected: ![image](https://github.com/mageddo/dns-proxy-server/assets/2248162/db5673c0-b367-45a7-9ec9-73d7236d01f7) 2. VPN connected: ![image](https://github.com/mageddo/dns-proxy-server/assets/2248162/4f945aa7-d0df-4b58-adc4-fb75b3a59eb9) 3. Cache cleared: ![image](https://github.com/mageddo/dns-proxy-server/assets/2248162/10a1d51c-58d9-4f0b-9c04-d48b76eaeac9)
Author
Owner

@rayout commented on GitHub (May 29, 2024):

I’m not really sure I’m on the right path. In Ubuntu 14-16, if two DNS servers were specified in the settings, the system would query the second DNS if the first didn’t respond. Something similar is described here - systemd issue #5755. Maybe I’m mistaken, but that’s how it felt.

It’s also possible that connecting to the VPN used to clear the DNS cache, which no longer happens.

Here’s my current scenario:
I have containers to which I assign hostnames in the configuration, and thanks to this wonderful project, I can refer to them by name instead of IP. I also have a VPN to the corporate network with many internal addresses (I’ve counted about 10 domains so far). Previously, all requests would go through the corporate DNS when connected to the VPN. This somewhat worked, but some addresses with external IPs were cached to the external address used for acme https, and I had to manually add them to /etc/hosts or the service’s admin panel.

A week ago, I tried to solve this problem, and now I have two Docker containers. The first is with this project, and the second with dnsmasq, configured as follows:

image

image

I also had to set ipv4.dns-search: "~." in /etc/netplan/vpn.yaml and ip4.dns: "172.17.0.1" (dnsmasq address), so that this DNS is applied when connecting to the VPN.

This scheme works more or less well. Only requests for the domains I specified go to the corporate DNS. This is also a drawback, as I need to maintain the list of these domains. Another drawback is that I can only access the Docker containers when the VPN is on.

Is there a simpler or better solution?

<!-- gh-comment-id:2137424377 --> @rayout commented on GitHub (May 29, 2024): I’m not really sure I’m on the right path. In Ubuntu 14-16, if two DNS servers were specified in the settings, the system would query the second DNS if the first didn’t respond. Something similar is described here - [systemd issue #5755](https://github.com/systemd/systemd/issues/5755). Maybe I’m mistaken, but that’s how it felt. It’s also possible that connecting to the VPN used to clear the DNS cache, which no longer happens. Here’s my current scenario: I have containers to which I assign hostnames in the configuration, and thanks to this wonderful project, I can refer to them by name instead of IP. I also have a VPN to the corporate network with many internal addresses (I’ve counted about 10 domains so far). Previously, all requests would go through the corporate DNS when connected to the VPN. This somewhat worked, but some addresses with external IPs were cached to the external address used for acme https, and I had to manually add them to /etc/hosts or the service’s admin panel. A week ago, I tried to solve this problem, and now I have two Docker containers. The first is with this project, and the second with dnsmasq, configured as follows: ![image](https://github.com/mageddo/dns-proxy-server/assets/2248162/9a32288e-5f3a-4985-b87d-961d4711d7a9) ![image](https://github.com/mageddo/dns-proxy-server/assets/2248162/0ddaa0ff-14c6-47e7-b91e-bd03d2be2ebd) I also had to set ipv4.dns-search: "~." in /etc/netplan/vpn.yaml and ip4.dns: "172.17.0.1" (dnsmasq address), so that this DNS is applied when connecting to the VPN. This scheme works more or less well. Only requests for the domains I specified go to the corporate DNS. This is also a drawback, as I need to maintain the list of these domains. Another drawback is that I can only access the Docker containers when the VPN is on. Is there a simpler or better solution?
Author
Owner

@mageddo commented on GitHub (May 29, 2024):

The NXDOMAIN response (no answer) will be cached for one hour.

Yes, the problem is indeed with the cache. When looking at /v1/caches/ (thanks, very useful), I can see two entries for the domain I need:

global: ttl": "PT20S" remote: "ttl": "PT1H" With the VPN disconnected, I run dig +noall +nocmd +answer @172.17.0.1 and get "nothing" because 8.8.8.8 does not have a record for this domain. Then I connect to the VPN, run the same command, and no matter how long I wait (more than 20 seconds), I do not get an IP or a TTL.

Here is what I see in the console during debugging:

<!-- gh-comment-id:2137945756 --> @mageddo commented on GitHub (May 29, 2024): The NXDOMAIN response (no answer) will be cached for one hour. > Yes, the problem is indeed with the cache. When looking at /v1/caches/ (thanks, very useful), I can see two entries for the domain I need: > > global: ttl": "PT20S" remote: "ttl": "PT1H" With the VPN disconnected, I run dig +noall +nocmd +answer @172.17.0.1 and get "nothing" because 8.8.8.8 does not have a record for this domain. Then I connect to the VPN, run the same command, and no matter how long I wait (more than 20 seconds), I do not get an IP or a TTL. > > Here is what I see in the console during debugging:
Author
Owner

@mageddo commented on GitHub (May 29, 2024):

I’m not really sure I’m on the right path. In Ubuntu 14-16, if two DNS servers were specified in the settings, the system would query the second DNS if the first didn’t respond. Something similar is described here - https://github.com/systemd/systemd/issues/5755. Maybe I’m mistaken, but that’s how it felt.

It looks like the same behavior, but the reason is another. I identified a new improvement to be done, I've done some definition for this new improvement at #455. It probably would fix your bad experience, what do you think?

<!-- gh-comment-id:2137953365 --> @mageddo commented on GitHub (May 29, 2024): > I’m not really sure I’m on the right path. In Ubuntu 14-16, if two DNS servers were specified in the settings, the system would query the second DNS if the first didn’t respond. Something similar is described here - https://github.com/systemd/systemd/issues/5755. Maybe I’m mistaken, but that’s how it felt. It looks like the same behavior, but the reason is another. I identified a new improvement to be done, I've done some definition for this new improvement at #455. It probably would fix your bad experience, what do you think?
Author
Owner

@mageddo commented on GitHub (May 29, 2024):

and thanks to this wonderful project

Appreciate your thanks, you're welcome!

Is there a simpler or better solution?

Actually I consider we can fix that by #455 or/and by creating a toggle for the entire cache. Despite this, DPS on version 3.12.1 have not this cache feature, then you can test it and check if has the behavior you want (not sure this version is stable for use but maybe it can make the job for now), this way we can validate the wanted behavior before I implement these two solutions on the new version. The two solutions aren't too big though.

The cache was implemented at 3.13.1 see the release notes.

@rayout

<!-- gh-comment-id:2137973157 --> @mageddo commented on GitHub (May 29, 2024): > and thanks to this wonderful project Appreciate your thanks, you're welcome! > Is there a simpler or better solution? Actually I consider we can fix that by #455 or/and by creating a toggle for the entire cache. Despite this, DPS on version `3.12.1` have not this cache feature, then you can test it and check if has the behavior you want (not sure this version is stable for use but maybe it can make the job for now), this way we can validate the wanted behavior before I implement these two solutions on the new version. The two solutions aren't too big though. The cache was implemented at `3.13.1` see the [release notes][1]. [1]: https://github.com/mageddo/dns-proxy-server/blob/master/RELEASE-NOTES.md#3131 @rayout
Author
Owner

@rayout commented on GitHub (Jun 3, 2024):

Create a watch dog to keep testing the remote servers circuit, it will clear the cache whenever a remote server goes down or gets health again.

I think this is a great idea and it will really solve the problem.

<!-- gh-comment-id:2144586946 --> @rayout commented on GitHub (Jun 3, 2024): > Create a watch dog to keep testing the remote servers circuit, it will clear the cache whenever a remote server goes down or gets health again. I think this is a great idea and it will really solve the problem.
Author
Owner

@mageddo commented on GitHub (Jun 4, 2024):

@rayout 3.19.0 is out implementing the watchdog, can you check it solves your usecase? Also consider calibrate your circuit breaker params.

<!-- gh-comment-id:2148215716 --> @mageddo commented on GitHub (Jun 4, 2024): @rayout `3.19.0` is out implementing the watchdog, can you check it solves your usecase? Also consider calibrate your circuit breaker params.
Author
Owner

@mageddo commented on GitHub (Jun 22, 2024):

I'm closing this issue, feel free to reopen if the issue persists

<!-- gh-comment-id:2183612918 --> @mageddo commented on GitHub (Jun 22, 2024): I'm closing this issue, feel free to reopen if the issue persists
Author
Owner

@rayout commented on GitHub (Jul 2, 2024):

Thank you! I have been testing for some time to wait for feedback, and then went on vacation.
Everything works fine now. When turning VPN on and off, everything works instantly.
But sometimes, if I have been without a VPN connection for a long time, when I turn on the VPN, any DNS requests stop working altogether until I completely restart the docker container with the DNS proxy.
I will continue testing and will create a task if I catch this issue.

<!-- gh-comment-id:2202334482 --> @rayout commented on GitHub (Jul 2, 2024): Thank you! I have been testing for some time to wait for feedback, and then went on vacation. Everything works fine now. When turning VPN on and off, everything works instantly. But sometimes, if I have been without a VPN connection for a long time, when I turn on the VPN, any DNS requests stop working altogether until I completely restart the docker container with the DNS proxy. I will continue testing and will create a task if I catch this issue.
Author
Owner

@mageddo commented on GitHub (Jul 2, 2024):

Thank you! I have been testing for some time to wait for feedback, and then went on vacation.
Everything works fine now. When turning VPN on and off, everything works instantly.

Glad we had an advance!

But sometimes, if I have been without a VPN connection for a long time, when I turn on the VPN, any DNS requests stop working altogether until I completely restart the docker container with the DNS proxy.
I will continue testing and will create a task if I catch this issue.

Sure, thanks for your contribution @rayout

<!-- gh-comment-id:2203322998 --> @mageddo commented on GitHub (Jul 2, 2024): > Thank you! I have been testing for some time to wait for feedback, and then went on vacation. > Everything works fine now. When turning VPN on and off, everything works instantly. Glad we had an advance! > But sometimes, if I have been without a VPN connection for a long time, when I turn on the VPN, any DNS requests stop working altogether until I completely restart the docker container with the DNS proxy. I will continue testing and will create a task if I catch this issue. Sure, thanks for your contribution @rayout
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/dns-proxy-server-mageddo#158
No description provided.