This is a strange issue I’m facing and I can’t quite understand what or how it’s happening, so please bear with me.
I run pi-hole in an LXC container, on IP 192.168.1.11
. I serve that as DNS to my regular LAN clients using DHCP option 6,192.168.1.11
to the LAN interface and that works well.
I have other interfaces mapped to specific zones, pi-hole is configured with interfaces connecting to each of them and they get their IPs correctly and it all works.
I have recently introduced a new set of interfaces to route certain traffic through a VPN. I’m running OpenVPN client on the router and creating a specific route table for it whilst removing any routing via the VPN on the default table.
I have a vpn_wan
interface that attaches to tun0
:
config interface 'vpn_wan'
option proto 'none'
option ifname 'tun0'
I have a vpn_lan
interface configured like so:
config interface 'vpn_lan'
option proto 'static'
option ipaddr '172.60.0.1'
option netmask '255.255.255.0'
option dns '1.1.1.1 1.0.0.1'
option delegate '0'
option type 'bridge'
option ifname 'lan2 lan4.15'
lan4.15
is for traffic coming from a home server I run where I create a vlan
interface with 802.1Q ID 15
. The default interface routes through the normal untagged LAN traffic on physical port 4.
This is the entirety of my /etc/firewall
in what affects the vpn_lan
and vpn_wan
interfaces:
config zone
option name 'vpn_wan'
option network 'vpn_wan'
option masq '1'
option mtu_fix '1'
option forward 'REJECT'
option input 'REJECT'
option output 'ACCEPT'
config zone
option name 'vpn_lan'
option network 'vpn_lan'
option forward 'REJECT'
option input 'REJECT'
option output 'ACCEPT'
config rule
option target 'ACCEPT'
option proto 'udp'
option dest_port '67-68'
option name 'Allow-vpn-DHCP'
option src 'vpn_lan'
config forwarding
option dest 'vpn_wan'
option src 'vpn_lan'
The idea is that clients on the vpn_lan
zone can only get DHCP information from the router and forward to vpn_wan
but do nothing else. One of the reasons is so VPN traffic doesn’t leak anything - including DNS.
What I’m puzzled about is that when I send a DNS request to 192.168.1.11
on VLAN 15 I still get a reply:
root@headquarters:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
11: enp2s0.15@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 9c:b6:54:07:e3:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.60.0.15/24 brd 172.60.0.255 scope global dynamic enp2s0.15
valid_lft 40787sec preferred_lft 40787sec
inet6 fe80::9eb6:54ff:fe07:e3f1/64 scope link
valid_lft forever preferred_lft forever
root@headquarters:~# dig vitrines.globo.com @192.168.1.11
; <<>> DiG 9.11.5-P4-5.1ubuntu2-Ubuntu <<>> vitrines.globo.com @192.168.1.11
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31626
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 763c4f5149d462b052717e4f5db5a85532cd9a690f43d6ae (good)
;; QUESTION SECTION:
;vitrines.globo.com. IN A
;; ANSWER SECTION:
vitrines.globo.com. 120 IN A 186.192.81.168
;; AUTHORITY SECTION:
globo.com. 111620 IN NS ns02.globo.com.
globo.com. 111620 IN NS ns01.globo.com.
globo.com. 111620 IN NS ns04.globo.com.
globo.com. 111620 IN NS ns03.globo.com.
;; Query time: 224 msec
;; SERVER: 192.168.1.11#53(192.168.1.11)
;; WHEN: Sun Oct 27 14:23:17 UTC 2019
;; MSG SIZE rcvd: 167
Note that this is from a network namespace where the only non-loopback interface is the VLAN one.
This is what I see on the router from that request:
turris# tcpdump -Snei any udp port 53 and host 192.168.1.11
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
13:55:49.315483 P 9c:b6:54:07:e3:f1 ethertype 802.1Q (0x8100), length 107: vlan 15, p 0, ethertype IPv4, 172.60.0.15.41718 > 192.168.1.11.53: 47376+ [1au] A? vitrines.globo.com. (59)
13:55:49.315483 P 9c:b6:54:07:e3:f1 ethertype IPv4 (0x0800), length 103: 172.60.0.15.41718 > 192.168.1.11.53: 47376+ [1au] A? vitrines.globo.com. (59)
13:55:49.315483 In 9c:b6:54:07:e3:f1 ethertype IPv4 (0x0800), length 103: 172.60.0.15.41718 > 192.168.1.11.53: 47376+ [1au] A? vitrines.globo.com. (59)
13:55:49.315565 Out ethertype IPv4 (0x0800), length 103: 10.16.0.8.41718 > 192.168.1.11.53: 47376+ [1au] A? vitrines.globo.com. (59)
13:55:49.322069 In ethertype IPv4 (0x0800), length 211: 192.168.1.11.53 > 10.16.0.8.41718: 47376 1/4/1 A 186.192.81.168 (167)
13:55:49.322108 Out d8:58:d7:00:9e:6d ethertype IPv4 (0x0800), length 211: 192.168.1.11.53 > 172.60.0.15.41718: 47376 1/4/1 A 186.192.81.168 (167)
13:55:49.322116 Out d8:58:d7:00:9e:6d ethertype IPv4 (0x0800), length 211: 192.168.1.11.53 > 172.60.0.15.41718: 47376 1/4/1 A 186.192.81.168 (167)
So it comes in via the VLAN, gets sent to the pi-hole which in turn seemingly routes it via the VPN IP 10.16.0.8
, then back to the VLAN interface on the host.
Note that the pi-hole is not configured to talk to that VPN address at all.
What’s interesting is that this particular host is blacklisted on the pi-hole, so should have resolved to 0.0.0.0
instead of the actual IP.
If I do the same query over a regular LAN client, that’s what I get:
cassiano@headquarters:~$ dig vitrines.globo.com @192.168.1.11
; <<>> DiG 9.11.5-P4-5.1ubuntu2-Ubuntu <<>> vitrines.globo.com @192.168.1.11
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9489
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;vitrines.globo.com. IN A
;; ANSWER SECTION:
vitrines.globo.com. 2 IN A 0.0.0.0
;; Query time: 3 msec
;; SERVER: 192.168.1.11#53(192.168.1.11)
;; WHEN: Sun Oct 27 14:28:24 UTC 2019
;; MSG SIZE rcvd: 63
And the tcpdump
output for this query:
turris# tcpdump -Snei any udp port 53 and host 192.168.1.11
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
14:28:24.013948 P 9c:b6:54:07:e3:f1 ethertype IPv4 (0x0800), length 103: 192.168.1.15.40826 > 192.168.1.11.53: 9489+ [1au] A? vitrines.globo.com. (59)
14:28:24.014024 Out 9c:b6:54:07:e3:f1 ethertype IPv4 (0x0800), length 103: 192.168.1.15.40826 > 192.168.1.11.53: 9489+ [1au] A? vitrines.globo.com. (59)
14:28:24.013948 P 9c:b6:54:07:e3:f1 ethertype IPv4 (0x0800), length 103: 192.168.1.15.40826 > 192.168.1.11.53: 9489+ [1au] A? vitrines.globo.com. (59)
14:28:24.014782 P 62:f0:75:3d:ac:ca ethertype IPv4 (0x0800), length 107: 192.168.1.11.53 > 192.168.1.15.40826: 9489* 1/0/1 A 0.0.0.0 (63)
14:28:24.014806 Out 62:f0:75:3d:ac:ca ethertype IPv4 (0x0800), length 107: 192.168.1.11.53 > 192.168.1.15.40826: 9489* 1/0/1 A 0.0.0.0 (63)
14:28:24.014814 Out 62:f0:75:3d:ac:ca ethertype IPv4 (0x0800), length 107: 192.168.1.11.53 > 192.168.1.15.40826: 9489* 1/0/1 A 0.0.0.0 (63)
14:28:24.014782 P 62:f0:75:3d:ac:ca ethertype IPv4 (0x0800), length 107: 192.168.1.11.53 > 192.168.1.15.40826: 9489* 1/0/1 A 0.0.0.0 (63)
So in this case everything looks normal and as expected.
Can someone help me understand what’s actually happening here?
Thanks!