HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
Disclaimer : This guide is intended to advanced users, beginners should not try to follow it and prefer the other guide i wrote on the topic which is intended to beginners :
http://ubuntuforums.org/showthread.php?t=159661
Please, don't post questions like "which port i need to open for this apps ?" this can be found easily in /etc/services file or using google.
1- Introduction
Hello, i wrote a first iptables tutorial for beginners but thought that advanced users may have interest in setting a more complex firewall which filter also outgoing traffic which is a little bit more tricky because you need to know almost all the ports you use.
However this firewall will give you a really good level of security.
As another great resource you can have a look at bodhi.zazen iptables page on his website:
http://bodhizazen.net/Tutorials/iptables/
2- Set your firewall script
2.1- Create your standard script
First read the first guide i wrote for beginners as you will need the flush script and the init.d script, we will just use another firewall script :
http://ubuntuforums.org/showthread.php?t=159661
Once you have created your flush script and init.d script, create your firewall script :
Code:
sudo gedit /etc/firewall.bash
Then paste this in it and modify the script to fit your needs :
Code:
#!/bin/bash
# No spoofing !!!
if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]
then
for filtre in /proc/sys/net/ipv4/conf/*/rp_filter
do
echo 1 > $filtre
done
fi
# No icmp
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
modprobe ip_tables
modprobe ip_nat_ftp
modprobe ip_nat_irc
modprobe ip_conntrack_irc
modprobe ip_conntrack_ftp
modprobe iptable_filter
modprobe iptable_nat
# Remove all rules
iptables -F
iptables -X
# first set the default behaviour => accept connections
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
# New chains
iptables -N FIREWALL
iptables -N TRUSTED
# Log chain
iptables -N LOG_DROP
iptables -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : '
iptables -A LOG_DROP -j DROP
# Allow ESTABLISHED and RELATED incoming connection
iptables -A FIREWALL -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow self communication
iptables -A FIREWALL -i lo -j ACCEPT
iptables -A FIREWALL -o lo -j ACCEPT
# Send all package to the TRUSTED chain
iptables -A FIREWALL -j TRUSTED
# DROP all other packets
iptables -A FIREWALL -j DROP
# Send all through the FIREWALL chain
iptables -A INPUT -j FIREWALL
iptables -A FORWARD -j DROP
iptables -A OUTPUT -j FIREWALL
# Allow dns
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 53 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 53 -j ACCEPT
# Allow http
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# Allow https
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 443 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 443 -j ACCEPT
# Allow amule
iptables -A TRUSTED -i eth0 -p udp -m udp --dport 8249 -j ACCEPT
iptables -A TRUSTED -i eth0 -p udp -m udp --dport 8251 -j ACCEPT
iptables -A TRUSTED -i eth0 -p tcp -m tcp --dport 8248 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --sport 8249 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --sport 8251 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --sport 8248 -j ACCEPT
# Allow some emule servers
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 4242 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 4661 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 3000 -j ACCEPT
#Allow IRC IDENT & DCC
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 6667 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -m state --state NEW -j ACCEPT
# Allow pop3s
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 995 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 995 -j ACCEPT
# Allow imap2
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 143 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 143 -j ACCEPT
# Allow imap3
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 220 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 220 -j ACCEPT
# Allow newsgroup
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 119 -j ACCEPT
# Allow smtp
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 25 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 465 -j ACCEPT
# Allow ftp
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow MSN
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 1863 -j ACCEPT
# bittorrent
iptables -A TRUSTED -i eth0 -p tcp -m tcp --dport 6881:6889 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --sport 6881:6889 -j ACCEPT
# azureus
iptables -A TRUSTED -i eth0 -p tcp -m tcp --dport 64433 -j ACCEPT
iptables -A TRUSTED -i eth0 -p udp -m udp --dport 64433 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 64433 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 64433 -j ACCEPT
# STEAM
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 27020:27050 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 27000:27015 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 1200 -j ACCEPT
# enemy territory
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 27950:27970 -j ACCEPT
# ekiga
iptables -A TRUSTED -o eth0 -p tcp -m tcp --sport 5000:5061 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --sport 5000:5061 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 5060 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 5060 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 5061 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 5061 -j ACCEPT
# Teamspeak
iptables -A TRUSTED -i eth0 -p tcp -m tcp --dport 8767 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 8767 -j ACCEPT
iptables -A TRUSTED -i eth0 -p udp -m udp --dport 8767 -j ACCEPT
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 8767 -j ACCEPT
# nicotine
iptables -A TRUSTED -i eth0 -p tcp -m tcp --dport 2234:2239 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 2234:2239 -j ACCEPT
# End message
echo " [End iptables rules setting]"
2.2- Explanation about the script structure
Some of you may be surprised by the structure used for the script so i will explain. Rather than handling the INPUT and OUTPUT chain directly as it is most often done i use two intermediary chains called FIREWALL and TRUSTED.
I'm using this structure in the spirit to separate things and make the script more clear.
The FIREWALL chain allow loopback interface and most common input connections then send all the rest into the TRUSTED chain where you will put your more specific rules and finally drop all packets that have not been allowed by the TRUSTED chain.
So all you don't allow explicitly in the TRUSTED chain will be dropped.
In the script all INPUT and OUTPUT packets are sent and handled through the FIREWALL and TRUSTED chain. Because all the INPUT and OUTPUT packets are sent to the FIREWALL and TRUSTED chain i use the "-i eth0" command to filter an INPUT packet and the "-o eth0" to filter an output packet (type man iptables to get details on this command).
2.3- Edit the script to fit your needs
Basically you will have to open output port for each apps you use, in general this is not hard to find through google or the /etc/services file where all your common ports are listed with their function.
When you need to open a port just add your rules in the TRUSTED chain.
For example if you want to open port for jabber, either you know directly the port to open and how to open it or you can just use google with "jabber iptables" has keyword and find the rules needed. On google you will find these 2 rules :
Code:
iptables -A INPUT -p tcp --sport 5222 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 5222 -m state --state NEW,ESTABLISHED -j ACCEPT
So to respect the structure of the script you will add your 2 news rules at the end of the TRUSTED chain like that :
Code:
iptables -A TRUSTED -i eth0 -p tcp --sport 5222 -m state --state ESTABLISHED -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp --dport 5222 -m state --state NEW,ESTABLISHED -j ACCEPT
-i eth0 allow to apply the rule on the INPUT packets (incoming packet on eth0) and -o eth0 allow to apply the rule on the OUPUT packets (outgoin packet on eth0)
Once you your script is finished, make your script executable :
Code:
sudo chmod +x /etc/firewall.bash
Then make it start on boot :
Code:
sudo update-rc.d firewall defaults
You're done :)
To test your firewall you can consult the following sites :
http://www.hackerwatch.org/probe/
https://www.grc.com/x/ne.dll?bh0bkyd2
3- Advanced topics
3.1- Create some log
To debug your firewall or maybe just if you wish some log here is how to do it using the syslog daemon.
You have surely noticed that in the script i provide a LOG_DROP chain was created, this chain will allow you to LOG the packets you dropped.
First open your syslog.conf file :
Code:
sudo gedit /etc/syslog.conf
Then add the folowing lines at the end of the file :
Code:
#IPTables logging
kern.debug;kern.info /var/log/firewall
and restart the daemon :
Code:
sudo /etc/init.d/sysklogd restart
Then just use LOG_DROP instead of DROP in your script everywhere you want to log dropped packets. Your log will be in /var/log/firewall.
3.2- Using more than one network interface
If you use more than one interface then you can either duplicate all the rules with "-i eth0" and "-o eth0" using the name of your second network interface or use the character "+" to apply rule on all devices beginning by "eth" so this would make "-i eth+" and "-o eth+".
I have not tested the second solution, feel free to report that it is working.
This guide is not complete and limited by my own knowledge so please feel free too share your knowledge and own iptables rules so that we can improve this guide together and provide the answer to most common needs.
Hope some find this useful.
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
Hi there. This is an excellent firewall script, and I'm using a slightly edited version of it myself right now.
I don't fully understand 100% why you went with the TRUSTED and FIREWALL chains, but I'm starting to get there. However, I have a question:
If I wanted to deny a specific port any inbound or outbound access what would be the best way to add this?
Thanks
Max
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
I guessed some would be surprized by this organisation (TRUSTED and FIREWALL chains), the goal is mainly to separate things and keep the script well organized so that you only have to add your additional rules to the TRUSTED CHAIN, the rest is more likely to never change.
That's the idea of these 2 chains.
By default anything you don't allow explicitly in the TRUSTED chain is dropped because all INPUT and OUTPUT packets are sent to the firewall chain and you will see that all is dropped at the end of the FIREWALL chain so if you don't allow a port explicitly in the TRUSTED chain all traffic on it will be dropped.
Hope to have answered your question.
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
Thanks frodon, I thought that was happening but I wanted to be sure.
Yes, the TRUSTED and FIREWALL chains do seem to make sense. The reason I'm having trouble getting used to them is because I'm only just starting out with iptables, and I'm used to the usual INPUT/OUTPUT chains that appear in most of the documentation Iv found, although I think Iv learned more by reading your script that from anywhere else so far!
Great firewall!
Max
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
Thanks,
The script organisation has its advantages and disadvantages, i did choose that in the spirit to make things more clear. I will try to explain this better in the first post. Thanks for the feedback and for using the script. I'm glad it helps.
EDIT: i have added some more explanations about the structure and an example with a jabber rule, hope the use of the script is more clear now.
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
Sorry to keep pestering you, but I have another question. In the script I see the following:
--dport
--destination-port
--sport
Are the first two the same thing? Iv Googled 'destination-port' and while Iv found it in a couple of scripts, Iv not found an explanation of what it actually is, whereas Iv found plenty of places that explain dport as the destination port. If they are the same thing, was there any particular reason that you wrote them differently?
Similarly Iv also found 'sport' in scripts, although that would appear to be source port.
Thanks
Max
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
This is explainedman page and alos in my first guide linked in first post. --dport and --destination-port are 2 ways to use the same command and indeicates a destination port whereas --sport indicates a source port.
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
hi frodon,
I would like to add new rule on your existing firewall script based on these articles but don't know how. I'm using the script that you provided on my machine. This is the link for the articles:
http://www.newartisans.com/blog_file...h.iptables.php
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
Add them to the TRUSTED chain as explained in 2.3 part of the guide, there's almost nothing to change to include them.
However most of these rules sounds unnecessary to me if you don't run web servers or stuff like that.
Re: HOWTO: Set a custom firewall (iptables) and Tips [Advanced user only]
I've had a couple of hours working on this and found your explanation very helpful - but I can't quite work out a couple of things for http and https:
--- + your code
# Allow http
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
# Allow https
iptables -A TRUSTED -o eth0 -p udp -m udp --dport 443 -j ACCEPT
iptables -A TRUSTED -o eth0 -p tcp -m tcp --dport 443 -j ACCEPT
--- - your code
1) Why do the rules for http and https differ? Does http have no udp element?
2) Is the direction incorrect? Your lines don't work for me until I replace -o with -i.
Thanks for any pointers on this.
Regards,
Geoff