
Using pfBlockerNG (And Block Lists) On pfSense
If you are also interested in pfBlockerNG (DNSBL) for ad and
malvertising blocking, I have a walk-through on it here!
–> Blocking Ads & Malvertising on pfSense Using pfBlockerNG (DNSBL) <–
In a previous post, I talked about implementing blocklists (aka IP reputation lists, ban lists, blacklists, etc.) generically on nearly any firewall to improve your security. The examples I used were on pfSense and OPNsense. I also discussed the methodology and some background as well so if you’re just coming into the conversation, it might be worth a read beforehand. (Previous Post: Using Firewall Block Lists)
There were some downfalls to the previously discussed approach such as the URL download (via aliases) only allowed updates every 1 day as the shortest timeframe. In addition, the “list” had to be in a very specific format so I originally wasn’t able to use known, high-quality lists with “split fields” like the original formats provided by DShield (Internet Storm Center) or Emerging Threats. Yes, I realize I could easily script this up to get rid of both of these limitations, but why if you don’t need to? 😉
If you are using pfSense, there is an amazing plug-in called pfBlockerNG that gets around many of these issues. pfBlockerNG is a free package originally written by some other folks, but now maintained by @BBcan177 (on Twitter). I’ve been pretty harsh on pfBlocker many years ago because it was primarily a way to blacklist countries based on IP ranges; I didn’t agree with this approach because it doesn’t work for most businesses and it would inevitably block much needed customer traffic at some point and it was a PITA to troubleshoot. While that particular functionality still exists in the package, I won’t talk about it here. Keep in mind this feature may be useful depending on your use case.
Instead, I’ll talk about using IPv4 blocklists in pfBlockerNG. At this point, I’m assuming you have already installed the package. If not, go do so and I’ll wait here…
After installing the package, you will need to enable it from the main page. Change the settings on the main screen as necessary. Items worth noting include that I would check the interfaces to verify all of your networks are there and the “kill states” is checked.
Next, go to the IPv4 section and we are going to add some fairly well-known lists. I already discussed the ban list from Binary Defense in the last blog. The IP banlist updates every 5 minutes and while we won’t update every 5 minutes, we are going to set it up to update every hour as shown below. The other difference is that we will set the list action to “deny both” to create firewall rules blocking traffic in both directions to offending IP addresses. Note: the header/label (BD_IPs for this example) is simply used as a placeholder. The label should, however, have something signifying which list it originates from. I’ll explain this a bit more later.
https://www.binarydefense.com/banlist.txt
Great! So we did the same thing as the previous post did with aliases, but now we are updating once an hour instead of once a day. What else can we do?
The big change is that we can add other lists in various formats. In addition to a huge, clean list of IP addresses like the banlist.txt from Binary Defense, we can also add list formats such as those used by Emerging Threats and DShield. Both of these include CIDRs (196.63.0.0/16), which would would block huge swaths of IP addresses vs. single IP addresses.
For what it is worth, you may have also seen previously that you can tie multiple blacklists to a single alias. So you may be asking, why am I separating them here? Based on experience, the free Emerging Threats lists only update every few days so to avoid unnecessary calls to their servers, once a day should suffice.
The one “block” list from Emerging Threats already includes the aforementioned CIDRs from DShield so we don’t need to include that list separately (as shown below).
https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt
Information from that feed header
*Those DShield CIDRs are also listed at the bottom of that feed
# Emerging Threats fwip rules. # # Raw IPs for the firewall block lists. These come from: # # Spam nets identified by Spamhaus (www.spamhaus.org) # Top Attackers listed by DShield (www.dshield.org) # Abuse.ch # More information available at www.emergingthreats.net |
The URL for the other list is below.
https://rules.emergingthreats.net/blockrules/compromised-ips.txt
After we add both URLs, the identifying headers/labels, change list action to ‘deny both,’ and update frequency to ‘once a day’ we are ready to go.
Click ‘save’ and if you followed my naming conventions, your aliases under IPv4 should look similar to mine below.
Update – firehol_level3 – 19 March 2017
I was notified of the numerous ban lists on http://iplists.firehol.org/ shortly after this write-up (and the related one on using firewall blocklists). Overall, the site has great explanations on the in’s and out’s of the various lists. Their comparisons/metrics include what percent of one list is included in another list, which ones might yield false positives, how an IP address would get added to a list, etc. After testing in a few environments for several weeks, I found the firehol_level3 list to be extremely effective and I haven’t yet experienced a false positive.
You configure firehol_level3 much in the same way the Binary Defense list was configured above, i.e. deny both, update every hour, etc. I also chose to update from the GitHub feed (vs. the firehol.org site) to avoid bandwidth costs for someone providing a free/low-cost service. Note: There are other feeds there that might be useful on the site as well. I chose the firehol_level3 feed because of what is included and what should be a fairly limited number of false positives.
https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level3.netset
Firewall Rules
If you go to the firewall rules section of your firewall, you should see two (or three) separate rules added automatically on the WAN side. Similar rules should have been added to the LAN side as well… Remember we are blocking in both directions.
WAN
LAN
As previously described, you can once again hover over either of the rules to see if the IP addresses/ranges have been pulled back by the firewall cron entry we setup a short time ago. You can also go to the diagnostics, table, pfB_[your list name] to look at all of the IP addresses and ranges for that particular alias/list.
The update page for pfBlockerNG also tends to be pretty solid if you need some assistance troubleshooting, e.g. why something won’t update. You can also force updates, see when the next run time is, etc. as well.
Last, but not least… Is it working? The alerts page on pfBlockerNG shows you timestamps for blocked IPs, what interface it was on, what rule triggered the block or reject, etc.
Note in the example above I’m seeing blocks on the WAN side. If you’re seeing blocks on the LAN, that means an internal machine is attempting to contact a known malicious IP address and is really, really ridiculously bad!
In all seriousness, keep an eye out for blocks on the LAN side as that can be a fantastic indicator that one of your internal machines is compromised.

Dallas Haselhorst has worked as an IT and information security consultant for over 20 years. During that time, he has owned his own businesses and worked with companies in numerous industries. Dallas holds several industry certifications and when not working or tinkering in tech, he may be found attempting to mold his daughters into card carrying nerds and organizing BSidesKC.
32 thoughts on “Using pfBlockerNG (And Block Lists) On pfSense”
Love this article! Very informative. Unfortunately for a few reasons I have migrated from pfSense to OPNsense and the pfBlockerNG plugin is not an options it seems.
I know it’s asking a great deal but would you consider putting out the script to smooth out the limitations on OPNsense?
thank you for your time!
Thanks for the feedback! I’m not the author of pfBlockerNG, but I’ve often wondered the same because of their similarities. Maybe the author will provide this plug-in for OPNsense in the future? In the meantime, you can utilize the previous write-up on using simple blocklists; as discussed, there are limitations to this technique such as the update timeframe, however, it is definitely better than nothing!
Can I ask why you moved from pfsense to opnsense? Also, how do you like it?
Great article
Thank you! Glad you enjoyed it!
So do you use firehol3 in addition to the previously mentioned EmergingThreats and BinaryDefense, or is firehol3 inclusive enough that you don’t think those other two are necessary?
Yes, I use firehol3 in addition to the others and it performs quite well. Make sure you don’t use firehol1 unless you change the interface rules as firehol1 includes private IP ranges. I’ll make some updates to the pfBlockerNG article when the new version is released too, so stay tuned!
Great info! What about firehol 2 and 4? Should some of the other lists be used as well?
Mark, happy to hear you found it useful! I don’t recall on firehol2, but I know firehol4 was expected to have a large number of false positives (their words, not mine). This is the sole reason I didn’t use it, i.e. I would rather let something pass than errantly block it. It really just depends on your environment and your tolerance for false positives. Firehol3 seemed to be the sweet spot for me, but your mileage may vary. Test it out and let me know!
In regards to other lists, I’m now utilizing roughly 60 lists and I will be performing another post on it very, very soon. With the 2.X branch of pfBlockerNG it would be ridiculously difficult to replicate my current setup IMO simply because of the amount of configuration. That being said, BBcan177 (the author of pfBlockerNG) has knocked it out of the park on the new version 3.0 that I’m currently beta testing. I expect 3.X to get released in the next month and it has a ton of new features beyond *just* config. As soon as it is released, check back here and I’ll have a write-up on the new config process as well as which lists I’m using/testing. I’ll include some of the gotchas I encountered along the way too.
@pfblocker now support domain blacklist services from Squidblacklist.org for your web filtering purposes.
#end shameless plug
Not a shameless plug at all! I was in the process of writing a post on DNSBL services when I started beta testing version 3 of pfBlockerNG so I held off on it for the time being. I’ll write a config guide on DNSBL as soon as the new version is released. FWIW, I double-checked and SquidBlackList is already listed as one of the “pre-configured” Ad feeds. 😉
Came across your article recently while trying to garner info on using pfBlockerNG effectively. I’m curious as to whether you configure any other feature in PFB other than the IPv4 blocking you illustrated so nicely above? (I have added these to our system – thanks!)
I’ve been using the GeoIP lists in PFB to block (deny_inbound) most countries. This works, but has limitations of control in that blocking USA sources (we’re in UK) also blocks a lot of legitimate inbound email – and it’s apparently not the “recommended” configuration. It results in having to manually make our own whitelists for customers using 3rd-party USA or European email scanning hosts (like messagelabs.com or similar).
I typically didn’t use country block for that same reason, i.e. users travel and so it was a constant source of angst. I also use DNSBL quite extensively to block ads (malicious especially). Since this post, I’ve added several feeds to the IP blocklists. Adding quality blocklists and DNSBL is made significantly easier in the yet unreleased version of pfBLockerNG, which I have been testing for some time. As soon as the new version is released, I will have corresponding posts to ease implementation. Take care!
I’m switching from pi-hole to pfBlockerNG which had to be set as the client DNS server for it to work. Is pfBlocker the same or can my computers use any DNS server and pfBlockerNQ will still filter requests?
DNS blackholing via pfBlockerNG does require your client’s DNS set to it similar to how a Pi-hole works. The reason for this is because of how DNS blackholes work, i.e. when your client sends a DNS query, the DNS server will respond with a different IP address (most often a local IP address) instead of the actual IP address. Also worth noting is that on a pfSense, the DHCP server will use itself as the primary DNS by default so manual client DNS entries are not necessary (assuming that is how you handled it before). Holler back if you have any other questions!
It seems like https://www.binarydefense.com/banlist.txt is not accessible anymore. Has something changed?
Thanks!
It appears the last banlist.txt download I received from Binary Defense was on March 26th so you are not alone. I reached out to Dave a short time ago and they are working on it. Thanks for the heads up!
Hi Dallas,
Thank you for this article. 5 minutes ago I’ve set everything up as you’ve explained in this article. Something very strange happened on my network where the mdns service on port 5353 was broadcasting to over 3125 hosts, consuming 202GB of data in a very short while. It brought my network to a complete halt and I was running around trying to figure out how to block this. To date, I am still unable to determine which device this was, where this came from, why this happened AND why pfSense did not block this. All the IPs it was broadcasting to started with 0.53.X.X. No matter what firewall rules I tried to implement, nothing helped… As I was busy setting up pfBlcokerNG, the *attack* stopped. As a result, I got blacklisted by a few service providers (including my own) and even ntop (claiming to be the best analytics tool) could not provide enough info for me about what happened… I am not sure if pfBlockerNG would prevent this from happening, but paranoia made me add ANOTHER tool to prevent this. (Not sure why I just told you all that, basically just wanted to say thank you for the article!)
Sometimes writing is great therapy! LOL!
So first, 0.53.X.X (and 0.0.0.0/8 in general) is a reserved network. Per RFC 6890, it is meant to represent the local network only. The firewall was the only OS/device where a simple utility like ping could even attempt communication with that range. FWIW, I didn’t try crafting packets or using raw sockets as I’m assuming those would have been allowed. I’m at a bit of a loss on what would cause this issue… A failing NIC? A misbehaving OS? Or something more nefarious? I would watch the network closely to see if you see any other anomalous activity. That aside, layered defense is the best approach and adding layers that make a difference REALLY helps. What I mean is you are on the right track whether pfBlockerNG would have helped in this instance or not. Something else you should consider is egress/outbound filtering. Best of luck and thanks for the feedback!
Derik, below is another, much better answer from a friend of mine who I posed your question to… Sadly, he also references an RFC! (Thanks Q)
Hope it helps!
—
Perhaps PfSense requires a rule specifically calling out 0.0.0.0/8
Honestly that is a head scratcher because 0.0.0.0 is not routable. My first thought would be a broadcast, but that is 255.255.255.255 in almost all instances.
RFC 3330:
0.0.0.0/8 – Addresses in this block refer to source hosts on “this” network. Address 0.0.0.0/32 may be used as a source address for this host on this network; other addresses within 0.0.0.0/8 may be used to refer to specified hosts on this network ([RFC1122], Section 3.2.1.3).- Local Broadcast… So all traffic appears to only be internal to a switched/router network
RFC1700 states, addresses 0 addresses “Can only be used as a source address”
RFC 1122 Section 3.2.1.3: (a) { 0, 0 } This host on this network. MUST NOT be sent, except as a source address as part of an initialization procedure by which the host learns its own IP address. See also Section 3.3.6 for a non-standard use of {0,0}.
RFC states that this traffic should only affect internal networks and it will only affect internal networks as that address can ever only be a source IP address, and that address can never be a destination. My hypothesis is the mdns service broadcasted a message outbound (perhaps through a NAT address?), any DNS Request message would work. The MDNS service was given the 0.53.x.x address as a configuration (either legitimate or illegitimate) and the NAT translated it for outbound traffic. The mdns service could have been compromised, or mis configured, and faultily performed the actions. If it was malicious, it could have been a reverse DDoS style attack, were the client systems DDoS themselves by having their providers cut their connection….
Thanks for the article, Dallas, looking forward to the new version. Do you cover any ipv6 lists/blocking in that tutorial? If not, please consider an article on that in the future.
I should have the new version of the walkthrough completed in the next week or so. FWIW, the new version of pfBlockerNG has IPv6 feeds built-in. Hopefully that is what you are looking for… If not, just give me a holler. Thanks for the feedback!
Great article. It’s great to see these sorts of tutorials/guides to help us all along.
I do have one query, I have just installed pfBlockerNG-devel v2.2.1. For some reason, under the feeds tab, when I click the +, and then need to change the action from Disabled to Unbound, there is no option for Unbound.
I’m assuming DNS resolver is enabled? Is the “server:include: /var/unbound/pfb_dnsbl.*conf” included in custom options? If all that checks out, I would un-check the “keep settings” and then uninstall/reinstall pfBlockerNG. You may also want to check your logs (and specifically pfBlockerNG logs) to see if there are any obvious errors there. I’d love to hear back what you figure out and especially if I should include it as a troubleshooting step in the write-up. Thanks!
What is the firewall rules when one is blocked and the other is permitted. Shall the blocked rule above permitted rules or vice versa? What is the priority order?
thanks
I’m assuming you are referring to IP blacklists instead of the DNSBL portion of pfBlockerNG? Firewall rules are run in order from the top to the bottom, i.e. if an IP blocklist is above other rules, the topmost rule will “hide” other, possibly related or even better suited rules below it. If you are using pfBlockerNG, the whitelist should be the topmost entry with “permit outbound” in the IPv4 summary list. Holler back if that doesn’t make sense or if that didn’t answer your question!
Awesome write up Mr. Haselhorst. Using pfBlockerNG with your recommended blocklists on pfSense 2.4.3. Works wonderfully. Only problem now is hunting down the machines(s) responsible for blocks on the LAN/OPT1 side of things. Going to blame those on the kids. Thanks again!
Excellent! You can always blame the kids! 😉 If you haven’t already done so, definitely check out the DNSBL portion of pfBlockerNG. It is a life-changer as well!
Blocking Ads & Malvertising on pfSense Using pfBlockerNG (DNSBL) https://linuxincluded.com/block-ads-malvertising-on-pfsense-using-pfblockerng-dnsbl/
Hi Dallas
Do you have plans to update this to follow the new layout of PFBlockerNG devel ? Some options have moved around and some are new so I got lost. ( not sure what some of the new options are doing). ex. the feed update for firehol3 failed. It was being blocked. And I don’t see an option to whitelist it.
[ pfB_Firehol3_v4 – Firehol3_v4 ] Download FAIL
I just tried accessing the firehol3 feed and it worked. The firehol feeds all pull from github and specifically, raw.githubusercontent.com, so that must be inaccessible due to your DNSBL config. Add it to your DNSBL whitelist and see if that changes your access to it. Even if you can’t get that working, I would still recommend adding the various IPv4 feed categories (just as you did with DNSBL) such as PRI1 and PRI2. I personally disable any feeds that indicate it is a paid feed (blue arrow in a door), but YMMV. I’ve been meaning to update the IP blocker guide for the new version but I haven’t had time to do so because it really is a re-write with all of the amazing changes BBcan177 made in the new version. 😉 Someday!
Hi Dallas,
What a wonderful tutorial, very detailed. However i am using pfsense in a official environment where client computers are configured with the DNS on the network (the DNS on the Domain Controller). How do i configure pfBlockerNG since i have to set it as the DNS for all client computers.
Thanks
This is something I’ve been meaning to do a brief write-up on… You still should have your client DNS pointing to the DCs, but on the DCs you set the pfSense IP as the forwarder. I tend to remove the “root hints” checkbox, but I also monitor my pfSense boxes quite extensively. Good luck and holler back if you have any issues!