Generating Firewall Rules with Perl
Listing 5. ports.conf
wan tcp 22 # ssh wan tcp 25 # smtp wan tcp 80 # http wan udp 53 # dns wan udp 1194 # openvpn wan udp 5060 # sip wan udp 4569 # iax2 wan udp 10000:20000 # rtp lo all lan tcp 22 # ssh lan tcp 25 # smtp lan udp 53 # dns lan tcp 53 # dns lan udp 67 # dhcp lan udp 68 # dhcp lan tcp 80 # http lan tcp 111 # portmapper lan udp 111 # portmapper lan tcp 143 # imap lan tcp 443 # https lan tcp 2049 # nfs lan udp 2049 # nfs lan tcp 3306 # mysql lan udp 4569 # iax2 lan udp 5060 # sip lan tcp 5432 # postgresql lan tcp 10000 # webmin lan all gig all tun all wifi udp 1194 # openvpn voip udp 5060 # sip voip udp 4569 # iax2 voip udp 53 # dns voip tcp 22 # ssh voip udp 10000:20000 # rtp voip tcp 80 # http
You'll notice that I have a rule that allows all traffic on the lo, or loopback, interface. This is important, because without this rule, many programs break in ways that are hard to diagnose. You also may be asking why I go to the effort of creating so many firewall rules for my LAN interface, only to have an all at the end. I do this for several reasons. The primary reason is that until my kids grow up and get on the Internet, I trust the traffic on my local network. However, by having rules for each service I run, I'm able to extract statistics about how much traffic each service generates. Also, security is an iterative process. Over time, I'll add rules that will further tighten my firewall; eventually, I'll remove the final all from the policy.
Now, back to the add_rules() function. Even though this is the longest function in the entire program, it's still not too hard to understand. The sections of code that deal with tcp and udp rules simply create two rules for each rule in the ports.conf file. One rule is tied to the destination port number; the other rule is tied to the source port number. At first, this may seem odd, because we are policing only inbound traffic. What we're doing is making sure that both inbound and outbound connections are allowed to pass. For example, a packet coming in on the WAN interface with the destination port set to 80 corresponds to an inbound connection to my Web server. On the other hand, an incoming packet on my WAN interface with the source port set to 80 is coming from an outside Web server in response to a request that came from inside my network.
The code that handles the all rules is a special case. In this case, we create a rule on the given interface for each of the protocols. In hindsight, this might be overly complex, but it has an interesting side effect. If the router encounters a packet containing an unknown protocol, such as IPSec, the firewall will fall back to its default policy even though we've asked it to pass all traffic on this interface. So, in a sense, “all protocols” actually means “all known protocols”. I think this is a good thing.
For what it's worth, the script will put firewall rules into the kernel in roughly the same order that they appear in the ports.conf file. I say roughly, because the rules will be put into the appropriate chain depending on which interface and protocol they match against. But within each chain, the rules will be executed in order.
The set_default_action() function creates rules that determine what happens to packets that don't match any previous rules. This sounds very similar to the purpose of the set_default_policy() function, but there is a subtle difference. The set_default_policy() function configures the default firewall policy, and the set_default_action() function creates firewall rules that catch unmatched traffic before the kernel falls back to the default policy, essentially capping each chain. Once these rules match a packet, they create a log entry for the packet, and then they implement whatever policy we want, in this case, DROP. Once again, the log entries allow me to determine what traffic is being dropped and why.
I'm not trying to tell you that this program is perfect, nor will it do everything you want it to do. You might even find bugs in it. In fact, by the time you read this article, I'll probably have made several improvements to the script. As it is right now, the script isn't able to configure any firewall policy for the ICMP protocol. It would be nice to be able to allow outbound ping requests and deny incoming requests, for example. It would also be useful to be able to configure firewall policy for outgoing and routed traffic. And because I'm using VoIP, I'm thinking of changing my script to allow me to configure Quality of Service (QoS). If you come up with useful modifications to this script, I'd like to hear about them.
But there you have it, such as it is. In less than 200 lines of Perl code, I'm able to implement a quite flexible and efficient firewall policy containing potentially hundreds of individual rules. At the same time, making changes to my firewall policy is simple enough that even most beginning Linux users can make correct changes.
Mike Diehl works for SAIC at Sandia National Laboratories in Albuquerque, New Mexico, where he writes network management software. Mike lives with his wife and two small boys and can be reached via e-mail at mdiehl@diehlnet.com.
Mike Diehl is a freelance Computer Nerd specializing in Linux administration, programing, and VoIP. Mike lives in Albuquerque, NM. with his wife and 3 sons. He can be reached at mdiehl@diehlnet.com
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
| Introduction to MapReduce with Hadoop on Linux | Jun 05, 2013 |
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- Linux Systems Administrator
- Validate an E-Mail Address with PHP, the Right Way
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Senior Perl Developer
- RSS Feeds
- Technical Support Rep
- Introduction to MapReduce with Hadoop on Linux
- Weechat, Irssi's Little Brother
- What the author describes
1 hour 7 min ago - Reply to comment | Linux Journal
5 hours 18 min ago - Reply to comment | Linux Journal
6 hours 3 min ago - Didn't read
6 hours 13 min ago - Reply to comment | Linux Journal
6 hours 18 min ago - Poul-Henning Kamp: welcome to
8 hours 29 min ago - This has already been done
8 hours 30 min ago - Reply to comment | Linux Journal
9 hours 15 min ago - Welcome to 1998
10 hours 3 min ago - notifier shortcomings
10 hours 27 min ago
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
Error in add_good_hosts subroutine
Hi Mike,
Trying to get this working.
I've only one good host, namely loopback so my good_hosts.conf looks like this:
127.0.0.1 loopback
and I'm getting the following error on stdout when I run the script:
Setting IP forwarding to 0.
Try `iptables -h' or 'iptables --help' for more information.
X: (512) iptables -A INPUT -s 127.0.0.1 loopback -j ACCEPT
Try `iptables -h' or 'iptables --help' for more information.
X: (512) iptables -A OUTPUT -d 127.0.0.1 loopback -j ACCEPT
Setting IP forwarding to 1.
I'm not much a Perl coder I'm afraid, and by the looks of it it's an iptables issue rather than a Perl issue.
Any help much appreciated.
sdt
Error in add_good_hosts subroutine
Are you putting a TAB after the IP address, or a SPACE? The script splits on tab. I'll bet this fixes your errors.
Email me directly if it doesn't. My address in in the article.
Mike.