Menu
How to configure iptables firewalls using the bash shell
By Anthony Weitekamp
Security is a major topic these days. Here we will discuss how to configure a common firewall used by Debian and its downstream Linux distributions for user machines, not for servers. For the purposes of this article, it is assumed that the user is behind a hardware router, on their own private network. The iptables firewall is the default firewall used by many Linux distributions. You can enjoy higher security on your network and byond by configuring your firewall to suit your needs. This "How To" is part of a series of articles where I take a layered approach to firewall configuration. Setting rules directly with iptables places limitations directly on your "always conected" firewal settings. This should provide basic security for your system. Then when you use gufw to configure the "Uncomplicated Firewall" or ufw, you add a layer that can be turned on/off as needed depending on your circumstances. I develop software for the web, OpenGL, and some cryptographic applications. There are times when I want extremely tight firewall settings to test new software and other times when I need a more open approach.Generally speaking, there are a couple of good rules to follow when using the command line to configure your firewall. Firet, read the 'man' or manual for the command. These man pages are generally written by software developers so educated users can use the command iine to quickly get work done. Another excellent rule is to have a script that will reset your firewall to its default settings before you start playing arond with the configuration. Finally, build a well documented script file with each command listed out along with a comment describing the action each line or group of lines will take. You do not want to go through the whole learning experience again to make a few changes six months or a year down the road.
Take a look at the man page for iptables by issuing the command...
$ man iptables
Iptables is used to set up, maintain, and inspect the tables of IPv4
packet filter rules in the Linux kernel. Several different tables may
be defined. Each table contains a number of built-in chains and may
also contain user-defined chains.
Each chain is a list of rules which can match a set of packets. Each rule specifies what to do with a packet that matches. This is called a `target', which may be a jump to a user-defined chain in the same table.
A firewall rule specifies criteria for a packet and a target. If the packet does not match, the next rule in the chain is the examined; if it does match, then the next rule is specified by the value of the tar‐ get, which can be the name of a user-defined chain or one of the special values ACCEPT, DROP, QUEUE or RETURN.
ACCEPT means to let the packet through. DROP means to drop the packet on the floor. QUEUE means to pass the packet to userspace. (How the packet can be received by a userspace process differs by the particular queue handler. 2.4.x and 2.6.x kernels up to 2.6.13 include the ip_queue queue handler. Kernels 2.6.14 and later additionally include the nfnetlink_queue queue handler. Packets with a target of QUEUE will be sent to queue number '0' in this case. Please also see the NFQUEUE target as described later in this man page.) RETURN means stop traversing this chain and resume at the next rule in the previous (calling) chain. If the end of a built-in chain is reached or a rule in a built-in chain with target RETURN is matched, the target specified by the chain policy determines the fate of the packet.
This man page is well written and includes examples of how to compose
commands to write rules for the firewall. It is still very well documented.
Most people can figure it out with a little trial and error.
We will be creating rules for these four (4) chains;
user-input, user-limit, user-limit-accept, and user-output.
Let's start out by creating a script that will
show us what our settings currently are. type the following command.
Each chain is a list of rules which can match a set of packets. Each rule specifies what to do with a packet that matches. This is called a `target', which may be a jump to a user-defined chain in the same table.
A firewall rule specifies criteria for a packet and a target. If the packet does not match, the next rule in the chain is the examined; if it does match, then the next rule is specified by the value of the tar‐ get, which can be the name of a user-defined chain or one of the special values ACCEPT, DROP, QUEUE or RETURN.
ACCEPT means to let the packet through. DROP means to drop the packet on the floor. QUEUE means to pass the packet to userspace. (How the packet can be received by a userspace process differs by the particular queue handler. 2.4.x and 2.6.x kernels up to 2.6.13 include the ip_queue queue handler. Kernels 2.6.14 and later additionally include the nfnetlink_queue queue handler. Packets with a target of QUEUE will be sent to queue number '0' in this case. Please also see the NFQUEUE target as described later in this man page.) RETURN means stop traversing this chain and resume at the next rule in the previous (calling) chain. If the end of a built-in chain is reached or a rule in a built-in chain with target RETURN is matched, the target specified by the chain policy determines the fate of the packet.
$ vim display_settingsNow copy the following lines and paste them into your file.
#!/bin/bash echo "#################################" echo "Table Filter Rules " iptables --table filter -S echo "#################################" echo "Table nat Rules " iptables --table nat -S echo "#################################" echo "Table mangle Rules " iptables --table mangle -S echo "#################################" echo "Table raw Rules " iptables --table raw -S echo "#################################" echo "Table security Rules " iptables --table security -S echo "#################################"Now press the escape key and type :wq then press enter to write and quit vim. Don't forget to change the mode of your file to executable.
$ chmod +x display_settingsNow execute your script.
$ sudo ./display_settingsThe next script we will prepare will reset our firewall settings to their default in the event we make an error along the way.
$ vim reset_rules
#!/bin/bash echo "Reset iptables rules to default" iptables --table filter -F iptables --table filter -X iptables --table nat -F iptables --table nat -X iptables --table mangle -F iptables --table mangle -X iptables --table raw -F iptables --table raw -X iptables --table security -F iptables --table security -X iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT echo "Default rules set"Write and quit the file, then make it executable.
$ chmod +x reset_rulesNow we are ready to start setting rules on the firewall. Open 2 terminal sessions. Use the first session to test your rules and the second to record the rules in a file. Test your settings each time you write a rule to make sure you did not break something important. You can always return to your current position by resetting the rules then running your successful rules script.
The default settings for iptables is another way of saying that your computer is always connected. It will allow all services and software to communicate freely over the network. It is now time to decide which services and other applications you want to allow through the firewall and which ones you want to deny. Personally, I dislike torrent downloads, so that is one service that I would block on my computers. Make a list of everything you have on the computer that needs to "talk" on the network. Then go to wikipedia to get a list of common ports and match them up like this.
Allow These Program Port Thunderbird POP2 109 (outgoing only) POP3 110 (outgoing only) POP3 (Secure) 995 (outgoing only) FireFox 80, 443 (outgoing only) Apache Server 80, 443 (in and out) But only allow from computers on my subnet or only allow from specific computers. Make sure to include the address of the computer you are using. MySQL 3306 ALLOW from this computer DENY ALL Incoming Deny These Program Port BitTorrent 6881–6890, 6891–6901 (incoming) Torrent Tracker 6969 (incoming) kTorrent amule ( in and out ) vnc (incoming) ssh (incoming) Note: Blocking these ports will also stop "Windows Live Messenger" services
This is not an exhaustive list, but it is an example of what you can limit from the outside world. I personnaly dislike torrents and it is nearly impossible to keep the software from being installed in Linux. So, I will not let the software communicate through my firewall. Did you see how I added the direction (in/out) of the communication? I did this to reduce the number of rules I will be writing on the firewall. 'Outgoing only' rules do not need a line in the configuration but you can include them if you are going to explicitly deny services from using these ports. 'Incoming or in and out' rules must have an entry. Bittorrent is an in/out connection, therefore it needs a rule. But in setting rules on torrents I will limit my use of "Windows Live Messenger". I do not use software from Microsoft so it is no problem.
For the rest of this session we will be setting rules on the filter table of the firewall. Now we will create default policies and name some rules. This will make administration a lot easier as we get further along in the process.
Policy Rules
#!/bin/bash # Default Policies iptables --table filter -P INPUT DROP iptables --table filter -P FORWARD DROP iptables --table filter -P OUTPUT ACCEPT
Rule Names
# Name Chains iptables --table filter -N user-input iptables --table filter -N user-limit iptables --table filter -N user-limit-accept iptables --table filter -N user-output
Append Rules to the names and provide comments
# Add rules to chains # Chain user-input iptables --table filter -A user-input -p tcp -m tcp --dport 6881 -j DROP iptables --table filter -A user-input -p udp -m udp --dport 6881 -j DROP iptables --table filter -A user-input -p udp -m udp --dport 4444 -j DROP iptables --table filter -A user-input -p tcp -m multiport --dports 2234:2239 -j DROP iptables --table filter -A user-input -p tcp -m tcp --dport 2242 -j DROP iptables --table filter -A user-input -p tcp -m tcp --dport 2240 -j DROP iptables --table filter -A user-input -p tcp -m multiport --dports 6881:6891 -j DROP iptables --table filter -A user-input -p udp -m multiport --dports 6881:6891 -j DROP iptables --table filter -A user-input -p tcp -m tcp --dport 4662 -j DROP iptables --table filter -A user-input -p udp -m udp --dport 4672 -j DROP # FTP iptables --table filter -A user-input -p tcp -m tcp --dport 20 -j DROP iptables --table filter -A user-input -p tcp -m tcp --dport 21 -j DROP # SSH iptables --table filter -A user-input -p tcp -m tcp --dport 22 -j DROP # TELNET iptables --table filter -A user-input -p tcp -m tcp --dport 23 -j DROP # SMTP iptables --table filter -A user-input -p tcp -m tcp --dport 25 -j DROP # VNC iptables --table filter -A user-input -p tcp -m tcp --dport 5900 -j DROP iptables --table filter -A user-input -p udp -m udp --dport 5900 -j DROP # APP Discovery and Access Protocol iptables --table filter -A user-input -p tcp -m tcp --dport 6350 -j DROP iptables --table filter -A user-input -p udp -m udp --dport 6350 -j DROP # Apache Webserver iptables --table filter -A user-input -p tcp -m tcp --dport 80 -j ACCEPT iptables --table filter -A user-input -p udp -m udp --dport 80 -j ACCEPT iptables --table filter -A user-input -p tcp -m tcp --dport 443 -j ACCEPT iptables --table filter -A user-input -p udp -m udp --dport 443 -j ACCEPT # Chain user-limit iptables --table filter -A user-limit -m limit --limit 3/min -j LOG --log-prefix "[LIMIT BLOCK] " iptables --table filter -A user-limit -j REJECT --reject-with icmp-port-unreachable iptables --table filter -A user-limit-accept -j ACCEPT # Chain user-output # Torrent programs iptables --table filter -A user-output -p tcp -m tcp --dport 6881 -j DROP iptables --table filter -A user-output -p udp -m udp --dport 6881 -j DROP iptables --table filter -A user-output -p udp -m udp --dport 4444 -j DROP iptables --table filter -A user-output -p tcp -m tcp --dport 4662 -j DROP iptables --table filter -A user-output -p udp -m udp --dport 4672 -j DROP iptables --table filter -A user-output -p tcp -m multiport --dports 6881:6891 -j DROP iptables --table filter -A user-output -p udp -m multiport --dports 6881:6891 -j DROP iptables --table filter -A user-output -p tcp -m tcp --dport 443 -j ACCEPTThis completes this lesson on how to configure your iptables firewall using the bash shell.