Skip to content

rpz trigger clientip and action rpz-passthru not working as expected #1029

Description

@DonOtuseGH

Describe the bug
We are running unbound as name server for clients, configured to forward/stub requests to an upstream name server and with an rpz.

For some clients, rpz-passthru has been configured in the rpz zone file, but it appears that further entries in the rpz zone file are also matched, so the client receives an unexpected response.

On the other hand, the behavior of rpz-drop seems to be as expected - no further entries in the rpz zone file are matched.

To reproduce

Made a little Docker setup to reproduce the behavior:

 ┌───────┐                                        .─────────.    
 │client1│───┐                                 ,─'           '─. 
 └───────┘   │   ┌───────┐      ┌───────┐     ;                 :
             ├──▶│  dns  │─────▶│  ns   │────▶:      INET       ;
 ┌───────┐   │   └───────┘      └───────┘      ╲               ╱ 
 │client2│───┘                                  '─.         ,─'  
 └───────┘                                         `───────'     

client1 (10.255.255.201)
  - Alpine Linux 
  - bind-tools
  - rpz-passthru

client2 (10.255.255.202):
  - Alpine Linux 
  - bind-tools
  - rpz-drop

dns (10.255.255.53):
  - unbound
  - forwarding/stubbing to ns
  - rpz

ns (10.255.255.53):
  - bind9
  - forwarding to INET
  - hosting example.com

rpz zone file:

$TTL     300
$ORIGIN  rpz.example.com.
@ IN SOA rpz.example.com. hosting.example.com. (
    2024031300 ; serial
    300        ; refresh
    150        ; retry
    604800     ; expiry
    60         ; minimum ttl
    )

www.example.com                 300 IN  A       192.168.192.168
32.201.255.255.10.rpz-client-ip 300 IN  CNAME   rpz-passthru.
32.202.255.255.10.rpz-client-ip 300 IN  CNAME   rpz-drop.

debugging client1 with rpz-passthru, when there's an additional match in the rpz zone file:

docker exec -ti client1 bash

client1:/# dig +short dns
10.255.255.53

client1:/# dig +short @dns www.example.com
192.168.192.168

===> unbound logs

2024-03-13 11:08:26 dns      | [1710324506] unbound[1:0] debug: rpz: trigger clientip 10.255.255.201/32 on 10.255.255.201 action=rpz-passthru
2024-03-13 11:08:26 dns      | [1710324506] unbound[1:0] debug: rpz: qname trigger www.example.com. with action=rpz-local-data
2024-03-13 11:08:26 dns      | [1710324506] unbound[1:0] info: rpz: applied [rpz.example.com] www.example.com. rpz-local-data 10.255.255.201@60529 www.example.com. A IN
2024-03-13 11:08:26 dns      | [1710324506] unbound[1:0] reply: 10.255.255.201 www.example.com. A IN NOERROR 0.000000 1 60

debugging client1 with rpz-passthru, when there's no other match in the rpz zone file:

docker exec -ti client1 bash

client1:/# dig +short @dns mail.example.com
10.255.255.25

===> unbound logs

2024-03-13 11:09:20 dns      | [1710324560] unbound[1:0] debug: rpz: trigger clientip 10.255.255.201/32 on 10.255.255.201 action=rpz-passthru
2024-03-13 11:09:20 dns      | [1710324560] unbound[1:0] reply: 10.255.255.201 mail.example.com. A IN NOERROR 0.000000 1 61

debugging client2 with rpz-drop and an additional match in the rpz zone file:

docker exec -ti client2 bash

client2:/# dig @dns www.example.com
;; communications error to 10.255.255.53#53: timed out
;; communications error to 10.255.255.53#53: timed out
;; communications error to 10.255.255.53#53: timed out

; <<>> DiG 9.18.24 <<>> @dns www.example.com
; (1 server found)
;; global options: +cmd
;; no servers could be reached

===> unbound logs

2024-03-13 11:10:16 dns      | [1710324616] unbound[1:0] debug: rpz: trigger clientip 10.255.255.202/32 on 10.255.255.202 action=rpz-drop
2024-03-13 11:10:16 dns      | [1710324616] unbound[1:0] info: rpz: applied [rpz.example.com] clientip www.example.com. rpz-drop 10.255.255.202@42675 www.example.com. A IN
2024-03-13 11:10:21 dns      | [1710324621] unbound[1:0] debug: rpz: trigger clientip 10.255.255.202/32 on 10.255.255.202 action=rpz-drop
2024-03-13 11:10:21 dns      | [1710324621] unbound[1:0] info: rpz: applied [rpz.example.com] clientip www.example.com. rpz-drop 10.255.255.202@59646 www.example.com. A IN
2024-03-13 11:10:26 dns      | [1710324626] unbound[1:0] debug: rpz: trigger clientip 10.255.255.202/32 on 10.255.255.202 action=rpz-drop
2024-03-13 11:10:26 dns      | [1710324626] unbound[1:0] info: rpz: applied [rpz.example.com] clientip www.example.com. rpz-drop 10.255.255.202@52502 www.example.com. A IN

Expected behavior

We expect that if the action rpz-passthru is used, no further entries in the rpz zone file are evaluated.

System:

  • Unbound version: 1.18.0 and 1.19.2

  • OS: Linux (openSUSE, Ubuntu, Alpine, doesn't matter)

  • unbound -V output:

Version 1.19.2

Configure line: --build=aarch64-alpine-linux-musl --host=aarch64-alpine-linux-musl --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man --localstatedir=/var --with-username=unbound --with-run-dir= --with-pidfile= --with-rootkey-file=/usr/share/dnssec-root/trusted-key.key --with-libevent --with-pthreads --disable-static --disable-rpath --enable-dnstap --with-ssl --without-pythonmodule --with-pyunbound
Linked libs: libevent 2.1.12-stable (it uses epoll), OpenSSL 3.1.4 24 Oct 2023
Linked modules: dns64 respip validator iterator

BSD licensed, see LICENSE in source package for details.
Report bugs to unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues

Additional information

Expecting the issue could be located somewhere here - but that's just a guess...

Please find the Docker setup attached.

unbound-debug.tgz

Thanks and best regards!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions