Linux's built-in firewall iptables is very useful, but pretty hard to configure. I used to use lokkit, but this caused problems when moving between different networks. I was also having problems with the network configuration tools in Ubuntu, which work but aren't automatic enough for me. And I wanted to be able to switch the firewall and the network configuration simultaneously.
In the end, I bit the bullet and worked out how to write a simple iptables script. Here it is:
#!/bin/bash # flush all chains iptables -F # set the default policy for each of the pre-defined chains iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP # allow establishment of connections initialised by my outgoing packets iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # drop everything else iptables -A INPUT -i eth+ -p udp -j DROP iptables -A INPUT -i eth+ -p tcp -m tcp --syn -j DROP # accept anything on localhost iptables -A INPUT -i lo -j ACCEPT
I have network interfaces on eth0 and eth1, so this script has rules which cover both; if your interfaces have different names, you will need to edit the rules to cover that. This drops everything incoming, except for connections which were initially established by my outgoing packets (thanks Luke! - see comments); which means it's no good for servers.
I put this script in /opt/scripts/iptables.script and made it executable. Once you run it, you can find out whether it has worked by displaying your current iptables rules with:
sudo iptables -L -v
I then created a simple init script to start/stop the firewall (in /etc/init.d/firewall):
#!/bin/bash if [[ $1 == start ]] ; then sudo /opt/scripts/iptables.script else sudo iptables -F fi
Then I symlinked this into my /etc/rc.* directories using the update-rc.d tool, so the firewall starts before the network comes up:
update-rc.d firewall start 20 2 3 4 5 . stop 99 0 1 6 .
I find having this script helps me a lot. I have it integrated with a start/stop script with my network, so I can easily switch network and firewall configuration from the command line.
Comments
Simpler Alternative (?)
For a personal home computer (running no services for the outside world), here is a simpler version :
#!/bin/bash#############################################################---- Script to setup a simple firewall using iptables -----#### * Blocks all incoming connections, except those opened by# me, or related to already open connections# * Blocks all forward requests# * Allows all outgoing connections################################################################ Clearing all previous rulesiptables -F# Setting Default Policiesiptables -P INPUT DROPiptables -P OUTPUT ACCEPTiptables -P FORWARD DROP# Allowing already-established and related-incoming connectionsiptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPTOoops! Forgot the LocalHost...
iptables -A INPUT -i lo -j ACCEPTThanks. That does look like
Thanks. That does look like an improvement. Like I said in the post, I'm not really an iptables expert!
firewall
Hi,
Great script - I've used it as the starter for my setup.
ShieldsUP notes that your script shows ports 0 and 1 as closed rather than in stealth mode, and also doesn't drop ICMP packets - meaning that if the machines are directly attached to the internet via ppp, or with an ADSL modem with no firewall, then they can be discovered.
Also your script doesn't handle dialup connections.
The following changes mitigates against these:
iptables -A INPUT -i ppp+ -p udp -j DROP
iptables -A INPUT -i ppp+ -p tcp -m tcp --syn -j DROP
iptables -A INPUT -i ppp+ -p icmp -j DROP
iptables -A INPUT -j DROP -p tcp --sport 0
iptables -A INPUT -j DROP -p udp --sport 0
iptables -A INPUT -j DROP -p tcp --dport 0
iptables -A INPUT -j DROP -p udp --dport 0
iptables -A INPUT -j DROP -p tcp --sport 1
iptables -A INPUT -j DROP -p udp --sport 1
iptables -A INPUT -j DROP -p tcp --dport 1
iptables -A INPUT -j DROP -p udp --dport 1
regards
Colin
short and sweet, works as
short and sweet, works as advertised! happy customer here.
Great, glad it was helpful.
Great, glad it was helpful.
iptables
One of the most impressive tools for building iptables firewalls is fwbuilder at www.fwbuilder.org.
This fantastic GUI app writes the iptables for you in a way that is easy to read.
Really good for heavy weight firewalling.
Roy.
Thanks for that, Roy. I've
Thanks for that, Roy. I've used some of the GUIs before, but the simple ones can't cope with the scenario outlined in the article. While fwbuilder probably could, I like the simplicity of my script, and have used it succesfully without touching it for about 3 years. I'm very happy with it.
So simple!
I've fooled with iptables off and on for a few years now. Never quite getting all the pieces right. Thanks for bringing it back down to Earth with a simple as pie approach to setting the rules and integrating with start up. It was good to learn a thing or two about update-rc.d. That was an interesting tool I hadn't seen before.
One note: Add your input accept rules (like port 80 for HTTP BEFORE you drop everything else). Took me a couple minutes to figure that one out, but otherwise, all else was smooth sailing.
--Michael
Thanks Michael. Glad to be
Thanks Michael. Glad to be of service.
Very helpful. Thanks for
Very helpful. Thanks for posting.
Hello, Very useful article
Hello,
Very useful article but one thing is missing, I think. You need rule like this: IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT to allow for instance dns queries.
Regards
Luke
Hello Luke. Thanks for the
Hello Luke. Thanks for the feedback. The rules I've got here are the ones I use every day. I found that providing I had a rule like this:
(which is included in the above script) I had no trouble getting DNS queries to work. Without this, it didn't work correctly. What does your suggested rule do? I'm not familiar with the state settings (like I say, I'm no iptables expert!).
Hello again
Hi,
Rule like IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT accepts connections that were once OK'ed. So with this rule you don't need yours: iptables -A INPUT -p udp -s 0/0 --sport 53 -d 0/0 -j ACCEPT.
And it is more secure since your port 53 UDP is not opened.
Luke
Hello Luke, thanks for
Hello Luke, thanks for clearing that up. I'll give it a go and change this howto once I'm happy I've got it working. Cheers for the tips.
Your welcome :)
cheers
Help with IPtables config
Greetings,
I would spell out everything I'm trying to do with IPtables but, to save time, I'll point you to the thread I started at http://ubuntuforums.org/showthread.php?t=337024
I've written my IPtables rules, saved them to a text file, and I'm now trying to install the rules I've written. I didn't think this portion of the process was going to be more difficult then actually learning IPtables, but go figure.
Anyway, I'm about to tear my hair out and would greatly appreciate your feedback.
Thank you for your time,
Nick
Nick, the above outline is
Nick, the above outline is how I do this myself. A few clarifications:
Hope this helps.
sudo
I'm new to all this so please bear with me! In your init script you use sudo to run the script, this is obviously necessary, but does that mean you've edited the sudoers file in order to launch that script without a pwassword?
I think (I'm not sure) that
I think (I'm not sure) that the script will run as root when you boot the machine (in all honesty, sudo is a mystery to me). The sudo is just there if you want to run the script as a normal user in the normal course of things. On Ubuntu, you could probably leave this out if you are only going to run the script as root (or during boot).
Easy Firewall Generator
For simple and effective firewall script try using Easy Firewall Generator
http://easyfwgen.morizot.net/gen/
It works as generator for you on end you simply have firewall.sh that you put where you want.
And you can always install it on your web server to have it locally so you can generate firewall.
Boris
Thanks for the reference.
Thanks for the reference. Could be useful for slightly more complex setups, but for my purposes it's over-kill. I like my short simple script which works in my environment.
Thank you!
Thank you for you iptables script. I have used your script every time I format my Linux machines. Its very handy. Its small and simple. I'm using pppoe connection so i have not created any links in initd but i call my firewall in my ppoe connection.
-TusharG
Glad you find it useful.
Glad you find it useful. When I was writing it, it was surprisingly hard to find simple examples, hence my howto.
thanks!
thanks!
You're welcome!
You're welcome!
shit
when i typed /etc/init.d/firewall stop ssh, apache gone away .. :(
why ?
What, the ports became
What, the ports became unavailable? Or the services stopped running? When you stopped the firewall? If you set it up as above, stopping the firewall shouldn't touch other services, and should definitely not block them.
Thx ;)
thanks!though iptables -A INPUT -p tcp -s 0/0 --dport 80 -j ACCEPT is needed!
Only if you're running a web
Only if you're running a web server :)