# HOWTO: Quick/Simple Personal Firewall

## Cornfed

IPTables Personal Firewall How-To

  This guide is written for people that just want a personal firewall running on their workstations.  You might be running Gentoo at work, and would like some protection from a crazy co-worker.  Or, you might like some added protection on your internal servers.

This is mostly from the wiki site:

http://gentoo-wiki.com/HOWTO_Iptables_for_newbies

  The script itself was really just taken from:

http://www2.warwick.ac.uk/services/its/safe/diy/linux/iptables/

Kernel Config

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

 *Quote:*   

>  Device Drivers--->
> 
>   Networking Support--->
> 
>    Networking Options---->
> ...

 

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

Necessary Utilities

Next you must emerge the userland tools for cofiguring iptables: 

```
 emerge iptables
```

Scripting

Now to the fun part.....iptables. We going to simply allow everything out, and nothing in. Create a file (vi or nano my-rules, or whatever name your script), and put this in there:

```
#!/bin/sh

# Set location of iptables

IPTABLES=/sbin/iptables

# Define interfaces

PUBLIC_IF="eth0"

# Flush current rules

$IPTABLES -t nat -F

$IPTABLES -t filter -F

$IPTABLES -t mangle -F

# Delete custom chains

$IPTABLES -t nat -X

$IPTABLES -t filter -X

$IPTABLES -t mangle -X

# Set default policies

$IPTABLES -t filter -P INPUT DROP

$IPTABLES -t filter -P FORWARD DROP

$IPTABLES -t filter -P OUTPUT ACCEPT

$IPTABLES -t nat -P PREROUTING ACCEPT

$IPTABLES -t nat -P OUTPUT ACCEPT

$IPTABLES -t nat -P POSTROUTING ACCEPT

$IPTABLES -t mangle -P PREROUTING ACCEPT

$IPTABLES -t mangle -P INPUT ACCEPT

$IPTABLES -t mangle -P FORWARD ACCEPT

$IPTABLES -t mangle -P OUTPUT ACCEPT

$IPTABLES -t mangle -P POSTROUTING ACCEPT

# Allow traffic from trusted interfaces

$IPTABLES -A INPUT -i lo -j ACCEPT

# Allow traffic from established connections

$IPTABLES -A INPUT -i $PUBLIC_IF -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow typical ICMP responses

$IPTABLES -A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT

$IPTABLES -A INPUT -p icmp -m icmp --icmp-type 4 -j ACCEPT

$IPTABLES -A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT

$IPTABLES -A INPUT -p icmp -m icmp --icmp-type 12 -j ACCEPT

$IPTABLES -A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT

$IPTABLES -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
```

Save, and chmod 700 the file. (or 755 if you wish.  I don't like anyone else to run my scripts so I keep it at 700 or sometimes 500).  Execute the script.

```
chmod 700 my-rules

./my-rules
```

Now let's save it.

```
/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
```

That should be the end of it.  Now if you want to add SSH, you can add this to your script:

```
# Allow traffic to sshd (TCP, port 22)

$IPTABLES -A INPUT -p tcp -m tcp --dport 22 --syn -j ACCEPT

```

Just make sure you re-run the script, and restart iptables if you modify your script

If you are interested in logging connections, you can add this to the end of your script:

```
# Log stuff we might be interested in

$IPTABLES -A INPUT  -p tcp -d x.x.x.x -i $PUBLIC_IF -j LOG

```

I'm really only interested in people trying to ssh to my wrokstation, or probing for services.  I used "-p tcp" to rule out UDP packets.  I used "-d x.x.x.x" (where x.x.x.x is my IP address) because I'm only interested in packets destined for my machine.

If anyone knows a better logging rule, please feel free to post.

----------

## nick58b

Thank you!

It (appears to) work perfectly, and is exactly what I've been putting off doing on all my workstations.

Copy, paste, run a couple of commands, I think it took me 30 seconds to get it running.

Thanks again.

----------

## Naib

you should check out firehol - generates iptable firewall with very easy script

```

root@Fluid ~ # cat /etc/firehol/firehol.conf

#!/usr/sbin/firehol

FIREHOL_LOG_MODE="LOG"

FIREHOL_LOG_LEVEL="2"

FIREHOL_LOG_BURST="5"

FIREHOL_LOG_FREQUENCY="10/minute"

interface eth0 home

        server  dns     accept  

        server  ftp     accept  

        server  dhcp    accept  

        server  http    accept  

        server  netbios_ssn     deny

        server  microsoft_ds    reject  with    tcp-reset

        server  samba           deny

        server  cups            deny

        client  all     accept

        protection      strong

        policy          reject

        server  ident   reject  with    tcp-reset

```

----------

## monotux

Your ruleset wasn't that smart...

I "optimized" it a bit  :Smile: 

```
#!/usr/sbin/firehol

interface eth0 home

        policy drop

        server "dns  ftp dhcp http" accept 

        server "microsoft_ds ident" reject with tcp-reset

        client all accept

        protection strong
```

----------

## wswartzendruber

Awesome Howto!  That's just what I need and nothing else.   :Smile: 

----------

## Naib

 *furiorc wrote:*   

> Your ruleset wasn't that smart...
> 
> I "optimized" it a bit 
> 
> ```
> ...

 

true that is actually alot better!!

However, I am now getting this occuring again:

https://forums.gentoo.org/viewtopic.php?t=289426

----------

## piwacet

Noob question - will this script make all my ports "stealth" to the outside world, in other words, when I do the "shieldsup" test at: 

https://grc.com/x/ne.dll?bh0bkyd2

Will I pass?  (get all stealth ports - i.e., the computer does not respond to any requests for access to any port - neither denies nor accepts, simply is quiet and pretends there's no computer at that IP address, and certainly won't allow any connections; and also does not respond to ping requests.)

Thanks!

----------

## tom56

Another alternative is firestarter for those like me who even find this too daunting.

----------

## outspoken

i find it easier to deal with iptables directly by making my own scripts like the one in the first post here. once you get into using programs like firestarter, firehol, shorewall, or one of the other hundred programs out there you begin to lose sight of what is really going on and you then have to rely on a 3rd party program which is scrambling everything that is really going on. in order for you to make iptables work you have to edit a script for a program which in turn then interfaces with iptables for you, you have just added a middleman which is really not needed. now if something happens and you need to figure out what is really going on with your iptables rules your going to be lost, unless you can call upon your scripting program.

it is a good idea to stick with learning the iptables commands as they will be used the same across any system. whereas if you learn firehol, firestarter, etc, when you sit down or login to some remote machine and have to alter the chains your going to be stuck stratching your head asking the admin if he could please install firestarter. (yes if your allowed to look at the scripts most likely you will have root access and the ability to install firestarter).

just my opinion on the subject of these 3rd party programs.

----------

## Gauss_Cleric

Hi there, I think this is the right place to post this.

I have a local network managed by my ADSL modem/router. I configured it to let all ports open so I can fine-tune the firewall direcly from the PCs in the LAN.

This is the iptables scipts I've got with the help from kmyfirewall (excelent app BTW):

```

#!/bin/sh

#

# copyright (c) the KMyFirewall developers 2002

#      mail to: Christian Hubinger <e9806056@student.tuwien.ac.at>

#

# KMyFirewall v0.9.6.2

# This is an automatic generated file DO NOT EDIT

#

IPT="/sbin/iptables"

MOD="/sbin/modprobe"

status="0"

startFirewall() {

echo

echo "Starting firewall..."

#  Define all custom chains

echo -n "Create custom chains...                "

  echo "Done."

#  Rules:

echo "Settup Rules in Table FILTER:

"

#  Define Rules for Chain: INPUT

echo -n "Create Rules for Chain: INPUT                    "

$IPT -t filter -A INPUT --protocol tcp  --destination-port 53 -j ACCEPT  || { status="1"; echo "Setting up Rule: DNS_TCP_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol udp  --destination-port 53 -j ACCEPT  || { status="1"; echo "Setting up Rule: DNS_UDP_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 80 -j ACCEPT  || { status="1"; echo "Setting up Rule: WWW_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 8080 -j ACCEPT  || { status="1"; echo "Setting up Rule: WWW-PROXY_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 443 -j ACCEPT  || { status="1"; echo "Setting up Rule: SEC_WWW_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 110 -j ACCEPT  || { status="1"; echo "Setting up Rule: POP3_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 25 -j ACCEPT  || { status="1"; echo "Setting up Rule: SMTP_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 21 -j ACCEPT  || { status="1"; echo "Setting up Rule: FTP_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 23 -j ACCEPT  || { status="1"; echo "Setting up Rule: TELNET_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 22 -j ACCEPT  || { status="1"; echo "Setting up Rule: SSH_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 137 -j ACCEPT  || { status="1"; echo "Setting up Rule: SMB_NS_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 138 -j ACCEPT  || { status="1"; echo "Setting up Rule: SMB_DGM_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 139 -j ACCEPT  || { status="1"; echo "Setting up Rule: SMB_SSN_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 2049 -j ACCEPT  || { status="1"; echo "Setting up Rule: NFS_TCP_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol udp  --destination-port 2049 -j ACCEPT  || { status="1"; echo "Setting up Rule: NFS_UDP_SERVER FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 27960:27970 -j ACCEPT  || { status="1"; echo "Setting up Rule: Custom_ET_TCP FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol udp  --destination-port 27960:27970 -j ACCEPT  || { status="1"; echo "Setting up Rule: Custom_ET_UDP FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 4660:4670 -j ACCEPT  || { status="1"; echo "Setting up Rule: Custom_aMule_TCP FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol udp  --destination-port 4670:4680 -j ACCEPT  || { status="1"; echo "Setting up Rule: Custom_aMule_UDP FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol tcp  --destination-port 6680:6690 -j ACCEPT  || { status="1"; echo "Setting up Rule: Custom_Azureus_TCP FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol udp  --destination-port 6680:6690 -j ACCEPT  || { status="1"; echo "Setting up Rule: Custom_Azureus_UDP FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --protocol icmp   --icmp-type echo-request --match limit --limit 5/minute -j ACCEPT  || { status="1"; echo "Setting up Rule: PING_INPUT FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --match state --state RELATED,ESTABLISHED -j ACCEPT  || { status="1"; echo "Setting up Rule: CONNRACK_INPUT FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT --destination 127.0.0.1 --in-interface lo -j ACCEPT  || { status="1"; echo "Setting up Rule: LOOPBACK_INPUT FAILED !!!"; exit 1; }

$IPT -t filter -A INPUT -m limit --limit 1/second --limit-burst 5 -j LOG --log-prefix "KMF: " || { status="1"; echo "Setting up Rule: Chain: INPUT Drop Logging FAILED !!!"; exit 1; }

$IPT -t filter -P INPUT DROP || { status="1"; echo "Setting up Rule: Chain: INPUT Default Target FAILED !!!"; exit 1; }

echo "Done."

#  Define Rules for Chain: OUTPUT

echo -n "Create Rules for Chain: OUTPUT                    "

$IPT -t filter -P OUTPUT ACCEPT || { status="1"; echo "Setting up Rule: Chain: OUTPUT Default Target FAILED !!!"; exit 1; }

echo "Done."

#  Define Rules for Chain: FORWARD

echo -n "Create Rules for Chain: FORWARD                    "

$IPT -t filter -P FORWARD ACCEPT || { status="1"; echo "Setting up Rule: Chain: FORWARD Default Target FAILED !!!"; exit 1; }

echo "Done."

echo -n "Disable IP Forwarding.  "

echo 0 > /proc/sys/net/ipv4/ip_forward

echo "Done.

"

 echo -n "Enable Reverse Path Filtering      "

for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do

echo 2 > $i 

done

echo "Done."

 echo -n "Enable log_martians (logging).             "

for i in /proc/sys/net/ipv4/conf/*/log_martians ; do

echo 1 > $i 

done

echo "Done."

 echo -n "Enable Syn Cookies.          "

echo 1 > /proc/sys/net/ipv4/tcp_syncookies

echo "Done."

}

stopFirewall() {

  echo -n "Shutdown KMyFirewall...       "

  $IPT -t filter -F || status="1"

  $IPT -t filter -X || status="1"

  $IPT -t filter -P INPUT ACCEPT || status="1"

  $IPT -t filter -P OUTPUT ACCEPT || status="1"

  $IPT -t filter -P FORWARD ACCEPT || status="1"

 echo "Done."

}

case $1 in

  start)

  stopFirewall

  startFirewall

  ;;

  stop)

  stopFirewall

  ;;

  restart)

  stopFirewall

  startFirewall

  ;;

  *)

  echo "Usage: sh kmyfirewall.sh { start | stop | restart } "

  ;;

  esac

if [ "$status" = "1" ]; then

  exit 1

else

  exit 0

fi

```

Now, if I turn this on the WindowsXP box in the LAN stops seeing by samba shares.   :Confused:   You can see in the code above that there are rules of exception fro the SMB ports. I guess there are other that should be left open but I missed it!

So, what ports must I leave open so that the samba clients in the LAN can acess my shares?

Cheers,

----------

## deprave

Nice Tutorial, But here is another realy easy way to do it, do everything above upto scripting then once you get to the scripting part of the tut do this instead.

```

#emerge gshield
```

Then

```
#/etc/init.d/gshield start
```

Works realy well for all kinds of things, Its the method ive been using lately for routing even

the config is /etc/gshield/gshield.conf

but it works right out of portage no scripting nessecary  :Smile: 

----------

## tommy_fila

A quick and simple question:

It says that the script allows "everything out and nothing in". But my internet still works? It doesn't seem like everything coming in is being blocked. Which part of the script is allowing things in?

----------

## iainel

 *piwacet wrote:*   

> Noob question - will this script make all my ports "stealth" to the outside world, in other words, when I do the "shieldsup" test at: 
> 
> https://grc.com/x/ne.dll?bh0bkyd2
> 
> Will I pass?  (get all stealth ports - i.e., the computer does not respond to any requests for access to any port - neither denies nor accepts, simply is quiet and pretends there's no computer at that IP address, and certainly won't allow any connections; and also does not respond to ping requests.)
> ...

 

It didn't for me.  :Confused: 

No ports were open, 9 were stealthed and the rest were closed.

It also says I failed the test on...  Solicited TCP Packets: RECEIVED (FAILED) and Ping Reply: RECEIVED (FAILED).

Can anybody post lines of code to add to the file to help pass the test or stealth all ports?

Don't worry you're not the only noob at iptables  :Razz: 

----------

## nitroburn

I want to lock down client machines so that they can get to only one website...I have been reading and trying different combinations in firehol ....can someone give me an example of what to do?!

----------

## zeb

 *nitroburn wrote:*   

> I want to lock down client machines so that they can get to only one website...I have been reading and trying different combinations in firehol ....can someone give me an example of what to do?!

 

This should do it:

```

interface eth0 net

        policy reject

        client dns accept

        client http accept dst "forums.gentoo.org www.gentoo.org"

```

Only name lookup and http access to some gentoo.org servers allowed.

----------

## tommy_fila

I'm sorry to ask again, but how do websites work in the original script. I thought the script blocked all incoming traffic. So how can programs such as Gaim, IRC, etc all work on my computer?

----------

## zeb

 *tommy_fila wrote:*   

> I'm sorry to ask again, but how do websites work in the original script. I thought the script blocked all incoming traffic. So how can programs such as Gaim, IRC, etc all work on my computer?

 

There is this line in the script:

```

# Allow traffic from established connections 

$IPTABLES -A INPUT -i $PUBLIC_IF -m state --state RELATED,ESTABLISHED -j ACCEPT

```

Traffic related to established connections is allowed in, so once your browser (or irc client/gaim/...) has connected out, incoming packets from that connection are allowed through.

----------

## tommy_fila

Sweet. Thanks for the explanation.

----------

## elusive-dragon

i use Guarddog. pretty simple to use, id like to learn more about routers and make better use of my wireless ap.

----------

## Syph3r

 *iainel wrote:*   

>  *piwacet wrote:*   Noob question - will this script make all my ports "stealth" to the outside world, in other words, when I do the "shieldsup" test at: 
> 
> https://grc.com/x/ne.dll?bh0bkyd2
> 
> Will I pass?  (get all stealth ports - i.e., the computer does not respond to any requests for access to any port - neither denies nor accepts, simply is quiet and pretends there's no computer at that IP address, and certainly won't allow any connections; and also does not respond to ping requests.)
> ...

 

If you run 'iptables -L' what is the output?

----------

## Koala Kid

Guys, what should I write in this script to allow another users to download from me in Nicotine/Amule ?

Thank you.

----------

## iainel

 *Syph3r wrote:*   

> If you run 'iptables -L' what is the output?

 

```

Chain INPUT (policy DROP)

target     prot opt source               destination         

ACCEPT     all  --  anywhere             anywhere            

ACCEPT     all  --  10.0.0.9             anywhere            

ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 

DROP       icmp --  anywhere             anywhere            icmp destination-unreachable 

DROP       icmp --  anywhere             anywhere            icmp source-quench 

DROP       icmp --  anywhere             anywhere            icmp time-exceeded 

DROP       icmp --  anywhere             anywhere            icmp parameter-problem 

DROP       icmp --  anywhere             anywhere            icmp echo-reply 

DROP       icmp --  anywhere             anywhere            icmp echo-request 

Chain FORWARD (policy DROP)

target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination         

ACCEPT     all  --  10.0.0.9             anywhere

```

It's the script from the original post by Cornfed.

----------

## Syph3r

 *iainel wrote:*   

>  *Syph3r wrote:*   If you run 'iptables -L' what is the output? 
> 
> ```
> 
> Chain INPUT (policy DROP)
> ...

 

The problem is the  first line "ACCEPT     all  --  anywhere             anywhere".  Get rid of that rule and it should work.

----------

## AussieAndrew

 *iainel wrote:*   

>  *piwacet wrote:*   Noob question - will this script make all my ports "stealth" to the outside world, in other words, when I do the "shieldsup" test at: 
> 
> https://grc.com/x/ne.dll?bh0bkyd2
> 
> Will I pass?  (get all stealth ports - i.e., the computer does not respond to any requests for access to any port - neither denies nor accepts, simply is quiet and pretends there's no computer at that IP address, and certainly won't allow any connections; and also does not respond to ping requests.)
> ...

 

I guess my (D-link) router is doing it's job... all tests passed, all ports stealth  :Smile: 

----------

## Ashe

I think, as much as ShieldsUp has contributed to making the net safer, and can be a useful tool, it has also engendered  a certain amount of paranoia amongst certain people.

Sometimes, ports are going to be open. It's a fact. Hell, if you run any kind of external-facing server, you're going to need certain ports to be unscreened. Same with many p2p apps. What matters in these cases is making sure the software that is world-facing is as up to date and secure as it can be. A firewall is an important part of your computer security, yes, but it's only a part.

That said, does anyone know if any of the newer (multiport/multi-address) iptables stuff is any good?

----------

## MdaG

Whenever I try to run the script I can't access the internet... I didn't dare save it since I'm not sure I would be able to revert the change.

----------

## equaeghe

I used (part of) the script and it seems to work nicely, 

but I have some remaining questions about logging 

(I use "$IPTABLES -A INPUT -i $INET_IF -j LOG"):  

* does this logging line log only dropped incoming packets?

* where is everything logged to (nothing to be found in /var/log/)?

Erik

----------

## bienchen

Hi there,

so, I just copied&pasted the rules from this howto and everything seems to work fine...but when I throw an "iptables -L" I get teh following:

```

Chain INPUT (policy DROP)

target     prot opt source               destination

ACCEPT     all  --  anywhere             anywhere

ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED

ACCEPT     icmp --  anywhere             anywhere            icmp destination-unreachable

ACCEPT     icmp --  anywhere             anywhere            icmp source-quench

ACCEPT     icmp --  anywhere             anywhere            icmp time-exceeded

ACCEPT     icmp --  anywhere             anywhere            icmp parameter-problem

ACCEPT     icmp --  anywhere             anywhere            icmp echo-reply

ACCEPT     icmp --  anywhere             anywhere            icmp echo-request

ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh flags:FIN,SYN,RST,ACK/SYN

Chain FORWARD (policy DROP)

target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

```

From how I understand this whole iptables issue, I would have expected no rule accepting each protocol from anywhere in chain INPUT...or do I misinterpret the output?

greetings,

bienchen

----------

## mephist0

Wonderful HowTo !!!!

Thank you very much!!

But how do prevent the logs from iptables to be shown in dmesg?

----------

## d2_racing

I would like to know that too, because right now, I long only what is critial and that's all.

I don't want to spam my dmesg  :Razz: 

----------

## Mike Hunt

I'm not a big iptables expert but I can offer this. Hopefully it's close enough.

Do you have something like this?

```
iptables -A INPUT -i lo -j ACCEPT
```

That would produce this output:

```
ACCEPT     all  --  anywhere             anywhere 
```

But you should probably have that for some ipc's, etc...

The others do what they say.

This one is for established, related, therefore permitted incoming connections. Required by networking that needs both ways traffic, like file sharing, etc...

```
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
```

The icmp ones are all described in RFC's see: here for RFC references such as RFC792 for detailed descriptions.

The tcp dpt ones are the explicitly opened ports allowed in the iptables config, i.e. 22 (ssh) in the above posted case.

Note that opening port 22 like that may leave you vulnerable to brute force attacks see /var/log/messages. Therefore be sure to use strong passwords on your box.

----------

## d2_racing

For the brute force ssh attack, you can ban the ip after 3 or 10 attempts, so you have something to work for sure.

----------

## Mike Hunt

Yes like this, you need "recent" and "state" match support enabled in the kernel Core Netfilter Configuration enabled for it to work:

```
iptables -A INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set

iptables -A INPUT -p tcp --dport 22 -i eth0 -m state --state ESTABLISHED -m recent --update --seconds 60 --hitcount 2 -j REJECT --reject-with tcp-reset
```

Alternatively you can use a non standard port number for ssh and tweak the Port setting in /etc/ssh/sshd_config and /etc/ssh/ssh_config 

or use ssh -p number ...  and scp -P number ...  commands.

----------

## d2_racing

In fact, many peoples use port TCP 6888 for ssh just to be sure that they think that's a bitorrent port  :Razz: 

----------

## dwbowyer

Hello all,

I've been working a script to generate iptables rules, with a few features to them that I want/need. Gentoo docs provide

a limited and simple set of rules that worked well for a home router http://www.gentoo.org/doc/en/home-router-howto.xml

(In fact that was how I found Gentoo 3yrs ago while using Ubuntu. Gentoo's great, easy to understand documentation is

the primary reason I had for trying Gentoo). However, the existing guide didn't really teach me what the rules did,

or how they might compare to other rulesets. I know there are automatic tools out there, but I wanted to learn how to

do it myself with just iptables, and not add a layer of configuring some other tool.

Since my ISP and many others have monthly usage limits, the first reason I had for getting into this project was

a monthly usage counter. Anyway, I've found just a few topics in the forums to help expand my knowlege, and after a bit

of googling too, I got down to experimenting, testing and refining...

.. and I present here, my quite usable work in progress.

The script generates rules simple enough for a home PC (or home router), but is well on it's way to being acceptable for 

a full server setup, whether for a simple FTP, http, or even an ISPs needs. I'm willing to accept any input for feature

requests, advice or comments.

firewall.sh v0.1.0.

Features:

Separate config file

----To separate user modified paramaters and documentation from the script itself

Default DROP policies

----Unlike the home-router-howto, only ACCEPT what we specifically want

Simple logging options

----Currently for INVALID packets, will add more later.

Monthly usage counters

----Pretty output to make it clear, plus easily support automatic printing and resetting of the needed counters with cron or atd in one line

				    (Still working to improve on that one)

Multiple NIC support

----For more than one lan, net NIC -- just add to a single variable.

				    (Default routes, bridging and load balancing NOT yet added.)

Thoroughly documented

----For those new to iptables, wanting to learn more.

```

#!/bin/bash

# Distributed under the terms of the GNU General Public License v2

# Our complete stateful firewall script.  This firewall can be customized for

# a laptop, workstation, router or even a server. :)

USAGE() {

    echo "USAGE: firewall.sh start|stop|counter|counter-reset"

}

confscript="${HOME}/bin/firewall.config"

source $confscript

#### NOTE: Functions used here not merely reduce redunancy of script, but mainly

####    to ensure that "iptables -L" and "iptable -S" produce consistent and 

####   nicely aligned output

    # If changes are made to /etc/sysctl.conf, then opts are persistent across boots

    # Done here simply for completion's sake

function configure {

    # Explicitly disable ECN

    if [ -e /proc/sys/net/ipv4/tcp_ecn ]

    then

   echo 0 > /proc/sys/net/ipv4/tcp_ecn

    fi

    # Disable spoofing on all interfaces

    for x in ${LOOP} ${LAN} ${WAN}

    do

   echo 1 > /proc/sys/net/ipv4/conf/"${x}"/rp_filter

    done

}

    # Monthly usage counters, Totaling all Inbound and Outbound Imternet traffic

    # All the following rules, not having a target -- are passthrough -- counting packets/bytes, but not

    # having any affect on packet destiny. Thus, the final rule is the sum of the preceeding rules.

    # Specifically excluding INVALID packets and the LOOP interface.

    # VARIABLE $1 is name of an interface IE eth0 eth1

function AddMonthlyCounter() {

    # Eventually rules can easily be inserted to count traffic for specific services.

    iptables -N "${1}-Cnt"

    iptables -A "${1}-Cnt" -i ${1}   -m comment --comment "subTOTAL ${1} INPUT /DOWLOAD "

    iptables -A "${1}-Cnt" -o ${1}   -m comment --comment "subTOTAL ${1} OUTPUT/UPLOAD  "

    iptables -A "${1}-Cnt"      -m comment --comment "   TOTAL ${1} BANDWIDTH      "

}

    # Simply causes jump (Within the generated rules) to the above generated Counter rule chains,

    # then returns 

function IncCounters() {

    iptables -A INPUT   -i ${1} -j "${1}-Cnt"

    iptables -A OUTPUT  -o ${1} -j "${1}-Cnt"

}

    # continuing established and related connections, for the given interface

function ServicesContinue() {

    iptables -A INPUT   -i ${1} -m state --state ESTABLISHED,RELATED -j ACCEPT

    iptables -A OUTPUT  -o ${1} -m state --state ESTABLISHED,RELATED -j ACCEPT

    iptables -A FORWARD -i ${1} -m state --state ESTABLISHED,RELATED -j ACCEPT

}

    # opening NEW connections

function ServicesNew() {

   TARGET="$1"   # either "INPUT -i", "OUTPUT -o", or "FORWARD -i"

   IF="$2"      # the interface to make rule for

   shift      # strip the target

   shift      # strip the interface

   SERVICES="$*"   # anything else should be services/ports

   

   # Three options exist for NEW traffic, accept all NEW traffic, deny all, or allow by ports and services

   # A for loop here would create a rule for each client service opened, do I want that? We'll give it a try.

   if [ "${SERVICES}" == "ALL" ]

   then

       iptables -A ${TARGET} ${IF} -m state --state NEW -j ACCEPT

   elif [ "${SERVICES}" == "NONE" ]

   then

       echo "No NEW \"${TARGET}\" connections allowed!"

   else

       for OPEN in ${SERVICES}

       do

      iptables -A ${TARGET} ${IF} -p tcp --dport ${OPEN} -m state --state NEW -j ACCEPT

      iptables -A ${TARGET} ${IF} -p udp --dport ${OPEN} -m state --state NEW -j ACCEPT

       done

   fi

}

case "$1" in

# BEGIN firewall.sh start

"start")

    if [ configure ]

    then

   echo "Starting firewall..." 

    else

   echo "Failed to modify /proc settings" && exit 1

    fi

    # Default policies are to block all traffic, silently

    iptables -P INPUT   DROP

    iptables -P OUTPUT  DROP

    iptables -P FORWARD DROP

    if [ "$LOG" ]

    then

   # Logging are passthrough rules and we want to catch all

   iptables -A INPUT  -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-uid

   iptables -A OUTPUT -m state --state INVALID -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-uid

   # and what to do after logging

   iptables -A INPUT  -m state --state INVALID -j DROP

   iptables -A OUTPUT -m state --state INVALID -j DROP

    fi

    # Some people use ( ! -i ${WAN} ) below, but I prefer naming the interface(s) to open, each as a

    # separate rule, not one(s) NOT to open. It makes the iptables counters more useful, as we can see

    # how much traffic we are getting on EACH interface, rather than ALL opened interfaces (or rather

    # all interfaces we HAVEN'T kept closed). Also enables there to be more than one WAN without jumping

    # through more hoops

    # Note that using (iptables -L -v), the counters for these 2 lines should, by definition, match.

    iptables -A INPUT   -i ${LOOP} -j ACCEPT

    iptables -A OUTPUT  -o ${LOOP} -j ACCEPT

    for IFACE in ${WAN} ${LAN}

    do

   AddMonthlyCounter $IFACE

    done

    if [ "$ROUTER" ]

    then

   # We're a router of some kind, enable IP forwarding

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

        if [ "$NAT" = "dynamic" ]

   then

       # Dynamic IP address, use masquerading

       echo "Enabling masquerading (dynamic ip)..."

       iptables -t nat -A POSTROUTING -o ${WAN} -j MASQUERADE

       # Only "dynamic NAT tested, as I have not got static IP. Can someone reprort success of static NAT?

       # The rule should be good, but just need to verify that all conditional code works.

   elif [ "$NAT" != "" ]

   then

       # Static IP, use SNAT

       echo "Enabling SNAT (static ip)..."

       iptables -t nat -A POSTROUTING -o ${WAN} -j SNAT --to ${LAN}

   fi

    fi

    # We ought not control a LAN interface and services provided on such if we are not a ROUTER,

    # so following code could be moved inside the above ROUTER if, but maybe I'm wrong in some cases

    if [ "$TRUSTED_LAN" ]

    then

   for IFACE in ${LAN}

   do

       IncCounters $IFACE

       iptables -A INPUT   -i ${IFACE} -j ACCEPT

       iptables -A OUTPUT  -o ${IFACE} -j ACCEPT

       iptables -A FORWARD -i ${IFACE} -j ACCEPT 

   done

    else

   # I have not yet tested this section of rule generation, as I do trust my LAN, but

   # It should work. Anyone care to experiment?

   for IFACE in ${LAN}

   do

       IncCounters $IFACE

       ServicesContinue ${IFACE}

       # You may opt to replace the following with individual lines to specific interfaces:

       # if, for instance, you wished to open a service for a particular subnet, connected to some

       # interfaces, but not others. (Place them ouside the loop)

       ServicesNew "INPUT -i" ${IFACE} ${SERVICES_LAN}

       # What sort of NEW OUTPUT from our firewall/router/server to our LAN would we want blocked?

       ServicesNew "OUTPUT -o" ${IFACE} ALL

       # And just to be clear, we open port above to NEW connections for services the router/firewall

       # PROVIDES to the lan. and below FORWARD services passing THROUGH the router.

       ServicesNew "FORWARD -i" ${IFACE} ${SERVICES_CLIENT} 

   done

    fi

    # Implicitly, only external network connections make it to these rules.

    for IFACE in ${WAN}

    do

   IncCounters $IFACE

   ServicesContinue ${IFACE}

   # Note that from the internet we only FORWARD related and established connections,

   # so those are taken care of above.

   # The next line enables public access to certain services, for

   # those services listed in the configuration

   ServicesNew "INPUT -i" ${IFACE} ${SERVICES_WAN}

   # outgoing NEW connections

   ServicesNew "OUTPUT -o" ${IFACE} ${SERVICES_CLIENT} 

    done

    # For some reason, bash is not interpeting "FALSE" as bool FALSE, nor "TRUE" as bool true, and I have to

    # actually test against value

    if [ ${STEALTHED} == FALSE ]

    then

   echo "Rejecting all unwanted inbound connections..."

   # NOT stealthed, by design.

   for CLOSED in ${WAN}

   do

       iptables -A INPUT -p tcp -i ${CLOSED} -j REJECT --reject-with tcp-reset

       iptables -A INPUT -p udp -i ${CLOSED} -j REJECT --reject-with icmp-port-unreachable

   done

    fi

    # Leaving these here as a reminder to work on rules that limit connection attempts

    # and traffic volume per time period

    #   iptables -A INPUT -p ICMP -m limit --limit 1/s -j ACCEPT 

    #   iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT

    ;;

### END "firewall.sh start"

"stop")

    echo "Stopping firewall..."

    iptables -F

    iptables -P INPUT ACCEPT

    iptables -P OUTPUT ACCEPT

    iptables -P FORWARD ACCEPT

    # Turn off NAT/masquerading, if any

    iptables -t nat -F POSTROUTING

    for IFACE in ${WAN} ${LAN}

    do

   # All rules must be flushed and references to chain must be deleted

   # before the chain can be deleted

   iptables -X "${IFACE}-Cnt"

    done

    ;;

"counter")

    for IFACE in ${WAN} ${LAN}

    do

   date && iptables -v -L ${IFACE}-Cnt

    done

    ;;

"counter-reset")

    for IFACE in ${WAN} ${LAN}

    do

   date && iptables -v -L eth0-Cnt -Z

    done

    ;;

*)

    USAGE

    ;;

esac

```

```

# firewall.config

# The machine's loopback device, needed for some local programs to talk to each other)

LOOP="lo"

# The next two may have more than one interface, separated by spaces

# While most home PCs, even home networks would have only one interface at most

# of each kind # I want the script to be extensible to use in a larger network

# without modification. The script may be complicated to a new user, but the 

# rules genterated should be simple and easy to read

# LAN (connection(s) to a network)

# WAN (connection(s) to the Internet)

LAN="eth1"

WAN="eth0"

# If you're a router (and thus should forward IP packets between interfaces),

# you want ROUTER="TRUE"; otherwise, ROUTER="FALSE"

ROUTER="TRUE"

# Change this next line to the static IP of your WAN interface for static SNAT, or

# "dynamic" if you have a dynamic IP.  If you don't do routing and thus don't need any NAT,

# set NAT to "" to disable it.

#NAT="1.2.3.4"

NAT="dynamic"

#NAT=""

# Do we trust our internal LAN users?

TRUSTED_LAN="TRUE"

# Do we log? Currently, just for dropped invalid packets.

LOG="TRUE"

# IF you want to just drop all unwanted connection attempts to be stealthed,

STEALTHED="TRUE"

# or have packets not specifically processed to be rejected. Some people suggest that

# being stealthed when IP address is known to be active actually encourages hacking attempts.

# However, using Shields Up! at https://www.grc.com/x/ne.dll?bh0bkyd2 informs me that

# while most ports read closed, certain MS Windows ports read as stealthed (because they aren't

# used under Linux). That could effectively tell someone we aren't using Windows, and why

# would we want to give them ANY info that could identify our system and how to attack it?

#STEALTHED="FALSE"

# Change this line so that it lists the assigned numbers or symbolic names (from

# /etc/services) of all the services that you'd like to provide to the general

# public. If you don't want any services enabled, set it to "NONE"

# Common services in the following line, consult /etc/services for a more complete list

#SERVICES_WAN="ftp ssh telnet smtp tftp http pop3 ntp rsync"

#SERVICES_WAN="NONE"

# DO NOT SET SERVICES_WAN="ALL" unless you are emulating a Microsoft Network

SERVICES_WAN="bittorrent"

# for bittorrent below 2 lines were added to the end of /etc/services

#echo "bittorrent   6881/tcp         # bittorrent Protocol" >> /etc/services

#echo "bittorrent   6881/udp         # bittorrent Protocol" >> /etc/services

# Otherwise, specify the port number, "6881", or range "6881:6889"

# AS above, but services would only be opened for ${LAN} interfaces

SERVICES_LAN="ntp distcc"

#SERVICES_LAN="NONE"

# DO NOT SET SERVICES_LAN="ALL" unless you are emulating a Microsoft Network

# Outbound services we'll be using as a client, not providing as a server

# Some IMPORTANT INFO HERE: due to how this script is written, it supports

# a paranoid level of firewalling including checking outbound connections.

# For most peeople that is not necessary or wanted so the DEFAULT IE

SERVICES_CLIENT="ALL"

# WILL OPEN NEW OUTBOUND CONNECTIONS FOR ALL PORTS

# The following line will actually BLOCK ALL NEW OUTBOUND CLIENT CONNECTIONS

#SERVICES_CLIENT="NONE"

# That would be useful for instance for public access computers that need to

# assume local users are not to be trusted (Public Library, Prisons, kiosks),

# or for use with dynamic iptables scripts that would open those ports only if

# certain conditions are met. Example, a net cafe could offer free use of computers

# for local-only usage IE word processing. But if service is paid for, then open

# the given system for full or limited internet usage, or local network gaming, etc.

# PLEASE NOTE that ANY other OPTIONS specified will ensure that ONLY those services

# listed will be able to establish NEW outgoing connections. Some spyware/worms/viruses

# once infecting a computer will "dial home". So for extra security, limiting outbound

# NEW connections to just the services/ports users actually use makes sense. This is true

# even on the average desktop PC, (unlike the above NONE option). But you BETTER know what

# services are used directly, and also which provide support services in the background.

# Luckily, if you are running Gentoo, you should, or know how to find out.

# I, myself am not quite there yet. (Not that paranoid)

#SERVICES_CLIENT="ftp http pop3 ntp irc https submission rsync pop3s bittorent svn"

# FOR completion's sake an option for services PROVIDED BY our LAN, for our LAN.

# Not used/implemented yet.

# For instance, if we had an HTTP server behind our firewall (rather that on it), and wanted

# access to that service, or wanted to have the help of others on our network for distributed compiling.

#SERVICES_CLIENT_LAN="distcc"

```

Some notes:

I have to note however that my ISP (Comcast) seems to count MUCH less traffic than is counted by my rules. I assume this

is because my script rules counts packet size and the ISP only counts the size of the contents of packets

(IE filesize, not transmission size). Then again I KNOW I download more than their monthly reports say I do.

Perhaps they don't count anything that might be cached on their servers?

Both due to the fact that so many of the rules have similar form, and so that the printing out of the rules using

"iptables -L" and "iptables -S" will be clear and easy to read, I use functions in the script. Also, minor changes

in one location can affect all similar generated rules.

Working toward supporting multiple interfaces for local network and internet connections (the script should do so),

although I don't currently use more than one of each. However, bridging and load balancing are not yet included,

and likely won't be included without help from users that actually have such a setup.

Rate Limiting connections or traffic are the goal of dynamic rules, that I want to work on soon.

In theory, the fewer rules a packet has to test against the lower the overhead of running the firewall. That's

probably why a lot of scripts use " [ ! WAN ] ACCEPT " setups to accept LAN and loopback traffic at the same time.

My thinking is, rules to accept loopback traffic could be near the end of the chains since few packets would

ever reach those rules. Furthermore, I might work on adding a config option to allow users to decide if LAN or WAN

rules should be added to chains first. That way if nearly all traffic is one or the other the majority of packets

would be caught in the first few rules.

----------

## dwbowyer

Example output of "iptables -L -v"

```

Chain INPUT (policy DROP 926 packets, 184K bytes)

 pkts bytes target     prot opt in     out     source               destination         

 1077 79652 LOG        all  --  any    any     anywhere             anywhere            state INVALID LOG level warning ip-options uid prefix `DROP INVALID ' 

 1077 79652 DROP       all  --  any    any     anywhere             anywhere            state INVALID 

    8   756 ACCEPT     all  --  lo     any     anywhere             anywhere            

30755   18M eth1-Cnt   all  --  eth1   any     anywhere             anywhere            

30755   18M ACCEPT     all  --  eth1   any     anywhere             anywhere            

 744K  508M eth0-Cnt   all  --  eth0   any     anywhere             anywhere            

 737K  508M ACCEPT     all  --  eth0   any     anywhere             anywhere            state RELATED,ESTABLISHED 

 1681  102K ACCEPT     tcp  --  eth0   any     anywhere             anywhere            tcp dpt:bittorrent state NEW 

 4120  389K ACCEPT     udp  --  eth0   any     anywhere             anywhere            udp dpt:bittorrent state NEW 

Chain FORWARD (policy DROP 0 packets, 0 bytes)

 pkts bytes target     prot opt in     out     source               destination         

 1496  241K ACCEPT     all  --  eth1   any     anywhere             anywhere            

 1505 1486K ACCEPT     all  --  eth0   any     anywhere             anywhere            state RELATED,ESTABLISHED 

Chain OUTPUT (policy DROP 0 packets, 0 bytes)

 pkts bytes target     prot opt in     out     source               destination         

  262 31912 LOG        all  --  any    any     anywhere             anywhere            state INVALID LOG level warning ip-options uid prefix `DROP INVALID ' 

  262 31912 DROP       all  --  any    any     anywhere             anywhere            state INVALID 

    8   756 ACCEPT     all  --  any    lo      anywhere             anywhere            

18010   44M eth1-Cnt   all  --  any    eth1    anywhere             anywhere            

18010   44M ACCEPT     all  --  any    eth1    anywhere             anywhere            

 816K  556M eth0-Cnt   all  --  any    eth0    anywhere             anywhere            

 792K  555M ACCEPT     all  --  any    eth0    anywhere             anywhere            state RELATED,ESTABLISHED 

24505 1584K ACCEPT     all  --  any    eth0    anywhere             anywhere            state NEW 

Chain eth0-Cnt (2 references)

 pkts bytes target     prot opt in     out     source               destination         

 744K  508M            all  --  eth0   any     anywhere             anywhere            /* subTOTAL eth0 INPUT /DOWLOAD  */ 

 816K  556M            all  --  any    eth0    anywhere             anywhere            /* subTOTAL eth0 OUTPUT/UPLOAD   */ 

1560K 1065M            all  --  any    any     anywhere             anywhere            /*    TOTAL eth0 BANDWIDTH       */ 

Chain eth1-Cnt (2 references)

 pkts bytes target     prot opt in     out     source               destination         

30755   18M            all  --  eth1   any     anywhere             anywhere            /* subTOTAL eth1 INPUT /DOWLOAD  */ 

18010   44M            all  --  any    eth1    anywhere             anywhere            /* subTOTAL eth1 OUTPUT/UPLOAD   */ 

48765   61M            all  --  any    any     anywhere             anywhere            /*    TOTAL eth1 BANDWIDTH       */ 

```

"iptables -S -v"

```

-P INPUT DROP -c 963 189188

-P FORWARD DROP -c 0 0

-P OUTPUT DROP -c 0 0

-N eth0-Cnt

-N eth1-Cnt

-A INPUT -m state --state INVALID -c 1101 80911 -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-uid 

-A INPUT -m state --state INVALID -c 1101 80911 -j DROP 

-A INPUT -i lo -c 8 756 -j ACCEPT 

-A INPUT -i eth1 -c 59714 38784970 -j eth1-Cnt 

-A INPUT -i eth1 -c 59714 38784970 -j ACCEPT 

-A INPUT -i eth0 -c 757143 514201777 -j eth0-Cnt 

-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -c 750282 513513461 -j ACCEPT 

-A INPUT -i eth0 -p tcp -m tcp --dport 6881 -m state --state NEW -c 1714 103913 -j ACCEPT 

-A INPUT -i eth0 -p udp -m udp --dport 6881 -m state --state NEW -c 4184 395215 -j ACCEPT 

-A FORWARD -i eth1 -c 2051 352749 -j ACCEPT 

-A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -c 1991 1934757 -j ACCEPT 

-A OUTPUT -m state --state INVALID -c 266 33089 -j LOG --log-prefix "DROP INVALID " --log-ip-options --log-uid 

-A OUTPUT -m state --state INVALID -c 266 33089 -j DROP 

-A OUTPUT -o lo -c 8 756 -j ACCEPT 

-A OUTPUT -o eth1 -c 36037 82036208 -j eth1-Cnt 

-A OUTPUT -o eth1 -c 36037 82036208 -j ACCEPT 

-A OUTPUT -o eth0 -c 833369 572271923 -j eth0-Cnt 

-A OUTPUT -o eth0 -m state --state RELATED,ESTABLISHED -c 808368 570656922 -j ACCEPT 

-A OUTPUT -o eth0 -m state --state NEW -c 25001 1615001 -j ACCEPT 

-A eth0-Cnt -i eth0 -m comment --comment "subTOTAL eth0 INPUT /DOWLOAD " -c 757143 514201777 

-A eth0-Cnt -o eth0 -m comment --comment "subTOTAL eth0 OUTPUT/UPLOAD  " -c 833369 572271923 

-A eth0-Cnt -m comment --comment "   TOTAL eth0 BANDWIDTH      " -c 1590512 1086473700 

-A eth1-Cnt -i eth1 -m comment --comment "subTOTAL eth1 INPUT /DOWLOAD " -c 59714 38784970 

-A eth1-Cnt -o eth1 -m comment --comment "subTOTAL eth1 OUTPUT/UPLOAD  " -c 36037 82036208 

-A eth1-Cnt -m comment --comment "   TOTAL eth1 BANDWIDTH      " -c 95751 120821178 

```

"firewall counter"

```

Sat Apr  3 16:06:00 PDT 2010

Chain eth0-Cnt (2 references)

 pkts bytes target     prot opt in     out     source               destination         

 775K  520M            all  --  eth0   any     anywhere             anywhere            /* subTOTAL eth0 INPUT /DOWLOAD  */ 

 855K  592M            all  --  any    eth0    anywhere             anywhere            /* subTOTAL eth0 OUTPUT/UPLOAD   */ 

1630K 1112M            all  --  any    any     anywhere             anywhere            /*    TOTAL eth0 BANDWIDTH       */ 

Sat Apr  3 16:06:00 PDT 2010

Chain eth1-Cnt (2 references)

 pkts bytes target     prot opt in     out     source               destination         

80856   56M            all  --  eth1   any     anywhere             anywhere            /* subTOTAL eth1 INPUT /DOWLOAD  */ 

48606  105M            all  --  any    eth1    anywhere             anywhere            /* subTOTAL eth1 OUTPUT/UPLOAD   */ 

 129K  161M            all  --  any    any     anywhere             anywhere            /*    TOTAL eth1 BANDWIDTH       */ 

```

----------

## lennarts

My box is behind the firewall of my router so I do not need another firewall - however ssh access is possible and it is rather annoing with alle those attacks  so  Mikes 2 lines just make it.

[quote="Mike Hunt"]Yes like this, you need "recent" and "state" match support enabled in the kernel Core Netfilter Configuration enabled for it to work:

```
iptables -A INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set

iptables -A INPUT -p tcp --dport 22 -i eth0 -m state --state ESTABLISHED -m recent --update --seconds 60 --hitcount 2 -j REJECT --reject-with tcp-reset
```

It is too restrictive in my environment so I have extended the last line by allowing access from within and allowing just one error from outside:

```

iptables -A INPUT -p tcp --dport 22 ! -s 192.168.1.0/24 -i eth0 -m state --state ESTABLISHED -m recent --update --seconds 60 --hitcount 3  -j REJECT --reject-with tcp-reset
```

----------

