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

Inconsistent RPZ handling for A record returned along with CNAME #954

Closed
imjosi opened this issue Oct 17, 2023 · 2 comments
Closed

Inconsistent RPZ handling for A record returned along with CNAME #954

imjosi opened this issue Oct 17, 2023 · 2 comments

Comments

@imjosi
Copy link

imjosi commented Oct 17, 2023

Describe the bug
Inconsistent RPZ handling for CNAME records in Unbound 1.17 - RPZ is applied to A record returned along with CNAME only for first request, but not for next requests for the same record until it expires from cache. None of these requests are logged in the RPZ log.

Records in source domain:

test.dev.        60      IN      A       10.10.10.10
blockme.test.dev. 30      IN      CNAME   test.dev.

RPZ file dev.rpz:

test.dev.rpz.   120     IN      A       10.99.99.99

Unbound configuration:

server:
        module-config: "respip validator iterator"
        logfile: "/var/log/unbound/unbound.log"
        log-time-ascii: yes
        log-queries: yes
        log-replies: yes

rpz:
        name: "rpz"
        zonefile: "dev.rpz"
        rpz-log: yes
        rpz-log-name: "rpz"

To reproduce
Steps to reproduce the behavior:

  1. Check if test.dev record is blocked - got correct response with RPZ IP and corresponding logfile entry
$ dig test.dev
;; ANSWER SECTION:
test.dev.               120     IN      A       10.99.99.99

Unbound log:

Oct 17 16:12:16 unbound[2190287:0] info: 127.0.0.1 test.dev. A IN
Oct 17 16:12:16 unbound[2190287:0] info: rpz: applied [rpz] test.dev. rpz-local-data 127.0.0.1@53017 test.dev. A IN
Oct 17 16:12:16 unbound[2190287:0] info: 127.0.0.1 test.dev. A IN NOERROR 0.000000 1 53
  1. Check if blockme.test.dev is blocked - got correct response with RPZ IP but no entry in logfile
$ dig blockme.test.dev
;; ANSWER SECTION:
blockme.test.dev.       30      IN      CNAME   test.dev.
test.dev.               120     IN      A       10.99.99.99

Unbound log:

Oct 17 16:17:56 unbound[2190287:0] info: 127.0.0.1 blockme.test.dev. A IN
Oct 17 16:17:56 unbound[2190287:0] info: 127.0.0.1 blockme.test.dev. A IN NOERROR 0.000539 0 75
  1. After few seconds check again if blockme.test.dev is blocked - got incorrect response with source domain IP and TTL and no entry in logfile
$ dig blockme.test.dev
;; ANSWER SECTION:
blockme.test.dev.       27      IN      CNAME   test.dev.
test.dev.               60      IN      A       10.10.10.10

Unbound log:

Oct 17 16:17:59 unbound[2190287:0] info: 127.0.0.1 blockme.test.dev. A IN
Oct 17 16:17:59 unbound[2190287:0] info: 127.0.0.1 blockme.test.dev. A IN NOERROR 0.000308 0 75

Expected behavior
RPZ must be always applied to A records returned along with CNAME and it must be logged.

System:

  • Unbound version: 1.17.1-2+deb12u1
  • OS: Debian GNU/Linux 12 (bookworm)
  • unbound -V output:
Version 1.17.1

Configure line: --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-option-checking --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --runstatedir=/run --disable-maintainer-mode --disable-dependency-tracking --with-pythonmodule --with-pyunbound --enable-subnet --enable-dnstap --enable-systemd --with-libnghttp2 --with-chroot-dir= --with-dnstap-socket-path=/run/dnstap.sock --disable-rpath --with-pidfile=/run/unbound.pid --with-libevent --enable-tfo-client --with-rootkey-file=/usr/share/dns/root.key --enable-tfo-server
Linked libs: libevent 2.1.12-stable (it uses epoll), OpenSSL 3.0.11 19 Sep 2023
Linked modules: dns64 python subnetcache respip validator iterator
TCP Fastopen feature available
@wcawijngaards
Copy link
Member

The fix makes it check for rpz qname actions after a CNAME is picked up from cache. Also, the rpz action is logged for actions after a CNAME, and after a CNAME from cache. That fixes the issue, in the test script.

Thank you for the detailed report! The fix commit is in the code repository.

@imjosi
Copy link
Author

imjosi commented Oct 18, 2023

Thanks, I can confirm that this issue is fixed. I backported this fix to Debian 1.17.1 version and it worked there too.

jedisct1 added a commit to jedisct1/unbound that referenced this issue Oct 24, 2023
* nlnet/master: (64 commits)
  Changelog entry for NLnetLabs#951. - Merge NLnetLabs#951: Cachedb no store. The cachedb-no-store: yes option is   used to stop cachedb from writing messages to the backend storage.   It reads messages when data is available from the backend. The   default is no.
  - Fix to print detailed errors when an SSL IO routine fails via   SSL_get_error.
  - Changelog entry for:   Merge NLnetLabs#955 from buevsan: fix ipset wrong behavior. - Update testdata/ipset.tdir test for ipset fix.
  - Update the dns64_lookup.rpl test for the DNS64 fallback patch.
  - Changelog entry for DNS64 patches from Daniel Gröber.
  Fixes for dns64 fallback to plain AAAA when no A records: - Cleanup if condition. - Rename variable for readability.
  dns64: Fall back to plain AAAA query with synthall but no A records
  Fixes for dns64 readability refactoring: - Move declarations to the top for C90 compliance. - Save cycles by not calling (yet) unneeded functions. - Possible use of uninitialised value. - Consistent formatting.
  dns64: Fix misleading indentation
  dns64: Refactor handle_event checks for readability
  fix ipset wrong behavior
  - Fix NLnetLabs#954: Inconsistent RPZ handling for A record returned along with   CNAME.
  - Update pymod tests for the new Python script variable.
  - For multi Python module setups, clean previously parsed module   functions in __main__'s dictionary, if any, so that only current   module functions are registered.
  - Expose the configured listening and outgoing interfaces, if any, as   a list of strings in the Python 'config_file' class instead of the   current Swig object proxy; fixes NLnetLabs#79.
  - Expose the script filename in the Python module environment 'mod_env'   instead of the config_file structure which includes the linked list   of scripts in a multi Python module setup; fixes NLnetLabs#79.
  - Better fix for infinite loop when reading multiple lines of input on   a broken remote control socket, by treating a zero byte line the   same as transmission end. Addesses NLnetLabs#947 and NLnetLabs#948.
  Apply suggestions from code review
  - cachedb-no-store, example conf and man page documentation.
  Changelog note for NLnetLabs#944. - Merge NLnetLabs#944: Disable EDNS DO.   Disable the EDNS DO flag in upstream requests. This can be helpful   for devices that cannot handle DNSSEC information. But it should not   be enabled otherwise, because that would stop DNSSEC validation. The   DNSSEC validation would not work for Unbound itself, and also not   for downstream users. Default is no. The option   is disable-edns-do: no
  ...
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