Generating Firewall Rules with Perl
Listing 2. interfaces.conf
lo = lo gig = eth0 lan = eth1 wifi = eth2 voip = eth3 wan = eth5 tun = tun0
The init() function does the initial setup for the iptables environment. First, we flush, or remove, all of the rules and user chains. Then, we clear all of the rule counters. Later on, these counters will allow us to determine how many packets were caught by each rule in our firewall. Then, the script sets up the IP masquerading. I also put in a rule that allows traffic that is related to an already established connection to pass through the firewall without further evaluation. This keeps the entire rule set from having to be evaluated for each incoming packet. The rules apply only to each new connection request.
The set_default_policy() function configures how we treat network traffic in the absence of any other firewall rules. In this case, I'm interested only in policing incoming traffic; the policy accepts outbound traffic and traffic that the kernel has to route to its final destination. Trivial modifications to this script would allow you to configure policies for each direction. By default, my script denies traffic and requires the administrator to list explicitly all of the allowable traffic. This is the safest way to build a firewall, as opposed to a firewall that allows traffic by default and relies on the administrator to deny dangerous traffic specifically. You can never know in advance all of the dangerous traffic, so denying everything but well-understood traffic is a good idea.
The add_good_hosts() function creates firewall rules that allow all traffic from hosts or networks listed in the good_hosts.conf file. Note that I don't tie these rules to any particular interface. Traffic from whitelisted hosts or networks can come in on any interface. I usually put an entry in this file for my workstation at my home office as well as the network at work. This way, even if I make a silly mistake that would have kept me from logging in to my router remotely, I can still get in from work or my office workstation to undo the change. Of course, this also assumes that my workstation and the network at work haven't been compromised. Usually, the contents of this file are quite short indeed.
Listing 3. good_hosts.conf
127.0.0.1 Loopback 18.104.22.168/8 Multicast 10.4.0.0/16 VPN 10.0.1.1/32 Home office
Conversely, the add_bad_hosts() function creates firewall rules that block all traffic from hosts or networks listed in the bad_hosts.conf file. This function works almost exactly like the add_good_hosts() function with one important difference. When traffic from a blacklisted host comes to the router, the router will not only log this fact, it will also include the comment from the bad_hosts.conf file in the log. This way, I can look at my log file and see why a particular host was blocked. A useful improvement to this function would be to have it place the bad host rules in a separate chain and have that chain called early on in the rule set. This would give you the ability to add and delete hosts conveniently from this chain from an external program, perhaps in response to entries in your server log files.
Listing 4. bad_hosts.conf
22.214.171.124 My_comment www.microsoft.com Microsoft
The build_chains() function builds a series of firewall rule chains. I build a separate chain for each combination of interface and protocol. For example, if I had a Linux router with eth0, eth1, eth2 and eth3, I would create chains for eth0-tcp, eth0-udp, eth1-tcp, eth1-udp and so on. Then, I build the rules necessary to send the decision-making process down the appropriate chain. What we end up with is a decision tree that determines what to do with each packet entering the router. Unlike a linear list of firewall rules, the decision tree prevents the kernel from having to evaluate obviously irrelevant rules. For example, a TCP packet coming in on the WAN interface will never be tested against the rules meant for UDP packets on the Wi-Fi interface.
I haven't done any objective testing to see if this tree-pruning actually makes a significant performance improvement. On the other hand, once the program is written and debugged, it costs me nothing to change the configuration files and have this decision tree generated automatically. So even if it improves performance by only a small amount, it adds so little to the program's complexity that I think it makes sense to do it.
The add_rules() function is where most of the work is done. This function reads the contents of ports.conf, which is shown in Listing 5. Before we discuss the add_rules() function in detail, we should discuss the format and content of the ports.conf file.
The ports.conf file contains one line for each firewall rule. Each line contains three columns and an optional comment preceded by the # character. The first column is the user-defined label for the interface that the rule will be applied to. The second column is the protocol, that is, tcp, udp or the special case, all. Using all for the protocol creates a rule that allows all traffic on the interface in question. Finally, we have the port number. For example, the first line of the file creates a rule that allows SSH traffic to come in on the wan interface.
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 email@example.com
Fast/Flexible Linux OS Recovery
On Demand Now
In this live one-hour webinar, learn how to enhance your existing backup strategies for complete disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible full-system recovery solution for UNIX and Linux systems.
Join Linux Journal's Shawn Powers and David Huffman, President/CEO, Storix, Inc.
Free to Linux Journal readers.Register Now!
- The Italian Army Switches to LibreOffice
- Download "Linux Management with Red Hat Satellite: Measuring Business Impact and ROI"
- Linux Mint 18
- Oracle vs. Google: Round 2
- Varnish Software's Varnish Massive Storage Engine
- The FBI and the Mozilla Foundation Lock Horns over Known Security Hole
- Devuan Beta Release
- Privacy and the New Math
- Ben Rady's Serverless Single Page Apps (The Pragmatic Programmers)
Until recently, IBM’s Power Platform was looked upon as being the system that hosted IBM’s flavor of UNIX and proprietary operating system called IBM i. These servers often are found in medium-size businesses running ERP, CRM and financials for on-premise customers. By enabling the Power platform to run the Linux OS, IBM now has positioned Power to be the platform of choice for those already running Linux that are facing scalability issues, especially customers looking at analytics, big data or cloud computing.
￼Running Linux on IBM’s Power hardware offers some obvious benefits, including improved processing speed and memory bandwidth, inherent security, and simpler deployment and management. But if you look beyond the impressive architecture, you’ll also find an open ecosystem that has given rise to a strong, innovative community, as well as an inventory of system and network management applications that really help leverage the benefits offered by running Linux on Power.Get the Guide