I have used pfSense on an Alix 2d13 board for about two years now. It works well with pretty much the default setup but the slow down of video content on YouTube due to CDN servers being slow prompted me to implement dnsmasq on pfSense to eliminate the lag, see if I could speed up some of my dns queries by caching dns results, and also block some unfriendly domains all at the same time.
Pfsense allows you to add dnsmasq with a simple click under ‘Services’ -> ‘DNS forwarder’. The key settings are “enable dns forwarder” and “query servers sequentially”. This set pfSense to resolve DNS queries locally first and if the answer is not cached it should go to the next DNS server in the list and then cache that locally. You can use your ISP’s DNS server as the secondary DNS server or use a public one like Google – 184.108.40.206 or 220.127.116.11.
You will see on this same page ‘Host Overrides’. This feature allows you to insert mappings into you host file. You can use this for local names on your network or external domains you want to block. In the case that you have a name you would like to block, you can set the ip to 127.0.0.1 and whenever a resource from the domain is called it will fail (and you will not get the advertisement or other object you are trying to block). Normally you would not want to hard code IP addresses to Domain names for purposes other than blocking or testing – however, on my network, I was bad and hardcoded our mail server domain to ip because I know pretty much every device we have will query this address. If my server ip address were to ever change, this would break mail for everyone on the network.
The ‘Host Overrides’ feature within the GUI of pfSense has a few downsides. It does not like when you enter multi domains with different IPs and it doesn’t allow for wildcard domains. An example of the wild card problem is something like doubleclick.net. They have several variations like ads.doubleclick.net and ads1.doublick.net and can add many new subdomains tomorrow. I want to be able to block them all.
The first thing I did was cruise to ‘Diagnositics’ – > ‘edit file’ and put in the filename of ‘/usr/local/etc/dnsmasq.conf’. I copied most of my setting from another server only changing the local domain which is halo. Here is my copy:
# Tells dnsmasq to never forward queries for plain names, without dots or domain parts, to upstream nameservers. # If the name is not known from /etc/hosts or DHCP then a "not found" answer is returned. domain-needed # Bogus private reverse lookups. # All reverse lookups for private IP ranges (ie 192.168.x.x, etc) which are not found in /etc/hosts or the DHCP leases file are answered # with "no such domain" rather than being forwarded upstream. bogus-priv # # LAN domain lookups # # Add local-only domains here, queries in these domains are answered # from /etc/hosts or DHCP only. local=/halo/ domain=halo # # Add the domain to simple names (without a period) in /etc/hosts in the same way as for DHCP-derived names. # Note that this does not apply to domain names in cnames, PTR records, TXT records etc. expand-hosts # # increase DNS cache size cache-size=10000 # Set the maximum number of concurrent DNS queries. The default value is 150 dns-forward-max=300 resolv-file=/var/etc/resolv.conf conf-dir=/usr/local/etc/dnsmasq.d
The last line is the directory where I am going to put all my hostnames and ip addresses. You could include them all in this config file but it will be easier to update later if you have the configuration separate.
To make the directory, I need to ssh into the pfSense router. By default ssh is turned off and should probably stay that way when you are not making edits. To open ssh, go to ‘System’ -> ‘Advanced’ and look for the checkbox to enable secure shell. Once that is done, you can fire up your favorite secure shell client and connect to the router with the same credentials you use for the web GUI. You will be hit with a menu of options, press 8 to drop to shell.
If you are on an Alix the drive is set to read-only to preserve the compact flash card. To make the needed changes (or if you want to install packages that will aid in scripting) you will need to type: “/etc/rc.conf_mount_rw” to remount the drive with read/write permissions. When you are done, you run: “/etc/rc.conf_mount_ro” to set it back to read-only.
Once you can write to the disk, type “mkdir /usr/local/etc/dnsmasq.d” and you will have the directory you need to add the extra configuration files for dnsmasq. At this point, you can either set the drive back to read-only and use the web GUI or you can use ‘vi’ to make your additional config files. When you are done with shell, type exit. One note – switching to read-write angered my web GUI and I had to restart it from the secure shell menu.
Now you are ready to start defining your addresses. Open up the file editor again. To get me started, I used an address list from yoyo.org. It is already in the correct format for a dnsmasq configuration file. There are plenty of these lists out there – you just have to do a google search and possibly change the format. The format should always look like this:
address=/101com.com/127.0.0.1 address=/101order.com/127.0.0.1 address=/103bees.com/127.0.0.1 address=/123found.com/127.0.0.1 address=/123pagerank.com/127.0.0.1 address=/180hits.de/127.0.0.1 address=/180searchassistant.com/127.0.0.1 address=/180solutions.com/127.0.0.1 address=/1x1rank.com/127.0.0.1
Wildcards will look like:
Of course in this same file you can also define good domains or local domains. When you are done, make sure you save the file in the “/usr/local/etc/dnsmasq.d” directory. You can name it anything – I named mine ad-domains. Now someone super serious about this would automate the process with a shell script that updates the file automatically. At this point I am too lazy and I want to see the overall impact first.
For the Comcast / Slow YouTube Issue – Here is what I did and it seems to be working well so far. I took a look at http://redirector.c.youtube.com/report_mapping to see where I was getting content from. Then I added the mappings for the appropriate hosts from the list on this forum.
After you make all of these changes, you should restart the dnsmasq service on the router to make sure the new configuration is happy and the hostnames are updated. If you have any issue with it restarting from the web GUI, you can always drop back into shell and type “dnsmasq” on the command line. You should get a message about what line in the config file is incorrect. If you see nothing but the shell prompt, all is well and your dnsmasq is running on your pfSense router.
From shell, you can type ‘dig google.com’ and you should see the response time and the ip address. The second time you type it, it should be cached and the result should be faster. If DHCP is set up correctly with DNS forwarding, you can try the same test from another computer on your network.