Secure your Server with iptables

Share this article

Central to securing a Linux server that’s connected to the Internet is having a good firewall and specific policies in place. Numerous options exist for those considering firewalls for Linux, however, a free and included solution is onoffer through Netfilter and iptables.

Stateful Firewall

As of Linux kernel 2.4 and above, Netfilter has been included as a kernel extension by the majority of (if not all) Linux distributors. iptables is its counterpart and the tool for managing firewall rules. The duo, which I call simply “iptables”, creates a stateful firewall on a Linux desktop or server. “Stateful” refers to the firewall’s ability to track the state of packets moving in and out of a server and/or network.

This is an improvement on the former ipchains, through which packet state was not available. Thus, iptables can distinguish between new and existing connections and keep track of traffic. iptables recognizes four kinds of packet states: new, established, related and invalid.

The developer can take any number of routes and options when deploying an iptables firewall: via prepackaged solutions like APF, from within a control panel such as Webmin, which has an iptables module, or by way of a GUI configuration tool such as Firestarter.

For the purpose of this article, we’ll focus on securing a single development Web server environment where multiple services are offered. This will be accomplished via configuring iptables manually in a command line text editor (which is traditionally stored at /etc/sysocnfig/iptables).

This also means we will only be discussing the filter table, which is one of three tables in the firewall system (others include Mangle, which manages quality of services issues with packet traffic, and the NAT (network address translation) table).

How iptables Works

iptables executes its rules based on the TCP protocol handshake. When a remote device connects to your server, a packet is sent with a SYN (short for synchronization) bit, which is generally acknowledged with a SYN/ACK (synchronization acknowledged) sent from your server back to the client. The client then acknowledges receipt of this with an ACK, and the network relationship is established.

This terminology has also become more familiar to non-network administrators in recent years due to some well-publicized cases of SYN flooding, which is used to execute denial-of-service attacks. This occurs when a remote malicious host (or hosts) repeatedly sends SYN packets to multiple ports on a server, which the server acknowledges. However, instead of sending an ACK back to open a legitimate connection, the remote malicious host(s) continues sending SYN packets and the server repeatedly attempts to acknowledge them, ultimately clogging bandwidth and system resources, and either severely hampering or blocking all other traffic.

We will look at an option to protect against SYN flooding later, when we configure our server’s firewall.

Getting Started

Only the root user can manage iptables, so the usual precautions — taking action as root — can cause damage to your server’s health if a user is not careful.

iptables may or may not be running on your system. You can check by issuing '/etc/rc.d/init.d/iptables status', which will either list the status of your firewall rules, or return something along the lines of ‘firewall is stopped’.

Controlling iptables operations is simple, with options such as start, stop, status and others using the above command.

At this point, we’ll assume that you don’t have an iptables configuration, and we’ll build the rules file from scratch. First, we need to identify the services you wish to enable (i.e. FTP, SSH, mail and HTTP), identify areas of concern (i.e. like SYN flooding) and potentially note any IP addresses whose access you may seek to ban.

If you are using a Red Hat-flavored system, as I am (Fedora Core 3 on a development server), you may find some generic rules in the /etc/sysconfig/iptables file. You will want to back up an existing iptables file if it has been in use. This can be done on the command line via 'cp /etc/sysconfig/iptables /etc/sysconfig/iptables.backup'.

To start building your rules, open that file in your favorite command line editor. I issue 'vi /etc/sysconfig/iptables'; you will press the Insert key or letter I key to start editing. Remember that when you’re finished editing, you’ll want to press the ESC key and type ‘:wq’ to save the file in Vi.

Allowing Targeted Access

Let’s build a set of firewall rules that will allow ftp, and allow ssh only to the IP addresses you specify and some additional ports you may need for other services. We’ll break each section down and discuss the details as we go.

One caveat: this firewall example will not be a completely hardened overview for the truly paranoid production box; it’s meant to serve as a primer to help you get used to handling basic rules with a solid level of packet filtering.

With the iptables file open in your favorite text editor, begin by setting some basic parameters. Use the following entry:

#My firewall config in /etc/sysconfig/iptables 
#It is good practice to comment, initial, and date your config files for the sake of shared #administrative environments and, also, so you remember what has been done in a file.
:FWALL-INPUT - [0:0]

This allows outgoing access from your server, and allows forwarding as well as accepting all incoming traffic (if passing packets through your server is not needed, simply change the FORWARD from ACCEPT to DROP). However, this code forwards all incoming traffic to our firewall rules (FWALL-INPUT) for filtering.

As SSH is a critical factor for system management, user access and other options such as requiring SFTP from your clients, let’s enable this service. Depending on how you manage your clients/users, you may simply allow all incoming SSH traffic:

#accept all incoming ssh traffic 
-A FWALL-INPUT -p tcp -m tcp -s 0/0 --dport 22 -j ACCEPT

Alternatively, SSH can be restricted to identified static IP address hosts:

#accept incoming ssh traffic from user John Doe 
-A FWALL-INPUT -p tcp -m tcp -s x.x.x.x --dport 22 -j ACCEPT
#end specific ssh access – this commenting is handy of you have multiple users here as #you can start and end sections if  users have multiple IPs from which they can access

In breaking down those lines of code, we see:

  • -A appends the rule to the firewall rule set
  • -p represents protocol (which can be tcp, udp and icmp in varying cases)
  • -m is for match and opens up options for extending packet management, for example to have granular control over SYN bits, defining destination and source ports. This is better explained at length in ‘man iptables’ than here, as multiple levels of options are available.
  • -s signifies the source address, where 0/0 stands for any host, a specific host IP address can be used (as in the example above), or a network segment can be denoted, such as
  • --dport points to the destination port; in the case of SSH, it’s 22.
  • -j selects the target (or jump target), which may be a custom target, or one of the common built-in targets such as ACCEPT or DROP.

Next, let’s consider FTP, an entry for the Webmin control panel, and a host of commonly used ports that are important to your server’s operation on the Internet.

# manage ftp port traffic
-A FWALL-INPUT-p tcp -m tcp --dport 21 -j ACCEPT
# end ftp port

#My webmin custom port
-A FWALL-INPUT-p tcp -m tcp --dport 42009 -j ACCEPT
# end webmin  

#SNMP monitoring so I can use a remote monitoring tool
-A FWALL-INPUT-p udp -m udp --dport 161 -j ACCEPT
-A FWALL-INPUT-p udp  -m udp --sport 1023:2999 -j ACCEPT
#end SNMP

A quick security note: when enabling remote access to SNMP, please be sure to have invested time in securing your SNMP configuration file(s), including changing community strings and using authentication.

# some standard out ports with port definition 
#POP mail
-A FWALL-INPUT-p tcp -m tcp --dport 110 -j ACCEPT  --syn
-A FWALL-INPUT-p tcp -m tcp --dport 443 -j ACCEPT  --syn
#SMTP Traffic
-A FWALL-INPUT-p tcp -m tcp --dport 25 -j ACCEPT  --syn
-A FWALL-INPUT-p tcp -m tcp --dport 80 -j ACCEPT  --syn
#In my case - Urchin
-A FWALL-INPUT-p tcp -m tcp --dport 9999 -j ACCEPT  --syn
#MySQL database server
-A FWALL-INPUT-p tcp -m tcp --dport 3306 -j ACCEPT  --syn
-A FWALL-INPUT-p udp -m udp --dport 3306 -j ACCEPT
#IMAP mail services
-A FWALL-INPUT-p tcp -m tcp --dport 143 -j ACCEPT  --syn
-A FWALL-INPUT-p tcp -m tcp --dport 53 -j ACCEPT  --syn
-A FWALL-INPUT-p udp -m udp --dport 53 -j ACCEPT
-A FWALL-INPUT-p udp -m udp -s 0/0 -d 0/0 --sport 53 -j ACCEPT
#Localhost traffic
#The below commits the rules to production for iptables to execute

You will notice we added the --syn flag. This is part of the previously mentioned -m (for matching) option in iptables. Here, we are specifically ensuring that only new connections with a SYN bit, and for which no ACK is set, are accepted.

At this point, you have a working development firewall. You can add and remove services to meet your own requirements. However, we can make some additional entries. We can add a final rule that drops all packets that do not qualify for any of our preceding ports.

#Drop all other new requests not meeting any existing rule requirements applied to traffic 
-A FWALL-INPUT -p tcp -m tcp -j REJECT  --syn
-A FWALL-INPUT -p udp -m udp -j REJECT
SYN Flood Protection

For some added protection, we can also seek to prevent the flooding of new requests (packets with the SYN bit set and no ACK, as discussed earlier in the article) by limiting the amount of requests to 5 seconds, which allows the system time to apply the rules.

-A FWALL-INPUT –p tcp --syn -m limit --limit 5/second -j ACCEPT

This should appear at the top of your rules, just above the first SSH entry.

Banning Access

If there are troublesome hosts you have discovered in your logs, these can be banned via iptables; however, be cautious in light of IP masquerading. Do some research on the IP address you wish to block, to ensure it is not a legitimate SMTP server, or worse: one of your clients who has been spoofed.

To block a specific host:

#Block malicious system 
-A FWALL-INPUT -p tcp -m tcp -s x.x.x.x -j DROP
Checking Firewall Logs

iptables traditionally logs basic entries to /var/log/messages. However, specific logging needs to be noted in your firewall rules if you’d like to track and research traffic. Many prefer to log only drop/reject actions, as this allows them to see any potential malicious behavior that’s being attempted.

This can be handled with an entry like the following:

#Option 1 logging drop/reject actions 
-A FWALL-INPUT -j LOG --log-level alert
#Option 2 logging with a prefix for easy search/grep of log file
-A FWALL-INPUT -j LOG --log-prefix "Dropped: "

Finally, a nice open source iptables log analyzer is available; it provides an interface similar to those commonly used to view Web traffic statistics. Found online at, this daemon can be implemented into a LAMP (specifically PHP and MySQL) environment and used to log all iptables actions in place of the default /var/log/messages.

Setup and configuration is straightforward and only a minor edit to your iptables file will start the reporting process.

Next Steps

The man pages for iptables are extensive and it is recommended to spend some time getting accustomed to the various options before moving a firewall into production. For example, options exist for using the -m (matching) option to manage packet states – i.e. allowing only new and established connections for specific services.

There are endless documents related to iptables on the Web, however, the best place to start is at the source: Netfilter’s Website. Tutorials range from basic networking concepts and packet filtering to setting up network address translation and advanced connection tracking options.

Finally, as noted before, this firewall does not represent the be-all and end-all configuration. It is a great place to start when exploring your options with iptables. Administrators, based on their environment, will have varying levels of paranoia to accommodate. Some systems I manage are locked as tight as possible, while others have fairly open doors for testing and development.

Frequently Asked Questions (FAQs) about Securing Your Server with IPTables

What is the importance of securing a server with IPTables?

IPTables is a user-space utility program that allows a system administrator to configure the IP packet filter rules of the Linux kernel firewall, implemented as different Netfilter modules. The filters are organized in different tables, which contain chains of rules for how to treat network traffic packets. Securing your server with IPTables is crucial as it provides a layer of protection against unauthorized access and various types of cyber attacks such as DDoS attacks, IP spoofing, and port scanning.

How can I set up IPTables on my Linux server?

Setting up IPTables on your Linux server involves several steps. First, you need to install the IPTables package using the package manager of your Linux distribution. Once installed, you can start configuring your firewall rules. This involves defining rules for the INPUT, OUTPUT, and FORWARD chains in the filter table. Each rule specifies what to do with a packet that matches certain criteria.

What are some common IPTables rules and commands?

Some common IPTables rules include allowing or denying traffic on specific ports, allowing or denying traffic from specific IP addresses, and allowing or denying all incoming or outgoing traffic. Common IPTables commands include ‘iptables -L’ to list all current rules, ‘iptables -F’ to flush (delete) all current rules, and ‘iptables -A’ to append a new rule.

How can I secure my server against DDoS attacks with IPTables?

You can secure your server against DDoS attacks by setting up rate-limiting rules with IPTables. These rules limit the number of connections that can be made to your server in a given time period, preventing an attacker from overwhelming your server with traffic.

How can I block IP spoofing with IPTables?

IP spoofing can be blocked by setting up rules in IPTables that drop packets from outside your network that claim to be from within your network. This can be done by specifying the source IP address range in the rule.

How can I allow or deny traffic from specific IP addresses with IPTables?

You can allow or deny traffic from specific IP addresses by setting up rules in IPTables that match the source or destination IP address. The ‘-s’ option is used to match the source IP address, and the ‘-d’ option is used to match the destination IP address.

How can I save and restore IPTables rules?

IPTables rules can be saved using the ‘iptables-save’ command, which outputs the current rules to stdout. These rules can then be saved to a file. To restore the rules, you can use the ‘iptables-restore’ command, which reads rules from stdin or from a file.

How can I log IPTables activity?

You can log IPTables activity by adding a rule with the ‘LOG’ target. This will log all packets that match the rule to the kernel log, which can be viewed with the ‘dmesg’ command or in the /var/log/messages file.

How can I test my IPTables rules?

You can test your IPTables rules by sending traffic that should match the rules and checking whether the expected action is taken. This can be done using tools like ‘ping’ and ‘netcat’, or by checking the IPTables counters with the ‘iptables -L -v’ command.

How can I troubleshoot problems with IPTables?

Troubleshooting problems with IPTables often involves checking the current rules with the ‘iptables -L’ command, checking the IPTables log for any logged packets, and testing the rules as described above. If you’re still having trouble, you may need to seek help from a knowledgeable colleague or online community.

Blane WarreneBlane Warrene
View Author
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form