Setup Pihole To Work With Pfsense (In Vmware ESXI) and To Redirect All DNS Traffic Back to Pihole

pfsensepfsense

Overview

  • Not all devices play nice. Some devices like to use their hardcoded DNS servers.
  • We call these rogue devices.
  • What this means is that the DNS traffic will reach out through the firewall to the public DNS, ignoring what your firewall's preferred DNS server is. In our case, we use Pihole.
  • Let's setup a system that transparently intercepts and redirects ALL DNS traffic to an internal DNS of our choice (Pihole).

Requirements

  • I'm assuming you already setup Pfense and Pihole.
  • Read article1 on how to setup Pfsense in Vmware ESXI.
  • Read article2 on how to setup Pfsense with Pihole.
  • With that knowledge, we can continue with this guide.

Network Guide

In this setup, I use a computer that has:

  • Onboard network card attached to motherboard
    • I assigned this as LAN Network in Pfsense
    • Cable attached to my switch, so all devices can communicate
  • First 1Gbps Intel NIC attached
    • I assigned this as WAN Network in Pfsense
    • There is a cable going to my Modem (and out to the internet)
  • Second 1Gbps Intel NIC attached
    • I assigned this as DMZ Network in Pfsense
    • There is no cable attached to this card, as this will be a virtual pc

Setting up Vmware ESXI

  • Power off your ESXI, physically install a new NIC inside the machine
    • By adding a new NIC, we can make it work
    • A cable doesn't need to be plugged into that port since the Pihole will be connected virtually to that port
  • Power on your ESXI
  • Networking, Physical NICs Tab,
    • This NIC will appear as vmnic2 (you can also verify the MAC address here)
  • Networking, Virtual Switches Tab, Select Add standard virtual switch
    • Name: DMZ-v-switch
    • Uplink: Select vmnic2
    • MAC Address changes: Change to Accept
    • Forged transmits: Change to Accept
  • Networking, Port Groups Tab, Select Add Port Group
    • Name: DMZ-port-group
    • vSwitch: DMZ-v-switch (we created earlier)

Setting up Pfsense in Virtual Machine

  • Power off your pfsense virtual machine
    • Edit, settings, select Add network adapter
      • This will add Network adapter 3 below
      • Select DMZ-port-group from drop-down
    • Save
  • Power on your pfsense virtual machine
  • Pfsense, Interfaces, Assignments
    • You'll see WAN, LAN, a new entry "Available network ports" (if you don't see this, it means something failed, go back to recheck your steps)
    • Select Add next to this 3rd network.
      • In my case, it was vmx2 (mac address)
      • You'll see a Interface has been added message on top
      • You'll see that the name is called OPT1
  • Pfsense, Interfaces, OPT1
    • Enable Enable Interface
    • Description: Rename from OPT1 to DMZ (so I recognize it)
    • IPv4: Change from None to Static IPv4 (which just means it's statically assigned, not dynamic)
    • IPv4 Address: Set as 192.168.2.1 (must be on separate network from LAN network)
      • then change /32 to /24
    • Save
    • Apply
  • Pfsense, Services, DHCP Server, DMZ tab
    • Select Enable DHCP server on DMZ interface
    • Range
      • From: 192.168.2.100
      • To: 192.168.2.200
      • DNS Servers: [blank for now] (later, we'll set to be the IP of Pihole)
    • Save
  • Pfsense, Firewall, Rules, DMZ Tab, Select Add
    • Action: Pass
    • Interface: DMZ
    • Address: IPv4
    • Protocol: Any
    • Source: DMZ Net
    • Destination: Any
    • Description: Allows all traffic on DMZ network
    • Save
    • Apply
    • NOTE: This firewall rule enables a lot of things, so traffic can flow in/out of DMZ network. I could have been more restrictive, but for this example, it's easier to just allow everything.
  • Pfsense, DNS Resolver, General Settings,
    • Under Network Interfaces, make sure DMZ is selected (otherwise none of your machines on DMZ network will be able to reach 192.168.2.1 and so DNS won't work until this is fixed)

Setting up Pihole (in Ubuntu) in Virtual Machine

  • Vmware ESXI, Virtual Machines, Pfsense, Edit, Settings
    • Make sure Network Adapter 1 is set as DMZ-port-group
  • Power on Pihole virtual machine
  • Once pihole boots into console:
    • sudo su
    • cd /etc/netplan/ (only works in Ubuntu, not Raspberry Pi)
    • ls (you'll see a file called 00-installer-config.yml or one similar to it it)
    • nano 00-installer-config.yaml (I used nano to edit this file, but feel free to use another text-editor)
      • IP address: 192.168.2.2/24
      • Gateway: 192.168.2.1 (this is the IP of pfsense gateway for DMZ network, we set earlier)
      • Nameservers (aka DNS): 192.168.2.1 (this is the IP of pfsense gateway for DMZ network, we set earlier)
    • Press Ctrl+O to write the changes, press enter, then Press Ctrl+X to exit.
  • To apply these configuration changes, type:
    • netplan apply

Configure Pihole Dashboard

  • Pihole dashboard, settings, DNS tab
    • Remove any public DNS servers
    • Set Custom 1 (IPv4) as 192.168.2.1 (OR you can use 192.168.1.1 since they both go to pfsense)
    • Under Interface listening behavior, set the option Listen only on interface ens160
    • Enable Use conditional forwarding
      • IP of your router: 192.168.2.1 (OR you can use 192.168.1.1 since they both go to pfsense)
      • Local domain name: mylocal
    • Save
caution

Under Interface listening behavior, if you set Listen on all interfaces, your Pihole won't work. Fix it by changing it to Listen only on interface ens160.

Let's send traffic to Pihole

  • Pfsense, Services, DHCP Server, LAN tab
    • DNS Servers: 192.168.2.2 (IP of pihole)
  • Pfsense, Services, DHCP Server, DMZ tab
    • DNS Servers: 192.168.2.2 (this step is optional, but to keep things consistent, we can set this)
  • The easiest way for the clients to get the DNS server from Pfsense, is to restart the clients

Apply firewall rule to redirect 'rogue devices' that use custom DNS, back to Pihole

  • Pfsense, Firewall, NAT, Port Forwarding Tab, Select Add (UP-arrow)
    • Interface: LAN
    • Protocol: TCP/UDP
    • Source: Any
    • Source port: Any
    • Destination Address:
      • Select Invert Match
      • Select LAN Address
    • Destination port: DNS (port 53)
    • Redirect Target IP: 192.168.2.2 (Pihole IP)
    • Redirect Target port: DNS (port 53)
    • Description: Redirect rogue devices back to pihole
  • Pfsense, Firewall, Rules, LAN tab,
    • Drag the newly created rule Redirect rogue devices back to pihole to the top of the list
      • It must be above the default rule of Allows all traffic on LAN network
    • Save
important
  • Without this firewall rule, you're going to have problems when trying to redirect traffic in and out the same interface with a port forward.
  • By moving Pihole to its own network segment, we can use port forward to solve this problem.

Test 1 - Normal use case

  • Pfsense should push the DNS server of 192.168.2.2 to any client on LAN 192.168.1.0/24 network.
  • Double check that your DNS is correct, otherwise, restarting the device would need to be done.
  • Go to any website or use anything that connects to internet
  • Go to your Pihole dashboard of 192.168.2.2, and you'll see that client's DNS queries and you'll see them being blocked!
    • Everything is working as intended!

Test 2 - Custom DNS client (that's on the wired network)

  • Now, let's consider the rogue client who's changed the DNS server to a custom one
  • Set your PC with custom DNS (any public one)
    • 8.8.4.4 or 1.0.0.1
  • This means that the traffic (in a typical use case) should be ignoring Pihole right now and going directly to public DNS servers.
  • Go to your Pihole dashboard of 192.168.2.2, and you'll see that client's DNS queries are being blocked.
    • So to the client, DNS entries appear to be going to public servers, but in reality, they end up in Pihole because of our NAT rule.
    • Everything is working as intended!

Test 3 - Custom DNS client (that's on the wireless network)

  • On my cellphone, I noticed that when I set a custom DNS to be a public IP, and checked to see if all traffic was being redirected to Pihole, it wasn't.
  • On my network, I have multiple wifi systems that have their own firewalls disabled, which forces everything back to pfsense.
    • They are acting like Access Points (if you heard the term before).
  • I have multiple wireless access points that all have custom settings:
    • IP of Access points: Statically assigned on 192.168.1.0/24 network
    • Gateway: 192.168.1.1 (my pfsense)
    • Primary DNS:
      • Previously set to 192.168.1.1 (I set this up by default, before I had Pihole)
      • Now, I set it to my Pihole IP 192.168.2.2
    • Secondary DNS:
      • Previously set to a public DNS Server
      • Now, I set it [blank]
  • Go to your Pihole dashboard of 192.168.2.2, and you'll see that client's DNS queries are being blocked.
    • So to the client, DNS entries appear to be going to public servers, but in reality, they end up in Pihole because of our NAT rule.
    • Everything is working as intended!

Confirming all DNS traffic is flowing normally

  • At this stage, you shouldn't have any problems. If you want to confirm that the traffic is flowing normally, read on.
  • Go to Pfsense, Diagnostics, pftop
  • DNS traffic on your LAN/DMZ network
    • Filter Expression: port 53
    • Sort by: Source Address
    • If you see Source 192.168.1.X:YYYY => Destination 192.168.2.2:53
      • This is traffic going from a LAN device to Pihole
        • This is expected
    • If you see Source 192.168.2.2:YYYY => Destination 192.168.1.1:53
      • This is traffic going from Pihole to Pfsense
        • This is expected
  • DNS traffic between your firewall and WAN
    • Filter Expression: port 853
    • Sort by: Destination Address
    • If you see Source XX.XX.XX.XX:YYYY => Destination 1.1.1.1:853 (or whatever you set)
      • This is traffic going from your WAN port of Pfsense to Public DNS servers (you set in Pfsense) over port 853 (DLS over TLS)
        • This is expected

Conclusion