pf not redirecting DNS queries

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

pf not redirecting DNS queries

Scott Bennett
I have an APU2 running 6.2, acting as pf NAT gateway, DHCP server, and
DNS cache (unbound) for my internal LAN.

I've attempted to make all DNS queries redirect to the APU2, as many
examples have illustrated, so that they can be forwarded to OpenDNS (to
take advantage of domain filtering). But it seems that it is still
possible for queries to evade the redirection.

Using dig as a concrete example, if I do the following simple
query from a client, I get an answer from unbound as expected:

$ dig openbsd.org

; <<>> DiG 9.4.2-P2 <<>> openbsd.org @192.168.2.1
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57692
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;openbsd.org.                   IN      A

;; ANSWER SECTION:
openbsd.org.            28755   IN      A       129.128.5.194

;; Query time: 217 msec
;; SERVER: 192.168.2.1#53(192.168.2.1)
;; WHEN: Mon Nov  6 20:15:30 2017
;; MSG SIZE  rcvd: 45


However, if I specify an alternate DNS server, I get a response from
that server:

$ dig openbsd.org @8.8.8.8

; <<>> DiG 9.4.2-P2 <<>> openbsd.org @8.8.8.8
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20902
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;openbsd.org.                   IN      A

;; ANSWER SECTION:
openbsd.org.            20716   IN      A       129.128.5.194

;; Query time: 19 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Nov  6 20:19:21 2017
;; MSG SIZE  rcvd: 45


I expected to receive the answer from unbound on the APU2 at
192.168.2.1, not 8.8.8.8. However, even if that is not how dig is
actually supposed to work, I can still see evidence where my LAN
clients are able to go around the internal unbound. Relevant APU2
configurations are below. Omitting the unbound configuration as it
seems unhelpful. I have verified that it works; just the
redirection isn't working.

What have I goofed up?


Scott


$ cat /etc/resolv.conf.tail
search 123090.net
lookup file bind
options edns0

$ cat /etc/dhclient.conf
send host-name "comet.123090.net";
supersede domain-name-servers 208.67.222.222, 208.67.220.220;

$ cat /etc/dhcpd.conf
option domain-name "123090.net";
subnet 192.168.2.0 netmask 255.255.255.0 {
         option routers 192.168.2.1;
         option domain-name-servers 192.168.2.1;
         range 192.168.2.2 192.168.2.199;
}
subnet 192.168.0.0 netmask 255.255.255.0 {
         option routers 192.168.0.1;
         option domain-name-servers 192.168.0.1;
         range 192.168.0.101 192.168.0.199;
}

$ doas cat /etc/pf.conf
wired = "{ vether0 em1 em2 }"
wifi = "athn0"
wired_ip = "192.168.0.1"
wifi_ip = "192.168.2.1"
icmp_types = "{ echoreq, unreach }"
udp_ports = "{ domain, ntp }"
tcp_ports = "{ ssh, smtp, domain, www, pop3, auth, http, https, pop3s }"

table <bad_ips> { 0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, \
                   172.16.0.0/12, 192.0.0.0/24, 192.0.2.0/24, \
                   192.168.0.0/16, 198.18.0.0/15, 198.51.100.0/24, \
                   203.0.113.0/24, 224.0.0.0/3 }
set block-policy drop
set loginterface egress
set skip on lo
match in all scrub (no-df random-id)
match out on egress set prio (5, 6)
match in on $wifi set prio (5, 6)
match proto tcp to port ssh set prio 7
match out on egress inet from !(egress:network) to any nat-to (egress:0)
antispoof quick for { egress, $wifi }
block in quick log on egress from <bad_ips> to any
block return out quick log on egress from any to <bad_ips>
block in quick on egress from no-route to any
block in quick on egress inet proto icmp all label "icmp-in"
block all
pass quick proto { tcp, udp } to port $udp_ports
pass inet proto icmp icmp-type $icmp_types
pass out on egress inet proto udp to port 33433:33626
pass inet proto tcp from $wifi:network to port $tcp_ports modulate state
pass from { self, $wifi:network } modulate state
pass in on $wired inet
# Redirect DNS Queries
pass in on $wifi  proto { udp, tcp } from any to any port domain \
     rdr-to $wifi_ip  port domain label "dns-redirect"
pass in on $wired proto { udp, tcp } from any to any port domain \
     rdr-to $wired_ip port domain label "dns-redirect"

Reply | Threaded
Open this post in threaded view
|

Re: pf not redirecting DNS queries

trondd-2
On Mon, November 6, 2017 8:50 pm, Scott Bennett wrote:

> I have an APU2 running 6.2, acting as pf NAT gateway, DHCP server, and
> DNS cache (unbound) for my internal LAN.
>
> I've attempted to make all DNS queries redirect to the APU2, as many
> examples have illustrated, so that they can be forwarded to OpenDNS (to
> take advantage of domain filtering). But it seems that it is still
> possible for queries to evade the redirection.
>
> Using dig as a concrete example, if I do the following simple
> query from a client, I get an answer from unbound as expected:
>
> However, if I specify an alternate DNS server, I get a response from
> that server:
>
> $ doas cat /etc/pf.conf
> wired = "{ vether0 em1 em2 }"
> wifi = "athn0"
> wired_ip = "192.168.0.1"
> wifi_ip = "192.168.2.1"
> icmp_types = "{ echoreq, unreach }"
> udp_ports = "{ domain, ntp }"
> tcp_ports = "{ ssh, smtp, domain, www, pop3, auth, http, https, pop3s }"
>
> table <bad_ips> { 0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, \
>                    172.16.0.0/12, 192.0.0.0/24, 192.0.2.0/24, \
>                    192.168.0.0/16, 198.18.0.0/15, 198.51.100.0/24, \
>                    203.0.113.0/24, 224.0.0.0/3 }
> set block-policy drop
> set loginterface egress
> set skip on lo
> match in all scrub (no-df random-id)
> match out on egress set prio (5, 6)
> match in on $wifi set prio (5, 6)
> match proto tcp to port ssh set prio 7
> match out on egress inet from !(egress:network) to any nat-to (egress:0)
> antispoof quick for { egress, $wifi }
> block in quick log on egress from <bad_ips> to any
> block return out quick log on egress from any to <bad_ips>
> block in quick on egress from no-route to any
> block in quick on egress inet proto icmp all label "icmp-in"
> block all
> pass quick proto { tcp, udp } to port $udp_ports

Because you're telling pf to pass all taffic on port domain to anywhere.
Quick rules stop evaluation and you never hit the rdr-to rules below.


> pass inet proto icmp icmp-type $icmp_types
> pass out on egress inet proto udp to port 33433:33626
> pass inet proto tcp from $wifi:network to port $tcp_ports modulate state
> pass from { self, $wifi:network } modulate state
> pass in on $wired inet
> # Redirect DNS Queries
> pass in on $wifi  proto { udp, tcp } from any to any port domain \
>      rdr-to $wifi_ip  port domain label "dns-redirect"
> pass in on $wired proto { udp, tcp } from any to any port domain \
>      rdr-to $wired_ip port domain label "dns-redirect"
>

What is on your LAN that isn't using your DHCP settings for DNS?  Why
redirect instead of just blocking DNS from the LAN to all but unbound?

Reply | Threaded
Open this post in threaded view
|

Re: pf not redirecting DNS queries

Scott Bennett
On 11/6/2017 9:29 PM, trondd wrote:
> On Mon, November 6, 2017 8:50 pm, Scott Bennett wrote:
>> pass quick proto { tcp, udp } to port $udp_ports
>
> Because you're telling pf to pass all taffic on port domain to anywhere.
> Quick rules stop evaluation and you never hit the rdr-to rules below.
>

Oh, duh. I thought it had to be something minor that I wasn't seeing.

>
>> # Redirect DNS Queries
>> pass in on $wifi  proto { udp, tcp } from any to any port domain \
>>       rdr-to $wifi_ip  port domain label "dns-redirect"
>> pass in on $wired proto { udp, tcp } from any to any port domain \
>>       rdr-to $wired_ip port domain label "dns-redirect"
>>
>
> What is on your LAN that isn't using your DHCP settings for DNS?  Why
> redirect instead of just blocking DNS from the LAN to all but unbound?
>

I want to be able to enforce that all queries get funneled to OpenDNS. I
don't want someone to be able to outsmart the filter, at least at this
one level. Redirection lets me configure the laptops to have their own
hard-coded configurations when out and about, and then when I come home
they transparently query the gateway with no changes. Blocking would
probably result in me trying to load a page when I get home, failing,
then remembering to change the DNS config.

Reply | Threaded
Open this post in threaded view
|

Re: pf not redirecting DNS queries

Stuart Henderson
On 2017-11-07, Scott Bennett <[hidden email]> wrote:

> On 11/6/2017 9:29 PM, trondd wrote:
>> On Mon, November 6, 2017 8:50 pm, Scott Bennett wrote:
>>> pass quick proto { tcp, udp } to port $udp_ports
>>
>> Because you're telling pf to pass all taffic on port domain to anywhere.
>> Quick rules stop evaluation and you never hit the rdr-to rules below.
>>
>
> Oh, duh. I thought it had to be something minor that I wasn't seeing.
>
>>
>>> # Redirect DNS Queries
>>> pass in on $wifi  proto { udp, tcp } from any to any port domain \
>>>       rdr-to $wifi_ip  port domain label "dns-redirect"
>>> pass in on $wired proto { udp, tcp } from any to any port domain \
>>>       rdr-to $wired_ip port domain label "dns-redirect"
>>>
>>
>> What is on your LAN that isn't using your DHCP settings for DNS?  Why
>> redirect instead of just blocking DNS from the LAN to all but unbound?
>>
>
> I want to be able to enforce that all queries get funneled to OpenDNS. I
> don't want someone to be able to outsmart the filter, at least at this
> one level. Redirection lets me configure the laptops to have their own
> hard-coded configurations when out and about, and then when I come home
> they transparently query the gateway with no changes. Blocking would
> probably result in me trying to load a page when I get home, failing,
> then remembering to change the DNS config.
>
>

If you redirect, you may then end up funneling requests which are meant
for an *authoritative* DNS server, towards a recursive resolver instead.

Can you just hardcode the laptops to OpenDNS's resolver addresses, and
just permit those through PF? Then, if wanted, you could redirect just
those addresses to your local unbound resolver, and block other port 53.


Reply | Threaded
Open this post in threaded view
|

Re: pf not redirecting DNS queries

Jeremie Courreges-Anglas-2
In reply to this post by Scott Bennett
On Mon, Nov 06 2017, Scott Bennett <[hidden email]> wrote:

[...]

> $ cat /etc/resolv.conf.tail
> search 123090.net
> lookup file bind
> options edns0

Just being curious, why use "options edns0" here?

--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply | Threaded
Open this post in threaded view
|

Re: pf not redirecting DNS queries

Scott Bennett
In reply to this post by Stuart Henderson
On 11/7/2017 8:46 AM, Stuart Henderson wrote:

> On 2017-11-07, Scott Bennett <[hidden email]> wrote:
>>
>> I want to be able to enforce that all queries get funneled to OpenDNS. I
>> don't want someone to be able to outsmart the filter, at least at this
>> one level. Redirection lets me configure the laptops to have their own
>> hard-coded configurations when out and about, and then when I come home
>> they transparently query the gateway with no changes. Blocking would
>> probably result in me trying to load a page when I get home, failing,
>> then remembering to change the DNS config.
>
> If you redirect, you may then end up funneling requests which are meant
> for an *authoritative* DNS server, towards a recursive resolver instead.
>
> Can you just hardcode the laptops to OpenDNS's resolver addresses, and
> just permit those through PF? Then, if wanted, you could redirect just
> those addresses to your local unbound resolver, and block other port 53.

That could be a solution. In what situations would there be a request
for an authoritative DNS server? There's not much on my network (at the
moment) that does anything more than general internet browsing.

Reply | Threaded
Open this post in threaded view
|

Re: pf not redirecting DNS queries

Scott Bennett
In reply to this post by Jeremie Courreges-Anglas-2
On 11/7/2017 9:39 AM, Jeremie Courreges-Anglas wrote:

> On Mon, Nov 06 2017, Scott Bennett <[hidden email]> wrote:
>
> [...]
>
>> $ cat /etc/resolv.conf.tail
>> search 123090.net
>> lookup file bind
>> options edns0
>
> Just being curious, why use "options edns0" here?

I haven't actually modified this file in a few years. This is
just a holdover from following a BSDnow guide when I set up my
first gateway, which recommended setting that option.

Reply | Threaded
Open this post in threaded view
|

Re: pf not redirecting DNS queries

Stuart Henderson
In reply to this post by Scott Bennett
On 2017-11-07, Scott Bennett <[hidden email]> wrote:

> On 11/7/2017 8:46 AM, Stuart Henderson wrote:
>> On 2017-11-07, Scott Bennett <[hidden email]> wrote:
>>>
>>> I want to be able to enforce that all queries get funneled to OpenDNS. I
>>> don't want someone to be able to outsmart the filter, at least at this
>>> one level. Redirection lets me configure the laptops to have their own
>>> hard-coded configurations when out and about, and then when I come home
>>> they transparently query the gateway with no changes. Blocking would
>>> probably result in me trying to load a page when I get home, failing,
>>> then remembering to change the DNS config.
>>
>> If you redirect, you may then end up funneling requests which are meant
>> for an *authoritative* DNS server, towards a recursive resolver instead.
>>
>> Can you just hardcode the laptops to OpenDNS's resolver addresses, and
>> just permit those through PF? Then, if wanted, you could redirect just
>> those addresses to your local unbound resolver, and block other port 53.
>
> That could be a solution. In what situations would there be a request
> for an authoritative DNS server? There's not much on my network (at the
> moment) that does anything more than general internet browsing.

Anything doing lookups directly, including tools like dig/nslookup, or
machines running their own DNS resolver.

With this change I'd be worried about forgetting that it's in place and
then later getting very confused when trying to debug a DNS issue with
some domain using the usual tools. At least if the queries are outright
blocked, it's more obvious.