# HOWTO: Iptables for newbies. PART I: Getting Started

## krunk

Linux Iptables for Newbies

Part I: Getting up and running

Part II: Hardening Your Firwall

I found the iptables documentation available to be severly un-newbie friendly. Most assumed a more than working knowledge of ipchains and pretty much picked up from there. Usually my approach to a new endeavor is that I want the option of getting up and going quickly, with minimal explanation. Afterwards I go back to read over more advanced options. This howto is designed with that in mind. It'll get you connected to the internet quickly through your linux router so you know your set-up is basically functional and than it will incrementally add rules and policies so that you'll know which specific command was the cause of any problems that may arise.

Also, this document will focus mainly on using a pppoe connection to the internet and the 2.6.x kernel, because that is what I have. However, the only adaptation that would need to be made is to replace 'ppp0' with 'eth0' (or whatever your output NIC is......this will become clear later.

Assumptions

1. All your hardware is in good working order. This means test each device and ensure that it is functional. Make sure that internet connections are possible without iptables enabled, etc, etc. There's nothing like cussing at a new software program for hours only to discover you have a bad network card or that your modem isn't configured properly.

2.You can read a man page. In fact I assume that while you walk through this Howto, the iptables man page is open right next to it for reference to what each command means.

3.You have a basic understanding of networking and gentoo admin. tools......and I mean really basic, such as how to use ifconfig, rc-update, /etc/conf.d/net, etc. If you don't, refer to 

The Gentoo Handbook

or 

Linux Help's Networking Basics 101

Kernel Config:

As for the kernel all you must do is enable iptable support.

First.

```

Device Drivers--->Networking Support--->Networking Options---->Network Packet Filtering (replace Ipchains)--->Netfilter Configuration

```

I enabled all the options as modules (in case I want to test other options later) and added ip_tables to my modules.autoload. This loads several modules as dependencies. Later you may want the ip_conntrack for logging. ***Don't forget to "modprobe ip_tables" before running scripts***  :Very Happy: 

Necessary Utilities:

Next you must emerge the userland tools for cofiguring iptables:

```

emerge iptables

```

Interface configuration:

In my set up, I have three NIC's, one is connected to the WAN through pppoe, the other two to my internal network. In order for them all to play nicely with iptables and masquerading (NAT'ing), they must be set to different subnets. For example, the two NIC's connected to my internal computers, e.g., the internal NIC's, are assigned: 192.168.1.78 and 192.168.2.78 respectively. It should be noted here that it is perfectly acceptable to connect these internal NIC's to any network capable device, such as a switch or hub. For pppoe conections we make sure the NIC connected to the outside world, e.g. the external NIC is not assigned any ip....it's entries in /etc/conf.d/net should be left blank. We must also assign proper netmasks and broadcast values to these interfaces. Your conf.d should look like this for the server:

Server

```

# For pppoe connections you do not want to set values for eth0, simply add \

# net.ppp0 to your default runlevel

#iface_eth0="192.168.0.78 broadcast 192.168.0.255 netmask 255.255.0.0"

iface_eth1="192.168.1.78 broadcast 192.168.1.255 netmask 255.255.255.0"

iface_eth2="192.168.2.78 broadcast 192.168.2.255 netmask 255.255.255.0"

```

Notice that no gateways have been set. 

On the client side, the conf.d should be:

Client One

```

iface_eth0="192.168.1.77 broadcast 192.168.1.255 netmask 255.255.255.0"

gateway="eth0/192.168.1.78"

```

Client Two

```

iface_eth0="192.168.2.77 broadcast 192.168.2.255 netmask 255.255.255.0"

gateway="eth0/192.168.2.78"

```

The gateways for the clients are set to the internal ip's of the NIC on the server as should be expected.

Now add all the interfaces to the default run level and restart connections:

Server

```

rc-update add net.eth1 default; rc-update add net.eth2 default; rc-update add net.ppp0 default; \

/etc/init.d/net.eth1 start; /etc/init.d/net.eth2 start; /etc/init.d/net.ppp0 start; 

```

Clients

```

/etc/init.d/net.eth0 restart

```

Now verify that you are connected to the internet on the server machine (the clients will not be.....yet) and that all the interfaces can ping each other.

Server

```

ping www.google.com;

ping 192.168.1.78

ping 192.168.2.78

ping 192.168.1.77

ping 192.168.2.77

```

Next ensure that your clients have appropriate DNS's set in your /etc/resolv.conf.

Now to the fun part.....iptables and NAT'ing. We first are going to simply forward addresses with an absolute minimal of rules to ensure that you can get out of the network. *WARNING* If your paranoid, this isn't the most secure thing to do....afterall your opening yourself up to the world with very little protection. But I'm assuming your setting up a SOHO and that you've taken your risperdal with a double helping of olanzapine this morning so that you can handle the tension:

```

 #!/bin/bash

IPTABLES='/sbin/iptables'

# Set interface values

EXTIF='ppp0'

INTIF1='eth1'

INTIF2='eth2'

# enable ip forwarding in the kernel

/bin/echo 1 > /proc/sys/net/ipv4/ip_forward

                                                                                

# flush rules and delete chains

$IPTABLES -F

$IPTABLES -X

                                                                                

# enable masquerading to allow LAN internet access

$IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

                                                                                

# forward LAN traffic from $INTIF1 to Internet interface $EXTIF

$IPTABLES -A FORWARD -i $INTIF1 -o $EXTIF -m state --state NEW,ESTABLISHED -j ACCEPT

                                                                                

# forward LAN traffic from $INTIF2 to Internet interace $EXTIF

$IPTABLES -A FORWARD -i $INTIF2 -o $EXTIF -m state --state NEW,ESTABLISHED -j ACCEPT

                                                                                

#echo -e "       - Allowing access to the SSH server"

$IPTABLES -A INPUT --protocol tcp --dport 22 -j ACCEPT

                                                                                

#echo -e "       - Allowing access to the HTTP server"

$IPTABLES -A INPUT --protocol tcp --dport 80 -j ACCEPT

                                                                                

# block out all other Internet access on $EXTIF

$IPTABLES -A INPUT -i $EXTIF -m state --state NEW,INVALID -j DROP

$IPTABLES -A FORWARD -i $EXTIF -m state --state NEW,INVALID -j DROP

```

**note**This script was written by someone on another forum....I've since lost the address to the thread or forum..., but thanks goes to him.

Now check any one of your clients and see if you can connect either to the internet or by ssh'ing to your server. If everything has checked out up to this point....you really should be good to go. If not, check for syntax errors or if you can ping the interfaces. Make sure the ip's and masks for client and server are set correctly.....you get the idea. 

If it does work, save the configurations:

```

/etc/init.d/iptables save

```

And than back up your working configuration in case you bork something later you can quickly revert:

```

cp /var/lib/iptables/rules-save /var/lib/iptables/rules.working

```

Now check up your iptables start-up script before adding iptables to your default runlevel:

```
 

/etc/init.d/iptables start; /etc/init.d/iptables stop; /etc/init.d/iptables start

```

The reason we start, than stop, than start again is because we haven't yet started the iptables script...so we must set the initialized status before stopping. Stopping essentially erases all settings and puts you back to zero.  Restarting will show you whether your network will still work after rebooting. Assuming success, we add iptables to our default runlevel:

```

rc-update add iptables default

```

Part II will cover expansion of rule sets and policies to further harden your router. If you can't wait though, you should be pretty well set to start on some of the other tutorials out there like:

Russel's iptables howto (the coder of iptables and ipchains)

Or any of the documentation on the Netfilters Home page

This is the first howto I've written, so I welcome and pm's with constructive criticism

 PART II is ready.

----------

## Krigare

Excellent! Its rare to see information about this topic in such easy-explained ways that you just did. Good work m8!

----------

## Floog

Indeed, a hearty thank you to Mr. Krunk.

I just built my first permanent gentoo install from Stage 1.   I'm coming from a Slackware background and have basic understanding of iptables.  Using gentoo, I wasn't clear on whether iptables was installed in the base installation.  And I couldn't figure out where to place my firewall rules -- right into the /etc/init.d/iptables or the /etc/conf.d/iptables.  

Your quick-doc. was enough to point me to the right places to install my script and get the firewall installed and started.  It took me alot longer to figure out the basics of getting a two-nic. setup running under Gentoo than it did to install my firewall.

Thank you again for your very helpful post.

Floog

----------

## jjasghar

THANK YOU THANK YOU THANK YOU SOOOOO MUCH 

i needed this thread like a fish needs water

----------

## icywolf

thank you!

----------

## Blue Fox

Very nice  :Wink: 

Congratulations

I think that would be interesting if you put references to softwares like fwbuilder, guarddog and jayfirewall

----------

## krunk

 *Blue Fox wrote:*   

> Very nice 
> 
> Congratulations
> 
> I think that would be interesting if you put references to softwares like fwbuilder, guarddog and jayfirewall

 

I wouldn't mind at all. I'm not familar with that software though. I did everything by hand. I did use Bastille for hardening the file system permissions. 

I would probably include such software after the next section. Which I'll put up right after I iron out some of the wrinkles in my firewall script. At the moment it's just too restrictive for an "everyday" desktop.

I'm learning as I do this, so I don't know alot about alternatives to doing it by hand (Mostly because I haven't looked, I do everything by hand the first time). Any nice software you know of post a link and I'll add it to a section after the Howto.  :Smile: 

----------

## krunk

Part II is ready.

----------

## davidsb

Nice tutorial  :Smile: 

This will help ppl getting into iptables.

Good work

----------

## ett_gramse_nap

Thank you! I think i'll throw Shorewall out the window and try to build my 'own' firewall tonight...

----------

## Braempje

Great tutorial, you do use very special ips however: 192.168.1.0.78 seems to have a 1 too much? I didn't know these ips were allowed in ipv6 either   :Wink: 

(I just don't like it when great tutorials contains small confusing mistakes, don't take this personal!)

----------

## krunk

 *Braempje wrote:*   

> Great tutorial, you do use very special ips however: 192.168.1.0.78 seems to have a 1 too much? I didn't know these ips were allowed in ipv6 either  
> 
> (I just don't like it when great tutorials contains small confusing mistakes, don't take this personal!)

 

Actually, there were several mistakes in that paragraph...so thank you for bringing my attention to them.  :Smile: 

----------

## req

Hello, great tutorial. Just one problem for me!

[ Ops, solved this five seconds after I posted it! In the /etc/init.d/iptables script the echo "1" /proc ...  was pointing to the wrong file, so I just edited it a little ] 

I've followed this step by step, use exactly your script for setting up iptables initially, and then save the rules. But when I 

```
rc-update add iptables default
```

and reboot (or /etc/init.d/iptables stop .... les start ) it does not forward any more! Then if I run the script again, it works.  Now, I could add the script to default runlevel, but I just know it's possible to get this to work the correct way, right? =).

The rules look exactly the same if I run the script or the /etc/init.d/iptables start. 

Thanks again,

Richard

----------

## krunk

 *req wrote:*   

> Hello, great tutorial. Just one problem for me!
> 
> [ Ops, solved this five seconds after I posted it! In the /etc/init.d/iptables script the echo "1" /proc ...  was pointing to the wrong file, so I just edited it a little ] 
> 
> I've followed this step by step, use exactly your script for setting up iptables initially, and then save the rules. But when I 
> ...

 

The iptables init script doesn't work for me either. I have to manually run the script. After starting. The first problem is that the iptables init script starts before rp-pppoe script...which is bad (you can assign rules to an ip that doesn't exist  :Smile: . I havent' had time to see if I should file a bug or not.

----------

## ed0n

/me is bookmarking this page so if I will need (which i will) iptables sometimes I can read something about it, and also in the gentoo security howto iptables is described good.

----------

## zpon

i have a problem, i don't know were to put in the long code! 

```

#!/bin/bash

IPTABLES='/sbin/iptables'

# Set interface values

EXTIF='ppp0'

INTIF1='eth1'

INTIF2='eth2'

# enable ip forwarding in the kernel

/bin/echo 1 > /proc/sys/net/ipv4/ip_forward

                                                                               

# flush rules and delete chains

$IPTABLES -F

$IPTABLES -X

                                                                               

# enable masquerading to allow LAN internet access

$IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

                                                                               

# forward LAN traffic from $INTIF1 to Internet interface $EXTIF

$IPTABLES -A FORWARD -i $INTIF1 -o $EXTIF -m state --state NEW,ESTABLISHED -j ACCEPT

                                                                               

# forward LAN traffic from $INTIF2 to Internet interace $EXTIF

$IPTABLES -A FORWARD -i $INTIF2 -o $EXTIF -m state --state NEW,ESTABLISHED -j ACCEPT

                                                                               

#echo -e "       - Allowing access to the SSH server"

$IPTABLES -A INPUT --protocol tcp --dport 22 -j ACCEPT

                                                                               

#echo -e "       - Allowing access to the HTTP server"

$IPTABLES -A INPUT --protocol tcp --dport 80 -j ACCEPT

                                                                               

# block out all other Internet access on $EXTIF

$IPTABLES -A INPUT -i $EXTIF -m state --state NEW,INVALID -j DROP

$IPTABLES -A FORWARD -i $EXTIF -m state --state NEW,INVALID -j DROP 

```

----------

## krunk

What is the problem?

----------

## zpon

well, i don't know if this is reight, but can i just copy 'n' past the script into my shell?? when i types iptables and a comand i get an error: 

FATAL: Module ip_tables not found.

iptables v1.2.9: can't initialize iptables table `filter': iptables who? (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

sorry about my english, hope you are able to read it...

----------

## krunk

 *zpon wrote:*   

> well, i don't know if this is reight, but can i just copy 'n' past the script into my shell?? when i types iptables and a comand i get an error: 
> 
> FATAL: Module ip_tables not found.
> 
> iptables v1.2.9: can't initialize iptables table `filter': iptables who? (do you need to insmod?)
> ...

 

From the howto:

```
I enabled all the options as modules (in case I want to test other options later) and added ip_tables to my modules.autoload. This loads several modules as dependencies. Later you may want the ip_conntrack for logging.

```

I should have also added:

```
modprobe ip_tables
```

if you they are not loaded.

lmk

 :Smile: 

----------

## mog

hi ... at first ... great stuff ... nice tutorial   :Laughing: 

it works fine for me, but I also have to rerun the ip forwarding activation everytime I restart iptables. I have found an if statement in the init.d script for iptables that does the activation, but it checks a variable which is never yes in my case. 

does anyone know what file one has to alter in order to get this statement to work without commenting out the if

----------

## mog

doh ... I should have looked first   :Embarassed:   ... the ENABLE_FORWARDING_IPv4 variable is in /etc/conf.d/iptables ... just set it to yes and forwarding will work just fine after starting/restarting iptables without prior running of the above script ...    :Laughing: 

----------

## acidburn

SWEET!! Thanks for the gouge.  It was easy to understand and makes things easier   :Smile: 

----------

## sobers_2002

hi everyone

                i am having a doubt here.......i am using ncftpd.....in which in dunno how to specify the passive ports........so since i am running a ftp server also i'll need to open them up. Another thing how do i stop ip tunneling??????

----------

## krunk

 *sobers_2002 wrote:*   

> hi everyone
> 
>                 i am having a doubt here.......i am using ncftpd.....in which in dunno how to specify the passive ports........so since i am running a ftp server also i'll need to open them up. Another thing how do i stop ip tunneling??????

 

This howto is a great example of what opensource documentation should be:

FrozenTux

You can probably find something there.

The iptables mailing list is extremely active as well:

netfilter@lists.netfilter.org

----------

## weyhan

 *Quote:*   

> Interface configuration:
> 
> In my set up, I have three NIC's, one is connected to the WAN through pppoe, the other two to my internal network. In order for them all to play nicely with iptables and masquerading (NAT'ing), they must be set to different subnets. For example, the two NIC's connected to my internal computers, e.g., the internal NIC's, are assigned: 192.168.1.78 and 192.168.2.78 respectively. It should be noted here that it is perfectly acceptable to connect these internal NIC's to any network capable device, such as a switch or hub. For pppoe conections we make sure the NIC connected to the outside world, e.g. the external NIC is not assigned any ip....it's entries in /etc/conf.d/net should be left blank. We must also assign proper netmasks and broadcast values to these interfaces. Your conf.d should look like this for the server:
> 
> Server
> ...

 

Just to point out that leaving external NIC setting blank will cause "/etc/init.d/net.eth0 start" to fail when you do:

 *Quote:*   

> 
> 
> Now add all the interfaces to the default run level and restart connections:
> 
> Server
> ...

 

Instead your example net file should be:

```
# For pppoe connections you do not want to set values for eth0, simply add \

# net.ppp0 to your default runlevel

iface_eth0="up"

iface_eth1="192.168.1.78 broadcast 192.168.1.255 netmask 255.255.255.0"

iface_eth2="192.168.2.78 broadcast 192.168.2.255 netmask 255.255.255.0"

```

Not sure why it worked for you in the first place.

----------

## krunk

 *weyhan wrote:*   

>  *Quote:*   Interface configuration:
> 
> In my set up, I have three NIC's, one is connected to the WAN through pppoe, the other two to my internal network. In order for them all to play nicely with iptables and masquerading (NAT'ing), they must be set to different subnets. For example, the two NIC's connected to my internal computers, e.g., the internal NIC's, are assigned: 192.168.1.78 and 192.168.2.78 respectively. It should be noted here that it is perfectly acceptable to connect these internal NIC's to any network capable device, such as a switch or hub. For pppoe conections we make sure the NIC connected to the outside world, e.g. the external NIC is not assigned any ip....it's entries in /etc/conf.d/net should be left blank. We must also assign proper netmasks and broadcast values to these interfaces. Your conf.d should look like this for the server:
> 
> Server
> ...

 

Actually I missed editing out net.eth0 in the starting of interfaces. Thanks for pointing it out. It works anyway because the rp-pppoe init script brings eth0 up properly. Thanks.

----------

## weyhan

 *Quote:*   

> Actually I missed editing out net.eth0 in the starting of interfaces. Thanks for pointing it out. It works anyway because the rp-pppoe init script brings eth0 up properly. Thanks.

 

You are using rp-pppoe to dialout?  I thought you need to use the rp-pppoe init.d script instead of the net.ppp0? AFAICT, net.ppp0 have nothing to do with rp-pppoe. No? Mind sharing how you get net.ppp0 up?

When I use net.ppp0 to bring up pppoe, it complains that the interface is not up.  :Sad:  So I do need to have:

```

# my external interface is eth1

iface_eth1="up"

```

in my net file. and do a:

```

/etc/init.d/net.eth1 start

```

I'm actually trying to get pppoeup without using the rp-pppoe package without much success but having good progress.

----------

## weyhan

Edit: Never mind. I have found a typo in my dhcp server's for the gateway entry...  :Embarassed: 

Anyway, great tips. Maybe it's time for me to move to part II 

Okay, I am going with rp-pppoe for now and have tried out your iptables script. I did have a little problem with the setting as it is.

I have a very similar setup as you have described except I have only 2 NIC on the server and only 2 subnets (192.168.0.x and 192.168.1.x). If I use the exact setup you have, I can't access the Internet from my clients. Not sure why the server is not routing the packets to my ADSL modem. However if I change the gateway to the dynamic IP my ISP have supply (IP of the ppp0 interface), it works. As in your example, the gateway is the NICs IP on the server.

Any ideas?

----------

## soulfire

great HOWTO, thank u !!!!

----------

## gwion

dear krunk,

thank you very much. this howto is exactly what i needed to get my router and my homenetwork going   :Very Happy: 

cheers,

gwion

----------

## BlinkEye

thanks a lot. this helped me to solve a problem. within time i'm trying out your PART II

----------

## siroxo

Awesome tutorial.

One question: Is it considered bad form to use iptables firewalls on your main box? (I'm living on a budget here hehe)

----------

## Lepaca Kliffoth

I'm tired... I just can't understand what is wrong. I used the script you posted. My setup: desktop with internet connection on ip 192.168.0.1 . Net access is through ppp0. Desktop's connected to a laptop with a cross-over cable. Laptop's ip is 192.168.0.2, gateway 192.168.0.1 and nameserver 192.168.0.1 . Here is the script. As you can see intif is eth0. There's no intif2, it's got just ONE ethernet card.

```

#!/bin/bash

IPTABLES='/sbin/iptables'

# Set interface values

EXTIF='ppp0'

INTIF1='eth0'

#INTIF2='eth2'

# enable ip forwarding in the kernel

/bin/echo 1 > /proc/sys/net/ipv4/ip_forward

# flush rules and delete chains

$IPTABLES -F

$IPTABLES -X

# enable masquerading to allow LAN internet access

$IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

# forward LAN traffic from $INTIF1 to Internet interface $EXTIF

$IPTABLES -A FORWARD -i $INTIF1 -o $EXTIF -m state --state NEW,ESTABLISHED -j ACCEPT

# forward LAN traffic from $INTIF2 to Internet interace $EXTIF

#$IPTABLES -A FORWARD -i $INTIF2 -o $EXTIF -m state --state NEW,ESTABLISHED -j ACCEPT

#echo -e "       - Allowing access to the SSH server"

$IPTABLES -A INPUT --protocol tcp --dport 22 -j ACCEPT

#echo -e "       - Allowing access to the HTTP server"

$IPTABLES -A INPUT --protocol tcp --dport 80 -j ACCEPT

```

I didn't bother with the last two lines since all that talk about security's good as crap until you put up a proper firewall (right?) however thing don't work anyway, even if I put those two lines back.  lsmod output:

```

bash-2.05b# lsmod

Module                  Size  Used by    Tainted: P

n_hdlc                  6496   1  (autoclean)

ppp_synctty             6560   1  (autoclean)

ppp_generic            20836   3  (autoclean) [ppp_synctty]

slhc                    5152   0  (autoclean) [ppp_generic]

agpgart                14248   3  (autoclean)

ipt_state                536   3  (autoclean)

ipt_MASQUERADE          1496   5  (autoclean)

iptable_nat            18094   1  (autoclean) [ipt_MASQUERADE]

ip_conntrack           22500   0  (autoclean) [ipt_state ipt_MASQUERADE iptable_nat]

iptable_filter          1740   1  (autoclean)

ip_tables              13056   6  [ipt_state ipt_MASQUERADE iptable_nat iptable_filter]

i810_audio             25308   0

ac97_codec             13396   0  [i810_audio]

sis900                 13292   1

crc32                   2912   0  [sis900]

supermount             77888   1  (autoclean)

nvidia               1965984   6

usb-ohci               19464   0  (unused)

ehci-hcd               19052   0  (unused)

usbcore                63628   2  [usb-ohci ehci-hcd]

```

After executing the script, setting ips gateways and everything like I said before, still the laptop cant't resolve the address www.google.it (or anything else). If I ping an external ip it's all nice and working, it's just that dns requests aren't being forwarded (or whatever). So please, someone help me  :Sad: (( Oh I'm on the experimental gentoo-sources 2.4.26

----------

## Lepaca Kliffoth

Sorry I'm the dumbest creature on earth. I just had to put my isp's dns in the client's /etc/resolv.conf. Sorry for that.

----------

## CompiledMonkey

Get ready for a stupid question...

Where exactly do I save this iptables config file?

----------

## krunk

 *CompiledMonkey wrote:*   

> Get ready for a stupid question...
> 
> Where exactly do I save this iptables config file?

 

Anywhere you want.  :Very Happy: 

I personally put it in /root/scripts. 

All you do is make it executeable and than ./firewall_script.  :Smile: 

----------

## BlinkEye

i prefer to put any script into either /usr/bin or /usr/sbin for superuser scripts so your script gets recognized with tabcompletion. of course you may export another path to PATH (within your .bashrc) but i don't like that alternative. to see which paths are exporteted execute

```
echo $PATH
```

you may save your file in any of these paths and it will be recognized simply by typing *myscript_name*

----------

## krunk

 *BlinkEye wrote:*   

> i prefer to put any script into either /usr/bin or /usr/sbin for superuser scripts so your script gets recognized with tabcompletion. of course you may export another path to PATH (within your .bashrc) but i don't like that alternative. to see which paths are exporteted execute
> 
> ```
> echo $PATH
> ```
> ...

 

Yes, I add a path to the root/scripts directory. My reasoning for throwing it there is I have all to often written a script, than forgot what I named it......silly, I know, but it keeps me from "losing" scripts amongst the /sbin/

----------

## CompiledMonkey

 *krunk wrote:*   

> 
> 
> Anywhere you want. 
> 
> I personally put it in /root/scripts. 
> ...

 

Awesome, thanks for the help!  I'm only trying to harden a firewall on my gentoo system, so I edited the config file you provided.  Can you tell me if this is correct?  All I want to allow is ssh to the machine, reject everything else.

```

#!/bin/bash

IPTABLES='/sbin/iptables'

# Set interface values

INTIF='eth0'

# enable ip forwarding in the kernel

/bin/echo 1 > /proc/sys/net/ipv4/ip_forward

                                                                               

# flush rules and delete chains

$IPTABLES -F

$IPTABLES -X

                                                                               

#echo -e "       - Allowing access to the SSH server"

$IPTABLES -A INPUT --protocol tcp --dport 22 -j ACCEPT

                                                                               

# block out all other Internet access on $INTIF

$IPTABLES -A INPUT -i $INTIF -m state --state NEW,INVALID -j DROP

$IPTABLES -A FORWARD -i $INTIF -m state --state NEW,INVALID -j DROP 

```

----------

## CompiledMonkey

I've noticed I cannot get out on port 80 anymore.  Could anybody help me out in understanding these rules.  I assume I just need a rule to let outgoing traffic through on port 80.  Only I don't know the syntax for the rule.

----------

## BlinkEye

add these lines after you flush the chains and rules

```
###  set default rules (DENY, ACCEPT)  ###

        ${IPTABLES} -P INPUT DROP

        ${IPTABLES} -P FORWARD ACCEPT

        ${IPTABLES} -P OUTPUT ACCEPT
```

and everything else afterwards

----------

## CompiledMonkey

I'm still not able to get out with wget or ping.  I've tried just running the "iptables save" command and running the script myself.  Neither seems to yield any different results.

```

#!/bin/bash

IPTABLES='/sbin/iptables'

# Set interface values

INTIF='eth0'

# enable ip forwarding in the kernel

/bin/echo 1 > /proc/sys/net/ipv4/ip_forward

# flush rules and delete chains

$IPTABLES -F

$IPTABLES -X

# set default rules (DENY, ACCEPT)

$IPTABLES -P INPUT DROP

$IPTABLES -P FORWARD ACCEPT

$IPTABLES -P OUTPUT ACCEPT

#echo -e "      - Allowing access to the SSH server"

$IPTABLES -A INPUT --protocol tcp --dport 22 -j ACCEPT

# block out all other Internet access on $INTIF

$IPTABLES -A INPUT -i $INTIF -m state --state NEW,INVALID -j DROP

$IPTABLES -A FORWARD -i $INTIF -m state --state NEW,INVALID -j DROP

```

Here is the output when I run "iptables --list":

```

zion bin # iptables --list

Chain INPUT (policy DROP)

target     prot opt source               destination

ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh

DROP       all  --  anywhere             anywhere            state INVALID,NEW

Chain FORWARD (policy ACCEPT)

target     prot opt source               destination

DROP       all  --  anywhere             anywhere            state INVALID,NEW

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

```

----------

## BlinkEye

i do have the same output of 

```
iptabels --list 
```

for the output chain. i don't know yet what's wrong but have a look at this thread as my current iptables script is the last but two posted post.

----------

## CompiledMonkey

Can I get some more replies...  :Very Happy: 

----------

## BlinkEye

stupid me, i forgot to post the link! i think with these information and my script (posted there) you should get it going https://forums.gentoo.org/viewtopic.php?t=175914&highlight=

----------

## CompiledMonkey

I trimmed that script down some, but it got me working.  Thanks a lot!  I think what I was missed was this part:

```

 echo "* enabling masquerading of internal hosts"

   # enable masquerading to allow LAN internet access    

   ${IPTABLES} -t nat -A POSTROUTING -o ${EXT_NIC} -j MASQUERADE

   

   ${IPTABLES} -t nat -P PREROUTING ACCEPT

   ${IPTABLES} -t nat -P POSTROUTING ACCEPT

   ${IPTABLES} -t nat -P OUTPUT ACCEPT 

```

----------

## Joe Kinley

Well, my script routes, but if i restart, i have to rerun the script for routing again. 

It does not save the ruleset..... in this thread there stood, i have tu check the ENABLE_FORWARDING_IPv4="yes" in the /etc/conf.d/iptables.

But for me this file looked like 

# Location in which iptables initscript will save set rules on 

# service shutdown

IPTABLES_SAVE="/var/lib/iptables/rules-save"

#Options to pass to iptables-save and iptables-restore 

SAVE_RESTORE_OPTIONS="-c"

now i just typed this variable in, but it does not route either.

Is my file corrupted ??

----------

## mudrii

Very good HOWTO, BIG THX

----------

## hjnenc

@Joe Kinley

Your file is OK, this was taken out in iptables-1.2.9-r1 (not exactly sure about the version). The ebuild prints these warnings:

```
!!! ipforwarding is now not a part of the iptables initscripts.

Until a more permanent solution is implemented adding the following

to /etc/conf.d/local.start will enable ipforwarding at bootup:

  echo "1" > /proc/sys/net/ipv4/conf/all/forwarding

```

----------

## BlackCat73

Hi,

This is a newbie question so please bear with me, I'm trying to install iptables in my newly compiled gentoo, here what I've done,

- I set the necessary option in the kernel and recompiled.

- I emerged iptables

- After reading this thread, I didn't know where to write my script so I typed 

```
/etc/init.d/iptables save
```

- This resulted in a file called /var/lib/iptables/rules-save

- I opened it using nano and wrote the script

- Here's what I wrote inside(this box will be an e-mail server behind a router,)

```

#!/bin/bash

IPTABLES='/sbin/iptables'

# Define shortcut values

NIC='eth0'

# Enable IP forwarding in the kernel

/bin/echo "1" > /proc/sys/net/ipv4/ip_forward

# Flush rules and delete chains

$IPTABLES -F

$IPTABLES -X

# Enable masquerading to allow LAN internet access

$IPTABLES -t nat -A POSTROUTING -o $NIC -j MASQUERADE

# Block out ALL incoming traffic by default

$IPTABLES -A INPUT -i $NIC -m state --state NEW,INVALID -j DROP

# Block out ALL forwading traffic by default

$IPTABLES -A FORWARD -i $NIC -m state --state NEW,INVALID -j DROP

# Allow ALL outgoing traffic

$IPTABLES -P OUTPUT ACCEPT

#echo -e "       - Allowing access to the SSH server"

$IPTABLES -A INPUT --protocol tcp --dport 22 -j ACCEPT

```

- Once saved I typed 

```
/etc/init/d/iptables start
```

- then I get this error

```

root@usagi / # /etc/init.d/iptables start

 * Loading iptables state and starting firewall...

 * Restoring iptables ruleset

iptables-restore: line 2 failed 

```

What have I done wrong? Is this what I suppose to do or am I suppose to compile/run this script and then do? 

```
/etc/init/d/iptables save
```

Help is much appreciated. Thanks

----------

## BlackCat73

Ok, I read other post in this or another thread that those long lines that I typed is a shell script.

So I copied it into my /root/scripts/iptables_script and made it executable by chmod it executable

then I ran it by doing 

```
./iptables_script
```

I then got error message

```

root@usagi scripts # ./iptables_script

modprobe: Can't locate module ip_tables

iptables v1.2.11: can't initialize iptables table `filter': iptables who? (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

modprobe: Can't locate module ip_tables

iptables v1.2.11: can't initialize iptables table `filter': iptables who? (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

modprobe: Can't locate module ip_tables

iptables v1.2.11: can't initialize iptables table `nat': iptables who? (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

modprobe: Can't locate module ip_tables

iptables v1.2.11: can't initialize iptables table `filter': iptables who? (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

modprobe: Can't locate module ip_tables

iptables v1.2.11: can't initialize iptables table `filter': iptables who? (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

modprobe: Can't locate module ip_tables

iptables v1.2.11: can't initialize iptables table `filter': iptables who? (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

modprobe: Can't locate module ip_tables

iptables v1.2.11: can't initialize iptables table `filter': iptables who? (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

```

Am I suppose to recompile it into the kernel as a module? 

Thanks.

----------

## BlackCat73

I got it fixed, I forgot to include the necessary components in my kernel   :Embarassed: 

After I did that, recompile my kernel, everything returns to normal   :Very Happy: 

----------

## BlindSpy

great guide! thanks

----------

## burmashave

Thanks for an excellent quickstart!

----------

## radsatori

I use this process on my Gentoo box and my Redhat VPS, and for me it is the simplest from all the ways I have tried.

Basically put in the ports of the services you want and comment out the ones you don't, and then run the script.  

Then after you run the script, do a /etc/init.d/iptables save, and then a /etc/init.d/iptables restart.

You can take a peek at what your current rules are by running the command iptables-save at any time.

And if you have just installed iptables, as mentioned do a rc-update add iptables default

SCRIPT  - I called mine firewall.sh and made it executable

**********************************************************

#!/bin/bash

#---------------------------------------------------------------

# Reset everything

#---------------------------------------------------------------

iptables -F

iptables -X

iptables -F -t nat

iptables -F -t mangle

#---------------------------------------------------------------

# Basically let this machine acces any port on itself

#---------------------------------------------------------------

iptables -A INPUT -i lo -j ACCEPT

iptables -A OUTPUT -o lo -j ACCEPT

#---------------------------------------------------------------

# Users on this computers can access the web with no problems

#---------------------------------------------------------------

iptables -A OUTPUT -m state --state NEW -j ACCEPT

iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 

#---------------------------------------------------------------

# Different ports to be accessed

#---------------------------------------------------------------

#-------   FTP SERVICES  ---------------------------------------

iptables -A INPUT -p tcp --dport 20 -j ACCEPT

iptables -A INPUT -p tcp --dport 21 -j ACCEPT

#-------   SSH SERVICES  ---------------------------------------

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

#-------   SMTP SERVICES  --------------------------------------

iptables -A INPUT -p tcp --dport 25 -j ACCEPT

#-------   NAME SERVER  ----------------------------------------

iptables -A INPUT -p tcp --dport 53 -j ACCEPT

iptables -A INPUT -p tcp --dport 953 -j ACCEPT

#-------   APACHE WEB SERVER  ----------------------------------

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

iptables -A INPUT -p tcp --dport 443 -j ACCEPT

#-------   POP3 SERVER  ----------------------------------------

iptables -A INPUT -p tcp --dport 110 -j ACCEPT

iptables -A INPUT -p tcp --dport 995 -j ACCEPT

#-------   IMAP SERVER  ----------------------------------------

iptables -A INPUT -p tcp --dport 143 -j ACCEPT

iptables -A INPUT -p tcp --dport 993 -j ACCEPT

----------

## Rooney

Just want to  say thank im not a noob to gentoo but certainly am to IP Tables and this helped big time.

Cheers.....Rooney

----------

## lundi

every time when I startup iptables service, I have to do 

"echo 1 > /proc/sys/net/ipv4/ip_forward" manually again. Do I some thing wrong?

----------

## Walmarde

Nice how-to !

----------

## zdra

 *lundi wrote:*   

> every time when I startup iptables service, I have to do 
> 
> "echo 1 > /proc/sys/net/ipv4/ip_forward" manually again. Do I some thing wrong?

 

I've the same problem ! ive tried with this in /etc/conf.d/iptables:

```
ENABLE_FORWARDING_IPv4="yes"
```

but doesn't works.... someone has an idea ?

thx.

----------

## Tazok

My router has only one NIC, which is connected to the adsl-modem and to the rest of the network via a switch. It looks like this:

```

         switch         ______

 ___         _           (            )

|      |-----|_|-------( LAN    )

|___|       |            (______)

router    |

                |

               |_| adsl-modem

```

Can anyone provide me with an absolutely minimal configuration for iptables, including masquerading (access to the internet from my LAN) and blocking all incoming connections from the internet (prevent access to nfs and other network services) ?

I would really like to learn iptables, but I need something to start with.

Thanks for any help!

----------

## res0r9lm

/etc/conf.d/iptables and /etc/init.d/iptables has changed and no longer have anything to do with ipforwarding in the latest ~x86 version not sure where this needs to be enable now but I think /etc/sysctl

----------

## j-m

Put the following in /etc/conf.d/local.start

```

echo "1" > /proc/sys/net/ipv4/conf/all/forwarding

```

This is also advised when you finish emerging iptables.

----------

## cocran

Hello. I am a new Linux and Gentoo supporter, and I have a problem with the Iptables.

I followed the great tutorial, but I stop without seeing "the light out out of the tunnel"

I compliled the kernel with genkernel and I enabled iptable support(not as a modul).  I merged the iptables and configured the network. But when trying to run the script I get

```

bash-2.05b# ./ipConfig.script

iptables v1.2.11: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

iptables v1.2.11: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

iptables v1.2.11: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

Warning: wierd character in interface `-o' (No aliases, :, ! or *).

Bad argument `eth0'

Try `iptables -h' or 'iptables --help' for more information.

iptables v1.2.11: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

iptables v1.2.11: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

iptables v1.2.11: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

iptables v1.2.11: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)

Perhaps iptables or your kernel needs to be upgraded.

bash-2.05b# 

```

I also tryed again but making enabling iptables in the kernel as a modul, then I making "modprobe ip_tables". Infact I have this result from lsmod

```

bash-2.05b# lsmod     

Module                  Size  Used by

ipt_MASQUERADE          3464  2 

iptable_nat            24620  2 ipt_MASQUERADE

ip_tables              17920  2 ipt_MASQUERADE,iptable_nat

ohci_hcd               17924  0 

snd_via82xx            21764  0 

snd_ac97_codec         59908  1 snd_via82xx

snd_pcm                76808  1 snd_via82xx

snd_page_alloc          8840  2 snd_via82xx,snd_pcm

snd_mpu401_uart         5504  1 snd_via82xx

snd_rawmidi            18852  1 snd_mpu401_uart

usbhid                 28480  0 

uhci_hcd               27792  0 

parport_pc             25920  0 

parport                32328  1 parport_pc

via_agp                 6784  1 

usb_storage            25088  0 

ehci_hcd               24580  0 

usbcore                91360  7 ohci_hcd,usbhid,uhci_hcd,usb_storage,ehci_hcd

```

But the result of the script is the same.I am using kernel 2.6.7

I really don't  know what I can invet to help me   :Crying or Very sad: 

Thanks     :Smile: 

----------

## Rooney

Just built my self a new system where as the old one worked fine with iptables but this one won't boot the modified kernel for some reason can some one look over my kernel option

< > Connection tracking (required for masq/NAT)                                                       │ │

  │ │                                             [ ] Connection mark tracking support                                                                  │ │

  │ │                                             < > Userspace queueing via NETLINK                                                                    │ │

  │ │                                             <M> IP tables support (required for filtering/masq/NAT)                                               │ │

  │ │                                             <M>   limit match support                                                                             │ │

  │ │                                             <M>   IP range match support                                                                          │ │

  │ │                                             <M>   MAC address match support                                                                       │ │

  │ │                                             <M>   Packet type match support                                                                       │ │

  │ │                                             <M>   netfilter MARK match support                                                                    │ │

  │ │                                             <M>   Multiple port match support                                                                     │ │

  │ │                                             <M>   TOS match support                                                                               │ │

  │ │                                             <M>   recent match support                                                                            │ │

  │ │                                             <M>   ECN match support                                                                               │ │

  │ │                                             <M>   DSCP match support                                                                              │ │

  │ │                                             <M>   AH/ESP match support                                                                            │ │

  │ │                                             <M>   LENGTH match support                                                                            │ │

  │ │                                             <M>   TTL match support                                                                               │ │

  │ │                                             <M>   tcpmss match support                                                                            │ │

  │ │                                             <M>   Owner match support                                                                             │ │

  │ │                                             <M>   address type match support                                                                      │ │

  │ │                                             <M>   realm match support                                                                             │ │

  │ │                                             <M>   SCTP protocol match support                                                                     │ │

  │ │                                             <M>   comment match support                                                                           │ │

  │ │                                             <M>   hashlimit match support                                                                         │ │

  │ │                                             <M>   Packet filtering                                                                                │ │

  │ │                                             <M>     REJECT target support                                                                         │ │

  │ │                                             <M>   LOG target support                                                                              │ │

  │ │                                             <M>   ULOG target support                                                                             │ │

  │ │                                             <M>   TCPMSS target support                                                                           │ │

  │ │                                             < > Packet mangling                                                                                   │ │

  │ │                                             < > raw table support (required for NOTRACK/TRACE)                                                    │ │

  │ │                                             < > ARP tables support                                                                                │ │

  │ │                                             < > ipchains (2.2-style) support                                                                      │ │

  │ │                                             < >   ipfwadm (2.0-style) support             

as these are all modules i wouldent have thought it would affect a boot as they are loaded on demaned and i havent yet added any thing to modules.autoload yet

####appendment####

i have found this is when i add my network card drivers i have also tried 2 xcard (e100 and 3c59x) but both fetch a kernel panic

----------

## torklingberg

What settings changes if I want forwarding for the client, but no firewalling?

----------

## edwardpayne

I installed a new gentoo system last night.

i can't get iptables to work on this machine. I figured out that i'm missing the ipt_state module (can't load it) since it's this line I can't execute:

```
$IPTABLES -A FORWARD -i eth0 -o eth1 -m state --state NEW,ESTABLISHED -j ACCEPT
```

It's very annoying.. I can't find where ipt_state is in the menconfig either.. I need help here! I'm using Gentoo 2003.4 with the gen-sources kernel (2.6).

Or am I wrong about ipt_state?

plz help.

----------

## Xamindar

Great howto!  Thanks.  

I have a couple of questions though.

What does this part do exactly?

```
# forward LAN traffic from $INTIF1 to Internet interface $EXTIF 

$IPTABLES -A FORWARD -i $INTIF1 -o $EXTIF -m state --state NEW,ESTABLISHED -j ACCEPT
```

As my internal network is able to communicate with the outside world just fine with only nabled, this command doesn't make sense.

Does the commented out "echo -e" even do anything?

```
#echo -e "       - Allowing access to the SSH server" 

$IPTABLES -A INPUT --protocol tcp --dport 22 -j ACCEPT 

 
```

And also, is there any way to ignore arp requests that my isp is continually sending out?  Or is that kind of pointless.

Thanks:D

----------

## SerfurJ

here's an even simpler starting point for people who don't need the system to be a router:

```
#!/bin/bash

IPTABLES='/sbin/iptables'

# Set interface values

EXTIF='eth1'

# flush rules and delete chains

$IPTABLES -F

$IPTABLES -X

                                                                               

#echo -e "       - Allowing access to the SSH server"

$IPTABLES -A INPUT --protocol tcp --dport 22 -j ACCEPT

                                                                               

#echo -e "       - Allowing access to the HTTP server"

$IPTABLES -A INPUT --protocol tcp --dport 80 -j ACCEPT

                                                                               

# block out all other Internet access on $EXTIF

$IPTABLES -A INPUT -i $EXTIF -m state --state NEW,INVALID -j DROP

$IPTABLES -A FORWARD -i $EXTIF -m state --state NEW,INVALID -j DROP 

```

----------

## imsdunn

Krunk, Very nice! Great instructions! I just set up my first network at home following your instructions.

----------

## odioworks_com

hm can't seem to get it to work...

Every time I run /etc/init.d/iptables start I get this error:

: No such file or directory

Here is my exact IPtables script:

http://www.odioworks.com/iptables_code.txt

I asked this question in another post (https://forums.gentoo.org/viewtopic-p-2283977.html#2283977) and MrUlterior has been graciously helping me.  He suggested adding the code:

 *Quote:*   

> 
> 
> for MODULE in `find /lib/modules/*/netfilter -name "*.ko" -type f -print "%f" | egrep -o "[^\.]+"`; do 
> 
>    echo "Loading ${MODULE}" 
> ...

 

Since iptables is built into my kernel and not loaded.  However this has not helped.  Anyone experience this before?  Is there another simple iptables script that people have had success with?  I'm just basically interested in NATing...

TIA,

Sam

----------

## eleanor

Can anyone explain this to me:

 *Quote:*   

> #!/bin/bash 
> 
> #--------------------------------------------------------------- 
> 
> # Reset everything 
> ...

 

I would like to know what are the basic rules when writing this.  I understang what "iptables -A INPUT -p tcp --dport 143 -j ACCEPT " that is the way it is, but I don't understand the other things. Please, need help?

----------

## volkmar

 *SerfurJ wrote:*   

> here's an even simpler starting point for people who don't need the system to be a router:
> 
> 

 

I've got another one here. It's using the DROP policy and some ACCEPTs on the INPUT chain. This way both eth0 and eth1 can be used as interfaces to the internet. 

```
######################### start ###########################

iptables -F

iptables -X

iptables -Z

iptables -t nat -F

iptables -t nat -X

iptables -t nat -Z

iptables -t mangle -F

iptables -t mangle -X

iptables -t mangle -Z

iptables -P INPUT DROP

iptables -P FORWARD DROP

iptables -P OUTPUT ACCEPT

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -i lo -j ACCEPT

iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT

iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT

iptables -A INPUT -p icmp --icmp-type 12 -j ACCEPT

iptables -A INPUT -p tcp --syn --dport 113 -j REJECT --reject-with tcp-reset

############################# end #################################
```

Since it's only a few lines you don't need a script for it. Simply type the commands into console, then run "iptables-save". On reboot it should be restored automatically by "iptables-restore". 

Additional lines for remote-login (ssh) or sip phone calls may be addes.

Thanks to Georgi Alexandrov's reply on the netfilter mailing list.

----------

## simongermain

Thanks a lot! this guide is REALLY helpful!

Good work man!

----------

## huckabuck

Hi, i've been trying to get my iptables working for 3 days now, and i am lost. These are the commands i've been running as root, 

tux ~ # modprobe ip_tables

tux ~ # iptables -F

tux ~ # iptables -X

tux ~ # iptables -Z

tux ~ # iptables -t mangle -F

tux ~ # iptables -t mangle -X

tux ~ # iptables -t mangle -Z

tux ~ # iptables -P INPUT DROP

tux ~ # iptables -P FORWARD DROP

tux ~ # iptables -P OUTPUT ACCEPT

tux ~ # iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables: No chain/target/match by that name

and the whole thing gets hung up with the last line. I just want to set up a basic firewall to be able to browse and torrent, and possible set up an ftp fileserver in the future. What am i doing wrong. I wanted to get the rules straight, and get an understanding of what each command did before i put it in a script to start up at boot. 

Can anyone point me in the right direction ? i know this was originally scripted for a box running as a router, but i have just my main system. I'm running gentoo-sources 2.6.26-r3.

Thanks in advance.

----------

