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

serve-expired behavior #138

Open
billatq opened this issue Aug 14, 2023 · 3 comments
Open

serve-expired behavior #138

billatq opened this issue Aug 14, 2023 · 3 comments

Comments

@billatq
Copy link

billatq commented Aug 14, 2023

Describe the bug
Unbound is configured with serve-expired: yes as a default. For someone casually using the docker container, this is not obvious and not mentioned anywhere in the documentation.

May websites work properly with this setting, but IP addresses can get frequently recycled or change. When the old one is no longer valid, weird behavior can occur, for example:

  • Weird TLS certificate errors because a new endpoint is being served from the same IP address
  • Applications that have strange errors and don't seem to work

And what makes this even weirder to debug is that after serving an expired record, the correct record will update in the background and assuming that it's not cached too long on a browser, the error will disappear.

To Reproduce
To reproduce this, do the following:

  1. Set up a DNS record pointing to a valid endpoint with a short TTL
  2. After the TTL has expired, change the IP address
  3. Try to access the host behind the DNS record, notice that it fails
  4. Wait a minute and refresh
  5. Find that the host now resolves to the correct record

Expected behavior
This feature should be documented and ideally enabled only behind a flag when the container is started.

If this feature is enabled by default, more guardrails should be enabled, for example, the default for unbound is to serve stale data with no limit: https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html#unbound-conf-serve-expired-ttl

If stale data is served by default, more conservative settings should be used. For example:

serve-expired-ttl defaults to 0, which sets no limit on how long a stale record can sit around before being served
serve-expired-client-timeout is disabled by default, but a reasonable default would be 1800 per the documentation.

Workaround
An easy way to workaround this issue is to copy the unbound configuration from https://github.com/MatthewVance/unbound-docker/blob/master/1.17.1/data/unbound.sh#L41-L363 and then make a new unbound.conf file.

Change the serve-expired: yes option to serve-expired: no

Then when mount this as a volume, similar to the other configuration files, e.g.
--volume=<my-host-path>/unbound.conf:/opt/unbound/etc/unbound/unbound.conf:ro

@MatthewVance
Copy link
Owner

@billatq those are fair points. I agree the defaults should change. I need to decide if I want to keep serve-expired: yes but tune with more conservative settings or disable it by default.

@mcm
Copy link

mcm commented Nov 12, 2024

Unbound has some docs about the RFC for serving expired records, and what the config settings are that would match the RFC's recommendations.

@billatq
Copy link
Author

billatq commented Nov 12, 2024

For the sake of completeness, the linked document has this configuration:

server:
    serve-expired: yes
    serve-expired-ttl: 86400            # one day, in seconds
    serve-expired-client-timeout: 1800  # 1.8 seconds, in milliseconds

serve-expired-ttl and serve-expired-client-timeout are currently not defined and are the default settings of zero, which correspond to "No expiration on the stale records" and "No need to wait before serving expired records. These do seem like more reasonable defaults, since you can't serve a record that's older than a day out of the cache, and you wont try to serve that record until you've waited 1800 milliseconds to get a reply and haven't already.

It sounds like the main change from what I'd originally proposed is that the expired TTL be set to 86400 if serve-expired: yes is enabled. That all seems reasonable to me.

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

3 participants