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
Iptables for just browsing
Guys any iptables for ubuntu for just browsing and secures the various states like 1-7 as also stops service requests on established connections. Also do i need to make changes on sysctl for the iptables to work? in case of kernel panic how does this ipables handle it?
Your iptables script
Thanks for your script, very nice. I especially like the part about update-rc.d. Your iptables script and the info on update-rc.d has given me a starting point and inspired me to delve deeper into iptables and start-up procedures in general.
All the best,
James
Hi,I have some problems
Hi,I have some problems about iptables rules under Ubuntu .
Is it necessary to create some script llike before to build the firewall,Will the rules got lost when I restart the server.
I create a simple firewall with the function of NAT,then restart the server.
type commands below in the terminal:
iptables -L -v
But display nothing.
And it seemd that the NAT function and the rules made last time are still available to use.
Hoping for your email.
Thanks.
Is this necessary?
As far as I was aware, the default ubuntu firewall rules block all unsolicited incoming traffic.
What does this do that is not already happening?
Or am I missing something obvious?
That might be the case now
That might be the case now (I notice Fedora now comes with default firewall rules, which I'm pretty sure it never used to). It wasn't the case on Ubuntu a few years ago when I wrote this article, however.
Time passes, things change :)
This worked perfectly for my
This worked perfectly for my needs. Thanks!
For those who want to ACCEPT specific ports for services like HTTPD, be sure to put those rules before the DROP rules. I fiddled with this for an hour before I figured out that the first rule that matches is the one that gets applied.
eg.
iptables -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT # ssh
iptables -A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT # http
iptables -A INPUT -i eth1 -p tcp --dport 3306 -s 10.176.84.219 -j ACCEPT
iptables -A INPUT -i eth1 -p tcp --dport 3306 -s 10.176.85.10 -j ACCEPT
iptables -A INPUT -i eth+ -p udp -j DROP
iptables -A INPUT -i eth+ -p tcp -m tcp --syn -j DROP
My example got formatted
My example got formatted queerly. The 1's are actually script comments. Cheers!
I was once try out the
I was once try out the ubuntu, but end up keep getting error on the eth0, in which I think it is related to the network card that I have. I try your script which I thought it got something to do with my error, but still fail. Would a firewall cause my eth0(network card) to have such error? I've tried changed few cards which is still the same.
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 init.d script
if you change the POLICIES to DROP and run the init.d script with anything other than a "start" argument, you will flush your rules, but since the policy is DROP , you will not be able to access
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.
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 :)