# HOWTO: Iptables for newbies. PART II: Securing your Network

## krunk

Iptables for Newbies

Part II: Hardening Your Firwall

(part one can be found here: Part I: Getting up and running)

First Draft

*NOTE* It takes me a bit of time putting these together. So if it helped an you'd like to see the series continue put a quick post so I know it's being used and not just glanced at.  :Very Happy: 

*NOTE* --2004-09-17--   I've let this howto lag for while, partly due to a lot of work and partly due to laziness. However, I've gotten a lot of responses, feedback, and input recently and it seems to be picking up popularity so I intend to give it an overhaul this week.

cheers!

In the following howto we're going to further secure our now functional firewall. By the time we are through we should have a set of tested rules and policies that will prevent not only attacks to our own computer, but also attacks from our computer to the internet. Protecting others from the possibility of being attacked by one of our compromised computers is an essential and often overlooked aspect of security and common internet courtesy. I would even say for the SOHO network this is the most important aspect. Normally virus infection is only a minor nussence to a small network and rarely results in data loss....for us 100% *nix users it practically doesn't even exist. However, since small soho networks are often less secure then larger ones they are a favorite target for crackers looking for a launchpad for DoS attacks or other underhanded skullduggary.

The follwing is offered in a piece meal fashion in a sequence which enables the easiest step by step testing. Each step may require that something be inserted before, after, or in the middle of our existing script. This was done so that (hopefully) your network will only go down for a brief period during setup. I've done it this way because I have assumed many of you (like me) have a stand alone linux firewall/server. Since my preferred method is ssh, the network going down can be a PITA involving crawling under tables and such. If your daring, you can just copy the script at the end and run it. It should be fully functional, but I have only tested it on my system so ymmv.

**change log**

1. Added ip_conntrack_ftp and ip_nat_ftp modules to eliminate PASV error when emerging.

2. Eliminated filtering on the nat chain. I was having some "unpredictable results" and this cleared it up. It should not affect security at all since the filter chain is still, well, filtered.  :Smile: 

Necessary Tools

3. Corrected typo error at end of script: changed 'iptables' to $IPT

    * ifconfig

    * iptables

    * grep

    * sed

Setting up environment variables

We will define our networks interfaces and various tools used in the script:

```
vim myfw
```

```
#!/bin/bash

# External interface

EXTIF='ppp0'

# Internal interface

INTIF1='eth0'

INTIF2='eth1'

# Loop device/localhost

LPDIF=lo

LPDIP=127.0.0.1

LPDMSK=255.0.0.0

LPDNET="$LPDIP/$LPDMSK"

# Text tools variables

IPT='/sbin/iptables'

IFC='/sbin/ifconfig'

G='/bin/grep'

SED='/bin/sed'

# Setting up external interface environment variables

EXTIP="`$IFC $EXTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`"

#EXTBC="`$IFC $EXTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

# The above EXTBC is for those lucky enough to have a straight up ethernet.

# For pppoe users we just hard set it to a all expansive value

EXTBC=255.255.255.255

EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

EXTNET="$EXTIP/$EXTMSK"

#echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"

echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"

# Setting up environment variables for internal interface one

INTIP1="`$IFC $INTIF1|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`"

INTBC1="`$IFC $INTIF1|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

INTMSK1="`$IFC $INTIF1|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

INTNET1="$INTIP1/$INTMSK1"

echo "INTIP1=$INTIP1 INTBC1=$INTBC1 INTMSK1=$INTMSK1 INTNET1=$INTNET1"

#Setting up environment variables for internal interface two

INTIP2="`$IFC $INTIF2|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`"

INTBC2="`$IFC $INTIF2|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

INTMSK2="`$IFC $INTIF2|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

INTNET2="$INTIP2/$INTMSK2"

```

*NOTE* I have commented out the external broadcast from the above script due to the ppp0 connection not having one. This would normally be used to prevent "egress broadcasts" or outgoing broadcast (I will talk more on this later). As a solution I set EXTBC to 255.255.255.255, as I believe this will accomplish the same goal. If anyone has insight into the hitch let me know.

Ok, now lets exit out of vim and test to ensure that our environment variables are being correctly set:

chmod 700 myfw;./myfw

Your output should be similar to this:

```
EXTIP=204.223.98.5 EXTBC=255.255.255.255 EXTMSK=255.255.255.255 EXTNET=204.223.98.5/255.255.255.255

INTIP1=192.168.0.78 INTBC1=192.168.0.255 INTMSK1=255.255.0.0 INTNET1=192.168.0.78/255.255.0.0

INTIP2=192.168.1.78 INTBC2=192.168.1.255 INTMSK2=255.255.255.0 INTNET2=192.168.1.78/255.255.255.0
```

Ok now we're going to set up the ACCEPTS which will allow us to communicate with our server. In reality this is very ill advised. A solid firewall policy should DENY than ACCEPT. But if you do that you lose all connections while your testing so your not sure if your ACCEPT rules work at all. So, though we are entering this first, it will be the second to last rule set in the final script.

```
$IPT -t nat -A PREROUTING                       -j ACCEPT

# $IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET -j SNAT --to $EXTIP

# Comment out next line (that has "MASQUERADE") to not NAT internal network

$IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET1 -j MASQUERADE

$IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET2 -j MASQUERADE

$IPT -t nat -A POSTROUTING                      -j ACCEPT

$IPT -t nat -A OUTPUT                           -j ACCEPT

                                                                               

$IPT -A INPUT   -p tcp --dport auth --syn -m state --state NEW -j ACCEPT

                                                                               

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

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

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

```

Next we are going to define a couple of custom chains which will log drop and reject events. This way we don't have to enter a separate line for each command entered. The logs will be sent to where your syslog default log messages are sent (usually /var/log/messages). Later I'm going to write a grep/sed script that will parse and organize these for easy viewing and set it as a daily cron job.

This should be inserted immediately after the above definitions. When you are done, run the script again. It should have no affect on functionality of the network since we're just setting definitions. But it will ensure that we have no errors thusfar.

```

# We are now going to create a few custom chains that will result in

# logging of dropped packets. This will enable us to avoid having to

# enter a log command prior to every drop we wish to log. The

# first will be first log drops the other will log rejects.

                                                                                                                                                       

# Do not complain if chain already exists (so restart is clean)

$IPT -N DROPl   2> /dev/null

$IPT -A DROPl   -j LOG --log-prefix 'DROPl:'

$IPT -A DROPl   -j DROP

                                                                                                                                                       

$IPT -N REJECTl 2> /dev/null

$IPT -A REJECTl -j LOG --log-prefix 'REJECTl:'

$IPT -A REJECTl -j REJECT

```

Ok, now that we see our devices are being detected properly, we are going to insert a flush commands. So that when our rules are assigned it will be done cleanly. These lines should be inserted after our utilities definitions, the last one being: SED='/bin/sed'

```

# Flush all existing chains and erase personal chains

CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`

for i in $CHAINS

do

    $IPT -t $i -F

done

                                                                                                                                                       

for i in $CHAINS

do

    $IPT -t $i -X

done

```

Now we're ready to start laying down some rules. First we are going to accept all packets from our loopback device if the ip address matches that of any of our local interfaces:

```

$IPT -A INPUT   -i $LPDIF -s   $LPDIP  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $EXTIP  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $INTIP1  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $INTIP2  -j ACCEPT

```

Now we will block broadcasts both incoming and outgoing. This is can prevent DoS attacks against us, as well as preventing our clients from being used to DoS someone else. This is part of what's called "Egress Protection". It's a do unto your neighbour sort of philosophy. If all SysAdmins followed this policy, than many of the more severe and costly DoS attacks would either not have occurred or been extremely limited.

```

# Blocking Broadcasts

$IPT -A INPUT   -i $EXTIF -d   $EXTBC  -j DROPl

$IPT -A INPUT   -i $INTIF1 -d   $INTBC1  -j DROPl

$IPT -A INPUT   -i $INTIF2 -d   $INTBC2  -j DROPl

$IPT -A OUTPUT  -o $EXTIF -d   $EXTBC  -j DROPl

$IPT -A OUTPUT  -o $INTIF1 -d   $INTBC1  -j DROPl

$IPT -A OUTPUT  -o $INTIF2 -d   $INTBC2  -j DROPl

$IPT -A FORWARD -o $EXTIF -d   $EXTBC  -j DROPl

$IPT -A FORWARD -o $INTIF1 -d   $INTBC1  -j DROPl

$IPT -A FORWARD -o $INTIF2 -d   $INTBC2  -j DROPl

```

Now test the script once more to ensure we have no syntax errors. Also notice that we are using our newly defined DROPl chain. This means that the dropped packets will be logged. Next we are going to block WAN access our LAN if not specifically intended for our ips assigne ip:

```

# Block WAN access to internal network

# This also stops nefarious crackers from using our network as a

# launching point to attack other people

# iptables translation:

# "if input going into  our external interface does not originate from our isp assigned

# ip address, drop it like a hot potato

                                                                               

$IPT -A INPUT   -i $EXTIF -d ! $EXTIP  -j DROPl

```

We're going to apply the same logic to our internal lan. In other words, any packets not originating from our predefined internal network will be rejected:

```

# Now we will block internal addresses originating from anything buy our

# two predefined interfaces.....just remember that if you jack your

# your laptop or another pc into one of these NIC's directly, you'll need

# to ensure that they either have the same ip or that you add a line explicitly

# that IP as well

                                                                               

# Interface one/internal net one

$IPT -A INPUT   -i $INTIF1 -s ! $INTNET1 -j DROPl

$IPT -A OUTPUT  -o $INTIF1 -d ! $INTNET1 -j DROPl

$IPT -A FORWARD -i $INTIF1 -s ! $INTNET1 -j DROPl

$IPT -A FORWARD -o $INTIF1 -d ! $INTNET1 -j DROPl

# Interface two/internal net two

$IPT -A INPUT   -i $INTIF2 -s ! $INTNET2 -j DROPl

$IPT -A OUTPUT  -o $INTIF2 -d ! $INTNET2 -j DROPl

$IPT -A FORWARD -i $INTIF2 -s ! $INTNET2 -j DROPl

$IPT -A FORWARD -o $INTIF2 -d ! $INTNET2 -j DROPl

```

Next we do some more Egress checking of outgoing packets and stop all icmp requests except for pinging:

```

# An additional Egress check

                                                                               

$IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROPl

                                                                               

# Block outbound ICMP (except for PING)

                                                                               

$IPT -A OUTPUT  -o $EXTIF -p icmp \

  --icmp-type ! 8 -j DROPl

$IPT -A FORWARD -o $EXTIF -p icmp \

    --icmp-type ! 8 -j DROPl

```

Ok, where moving along now and we should test the script for errors. Assuming an all clear we're going to start plugging some of the more bothersome port holes:

```

# COMmon ports:

# 0 is tcpmux; SGI had vulnerability, 1 is common attack

# 13 is daytime

# 98 is Linuxconf

# 111 is sunrpc (portmap)

# 137:139, 445 is Microsoft

# SNMP: 161,2

# Squid flotilla: 3128, 8000, 8008, 8080

# 1214 is Morpheus or KaZaA

# 2049 is NFS

# 3049 is very virulent Linux Trojan, mistakable for NFS

# Common attacks: 1999, 4329, 6346

# Common Trojans 12345 65535

COMBLOCK="0:1 13 98 111 137:139 161:162 445 1214 1999 2049 3049 432

# TCP ports:

# 98 is Linuxconf

# 512-5!5 is rexec, rlogin, rsh, printer(lpd)

#   [very serious vulnerabilities; attacks continue daily]

# 1080 is Socks proxy server

# 6000 is X (NOTE X over SSH is secure and runs on TCP 22)

# Block 6112 (Sun's/HP's CDE)

TCPBLOCK="$COMBLOCK 98 512:515 1080 6000:6009 6112"

                                                                               

# UDP ports:

# 161:162 is SNMP

# 520=RIP, 9000 is Sangoma

# 517:518 are talk and ntalk (more annoying than anything)

UDPBLOCK="$COMBLOCK 161:162 520 123 517:518 1427 9000"

9 6346 3128 8000 8008 8080 12345 65535"

```

After defining the environment variables all we have to do is a simple for loop to assign rules to them all:

```

echo -n "FW: Blocking attacks to TCP port"

for i in $TCPBLOCK;

do

echo -n "$i "

  $IPT -A INPUT   -p tcp --dport $i  -j DROPl

  $IPT -A OUTPUT  -p tcp --dport $i  -j DROPl

  $IPT -A FORWARD -p tcp --dport $i  -j DROPl

done

echo ""

                                                                               

echo -n "FW: Blocking attacks to UDP port "

for i in $UDPBLOCK;

do

  echo -n "$i "

    $IPT -A INPUT   -p udp --dport $i  -j DROPl

    $IPT -A OUTPUT  -p udp --dport $i  -j DROPl

    $IPT -A FORWARD -p udp --dport $i  -j DROPl

done

echo ""

```

Ok, now with iptables each time we run the script it simply appends these to already existing chains...so things are probably getting a bit messy. For that reason we're going to jump to the beginning of our script....right after the enviroment variables for sed and grep, but before those of EXTIP and EXTBC and add a loop that deletes and flushes. This ensure we're working from a clean state. We didn't want to do that before because we couldn't have tested our script without either shutting down our connection or dropping our firewall completely. This script first sets all policies to DROP, than flushes and deletes our chains. In order to ensure that we can still ssh back into our server after a script restart we are going to append an INPUT chain for ssh. This should always be placed at the end of the script for now. This done in order to prevent a window from opening up while we reset rules which is a common error made:

```

# Deny than accept: this keeps holes from opening up

# while we close ports and such

                                                                               

$IPT        -P INPUT       DROP

$IPT        -P OUTPUT      DROP

$IPT        -P FORWARD     DROP

                                                                               

# Flush all existing chains and erase personal chains

CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`

for i in $CHAINS;

do

    $IPT -t $i -F

done

                                                                               

for i in $CHAINS;

do

    $IPT -t $i -X

done

$IPT -A INPUT   -i $INTIF1 -p tcp                      --dport 22 \

   --syn -m state --state NEW -j ACCEPT

```

Right afterwards we are going to activate the sysctl's for tcp_syncookies, icmp_echo_ignore_broadcasts, rp_filter, and accept_source_route. Heretofore many of the rules we've been "testing" haven't been able to actually work. In essence we were simply doing syntax error tests. Now our rules will be "for real":

```

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

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

                                                                               

# Source Address Verification

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

        echo 1 > $f

done

# Disable IP source routing and ICMP redirects

for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do

        echo 0 > $f

done

for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do

        echo 0 > $f

done

                                                                               

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

```

Now we're going to add ftp connection tracking so that we won't get PASV errors when emerging packages:

```

# Opening up ftp connection tracking

MODULES="ip_nat_ftp ip_conntrack_ftp"

for i in $MODULES;

do

  echo "Inserting module $i"

  modprobe $i

done

```

Now back to end of our script, we are going to open up services for systems behind our firewall. I have included services such as IRC, MSN, ICQ, and NFS, FTP, domain, and time. And some others. The important thing to note is that these will ONLY be availabe BEHIND the firewall. So this will not enable someone to ftp into your LAN:

```

IRC='ircd'

MSN=1863

ICQ=5190

NFS='sunrpc'

# We have to sync!!

PORTAGE='rsync'

OpenPGP_HTTP_Keyserver=11371

                                                                               

# All services ports are read from /etc/services

                                                                               

TCPSERV="domain ssh http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE \

            $IRC $MSN $ICQ $OpenPGP_HTTP_Keyserver"

UDPSERV="domain time"

echo -n "FW: Allowing inside systems to use service:"

for i in $TCPSERV;

do

   echo -n "$i "

   $IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP  \

    --dport $i --syn -m state --state NEW -j ACCEPT

   $IPT -A FORWARD -i $INTIF1 -p tcp -s $INTNET1 \

    --dport $i --syn -m state --state NEW -j ACCEPT

   $IPT -A FORWARD -i $INTIF2 -p tcp -s $INTNET2 \

    --dport $i --syn -m state --state NEW -j ACCEPT

                                                                               

done

echo ""

                                                                               

echo -n "FW: Allowing inside systems to use service:"

for i in $UDPSERV;

do

    echo -n "$i "

    $IPT -A OUTPUT  -o $EXTIF -p udp -s $EXTIP  \

        --dport $i -m state --state NEW -j ACCEPT

    $IPT -A FORWARD -i $INTIF1 -p udp -s $INTNET1 \

        --dport $i -m state --state NEW -j ACCEPT

    $IPT -A FORWARD -i $INTIF2 -p udp -s $INTNET2 \

done

echo ""

```

Now we're done all that's left is allowing us to ping the outside world by opening up pinging out of the firewall:

```

# Allow to ping out

$IPT -A OUTPUT  -o $EXTIF -p icmp -s $EXTIP  \

    --icmp-type 8 -m state --state NEW -j ACCEPT

$IPT -A FORWARD -i $INTIF1 -p icmp -s $INTNET1 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

$IPT -A FORWARD -i $INTIF2 -p icmp -s $INTNET2 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

                                                                               

# Allow firewall to ping internal systems

$IPT -A OUTPUT  -o $INTIF1 -p icmp -s $INTNET1 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

$IPT -A OUTPUT  -o $INTIF2 -p icmp -s $INTNET2 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

```

Now we are going to default to DROP and Log anything that's left in case we overlooked something. The ACCEPT entry's we made at the very beginning would come right before this in the final script:

```

# Log & block whatever is left

$IPT -A INPUT             -j DROPl

$IPT -A OUTPUT            -j REJECTl

$IPT -A FORWARD           -j DROPl

```

And your done. I had a friend nmap and nessus my connection with this rule set and as far as both of them were concerned the only thing it was even slightly sure about was that the ip existed...other than that nothing. I can IRC, MSN, ICQ, ane emerge sync to my hearts content.

*CREDITS* I take absolutely NO credit for this, I gathered most from other tutorials and implemented some fixes and loops from yet other howtos to make things more comprehensive and/or efficient. ABSOLUTELY NONE of this should be credited to me.  :Smile: 

PART III will cover setting up some essential SOHO services like NFS and CUPS in a security conscious manner.

Now here's the full script in all it's glory (I also put the ssh forwarding in a more appropriate place):

```

# External interface

EXTIF=ppp0

# Internal interface

INTIF1=eth1

INTIF2=eth2

                                                                               

# Loop device/localhost

LPDIF=lo

LPDIP=127.0.0.1

LPDMSK=255.0.0.0

LPDNET="$LPDIP/$LPDMSK"

                                                                               

# Text tools variables

IPT='/sbin/iptables'

IFC='/sbin/ifconfig'

G='/bin/grep'

SED='/bin/sed'

                                                                               

# Last but not least, the users

JAMES=192.168.1.77

TERESA=192.168.2.77

                                                                               

# Deny than accept: this keeps holes from opening up

# while we close ports and such

                                                                               

$IPT        -P INPUT       DROP

$IPT        -P OUTPUT      DROP

$IPT        -P FORWARD     DROP

                                                                               

# Flush all existing chains and erase personal chains

CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`

for i in $CHAINS;

do

    $IPT -t $i -F

done

                                                                               

for i in $CHAINS;

do

    $IPT -t $i -X

done

                                                                               

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

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

                                                                               

# Source Address Verification

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

        echo 1 > $f

done

# Disable IP source routing and ICMP redirects

for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do

        echo 0 > $f

done

for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do

        echo 0 > $f

done

                                                                               

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

                                                                               

                                                                               

# Setting up external interface environment variables

EXTIP="`$IFC $EXTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`"

#EXTBC="`$IFC $EXTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

EXTBC="255.255.255.255"

EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

EXTNET="$EXTIP/$EXTMSK"

#echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"

echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"

                                                                               

# Due to absence of EXTBC I manually set it to 255.255.255.255

# this (hopefully) will server the same purpose

                                                                               

                                                                               

# Setting up environment variables for internal interface one

INTIP1="`$IFC $INTIF1|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`"

INTBC1="`$IFC $INTIF1|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

INTMSK1="`$IFC $INTIF1|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

INTNET1="$INTIP1/$INTMSK1"

echo "INTIP1=$INTIP1 INTBC1=$INTBC1 INTMSK1=$INTMSK1 INTNET1=$INTNET1"

                                                                               

#Setting up environment variables for internal interface two

INTIP2="`$IFC $INTIF2|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`"

INTBC2="`$IFC $INTIF2|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

INTMSK2="`$IFC $INTIF2|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

INTNET2="$INTIP2/$INTMSK2"

echo "INTIP2=$INTIP2 INTBC2=$INTBC2 INTMSK2=$INTMSK2 INTNET2=$INTNET2"

                                                                               

# We are now going to create a few custom chains that will result in

# logging of dropped packets. This will enable us to avoid having to

# enter a log command prior to every drop we wish to log. The

# first will be first log drops the other will log rejects.

                                                                               

# Do not complain if chain already exists (so restart is clean)

                                                                               

# Do not complain if chain already exists (so restart is clean)

$IPT -N DROPl   2> /dev/null

$IPT -A DROPl   -j LOG --log-prefix 'DROPl:'

$IPT -A DROPl   -j DROP

                                                                               

$IPT -N REJECTl 2> /dev/null

$IPT -A REJECTl -j LOG --log-prefix 'REJECTl:'

$IPT -A REJECTl -j REJECT

                                                                               

# Now we are going to accpet all traffic from our loopback device

# if the IP matches any of our interfaces.

                                                                               

$IPT -A INPUT   -i $LPDIF -s   $LPDIP  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $EXTIP  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $INTIP1  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $INTIP2  -j ACCEPT

                                                                               

# Blocking Broadcasts

$IPT -A INPUT   -i $EXTIF -d   $EXTBC  -j DROPl

$IPT -A INPUT   -i $INTIF1 -d   $INTBC1  -j DROPl

$IPT -A INPUT   -i $INTIF2 -d   $INTBC2  -j DROPl

$IPT -A OUTPUT  -o $EXTIF -d   $EXTBC  -j DROPl

$IPT -A OUTPUT  -o $INTIF1 -d   $INTBC1  -j DROPl

$IPT -A OUTPUT  -o $INTIF2 -d   $INTBC2  -j DROPl

$IPT -A FORWARD -o $EXTIF -d   $EXTBC  -j DROPl

$IPT -A FORWARD -o $INTIF1 -d   $INTBC1  -j DROPl

$IPT -A FORWARD -o $INTIF2 -d   $INTBC2  -j DROPl

                                                                               

# Block WAN access to internal network

# This also stops nefarious crackers from using our network as a

# launching point to attack other people

# iptables translation:

# "if input going into  our external interface does not originate from our isp assigned

# ip address, drop it like a hot potato

                                                                               

$IPT -A INPUT   -i $EXTIF -d ! $EXTIP  -j DROPl

                                                                               

# Now we will block internal addresses originating from anything butour

# two predefined interfaces.....just remember that if you jack your

# your laptop or another pc into one of these NIC's directly, you'll need # to ensure that they either have the same ip or that you add a line explicitly

# that IP as well                                                                                

# Interface one/internal net one

$IPT -A INPUT   -i $INTIF1 -s ! $INTNET1 -j DROPl

$IPT -A OUTPUT  -o $INTIF1 -d ! $INTNET1 -j DROPl

$IPT -A FORWARD -i $INTIF1 -s ! $INTNET1 -j DROPl

$IPT -A FORWARD -o $INTIF1 -d ! $INTNET1 -j DROPl

                                                                               

# Interface two/internal net two

$IPT -A INPUT   -i $INTIF2 -s ! $INTNET2 -j DROPl

$IPT -A OUTPUT  -o $INTIF2 -d ! $INTNET2 -j DROPl

$IPT -A FORWARD -i $INTIF2 -s ! $INTNET2 -j DROPl

$IPT -A FORWARD -o $INTIF2 -d ! $INTNET2 -j DROPl

                                                                               

# An additional Egress check

                                                                               

$IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROPl

                                                                               

# Block outbound ICMP (except for PING)

                                                                               

$IPT -A OUTPUT  -o $EXTIF -p icmp \

  --icmp-type ! 8 -j DROPl

$IPT -A FORWARD -o $EXTIF -p icmp \

    --icmp-type ! 8 -j DROPl

                                                                               

# COMmon ports:

# 0 is tcpmux; SGI had vulnerability, 1 is common attack

# 13 is daytime

# 98 is Linuxconf

# 111 is sunrpc (portmap)

# 137:139, 445 is Microsoft

# SNMP: 161,2

# Squid flotilla: 3128, 8000, 8008, 8080

# 1214 is Morpheus or KaZaA

# 2049 is NFS

# 3049 is very virulent Linux Trojan, mistakable for NFS

# Common attacks: 1999, 4329, 6346

# Common Trojans 12345 65535

COMBLOCK="0:1 13 98 111 137:139 161:162 445 1214 1999 2049 3049 4329 6346 3128 8000 8008 8080 12345 65535"

                                                                               

# TCP ports:

# 98 is Linuxconf

# 512-5!5 is rexec, rlogin, rsh, printer(lpd)

#   [very serious vulnerabilities; attacks continue daily]

# 1080 is Socks proxy server

# 6000 is X (NOTE X over SSH is secure and runs on TCP 22)

# Block 6112 (Sun's/HP's CDE)

TCPBLOCK="$COMBLOCK 98 512:515 1080 6000:6009 6112"

                                                                               

# UDP ports:

# 161:162 is SNMP

# 520=RIP, 9000 is Sangoma

# 517:518 are talk and ntalk (more annoying than anything)

UDPBLOCK="$COMBLOCK 161:162 520 123 517:518 1427 9000"

                                                                               

echo -n "FW: Blocking attacks to TCP port"

for i in $TCPBLOCK;

do

echo -n "$i "

  $IPT -A INPUT   -p tcp --dport $i  -j DROPl

  $IPT -A OUTPUT  -p tcp --dport $i  -j DROPl

  $IPT -A FORWARD -p tcp --dport $i  -j DROPl

done

echo ""

                                                                               

echo -n "FW: Blocking attacks to UDP port "

for i in $UDPBLOCK;

do

  echo -n "$i "

    $IPT -A INPUT   -p udp --dport $i  -j DROPl

    $IPT -A OUTPUT  -p udp --dport $i  -j DROPl

    $IPT -A FORWARD -p udp --dport $i  -j DROPl

done

echo ""

# Opening up ftp connection tracking

MODULES="ip_nat_ftp ip_conntrack_ftp"

for i in $MODULES;

do

  echo "Inserting module $i"

  modprobe $i

done

                                                                            

# Defining some common chat clients. Remove these from your accepted list for better security.

IRC='ircd'

MSN=1863

ICQ=5190

NFS='sunrpc'

# We have to sync!!

PORTAGE='rsync'

OpenPGP_HTTP_Keyserver=11371

                                                                               

# All services ports are read from /etc/services

                                                                               

TCPSERV="domain ssh http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE \             $IRC $MSN $ICQ $OpenPGP_HTTP_Keyserver"

UDPSERV="domain time"

                                                                               

echo -n "FW: Allowing inside systems to use service:"

for i in $TCPSERV;

do

   echo -n "$i "

   $IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP  \

    --dport $i --syn -m state --state NEW -j ACCEPT

   $IPT -A FORWARD -i $INTIF1 -p tcp -s $INTNET1 \

    --dport $i --syn -m state --state NEW -j ACCEPT

   $IPT -A FORWARD -i $INTIF2 -p tcp -s $INTNET2 \

    --dport $i --syn -m state --state NEW -j ACCEPT

                                                                               

done

echo ""

                                                                               

echo -n "FW: Allowing inside systems to use service:"

for i in $UDPSERV;

do

    echo -n "$i "

    $IPT -A OUTPUT  -o $EXTIF -p udp -s $EXTIP  \

        --dport $i -m state --state NEW -j ACCEPT

    $IPT -A FORWARD -i $INTIF1 -p udp -s $INTNET1 \

        --dport $i -m state --state NEW -j ACCEPT

    $IPT -A FORWARD -i $INTIF2 -p udp -s $INTNET2 \

        --dport $i -m state --state NEW -j ACCEPT

done

echo ""

                                                                               

# Allow to ping out

$IPT -A OUTPUT  -o $EXTIF -p icmp -s $EXTIP  \

    --icmp-type 8 -m state --state NEW -j ACCEPT

$IPT -A FORWARD -i $INTIF1 -p icmp -s $INTNET1 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

$IPT -A FORWARD -i $INTIF2 -p icmp -s $INTNET2 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

                                                                               

# Allow firewall to ping internal systems

$IPT -A OUTPUT  -o $INTIF1 -p icmp -s $INTNET1 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

$IPT -A OUTPUT  -o $INTIF2 -p icmp -s $INTNET2 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

                                                                                                                                                    

$IPT -A INPUT   -i $INTIF1 -p tcp                      --dport 22 \

   --syn -m state --state NEW -j ACCEPT

                                                                               

$IPT -t nat -A PREROUTING                       -j ACCEPT

$IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET1 -j MASQUERADE

$IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET2 -j MASQUERADE

$IPT -t nat -A POSTROUTING                      -j ACCEPT

$IPT -t nat -A OUTPUT                           -j ACCEPT

                                                                               

$IPT -A INPUT   -p tcp --dport auth --syn -m state --state NEW -j ACCEPT

                                                                               

$IPT -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPT -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

                                                                               

# block and log what me may have forgot

$IPT -A INPUT             -j DROPl

$IPT -A OUTPUT            -j REJECTl

$IPT -A FORWARD           -j DROPl

```

----------

## Fear

I really like these Tutorial, it helps me allot to understand and use iptables. I got a ppp0 connection to the internet aswell and I'd like to use iptables to savely connect my 2 desktops and 2 laptops to the internet useing an old PII 300MHZ as the Gentoo box with a 2.6.1 Kernel. 

Found maybe 1 glitch in your script:

```
echo -n "FW: Allowing inside systems to use service:" 

for i in $TCPSERV; 

do 

   echo -n "$i " 

   $IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP  \ 

    --dport $i --syn -m state --state NEW -j ACCEPT 

   $IPT -A FORWARD -i $INTIF1 -p tcp -s $INTNET1 \ <-- double??

   $IPT -A FORWARD -i $INTIF1 -p tcp -s $INTNET1 \ 

    --dport $i --syn -m state --state NEW -j ACCEPT 

   $IPT -A FORWARD -i $INTIF2 -p tcp -s $INTNET2 \ 

    --dport $i --syn -m state --state NEW -j ACCEPT 

                                                                                

done 

```

Keep up the good work.

----------

## Andersson

 *krunk wrote:*   

> *CREDITS* I take absolutely NO credit for this, I gathered most from other tutorials and implemented some fixes and loops from yet other howtos to make things more comprehensive and/or efficient. ABSOLUTELY NONE of this should be credited to me. 

 

Come on! At least take credit for putting the guide together!  :Smile: 

 *krunk wrote:*   

> PART III will cover setting up some essential SOHO services like NFS and CUPS in a security conscious manner.

 

What exactly is SOHO? You use that word a lot yet I haven't heard it before. Small Office, Home and Other networks perhaps?  :Very Happy:  Anyway, I'm looking forward to the next part.

----------

## mr.isomer

ok i am having problems with this line

```
# Do not complain if chain already exists (so restart is clean)

$IPT -N DROPl   2> /dev/null

$IPT -A DROPl   -j LOG --log-prefix 'DROPl:'

$IPT -A DROPl   -j DROP

                                                                               

$IPT -N REJECTl 2> /dev/null

$IPT -A REJECTl -j LOG --log-prefix 'REJECTl:'

$IPT -A REJECTl -j REJECT 
```

Also should it not be DROP insted of DROPl and REJECT instead of REJECTl??

regardless is still get:

 *Quote:*   

> iptables: No chain/target/match by that name
> 
> iptables: No chain/target/match by that name
> 
> 

 

----------

## Andersson

They look good to me. DROPl and REJECTl are the new chains being created. Only the last command (after -j on line 4 and 8) should be the normal DROP / REJECT.

What errors do you get if you leave the lines like in the original?

----------

## krunk

 *Fear wrote:*   

> I really like these Tutorial, it helps me allot to understand and use iptables. I got a ppp0 connection to the internet aswell and I'd like to use iptables to savely connect my 2 desktops and 2 laptops to the internet useing an old PII 300MHZ as the Gentoo box with a 2.6.1 Kernel. 
> 
> Found maybe 1 glitch in your script:
> 
> ```
> ...

 

Thank you, I must have made an error in the transfer. In fact, that line should have caused either errors or unexpected results. If I interpret correctly, I believe it would have allowed all tcp ports from interface one with source of internal net one to be forwarded rather than just our defined ones. Not a hole really, but not ast tight as intended.  :Smile: 

```
# Do not complain if chain already exists (so restart is clean)

$IPT -N DROPl   2> /dev/null

$IPT -A DROPl   -j LOG --log-prefix 'DROPl:'

$IPT -A DROPl   -j DROP

                                                                               

$IPT -N REJECTl 2> /dev/null

$IPT -A REJECTl -j LOG --log-prefix 'REJECTl:'

$IPT -A REJECTl -j REJECT
```

Yes this is a chain definition. Any time it is appended it drops the packet and creates a log entry with a prefix of "DROPl:" or "REJECTl:", this allow us to append this in lieu of DROP and not have to create another iptable command for each log entry. The output appears in /var/log/messages and looks something like this:

```
Apr 12 18:30:44 tuxmac DROPl:IN=ppp0 OUT= MAC= SRC=<Packet Source IP> DST=<Packet Destination IP> LEN=48 TOS=0x00 PREC=0x00 TTL=111 ID=11203 DF PROTO=TCP SPT=4556 DPT=135 WINDOW=64240 RES=0x00 SYN URGP=0
```

Some have no entry, like MAC= ....this means there is no value for that variable. (this makes since when you consider that ppp0 is a "virtual device") . You can use these logs to help you form new rules, such as if a packet is being dropped that you want to let through. You just use the -s switch for source, --dport for destination port. Etc.

Please let me know if you run into any hitches. I have found that the /etc/init.d/iptables script doesn't seem to restore them properly (they seem to set their own "pre-rules"). It also insists on starting before net.ppp0, which screws everything up. I'm working on revising the scripts, but for now just manually run the script after boot up......

Please let me know if you have any errors and remember to put specific error output in post.

*NOTE* I have CUPS up and working well.....it put up a good fight though.  :Smile:  NFS is next, which is proving to a bit more of a challenge due to dynamic port assignment by portmapper. There is a decent thread on the topic on the forums: search--> iptables NFS

If you absolutely, MUST have CUPS NOW, send me a pm and I'll send my updated script to you.

----------

## krunk

 *Andersson wrote:*   

> They look good to me. DROPl and REJECTl are the new chains being created. Only the last command (after -j on line 4 and  should be the normal DROP / REJECT.
> 
> What errors do you get if you leave the lines like in the original?

 

Could you quote the line please? 

My intention was to LOG every drop and reject.

----------

## Andersson

 *krunk wrote:*   

> NFS is next, which is proving to a bit more of a challenge due to dynamic port assignment by portmapper. There is a decent thread on the topic on the forums: search--> iptables NFS

 

I was just going to point you to the nfs howto at tldp, but it seems to be the same advice as in the post here ( https://forums.gentoo.org/viewtopic.php?t=77748 ).

----------

## Rug

Thanks for posting this - it got me started on setting things up, and really helped me.  One thing that you do want to mention though - this only works if you have a static IP from your ISP.  I get a DHCP IP from the ISP, so I can't set fixed rules that use EXTIP.  I could set them up so that any IP in the range given by the ISP would work, but then I need to trust the other home networks on the cable modem line - which I most definately don't want to do, since I know some of them are compromised.  Anybody dealt with this?  I'm still getting a feeling for iptables - does it have the ability to take as a parameter "whatever is the ip address currently assigned to interface X" ?

Thanks again for the guide!

----------

## krunk

 *Rug wrote:*   

> Thanks for posting this - it got me started on setting things up, and really helped me.  One thing that you do want to mention though - this only works if you have a static IP from your ISP.  I get a DHCP IP from the ISP, so I can't set fixed rules that use EXTIP.  I could set them up so that any IP in the range given by the ISP would work, but then I need to trust the other home networks on the cable modem line - which I most definately don't want to do, since I know some of them are compromised.  Anybody dealt with this?  I'm still getting a feeling for iptables - does it have the ability to take as a parameter "whatever is the ip address currently assigned to interface X" ?
> 
> Thanks again for the guide!

 

There are som other things you must add for dhcp...to free up the necessary ports I believe. But running the script after you have an ip *should* work if I'm not mistaken. The script greps all the ips from the interface at the beginning and the rules are based on that reading...someone please correct me if I'm wrong.

----------

## jjasghar

hey simply put what's the iptables command that opens a port?

```

iptables -A INPUT -p tcp -m tcp --dport 3632 -j ACCEPT

iptables -A OUTPUT -p tcp -m tcp --dport 3632 -j ACCEPT

```

????

i really would like distcc running, and also ssh from the outside and man i'm so lost.

----------

## Andersson

 *jjasghar wrote:*   

> hey simply put what's the iptables command that opens a port?
> 
> ```
> iptables -A INPUT -p tcp -m tcp --dport 3632 -j ACCEPT
> 
> ...

 

You don't need the -m. Does distcc work if you open all ports?

 *jjasghar wrote:*   

> ...and also ssh from the outside...

 

ssh uses port 22, but you could use this, it's from the gentoo security guide I think.

```

# Incoming traffic

$IPTABLES -N allow-ssh-traffic-in

$IPTABLES -F allow-ssh-traffic-in

# Flood protection

$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags ALL RST --dport ssh -j ACCEPT

$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags ALL FIN --dport ssh -j ACCEPT

$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags ALL SYN --dport ssh -j ACCEPT

$IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT

# Outgoing traffic

$IPTABLES -N allow-ssh-traffic-out

$IPTABLES -F allow-ssh-traffic-out

$IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT

# Apply the chains...

$IPTABLES -A INPUT -j allow-ssh-traffic-in

$IPTABLES -A OUTPUT -j allow-ssh-traffic-out

```

----------

## jjasghar

 *Andersson wrote:*   

>  *jjasghar wrote:*   hey simply put what's the iptables command that opens a port?
> 
> ```
> iptables -A INPUT -p tcp -m tcp --dport 3632 -j ACCEPT
> 
> ...

 

this is going to sound pathetic but how do i allow all traffic? i tried flushing all the connections and i lost my connections.  i nmaped and it still showed everything closed.  do you want to see my /etc/iptables.conf?

----------

## icywolf

I used that tutorial (with part 1) so thank you!

----------

## Andersson

 *jjasghar wrote:*   

> this is going to sound pathetic but how do i allow all traffic? i tried flushing all the connections and i lost my connections.  i nmaped and it still showed everything closed.  do you want to see my /etc/iptables.conf?

 

You probably still have the default set to DROP. After you flush, try this:

```
$IPTABLES -P FORWARD ACCEPT

$IPTABLES -P INPUT ACCEPT

$IPTABLES -P OUTPUT ACCEPT
```

If that doesn't work, post your config. By the way, you're not using a router do you? This firewall is on the same machine where you want distcc and ssh?

By the way, in this example and the one above, $IPTABLES=/sbin/iptables.

----------

## jjasghar

ok, this is my ideal setup is my router/home server run iptables this /etc/iptables.conf and allow incoming ssh, ftp, http, distcc on the private side

/etc/iptables.conf

```
# Generated by iptables-save v1.2.9 on Sun Apr 18 13:57:12 2004

*filter

:INPUT DROP [100:14702]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [219:18340]

-A INPUT -m state --state RELATED -j ACCEPT 

-A INPUT -i ! eth0 -m state --state NEW -j ACCEPT 

-A INPUT -p icmp -j ACCEPT 

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

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

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

COMMIT

# Completed on Sun Apr 18 13:57:12 2004

# Generated by iptables-save v1.2.9 on Sun Apr 18 13:57:12 2004

*nat

:PREROUTING ACCEPT [79:20611]

:POSTROUTING ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

-A POSTROUTING -o eth0 -j MASQUERADE 

COMMIT

# Completed on Sun Apr 18 13:57:12 2004

# Generated by iptables-save v1.2.9 on Sun Apr 18 13:57:12 2004

*mangle

:PREROUTING ACCEPT [269:42348]

:INPUT ACCEPT [269:42348]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [219:18340]

:POSTROUTING ACCEPT [219:18340]

COMMIT

# Completed on Sun Apr 18 13:57:12 2004

```

what does this all mean?!?

but i figure that i need to write a bash script to do this and i'm learning about it...slowly.

i'm reading a book called Linux Firewalls Second Edition by Robert L. Ziegler, horribly writen but informaitave.

----------

## tdphys

Ack ... Why would this not work?!

Here's the honest to goodness command line I entered and the opposing error message

```
 iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT

iptables: No chain/target/match by that name

```

Thanks

----------

## Souperman

 *Andersson wrote:*   

> What exactly is SOHO? You use that word a lot yet I haven't heard it before. Small Office, Home and Other networks perhaps?  Anyway, I'm looking forward to the next part.

 

Small Office/Home Office.  :Wink: 

----------

## tdphys

As per my previous post, there was a few things I missed compiling into my kernel,   recompiling with the right options did the trick....

again...   :Smile: 

----------

## AltBuTT

On my local network there's a Win XP (we don't always choose our roomate's OS) and my linux box is the gateway. I'm using samba to share files. 

I try to set a good firewall. The script block ports 137:139 (netbios) that windows use to share network. It also appear that Win XP broadcast on the network.

```
DROPl:IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:00:40:f4:64:d9:c2:08:00 SRC=192.164.0.79 DST=192.164.0.255 LEN=78 TOS=0x00 PREC=0x00 TTL=128 ID=63116 PROTO=UDP SPT=137 DPT=137 LEN=58
```

Is that a security hole if before blocking boradcast in the script I accept all connection from that user on ports 137:139 ?

```

#Since USER is under Windows, he must access to netbios ports

$IPT -A INPUT -i $INTIF1 -s $USER -p tcp --dport 137:139 -j ACCEPT

$IPT -A INPUT -i $INTIF1 -s $USER -p udp --dport 137:139 -j ACCEPT

```

It seems to work but I don't no if its a good thing.

If not, is there a good way to do that ? (except throwing the XP box out)

----------

## amanset

 *Andersson wrote:*   

> 
> 
> If that doesn't work, post your config. By the way, you're not using a router do you? This firewall is on the same machine where you want distcc and ssh?
> 
> By the way, in this example and the one above, $IPTABLES=/sbin/iptables.

 

Sorry for asking, but I am having the same problem and those three lines you suggested didn't work for me. I am trying to let my NAT'd PCs have full net access. I have used this script, adapted from part one of the tutorial:

```

 #!/bin/bash

IPTABLES='/sbin/iptables'

# Set interface values

EXTIF='eth0'

INTIF1='eth1'

# 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

#echo -e "       - Allowing HTTP Traffic"

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

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

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

$IPTABLES -P FORWARD ACCEPT

$IPTABLES -P INPUT ACCEPT

$IPTABLES -P OUTPUT 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

```

Yet all that appears to work right now is port 80, the one I specifically stated as a test. I've obviously missed something out somewhere, I don't suppose you know what?

----------

## lokelo

Ok, just configured and modified the script to work with a single internal interface and an ethernet external interface and i'm getting an error with syncookies

```

line 42: /proc/sys/net/ipv4/tcp_syncookies: No such file or directory

```

what do i do to install this?

----------

## Souperman

You need to enable it in your kernel .config.  I'm not sure exactly where it is, but if you 'make menuconfig' and drill down the networking options you should see it.

----------

## Lepaca Kliffoth

I was wondering if I can use this script. I've got a desktop connected to the internet through adsl and I want it to share the connection with a laptop. The laptop's conneted to my desktop with a cross-over cable. How should I modify the script?

----------

## tomaw

Any chance anyone has an example that will enforce a local transparent proxy?  Just want to set a forced privoxy...

/edit

Also, it seems this stops spamd from working...?

----------

## tomaw

OK, after playing around for a while I have the following.  It doesn't include transparent proxy though, as I decided I probably don't want it anyway:

Main Changes:

Allowed a list of loopback services so local provoxy, shh and spamd will work.

Does anyone see any security problems with what I've done?

```
# External interface

EXTIF=eth0

# Internal interface

INTIF1=wlan0

# Loop device/localhost

LPDIF=lo

LPDIP=127.0.0.1

LPDMSK=255.0.0.0

LPDNET="$LPDIP/$LPDMSK"

# Text tools variables

IPT='/sbin/iptables'

IFC='/sbin/ifconfig'

G='/bin/grep'

SED='/bin/sed'

                                                                               

# Last but not least, the users

PALM=192.168.0.2

                                                                               

# Deny than accept: this keeps holes from opening up

# while we close ports and such

                                                                               

$IPT        -P INPUT       DROP

$IPT        -P OUTPUT      DROP

$IPT        -P FORWARD     DROP

                                                                               

# Flush all existing chains and erase personal chains

CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`

for i in $CHAINS;

do

    $IPT -t $i -F

done

                                                                               

for i in $CHAINS;

do

    $IPT -t $i -X

done

                                                                               

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

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

                                                                               

# Source Address Verification

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

        echo 1 > $f

done

# Disable IP source routing and ICMP redirects

for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do

        echo 0 > $f

done

for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do

        echo 0 > $f

done

                                                                               

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

                                                                               

                                                                               

# Setting up external interface environment variables

EXTIP="`$IFC $EXTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`"

EXTBC="`$IFC $EXTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

EXTNET="$EXTIP/$EXTMSK"

echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"

                                                                               

# Setting up environment variables for internal interface one

INTIP1="`$IFC $INTIF1|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`"

INTBC1="`$IFC $INTIF1|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

INTMSK1="`$IFC $INTIF1|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

INTNET1="$INTIP1/$INTMSK1"

echo "INTIP1=$INTIP1 INTBC1=$INTBC1 INTMSK1=$INTMSK1 INTNET1=$INTNET1"

                                                                               

# We are now going to create a few custom chains that will result in

# logging of dropped packets. This will enable us to avoid having to

# enter a log command prior to every drop we wish to log. The

# first will be first log drops the other will log rejects.

                                                                               

# Do not complain if chain already exists (so restart is clean)

$IPT -N DROPl   2> /dev/null

$IPT -A DROPl   -j LOG --log-prefix 'DROPl:'

$IPT -A DROPl   -j DROP

                                                                               

$IPT -N REJECTl 2> /dev/null

$IPT -A REJECTl -j LOG --log-prefix 'REJECTl:'

$IPT -A REJECTl -j REJECT

                                                                               

# Now we are going to accpet all traffic from our loopback device

# if the IP matches any of our interfaces.

                                                                               

$IPT -A INPUT   -i $LPDIF -s   $LPDIP  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $EXTIP  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $INTIP1  -j ACCEPT

                                                                               

# Blocking Broadcasts

$IPT -A INPUT   -i $EXTIF -d   $EXTBC  -j DROPl

$IPT -A INPUT   -i $INTIF1 -d   $INTBC1  -j DROPl

$IPT -A OUTPUT  -o $EXTIF -d   $EXTBC  -j DROPl

$IPT -A OUTPUT  -o $INTIF1 -d   $INTBC1  -j DROPl

$IPT -A FORWARD -o $EXTIF -d   $EXTBC  -j DROPl

$IPT -A FORWARD -o $INTIF1 -d   $INTBC1  -j DROPl

                                                                               

# Block WAN access to internal network

# This also stops nefarious crackers from using our network as a

# launching point to attack other people

# iptables translation:

# "if input going into  our external interface does not originate from our isp assigned

# ip address, drop it like a hot potato

                                                                               

$IPT -A INPUT   -i $EXTIF -d ! $EXTIP  -j DROPl

                                                                               

# Now we will block internal addresses originating from anything butour

# two predefined interfaces.....just remember that if you jack your

# your laptop or another pc into one of these NIC's directly, you'll need # to ensure that they either have the same ip or that you add a line explicitly

# that IP as well                                                                               

# Interface one/internal net one

$IPT -A INPUT   -i $INTIF1 -s ! $INTNET1 -j DROPl

$IPT -A OUTPUT  -o $INTIF1 -d ! $INTNET1 -j DROPl

$IPT -A FORWARD -i $INTIF1 -s ! $INTNET1 -j DROPl

$IPT -A FORWARD -o $INTIF1 -d ! $INTNET1 -j DROPl

                                                                               

# An additional Egress check

                                                                               

$IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROPl

                                                                               

# Block outbound ICMP (except for PING)

                                                                               

$IPT -A OUTPUT  -o $EXTIF -p icmp \

  --icmp-type ! 8 -j DROPl

$IPT -A FORWARD -o $EXTIF -p icmp \

    --icmp-type ! 8 -j DROPl

                                                                               

# COMmon ports:

# 0 is tcpmux; SGI had vulnerability, 1 is common attack

# 13 is daytime

# 98 is Linuxconf

# 111 is sunrpc (portmap)

# 137:139, 445 is Microsoft

# SNMP: 161,2

# Squid flotilla: 3128, 8000, 8008, 8080

# 1214 is Morpheus or KaZaA

# 2049 is NFS

# 3049 is very virulent Linux Trojan, mistakable for NFS

# Common attacks: 1999, 4329, 6346

# Common Trojans 12345 65535

COMBLOCK="0:1 13 98 111 137:139 161:162 445 1214 1999 2049 3049 4329 6346 3128 8000 8008 8080 12345 65535"

                                                                               

# TCP ports:

# 98 is Linuxconf

# 512-5!5 is rexec, rlogin, rsh, printer(lpd)

#   [very serious vulnerabilities; attacks continue daily]

# 1080 is Socks proxy server

# 6000 is X (NOTE X over SSH is secure and runs on TCP 22)

# Block 6112 (Sun's/HP's CDE)

TCPBLOCK="$COMBLOCK 98 512:515 1080 6000:6009 6112"

                                                                               

# UDP ports:

# 161:162 is SNMP

# 520=RIP, 9000 is Sangoma

# 517:518 are talk and ntalk (more annoying than anything)

UDPBLOCK="$COMBLOCK 161:162 520 123 517:518 1427 9000"

                                                                               

echo -n "FW: Blocking attacks to TCP port"

for i in $TCPBLOCK;

do

echo -n "$i "

  $IPT -A INPUT   -p tcp --dport $i  -j DROPl

  $IPT -A OUTPUT  -p tcp --dport $i  -j DROPl

  $IPT -A FORWARD -p tcp --dport $i  -j DROPl

done

echo ""

                                                                               

echo -n "FW: Blocking attacks to UDP port "

for i in $UDPBLOCK;

do

  echo -n "$i "

    $IPT -A INPUT   -p udp --dport $i  -j DROPl

    $IPT -A OUTPUT  -p udp --dport $i  -j DROPl

    $IPT -A FORWARD -p udp --dport $i  -j DROPl

done

echo ""

# Opening up ftp connection tracking

MODULES="ip_nat_ftp ip_conntrack_ftp"

for i in $MODULES;

do

  echo "Inserting module $i"

  modprobe $i

done

                                                                           

# Defining some common chat clients. Remove these from your accepted list for better security.

IRC='ircd'

MSN=1863

ICQ=5190

NFS='sunrpc'

PORTAGE='rsync'

RDP=3389

YAHOO='3477 5050'

JABBER=5222

OpenPGP_HTTP_Keyserver=11371

PRIVOXY=8118

SPAMD=783

                                                                               

# All services ports are read from /etc/services

                                                                               

TCPSERV="domain ssh http https ftp ftp-data mail pop3 time $PORTAGE $IRC $MSN $OpenPGP_HTTP_Keyserver $RDP $JABBER $YAHOO"

UDPSERV="domain time"

LOTCP="ssh $PRIVOXY $SPAMD"

echo -n "FW: Allowing inside systems to use service (TCP):"

for i in $TCPSERV;

do

   echo -n "$i "

   $IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP  \

    --dport $i --syn -m state --state NEW -j ACCEPT

   $IPT -A FORWARD -i $INTIF1 -p tcp -s $INTNET1 \

    --dport $i --syn -m state --state NEW -j ACCEPT

                                                                               

done

echo ""

                                                                               

echo -n "FW: Allowing inside systems to use service (UDP):"

for i in $UDPSERV;

do

    echo -n "$i "

    $IPT -A OUTPUT  -o $EXTIF -p udp -s $EXTIP  \

        --dport $i -m state --state NEW -j ACCEPT

    $IPT -A FORWARD -i $INTIF1 -p udp -s $INTNET1 \

        --dport $i -m state --state NEW -j ACCEPT

done

echo ""

echo -n "FW: Allowing loopback access for:"

for i in $LOTCP;

do

    echo -n "$i "

    $IPT -A OUTPUT -o lo -p tcp --dport $i -m state --state NEW -j ACCEPT

done

echo ""

# Allow to ping out

$IPT -A OUTPUT  -o $EXTIF -p icmp -s $EXTIP  \

    --icmp-type 8 -m state --state NEW -j ACCEPT

$IPT -A FORWARD -i $INTIF1 -p icmp -s $INTNET1 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

                                                                               

# Allow firewall to ping internal systems

$IPT -A OUTPUT  -o $INTIF1 -p icmp -s $INTNET1 \

    --icmp-type 8 -m state --state NEW -j ACCEPT

# External access to SSH server here

$IPT -A INPUT   -i $EXTIF -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT

#$IPT -t nat -A PREROUTING                       -j ACCEPT

$IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET1 -j MASQUERADE

$IPT -t nat -A POSTROUTING                      -j ACCEPT

$IPT -t nat -A OUTPUT                           -j ACCEPT

                                                                               

$IPT -A INPUT   -p tcp --dport auth --syn -m state --state NEW -j ACCEPT

                                                                               

$IPT -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPT -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# block and log what me may have forgot

$IPT -A INPUT             -j DROPl

$IPT -A OUTPUT            -j REJECTl

$IPT -A FORWARD           -j DROPl 

```

----------

## Lepaca Kliffoth

Up and working. Thanks!

----------

## stahlsau

many thanx for your work, it´s really inspiring!

Again, i learned lots of thing, cause i never had the ambition to do a firewall-script on my own, but with this help it´s fun  :Wink: 

----------

## omné

Hello, I'm totally newby about server and all this things.

Thank's a lot.

I use the script, and everithing seems to work well but I can't ssh in any way.

Nither from server to my computer nore in the other way.

I setup ssh from this howto : http://gentoo-wiki.com/HOWTO_setup_a_home-server#Configuring_ssh

My config :

...-------

..|  net  |

...--------

.......|

.....MYIP (eth0)

.......|

....--------------------

...|    server           |

....---------------------

......|.....................|

...192.168.1.1...192.168.2.1

....(eth1)............(eth2)

......|.....................|

......|.....................|

...192.168.1.10....192.168.2.10

......|.....................|

..------------........-------------------

.|My comp|........|  Friends laptop|

..-----------.........-------------------

How can I ssh from net to server, from My comp to server ?

Can this script deal with dnsmasq, explain here : http://gentoo-wiki.com/HOWTO_setup_a_home-server#Using_dnsmasqserver ?

For friend to just connect there laptop. 

Again thank's

Némo.

[EDIT]

Solve my problem, it was just that I had to coment the 

```
#EXTBC="255.255.255.255"
```

Now triing to get my mldonkey and jabber working

----------

## ragdon

Hi,

I've used your script, but cannot see my samba drive on a networked PC. by using another firewall script (jay's i think) I can. Will part three discuss howto allow samba drives to be seen?

I've tried allowing TCP and UDP access to ports 137:139 but it doesn't seem to work.

cheers,

Roger

----------

## krunk

Damn, I've let this lie for quite a while but so many people are still referrring to it I need to update it this weekend. 

With Samba, it would be a matter of opening up the proper port. A quick google search says these are 138 and 139.

----------

## raistlinr

hello all. this is actually my first post on these forums. I was actually searching on how to compile the kernel with iptables-capability, and I found this and part I. I was intrigued and just kept on reading. Someone had asked some question about DHCP assigned ip address for the external, and I though I would post the firewall I have used. The guy who helped me write it wrote it for fedora core 2, but you should be able to change the saving method, adn the rest still works fine. (unless some wierd rule changed has happened). I think it is pretty well commented.

edit:by the way I use all kinds of internal servers such as samba with this setup, never had a problem. And I am using the machine this is on as a firewall/router

#!/bin/sh

#

# Save this to /root/iptables-gw

#

# For a system to function as a firewall the kernel has to be told to forward

# packets between interfaces, i.e., it needs to be a router. Since you'll save

# the running config with 'iptables save' for RedHat to reinstate at the next

# boot IP fordarding must be enabled by other than this script for production

# use. That's best done by editing /etc/sysctl.conf and setting:

#

# net.ipv4.ip_forward = 1

#

# Since that file will only be read at boot, you can uncomment the following

# line to enable forwarding on the fly for initial testing. Just remember that

# the saved iptables data won't include the command.

#

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

#

# Once the rule sets are to your liking you can easily arrange to have them

# installed at boot on a Redhat box (7.1 or later). Save the rules with:

#

# service iptables save

#

# which saves the running ruleset to /etc/sysconfig/iptables. When

# /etc/init.d/iptables executes it will see the file and restore the rules.

#

# I find it easier to modify this file and run it (make sure it is executable

# with 'chmod +x iptables-gw') to change the rulesets, rather than

# modifying the running rules. That way I have a readable record

# of the firewall configuration.

# 

# Set an absolute path to IPTABLES and define the interfaces.

#

IPT=iptables

#

# OUTSIDE is the outside or untrusted interface that connects to the Internet

# and INSIDE is, well that ought to be obvious. 

#

OUTSIDE=eth0

INSIDE=eth1

INSIDE_IP=192.168.0.1

#

# Clear out any existing firewall rules, and any chains that might have

# been created. Then set the default policies.

#

$IPT -F

$IPT -F INPUT

$IPT -F OUTPUT

$IPT -F FORWARD

$IPT -F -t mangle

$IPT -F -t nat

$IPT -X

$IPT -P INPUT DROP

$IPT -P OUTPUT ACCEPT

$IPT -P FORWARD ACCEPT

#

# Begin setting up the rulesets. First define some rule chains to handle

# exception conditions. These chains will receive packets that we aren't

# willing to pass. Limiters on logging are used so as to not to swamp the

# firewall in a DOS scenario.

#

# silent       - Just dop the packet

# tcpflags     - Log packets with bad flags, most likely an attack

# firewalled   - Log packets that that we refuse, possibly from an attack

# 

$IPT -N silent

$IPT -A silent -j DROP

$IPT -N tcpflags

$IPT -A tcpflags -m limit --limit 15/minute -j LOG --log-prefix TCPflags:

$IPT -A tcpflags -j DROP

$IPT -N firewalled

$IPT -A firewalled -m limit --limit 15/minute -j LOG --log-prefix Firewalled:

$IPT -A firewalled -j DROP

#

# Use  NPAT if you have a dynamic IP. Otherwise comment out the following

# line and use the Source NAT below.

#

$IPT -t nat -A POSTROUTING -o $OUTSIDE -j MASQUERADE

#

# Use Source NAT if to do the NPAT you have a static IP or netblock.

# Remember to change the IP to be that of your OUTSIDE NIC.

#

#$IPT -t nat -A POSTROUTING -o $OUTSIDE -j SNAT --to 1.2.3.4

#

# These are all TCP flag combinations that should never, ever, occur in the

# wild. All of these are illegal combinations that are used to attack a box

# in various ways.

#

$IPT -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j tcpflags

$IPT -A INPUT -p tcp --tcp-flags ALL ALL -j tcpflags

$IPT -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j tcpflags

$IPT -A INPUT -p tcp --tcp-flags ALL NONE -j tcpflags

$IPT -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j tcpflags

$IPT -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j tcpflags

#

# Allow selected ICMP types and drop the rest.

#

$IPT -A INPUT -p icmp --icmp-type 0 -j ACCEPT

$IPT -A INPUT -p icmp --icmp-type 3 -j ACCEPT

$IPT -A INPUT -p icmp --icmp-type 11 -j ACCEPT

$IPT -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT

$IPT -A INPUT -p icmp -j firewalled

#

# Don't leak SMB traffic onto the Internet. We've slipped the surly bonds of windows

# and are dancing on the silvery wings of Linux.

#

$IPT -A FORWARD -p udp --dport 137 -j silent

$IPT -A FORWARD -p udp --dport 138 -j silent

$IPT -A FORWARD -p udp --dport 139 -j silent

$IPT -A FORWARD -p udp --dport 445 -j silent

#

# If you want to be able to connect via SSH from the Internet

# uncomment the next line.

#

#$IPT -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 22 -j ACCEPT

#

# Examples of Port forwarding.

#

# The first forwards HTTP traffic to 10.0.0.10

# The second forwards SSH to 10.0.0.10

# The third forwards a block of tcp and udp ports (2300-2400) to 10.0.0.10

#

# Remember that if you intend to forward something that you'll also

# have to add a rule to permit the inbound traffic.

#

#$IPT -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 80 -j DNAT --to 10.0.0.10

#$IPT -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 22 -j DNAT --to 10.0.0.10

#$IPT -t nat -A PREROUTING -i $OUTSIDE -p tcp --dport 2300:2400 -j DNAT --to 10.0.0.10

#$IPT -t nat -A PREROUTING -i $OUTSIDE -p udp --dport 2300:2400 -j DNAT --to 10.0.0.10

#

# Examples of allowing inbound for the port forwarding examples above.

#

#$IPT -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 80 -j ACCEPT

#$IPT -A INPUT -i $OUTSIDE -d 0/0 -p tcp --dport 2300:2400 -j ACCEPT

#$IPT -A INPUT -i $OUTSIDE -d 0/0 -p udp --dport 2300:2400 -j ACCEPT

#

# The loopback interface is inheritly trustworthy. Don't disable it or

# a number of things on the firewall will break. 

#

$IPT -A INPUT -i lo -j ACCEPT

#

# Uncomment the following  if the inside machines are trustworthy and

# there are services on the firewall, like DNS, web, etc., that they need to

# access. And remember to change the  IP to be that of the INSIDE interface

# of the firewall.

#

$IPT -A INPUT -i $INSIDE -d $INSIDE_IP -j ACCEPT

#

# If you are running a DHCP server on the firewall uncomment the next line

#

$IPT -A INPUT -i $INSIDE -d 255.255.255.255 -j ACCEPT

#

# Allow packets that are part of an established connection to pass

# through the firewall. This is required for normal Internet activity

# by inside clients.

#

$IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

#

# Anything that hasn't already matched gets logged and then dropped.

#

$IPT -A INPUT -j firewalled

----------

## 59729

A question, if all DEFAULT ?POLICIE'S/POLICYS? is set to 'DROP' why have all those REJECT/DROP rules... arent they redundant?

----------

## raistlinr

 *lappen wrote:*   

> A question, if all DEFAULT ?POLICIE'S/POLICYS? is set to 'DROP' why have all those REJECT/DROP rules... arent they redundant?

 

indeed they are. HTe only reason I do both is so that if I forget to firewall something important, I don't get fried. I suppose the rest of it is just an exercise in how to build a firewall. Either way, it seems to be fairly common practice, tallking to the CS guys who run the labs at CU. Here are a couple more examples of people doing it as well:

http://www.faqs.org/docs/iptables/examplecode.html

http://www.linux-sec.net/Wireless/Install-HOWTO/other-config-files/rc.firewall

I am also told it is a way to keep track in your mind what you want to allow and what you don't after setting the defaults. better safe than sorry

----------

## [smeagol]

Does anyone know what specifically it takes to get this script working with DHCP?

When I set 

```

iptables -A INPUT -j DROP

iptables -A FORWARD -j DROP

iptables -A OUTPUT -j DROP

```

nothing works. However, once I change it to ACCEPT, things work fine.

When I have it set to drop, it seems that I can access the dhcp server(on my router) and get assigned an ip, but then the router itself can't seem to get anything from the dhcp server at the ISP.

this is the code I am using to open up output ports

```

echo -n "FW: Allowing inside system to use service"

for i in $TCPSERVOUT

do

        echo -n "$i "

        $IPT -A OUTPUT -o $EXTIF -p tcp -s $EXTIP --dport $i --syn -m state --state NEW -j ACCEPT

        $IPT -A FORWARD -i $INTIF -p tcp -s $INTNET --dport $i --syn -m state --state NEW -j ACCEPT

done

echo ""

for i in $UDPSERVOUT

do

        echo -n "$i "

        $IPT -A OUTPUT -o $EXTIF -p udp -s $EXTIP --dport $i -m state --state NEW -j ACCEPT

        $IPT -A FORWARD -i $INTIF -p udp -s $INTNET --dport $i --syn -m state -state NEW -j ACCEPTd$

echo ""

```

Where $TCPSERVOUT and $UDPSERVOUT would have the ports to output to, mine are:

```
TCPSERVOUT="mysql bootps domain ssh www https mail ftp ftp-data imaps imap3 time $DHCP"

UDPSERVOUT="bootps domain time $YAHOO $DHCP"

```

I defined $DHCP as 67

[/code]

----------

## john82382

 *raistlinr wrote:*   

>  *lappen wrote:*   A question, if all DEFAULT ?POLICIE'S/POLICYS? is set to 'DROP' why have all those REJECT/DROP rules... arent they redundant? 
> 
> indeed they are. HTe only reason I do both is so that if I forget to firewall something important, I don't get fried. I suppose the rest of it is just an exercise in how to build a firewall. Either way, it seems to be fairly common practice, tallking to the CS guys who run the labs at CU. Here are a couple more examples of people doing it as well:
> 
> http://www.faqs.org/docs/iptables/examplecode.html
> ...

 

Also, isn't it good for logging and analysis to have what is dropped or rejected be separated into different categories?

----------

## neurolabs

nice guide, it helped me improve my setup...

I have extended the script to allow (internal and external) services on the firewall, p2p clients, cleaned it up a bit and made it more flexible.

Since I don't want to post the script inline and don't want to maintain it on a server I'll pm the author so he can integrate my changes. If anyone can't wait, feel free to pm me...

[edit]

I discovered a mistake in the script. These lines:

 *Quote:*   

> 
> 
> iptables -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
> 
> iptables -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
> ...

 

should look like this:

 *Quote:*   

> 
> 
> $IPT -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
> 
> $IPT -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
> ...

 

else the script won't run non interactively e.g from /etc/ppp/ip-up

also you should probably use these lines for generation of network information, since they work on localized machines as well:

 *Quote:*   

> 
> 
> # Setting up external interface environment variables
> 
> EXTIP="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
> ...

 

[/edit]

----------

## imrambi

Hey krunk, sorry but this is month 8. Anywho, I just started using your post to set up my firewall. Going from a linksys to a gentoo server/router. Part I was a great help, and once I tighted security, my change will occur.

----------

## cato`

 *[smeagol] wrote:*   

> Does anyone know what specifically it takes to get this script working with DHCP?
> 
> When I set 
> 
> ```
> ...

 

I have exactly the same problem, anyone able to help us out?

----------

## [smeagol]

Well, I think I made a typo somewhere in there. Here's a copy of my working iptables

```

####

#Std Vars

####

EXTIF=eth0 

INTIF1=eth1

LPDIF=lo 

LPDIP=127.0.0.1 

LPDMSK=255.0.0.0 

LPDNET="$LPDIP/$LPDMSK" 

IPT='/sbin/iptables' 

IFC='/sbin/ifconfig' 

G='/bin/grep' 

SED='/bin/sed' 

####

#Hostnames

####

C20='10.0.0.20'

C12='10.0.0.12'

C17='10.0.0.17'

C32='10.0.0.32'                                                                                 

####

#Deny EVERYTHING

####

                                                                                 

$IPT        -P INPUT       DROP 

$IPT        -P OUTPUT      DROP 

$IPT        -P FORWARD     DROP 

                                                                                 

####

#Flush Existing Chains

####

CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null` 

for i in $CHAINS; 

do 

    $IPT -t $i -F 

done 

for i in $CHAINS; 

do 

    $IPT -t $i -X 

done 

####

#/proc Settings

####

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

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

# Source Address Verification 

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

        echo 1 > $f 

done 

# Disable IP source routing and ICMP redirects 

for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do 

        echo 0 > $f 

done 

for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do 

        echo 0 > $f 

done 

echo 1 > /proc/sys/net/ipv4/conf/all/log_martians

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

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

####

#Interface Variables

####

EXTIP="`$IFC $EXTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" 

EXTBC="`$IFC $EXTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" 

EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" 

EXTNET="$EXTIP/$EXTMSK" 

                                                                                 

INTIP1="`$IFC $INTIF1|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" 

INTBC1="`$IFC $INTIF1|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" 

INTMSK1="`$IFC $INTIF1|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" 

INTNET1="$INTIP1/$INTMSK1" 

####

#Logging

####

$IPT -N DROPl   2> /dev/null 

$IPT -A DROPl   -j LOG --log-prefix 'DROPl:' 

$IPT -A DROPl   -j DROP 

$IPT -N REJECTl 2> /dev/null 

$IPT -A REJECTl -j LOG --log-prefix 'REJECTl:' 

$IPT -A REJECTl -j REJECT 

####

#Lax Loopback Filters

####

                                                                                 

$IPT -A INPUT   -i $LPDIF -s $LPDIP  -j ACCEPT 

$IPT -A INPUT   -i $LPDIF -s $EXTIP  -j ACCEPT 

$IPT -A INPUT   -i $LPDIF -s $INTIP1 -j ACCEPT 

$IPT -A OUTPUT -o $LPDIF  -d $LPDIP  -j ACCEPT

$IPT -A OUTPUT -o $INTIF1 -d $INTIP1 -j ACCEPT

$IPT -A OUTPUT -o $EXTIF  -d $EXTIP  -j ACCEPT                                                                                 

####

#Blocking Broadcasts Both In and Out

####

$IPT -A INPUT   -i $EXTIF -d   $EXTBC  -j DROPl 

$IPT -A INPUT   -i $INTIF1 -d   $INTBC1  -j DROPl 

$IPT -A OUTPUT  -o $EXTIF -d   $EXTBC  -j DROPl 

$IPT -A OUTPUT  -o $INTIF1 -d   $INTBC1  -j DROPl 

$IPT -A FORWARD -o $EXTIF -d   $EXTBC  -j DROPl 

$IPT -A FORWARD -o $INTIF1 -d   $INTBC1  -j DROPl 

                                                                                 

 # Block WAN access to internal network 

 # This also stops nefarious crackers from using our network as a 

 # launching point to attack other people 

 # iptables translation: 

 # "if input going into  our external interface does not originate from our isp assigned 

 # ip address, drop it like a hot potato 

                                                                                 

 $IPT -A INPUT   -i $EXTIF -d ! $EXTIP  -j DROPl 

                                                                                 

 # Now we will block internal addresses originating from anything butour 

 # two predefined interfaces.....just remember that if you jack your 

 # your laptop or another pc into one of these NIC's directly, you'll need # to ensure that they either have the same ip or that you add a line explicitly 

 # that IP as well                                                                                

 # Interface one/internal net one 

 $IPT -A INPUT   -i $INTIF1 -s ! $INTNET1 -j DROPl 

 $IPT -A OUTPUT  -o $INTIF1 -d ! $INTNET1 -j DROPl 

 $IPT -A FORWARD -i $INTIF1 -s ! $INTNET1 -j DROPl 

 $IPT -A FORWARD -o $INTIF1 -d ! $INTNET1 -j DROPl 

                                                                                 

# An additional Egress check 

$IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROPl 

                                                                                 

# Block outbound ICMP (except for PING) 

$IPT -A OUTPUT  -o $EXTIF -p icmp --icmp-type ! 8 -j DROPl 

$IPT -A FORWARD -o $EXTIF -p icmp --icmp-type ! 8 -j DROPl 

####

#Blocking Bad Ports

####

 # COMmon ports:

 # 0 is tcpmux; SGI had vulnerability, 1 is common attack

 # 13 is daytime

 # 98 is Linuxconf

 # 111 is sunrpc (portmap)

 # 137:139, 445 is Microsoft

 # SNMP: 161,2

 # Squid flotilla: 3128, 8000, 8008, 8080

 # 1214 is Morpheus or KaZaA

 # 2049 is NFS

 # 3049 is very virulent Linux Trojan, mistakable for NFS

 # Common attacks: 1999, 4329, 6346

 # Common Trojans 12345 65535

 COMBLOCK="0:1 13 98 111 137:139 161:162 445 1214 1999 2049 3049 4329 6346 3128 8000 8008 8080 12345 65535"

 # TCP ports:

 # 98 is Linuxconf

 # 512-5!5 is rexec, rlogin, rsh, printer(lpd)

 #   [very serious vulnerabilities; attacks continue daily]

 # 1080 is Socks proxy server

 # 6000 is X (NOTE X over SSH is secure and runs on TCP 22)

 # Block 6112 (Sun's/HP's CDE)

 TCPBLOCK="$COMBLOCK 98 512:515 1080 6000:6009 6112"

 # UDP ports:

 # 161:162 is SNMP

 # 520=RIP, 9000 is Sangoma

 # 517:518 are talk and ntalk (more annoying than anything)

 UDPBLOCK="$COMBLOCK 161:162 520 123 517:518 1427 9000"

 for i in $TCPBLOCK;

 do

   $IPT -A INPUT   -p tcp --dport $i  -j DROPl

   $IPT -A OUTPUT  -p tcp --dport $i  -j DROPl

   $IPT -A FORWARD -p tcp --dport $i  -j DROPl

 done

 for i in $UDPBLOCK;

 do

     $IPT -A INPUT   -p udp --dport $i  -j DROPl

     $IPT -A OUTPUT  -p udp --dport $i  -j DROPl

     $IPT -A FORWARD -p udp --dport $i  -j DROPl

 done

################################

# Outside Server Filtering crap#

################################

$IPT -N INETIN

$IPT -F INETIN

$IPT -t filter -A INETIN -p icmp --icmp-type echo-request -m limit --limit 1/second --limit-burst 5 -j ACCEPT

$IPT -t filter -A INETIN -p icmp -j DROPl

$IPT -t filter -A INETIN -p icmp --icmp-type ! echo-request -j ACCEPT

#ODD TCP occurences

$IPT -t filter -N ODDTCP

$IPT -t filter -A INETIN -p tcp --tcp-flags SYN,FIN SYN,FIN -j ODDTCP

$IPT -t filter -A INETIN -p tcp --tcp-flags SYN,RST SYN,RST -j ODDTCP

$IPT -t filter -A INETIN -p tcp --tcp-flags SYN,URG SYN,URG -j ODDTCP

$IPT -t filter -A INETIN -p tcp --tcp-flags SYN,URG SYN,URG -j ODDTCP

$IPT -t filter -A ODDTCP -p tcp -m state --state ESTABLISHED -j LOG --log-prefix "ODDTCP" --log-level 1

$IPT -t filter -A ODDTCP -p tcp -m state --state ESTABLISHED -j RETURN

$IPT -t filter -A ODDTCP -j DROP

$IPT -t filter -A INETIN -m state --state INVALID -j DROP

#######################

# Port Scan Filtering #

#######################

  $IPT -N check-flags

  $IPT -F check-flags

  $IPT -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit --limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:" 

  $IPT -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP

  $IPT -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit  5/minute -j LOG --log-level 1 --log-prefix "XMAS:"

  $IPT -A check-flags -p tcp --tcp-flags ALL ALL -j DROP

  $IPT -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG  -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"

  $IPT -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

  $IPT -A check-flags -p tcp --tcp-flags ALL NONE -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"

  $IPT -A check-flags -p tcp --tcp-flags ALL NONE -j DROP

  $IPT -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"

  $IPT -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

  $IPT -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"

  $IPT -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

####

#Allowing and Blocking Services

####

source /etc/firewall/firewall.services

for i in $EXTTCPINPUT;

do

   $IPT -t filter -A INETIN -p tcp --dport $i -j ACCEPT

done

for i in $EXTUDPINPUT;

do

   $IPT -t filter -A INETIN -p udp --dport $i -j ACCEPT

done

for i in $EXTTCPFORWARD;

do

   $IPT -A FORWARD -p tcp --dport $i -j ACCEPT

done

for i in $EXTUDPFORWARD;

do

   $IPT -A FORWARD -p udp --dport $i -j ACCEPT

done

for i in $EXTTCPOUTPUT;

do

   $IPT -A OUTPUT -p tcp --dport $i -j ACCEPT

done

for i in $EXTUDPOUTPUT;

do

   $IPT -A OUTPUT -p udp --dport $i -j ACCEPT

done

for i in $INTTCPSERV;

do

   $IPT -A INPUT   -s $INTNET1 -p tcp --dport $i -j ACCEPT

        $IPT -A OUTPUT  -d $INTNET1 -p tcp --dport $i -j ACCEPT

done

for i in $INTUDPSERV;

do

   $IPT -A INPUT   -s $INTNET1 -p udp --dport $i -j ACCEPT

        $IPT -A OUTPUT  -d $INTNET1 -p udp --dport $i -j ACCEPT

done

#allowing outbound connections

$IPT -t filter -A INETIN -m state --state ESTABLISHED -j ACCEPT

#$IPT -t filter -A INETIN -p tcp --dport 1024:65535 -m state --state RELATED -j TCPACCEPT

#$IPT -t filter -A INETIN -p udp --dport 1024:65535 -m state --state RELATED -j UDPACCEPT

####

#Pings

####

# Allow to ping out 

$IPT -A OUTPUT  -o $EXTIF -p icmp -s $EXTIP --icmp-type 8 -m state --state NEW -j ACCEPT 

$IPT -A FORWARD -i $INTIF1 -p icmp -s $INTNET1 --icmp-type 8 -m state --state NEW -j ACCEPT 

# allow others to ping in

$IPT -A INPUT   -i $INTIF1 -p icmp -s $INTNET1 --icmp-type 8 -m state --state NEW -j ACCEPT

# Allow firewall to ping internal systems 

$IPT -A OUTPUT  -o $INTIF1 -p icmp -s $INTNET1 --icmp-type 8 -m state --state NEW -j ACCEPT 

####

#SSH always on

####

$IPT -A INPUT   -i $INTIF1 -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT 

####

#NAT

####

$IPT -t nat -A PREROUTING                       -j ACCEPT 

$IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET1 -j MASQUERADE 

$IPT -t nat -A POSTROUTING                      -j ACCEPT 

$IPT -t nat -A OUTPUT                           -j ACCEPT 

####

#Auth Always On ???

####

$IPT -A INPUT   -p tcp --dport auth --syn -m state --state NEW -j ACCEPT 

####

#If already established, accept

####

$IPT -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT 

$IPT -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT 

$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 

####

#Block and Log Everything Else

####

$IPT -A INPUT        -j INETIN

$IPT -A INPUT        -j check-flags

$IPT -A INPUT             -j DROPl 

$IPT -A OUTPUT            -j REJECTl 

$IPT -A OUTPUT              -j check-flags

$IPT -A FORWARD           -j DROPl

$IPT -A FORWARD        -j check-flags 

$IPT -A FORWARD        -j INETIN

```

and the file that file includes

```

IRC='ircd'

AIM='5190 2996'

OpenPGP_HTTP_Keyserver=11371

SPAMD=783

CLAMAV=3310

DHCP=67

CVS=2401

WHOIS=43

YAHOO='5000 5001 5050'

AMAVIS=10024

TCPSERV="domain ssh www https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE $IRC $MSN $ICQ $OpenPGP_HTTP_Keyserver"

UDPSERV="domain time ldap ldaps"

#EXTSERVTCP="ssh http https ftp mail pop3 pop3s imap3 imaps time rsync $AIM ldap ldaps"

EXTTCPINPUT="ftp mail imaps http https"

EXTUDPINPUT=""

EXTTCPFORWARD="domain ssh time www http https ftp mail imap3 imaps time rsync $YAHOO $WHOIS $AIM $CVS $IRC"

EXTUDPFORWARD="domain time $WHOIS $AIM $IRC $YAHOO"

EXTTCPOUTPUT="$EXTTCPFORWARD"

EXTUDPOUTPUT="$EXTUDPFORWARD"

INTTCPSERV="www https ftp mysql time rsync ssh $SPAMD $CLAMAV $AMAVIS"

INTUDPSERV="$DHCP $AMAVIS"
```

----------

## krunk

Hello, neurolabs did some housecleaning on my original script and changed the ip/broadcasting to awk for greater portability on other platforms. You'll also notice a P2P section based on uid, so make sure you put the apropriate username in there.  :Smile: 

```

#!/bin/sh 

# 

# ********** VARIABLE DEFINITIONS ********** 

# 

# External interface 

EXTIF="ppp0" 

# Internal interface 

INTIF="eth1" 

# Loop device/localhost 

LPDIF="lo" 

LPDIP="127.0.0.1" 

LPDMSK="255.0.0.0" 

LPDNET="$LPDIP/$LPDMSK" 

# Text tools variables 

IPT="/sbin/iptables" 

IFC="/sbin/ifconfig" 

G="/bin/grep" 

SED="/bin/sed" 

AWK="/bin/awk" 

# Setting up external interface environment variables 

# The following doesn't play nice with localization 

#EXTIP="`$IFC $EXTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" 

# This one does AFAIK 

EXTIP="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`" 

#EXTBC="`$IFC $EXTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" 

EXTBC="255.255.255.255" 

# same problem here with localization 

EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" 

EXTMSK="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`" 

EXTNET="$EXTIP/$EXTMSK" 

echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET" 

# Due to absence of EXTBC I manually set it to 255.255.255.255 

# this (hopefully) will serve the same purpose 

# Setting up environment variables for internal interface 

INTIP="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`" 

#INTIP="`$IFC $INTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" 

INTBC="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`" 

#INTBC="`$IFC $INTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" 

INTMSK="`$IFC $INTIF|$AWK /$INTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`" 

#INTMSK="`$IFC $INTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" 

INTNET="$INTIP/$INTMSK" 

echo "INTIP=$INTIP INTBC=$INTBC INTMSK=$INTMSK INTNET=$INTNET" 

# Last but not least, the users for owner matching 

P2PUSER="ole" 

# ********** INITIALIZATION ********** 

# 

# Deny then accept: this keeps holes from opening up 

# while we close ports and such 

$IPT        -P INPUT       DROP 

$IPT        -P OUTPUT      DROP 

$IPT        -P FORWARD     DROP 

#IPT        -P INPUT       ACCEPT 

#IPT        -P OUTPUT      ACCEPT 

#IPT        -P FORWARD     ACCEPT 

# Flush all existing chains and erase personal chains 

CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null` 

for i in $CHAINS; 

do 

    $IPT -t $i -F 

done 

for i in $CHAINS; 

do 

    $IPT -t $i -X 

done 

# enable syncookies & ignore icmp broadcasts 

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

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

# Source Address Verification 

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

        echo 1 > $f 

done 

# Disable IP source routing and ICMP redirects 

for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do 

        echo 0 > $f 

done 

for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do 

        echo 0 > $f 

done 

# Log Martians 

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

        echo 1 > $i 

done 

# activate forwarding & dynamic address 

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

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

# Loading necessary kernel modules 

# example: MODULES="ip_nat_ftp ip_conntrack_ftp" 

MODULES="ipt_owner" 

for i in $MODULES; 

do 

  echo "Inserting module $i" 

  modprobe $i 

done 

# ********** LOGGING CHAINS ********** 

# 

# We are now going to create a few custom chains that will result in 

# logging of dropped packets. This will enable us to avoid having to 

# enter a log command prior to every drop we wish to log. The 

# first will be first log drops the other will log rejects. 

# Do not complain if chain already exists (so restart is clean) 

$IPT -N DROPl   2> /dev/null 

$IPT -A DROPl -m limit --limit 3/minute --limit-burst 10 -j LOG --log-prefix 'FIREWALL DROP BLOCKED:' 

$IPT -A DROPl   -j DROP 

$IPT -N REJECTl 2> /dev/null 

$IPT -A REJECTl -m limit --limit 3/minute --limit-burst 10 -j LOG --log-prefix 'FIREWALL REJECT BLOCKED:' 

$IPT -A REJECTl -j REJECT 

$IPT -N DROP2   2> /dev/null 

$IPT -A DROP2 -m limit --limit 3/second --limit-burst 10 -j LOG --log-prefix 'FIREWALL DROP UNKNOWN:' 

$IPT -A DROP2   -j DROP 

$IPT -N REJECT2 2> /dev/null 

$IPT -A REJECT2 -m limit --limit 3/second --limit-burst 10 -j LOG --log-prefix 'FIREWALL REJECT UNKNOWN:' 

$IPT -A REJECT2 -j REJECT 

# For testing, a logging ACCEPT chain 

$IPT -N ACCEPTl   2> /dev/null 

$IPT -A ACCEPTl -m limit --limit 10/second --limit-burst 50 -j LOG --log-prefix 'FIREWALL ACCEPT:' 

$IPT -A ACCEPTl   -j ACCEPT 

# ********** SANE COMMON RULES ********** 

# 

# Now we are going to accept all traffic from or to our loopback device 

# if the IP matches any of our interfaces. 

$IPT -A INPUT   -i $LPDIF -s   $LPDIP  -j ACCEPT 

$IPT -A INPUT   -i $LPDIF -s   $EXTIP  -j ACCEPT 

$IPT -A INPUT   -i $LPDIF -s   $INTIP  -j ACCEPT 

$IPT -A OUTPUT   -o $LPDIF -d   $LPDIP  -j ACCEPT 

$IPT -A OUTPUT   -o $LPDIF -d   $EXTIP  -j ACCEPT 

$IPT -A OUTPUT   -o $LPDIF -d   $INTIP  -j ACCEPT 

# Blocking Broadcasts 

$IPT -A INPUT   -i $EXTIF -d   $EXTBC  -j DROPl 

$IPT -A INPUT   -i $INTIF -d   $INTBC  -j DROPl 

$IPT -A OUTPUT  -o $EXTIF -d   $EXTBC  -j DROPl 

$IPT -A OUTPUT  -o $INTIF -d   $INTBC  -j DROPl 

$IPT -A FORWARD -o $EXTIF -d   $EXTBC  -j DROPl 

$IPT -A FORWARD -o $INTIF -d   $INTBC  -j DROPl 

# Block WAN access to internal network 

# This also stops nefarious crackers from using our network as a 

# launching point to attack other people 

# iptables translation: 

# "if input going into  our external interface does not  our isp assigned 

# ip address, drop it like a hot potato 

$IPT -A INPUT   -i $EXTIF -d ! $EXTIP  -j DROPl 

# Now we will block internal addresses originating from anything but our 

# predefined interface.....just remember that if you jack your 

# laptop or another pc into one of these NIC's directly, you'll need 

# to ensure that they either have the same ip or that you add a line explicitly 

# that IP as well 

# Interface one/internal net one 

$IPT -A INPUT   -i $INTIF -s ! $INTNET -j DROPl 

$IPT -A OUTPUT  -o $INTIF -d ! $INTNET -j DROPl 

$IPT -A FORWARD -i $INTIF -s ! $INTNET -j DROPl 

$IPT -A FORWARD -o $INTIF -d ! $INTNET -j DROPl 

# An additional Egress check 

$IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROPl 

# Block outbound ICMP (except for PING) 

$IPT -A OUTPUT  -o $EXTIF -p icmp \ 

  --icmp-type ! 8 -j DROPl 

$IPT -A FORWARD -o $EXTIF -p icmp \ 

    --icmp-type ! 8 -j DROPl 

# Allow to ping out 

$IPT -A OUTPUT  -o $EXTIF -p icmp -s $EXTIP  \ 

    --icmp-type 8 -m state --state NEW -j ACCEPT 

$IPT -A FORWARD -i $INTIF -p icmp -s $INTNET \ 

    --icmp-type 8 -m state --state NEW -j ACCEPT 

# Allow internal network to ping internal systems 

$IPT -A OUTPUT  -o $INTIF -p icmp -s $INTNET \ 

    --icmp-type 8 -m state --state NEW -j ACCEPT 

$IPT -A INPUT   -i $INTIF -p icmp -s $INTNET \ 

    --icmp-type 8 -m state --state NEW -j ACCEPT 

# ********** BLOCKING THE EVIL PORTS ********** 

# 

# COMmon ports: 

# 0 is tcpmux; SGI had vulnerability, 1 is common attack 

# 13 is daytime 

# 98 is Linuxconf 

# 111 is sunrpc (portmap) 

# 135 is DCOM RPC 

# 137:139, 445 is Microsoft 

# SNMP: 161,2 

# Squid flotilla: 3128, 8000, 8008, 8080 

# 1214 is Morpheus or KaZaA 

# 2049 is NFS 

# 3049 is very virulent Linux Trojan, mistakable for NFS 

# Common attacks: 1999, 4329, 6346 (gnutella - removed) 

# Common Trojans 12345 65535 

INTCOMBLOCK="0:1 13 98 111 135 161:162 1214 1999 2049 3049 4329 3128 8000 8008 8080 12345 65535" 

EXTCOMBLOCK="137:139 445" 

# TCP ports: 

# 512-5!5 is rexec, rlogin, rsh, printer(lpd) 

#   [very serious vulnerabilities; attacks continue daily] 

# 1080 is Socks proxy server 

# 6000 is X (NOTE X over SSH is secure and runs on TCP 22) 

# Block 6112 (Sun's/HP's CDE) 

INTTCPBLOCK="$INTCOMBLOCK 512:515 1080 6000:6009 6112" 

EXTTCPBLOCK="$INTCOMBLOCK $EXTCOMBLOCK 512:515 1080 6000:6009 6112" 

# UDP ports: 

# 161:162 is SNMP 

# 520=RIP, 9000 is Sangoma 

# 517:518 are talk and ntalk (more annoying than anything) 

INTUDPBLOCK="$INTCOMBLOCK 161:162 520 517:518 1427 9000" 

EXTUDPBLOCK="$INTCOMBLOCK $EXTCOMBLOCK 161:162 520 123 517:518 1427 9000" 

echo -n "FW: Blocking internal attacks to TCP port: " 

for i in $INTTCPBLOCK; 

do 

echo -n "$i " 

  $IPT -A INPUT   -p tcp -s $INTNET --dport $i  -j DROPl 

  $IPT -A OUTPUT  -p tcp -s $INTNET --dport $i  -j DROPl 

  $IPT -A FORWARD -p tcp -s $INTNET --dport $i  -j DROPl 

done 

echo "" 

echo -n "FW: Blocking external attacks to TCP port: " 

for i in $EXTTCPBLOCK; 

do 

echo -n "$i " 

  $IPT -A INPUT   -p tcp -s ! $INTNET --dport $i  -j DROPl 

  $IPT -A OUTPUT  -p tcp -s ! $INTNET --dport $i  -j DROPl 

  $IPT -A FORWARD -p tcp -s ! $INTNET --dport $i  -j DROPl 

done 

echo "" 

echo -n "FW: Blocking internal attacks to UDP port: " 

for i in $INTUDPBLOCK; 

do 

  echo -n "$i " 

    $IPT -A INPUT   -p udp -s $INTNET --dport $i  -j DROPl 

    $IPT -A OUTPUT  -p udp -s $INTNET --dport $i  -j DROPl 

    $IPT -A FORWARD -p udp -s $INTNET --dport $i  -j DROPl 

done 

echo "" 

echo -n "FW: Blocking external attacks to UDP port: " 

for i in $EXTUDPBLOCK; 

do 

  echo -n "$i " 

    $IPT -A INPUT   -p udp -s ! $INTNET --dport $i  -j DROPl 

    $IPT -A OUTPUT  -p udp -s ! $INTNET --dport $i  -j DROPl 

    $IPT -A FORWARD -p udp -s ! $INTNET --dport $i  -j DROPl 

done 

echo "" 

# ********** ALLOWING INSIDE TO OUTSIDE SERVICES ********** 

# 

# This is where things go you want to use from your network on the internet 

# 

# Defining some common chat clients. Remove these from your accepted list for better security. 

IRC='ircd' 

MSN=1863 

ICQ=5190 

NFS='sunrpc' 

# We have to sync!! 

PORTAGE='rsync' 

OpenPGP_HTTP_Keyserver=11371 

# All services ports are read from /etc/services 

TCPSERV="domain ssh http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE $IRC $OpenPGP_HTTP_Keyserver" 

UDPSERV="domain time" 

echo -n "FW: Allowing inside systems to use services: " 

for i in $TCPSERV; 

do 

   echo -n "$i " 

   $IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP  \ 

    --dport $i --syn -m state --state NEW -j ACCEPT 

   $IPT -A FORWARD -i $INTIF -p tcp -s $INTNET \ 

    --dport $i --syn -m state --state NEW -j ACCEPT 

done 

echo "" 

echo -n "FW: Allowing inside systems to use services: " 

for i in $UDPSERV; 

do 

    echo -n "$i " 

    $IPT -A OUTPUT  -o $EXTIF -p udp -s $EXTIP  \ 

        --dport $i -m state --state NEW -j ACCEPT 

    $IPT -A FORWARD -i $INTIF -p udp -s $INTNET \ 

        --dport $i -m state --state NEW -j ACCEPT 

done 

echo "" 

# ********** ALLOWING SERVICES ON FIREWALL ********** 

# 

# DAEMONS on firewall which should be accessible to inside/outside. 

# it is presumed that DAEMONS advertised to the outside can also 

# be advertised safely to the inside 

# 

# This is generally NOT A GOOD IDEA (as told by "security experts") 

# since if some service on this machine gets hacked, the firewall is 

# compromised as well, but what the heck ;) it's only a home network 

# 

# 50369 is my p2p port 

# microsoft-ds is for samba 

# 5901 is vnc 

# domain is nameserver 

# ntp is for timeserving 

#EXTTCPDAEMONS="ssh http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2" 

EXTTCPDAEMONS="ssh auth 50369" 

INTTCPDAEMONS="$EXTTCPDAEMONS microsoft-ds 5901" 

EXTUDPDAEMONS="" 

INTUDPDAEMONS="$EXTUDPDAEMONS domain ntp" 

echo -n "FW: Allowing external systems to use tcp services on localhost: " 

for i in $EXTTCPDAEMONS; 

do 

   echo -n "$i " 

   $IPT -A INPUT -i $EXTIF -p tcp -d $EXTIP  \ 

    --dport $i --syn -m state --state NEW -j ACCEPT 

done 

echo "" 

echo -n "FW: Allowing internal systems to use tcp services on localhost: " 

for i in $INTTCPDAEMONS; 

do 

   echo -n "$i " 

   $IPT -A INPUT -i $INTIF -p tcp -d $INTIP  \ 

    --dport $i --syn -m state --state NEW -j ACCEPT 

done 

echo "" 

echo -n "FW: Allowing external systems to use udp services on localhost: " 

for i in $EXTUDPDAEMONS; 

do 

    echo -n "$i " 

    $IPT -A INPUT -i $EXTIF -p udp -d $EXTIP  \ 

     --dport $i -m state --state NEW -j ACCEPT 

done 

echo "" 

echo -n "FW: Allowing internal systems to use udp services on localhost: " 

for i in $INTUDPDAEMONS; 

do 

    echo -n "$i " 

    $IPT -A INPUT -i $INTIF -p udp -d $INTIP  \ 

     --dport $i -m state --state NEW -j ACCEPT 

done 

echo "" 

# ********** ALLOWING P2P FROM FIREWALL ********** 

# 

# Even worse idea :) 

# 

# Allowing all packages generated by processes owned by the P2PUSER out 

$IPT -A OUTPUT -o $EXTIF -d ! $INTNET -m owner --uid-owner $P2PUSER -j ACCEPT 

# ********** FINALIZING NAT & FIREWALL ********** 

# 

# Setup NAT 

$IPT -t nat -A PREROUTING                       -j ACCEPT 

$IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET -j MASQUERADE 

$IPT -t nat -A POSTROUTING                      -j ACCEPT 

$IPT -t nat -A OUTPUT                           -j ACCEPT 

# allow existing connections 

$IPT -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT 

$IPT -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT 

$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT 

# block and log what me may have forgot 

$IPT -A INPUT             -j DROP2 

$IPT -A OUTPUT            -j REJECT2 

$IPT -A FORWARD           -j DROP2 

```

I also like the dual logging chains for explicitly blocked and ambiguously blocked packets. It helps a lot when pouring over logs to determine new rules.

Cheers!

----------

## JanErik

Hmm... a little question,  I am a true Iptables-newbie.

I am thinking of using this to allow an extra machine to get Internet access through my main workstation (which has to NICs and one of them is connected to the Internet). It only needs to send results to folding@home and sync portage once in a while.

Will this filter act as a firewall locally on my main workstation aswell? Just as if I had a personal firewall like ZoneAlarm installed under Windoze? Or is it more like a routing firewall that isn't supposed to have any local processes accessing the Internet?

----------

## krunk

It's a full fledged stateful firewall. It can be as restrictive or lenient as you'd like. 

Think of how the flow of traffic goes:

client------>server---->internet

internet----->server---->client

All traffic coming into and out of the client must pass through the server. Therefore, when youfirewall the server you firewall your whole network that is behind the server.

----------

## JanErik

Well, but when the server is also the client?

----------

## c0ol

WoW....

This is a very  complete HowTo. It helped me chunk my linksys POS wireless router in favor of using my gentoo box as a DHCPD/wifi AP/router. THANKS!

----------

## JanErik

I'm getting this error message, and notwork.

I also got the syncookie error, but that shouldn't be related to this.

Removed all the rules containing INTIF2 since I only have one internal interface.

Linebreak errors from pasting from forum?

```
FW: Allowing inside systems to use service:domain iptables: No

chain/target/match by that name

iptables: No chain/target/match by that name

ssh iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

http iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

https iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

ftp iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

ftp-data iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

mail iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

pop3 iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

pop3s iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

imap3 iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

imaps iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

imap2 iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

time iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

rsync iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

\ iptables v1.2.11: invalid TCP port/service `\' specified

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

iptables v1.2.11: invalid TCP port/service `\' specified

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

ircd iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

1863 iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

5190 iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

11371 iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

FW: Allowing inside systems to use service:domain iptables: No

chain/target/match by that name

iptables: No chain/target/match by that name

time iptables: No chain/target/match by that name

iptables: No chain/target/match by that name

```

----------

## JanErik

OK, now it works, I had forgot to compile in some stuff in the netfilter configuration.

But one thing... I want to be able to ssh from the firewall machine (which is my primary workstation) to the machine on the inside. It works with the configuration from the Gentoo router guide, but not with this. How do I add a rule for that?

And, I might add, I am able to ssh out from the firewall, aswell as ssh in from the Internet.

Both of the machines are running folding@home, will it be able to get work and send results?

----------

## C.M

Great howtos! I'm trying to figure out if I should use dhcpd + dnsmasq or just dnsmasq? Does anyone have a hint? Right now I just followed the Home Router Guide, wich uses both. Another tutorial, http://gentoo-wiki.com/HOWTO_setup_a_home-server was equally confusing on that topic. At least the net works now..  

Thanks to everyone who know enough to make these tutorials though!   :Smile: 

----------

## kannX

 *tomaw wrote:*   

> OK, after playing around for a while I have the following.  It doesn't include transparent proxy though, as I decided I probably don't want it anyway:
> 
> 

 

Adding a transparent proxy is quite simple (in the case squid is running on the same machine):

```

$IPT -t nat -A PREROUTING -i $INTIF1 -s $INTNET1 -p tcp --dport 80 -j REDIRECT --to-port 3128

```

edit: removed INPUT-rule - doesn't make senseLast edited by kannX on Wed Sep 22, 2004 5:57 pm; edited 1 time in total

----------

## krunk

***edited****

----------

## kannX

 *krunk wrote:*   

> 
> 
> ```
> 
> $IPT -A PREROUTING -i $INTIF1 -s $INTNET1 -p tcp --dport 80 -j REDIRECT --to-port 3128
> ...

 

hmm, doesn't work for me:

```

iptables -A PREROUTING -i eth0 -s 192.168.0.0/24 -p tcp --dport 80 -j REDIRECT --to-port 3128

iptables: No chain/target/match by that name

```

----------

## krunk

I'm an idiot, that's what I get for posting before coffee. Pay no attention to my previous post.

----------

## ilyung

I really appreciate this HOWTO.

However, I am having some trouble with ntp.

I followed every step on this HOWTO. Everything works fine except NTP.

On the boot, ntp-client does not work properly. Actually, this service won't start at all. 

Here is the log info.

--------------

[ntpd] Frequency format error in /var/lib/ntp/ntp.drift

[ntpd] sendto(204.17.42.198) : Operation not permitted

----------------

I wonder if this problem is connected to firewall?

Thank you in advance,

----------

## 59729

 *kannX wrote:*   

>  *krunk wrote:*   
> 
> ```
> 
> $IPT -A PREROUTING -i $INTIF1 -s $INTNET1 -p tcp --dport 80 -j REDIRECT --to-port 3128
> ...

 

I think you have to create the CHAIN first

```

# Have this before the rule that require this CHAIN

$IPT -N REDIRECT

```

I am not sure though

----------

## kannX

ntpd uses broadcasts to sync clients, maybe you want to allow them

```

$IPT -A OUTPUT   -o $INTIF1 -s $INTIP1 -d $INTBC1  -p udp --sport ntp -j ACCEPT

```

and of course you must allow ntp requests in

```

$IPT -A INPUT    -i $INTIF1 -s $INTNET1 -d $INTIP1  -p udp --dport ntp -j  ACCEPT

$IPT -A OUTPUT -o $INTIF1 -s $INTIP1 -d $INTNET1  -p udp --sport ntp -j ACCEPT

```

if you use bootp you probably want to allow this

```

$IPT -A INPUT    -i $INTIF1 -s $INTNET1 -d $INTIP1  -p udp --sport bootpc --dport bootps -j ACCEPT

$IPT -A OUTPUT -o $INTIF1 -s $INTIP1 -d $INTBC1  -p udp --sport bootps --dport bootpc -j  ACCEPT

```

Last edited by kannX on Fri Oct 01, 2004 2:51 am; edited 1 time in total

----------

## kannX

 *lappen wrote:*   

> 
> 
> I think you have to create the CHAIN first
> 
> ```
> ...

 

REDIRECT is a build in target and only valid in the nat table.

```

   REDIRECT

       This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are  only

       called from those chains.  It alters the destination IP address to send the packet to the machine itself (locally-gener-

       ated packets are mapped to the 127.0.0.1 address).  It takes one option:

       --to-ports port[-port]

              This specifies a destination port or range of ports to use: without this, the destination port is never  altered.

              This is only valid if the rule also specifies -p tcp or -p udp.

```

----------

## ilyung

KannX,

Thank you so much for the help. I could solve this problem with your advice.

By the way, I have another question about firewall..(It sucks!)

One of my friend is running ftp service with a certain port rather than 21.

He is running with 1xxxx port for ftp. 

I edited firewall so I could connect this ftp server. However, I am not able to see the contents in it. I mean, I can log in but I can not list up the files for example.

Thanks in advance,

----------

## 59729

You probably need to use the module 'ip_conntrack_ftp'

If I remember correctly you only have to allow the port, then add something like

modprobe ip_conntrack_ftp(portnr)

If you don' have that module you have to enable it in the kernel,

make menuconfig

#find enable the connection tracking module for ftp

make && make modules

# make install  # maybe? don't remember

----------

## nadsys

krunk or neurolabs,

i am using neurolabs script which is a redo of krunks.  i cant get my clients out to the internet or even to ping anything. i keep getting "connect: network is unreachable" with a ping or with an ftp session. 

please advise.  i have my configuration on another post:

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

thank you for any advise.  i like the firewall, just getting hacked off i cant fully understand it all yet and small things dont work. odd.

maybe you never intended for clients to have internet access but from the section saying "allow internal machine to use services" i assume you did?

----------

## krunk

from the scirpt in you post looks like you copy'd and pasted the one before I corrected an error at the bottom.

change the last iptables entries from 'iptables' to $IPT and give it a shot. when you run the script look for errors.

----------

## nadsys

ty for quick reply krunk.  the script on page 2 of this thread posted by you (the neurolabs redo) still has that iptables error in it. hence why i had it  :Smile: .

i changed script, ran it. only error i get are two warnings about the two modules already busy, think its more of a red herring.

i have put the script that i now run in the last post of my link above.  in it the only changes i made were to add two variables. one for ports i want to use for ftp'ing, second for ports i want the ftp client/firewall to use for passive (still not sure how to tell it to use the range of 14000:14500).  i read up on the ftp firewalling rules.  it talks about the "related" rule being what you need and that is near the bottom of your script so i would assume it would have worked. yet it doesn't work on any other port than 21. 

just to clarify, this is not for an ftp server, this is for an ftp client, ftp server works fine.

also, my client PC still cannot see the outside world, keeps getting "connect : Netowrk is unreachable.  only thing it can do is ping the server.  it does work when firewalls off. so it is a firewall related problem. nothing else (using dnsmasq and dhcp, they still work).

any help/suggestions welcome.

thank you klunk + anyone else who is brave enough to take this on  :Smile: 

Neil

----------

## nadsys

quick note, i thought "what the hell", lets try it on my second pc, the 12.168.0.10 machine.  so i booted it up and tried "ping www.yahoo.com", it worked, then i tried a mozilla session, bingo, worked first time.

so why does one pc work and the other (192.168.0.9) not work.  any idea's?

the .10 machine runs fedora core 2.  the .9 machine is gentoo 2.6.7,  server .25 is gentoo 2.6.8

thank you,

Neil

----------

## krunk

Sorry bout the error, I've edited (for real) now so no one else wil l have to deal with it. 

That is very odd. But here is what I would suggest:

On machine where iptables is running do a:

```
tail -f /var/log/messages 
```

*or where ever your logs are being sent to*

Than attempt a connection, if iptables is blocking the packets you should see the logs begin to scroll in which case post the appropriate ones here.

Secondly, if the rule set works on one machine and not the other, I would expect a configuration error somewhere on the client. The rules dynamically grab ip's and netmasks of appropriate devices. It would better help us wrap our mind around the issue with a network schematic like the [url

=http://www.tuxmac.homelinux.org/~james/Documents/network_schematic_example.jpg]following[/url[

See, as far as your server is concerned in the vast majority of cases, there should be any rule difference between xxx.xxx.xxx.9 and xxx.xxx.xxx.10 as long as they are on the same subnet or unless you have some ip specific filters running. In otherwords, most rules which client your are coming from, but which subnet. (e.g. the subnet of a particular interface).

So post/check everything related to networking on the trouble client you can as well as logs of dropped packets.

----------

## nadsys

ok, fixed it.  forgot about the conf.d/net file.  the 2nd pc was setup as a server at one point so dhcp settings were slightly off.  needed to add gateway and -N -h to make it a client.

sorry to have wasted your time.

BUT there still does remain a problem.  the firewall script i posted will only allow Active ftp on port 21. i cant get passive to work on any port,  or active on any port except 21.

the ports i have been trying are in my script as a variable. so i can connect to server, but when it tries to list "list -a OR -aL" it fails.

im assuming this is because the ports its trying to use for passive are not the ones i want it to use. i.e. the range of 14000:14500.

any idea's/hints on what i should check.

last but not least, everyone talks about /var/log/messages.  i use metalog, there is no such file. i have /everything/current or /kernel/current.  but no /messages.

many thanx,

Neil

----------

## 59729

Passive uses several ports, one for connection and another for transfer and listing, if I remember correctly... don't know which ports I think it's randomized between all high port numbers

I think thats what the ftp tracking module should do ip_conntrack_ftp which should be included with your kernel sources and are very easy to add

----------

## krunk

 *lappen wrote:*   

> I think thats what the ftp tracking module should do ip_conntrack_ftp which should be included with your kernel sources and are very easy to add

 

Your are exactly correct.

----------

## nadsys

to answer you above, i do have conntrack_ftp and nat_ftp running as modules.  i seem to be getting more success with the server off of port 21, still not 100% but i'll look into it further.

easier example then, playing yahoo games, should only require http port, correct? + it runs on java so java must be installed but thats not an issue.

works when firewall is off, not when its on. firewall reject messages are as below. is it safe to tell the server to allow all ports above 1024 and if so how?

or is it possible to say "for this application allow all traffic on these ports"  i.e. application filtering.  im used to kerio personal firewall and all i had to do was block all lower ports except ones i needed, then add rules for eevery app and ports it used so they were filtered then deny all at the bottom, worked like a charm.  no such ability to do that for say mozilla/gftp?

```

Oct  3 22:42:48 [kernel] FIREWALL REJECT UNKNOWN:IN= OUT=ppp0 SRC=84.57.35.49 DST=66.218.71.6 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=30774 DF PROTO=TCP SPT=34173 DPT=11999 WINDOW=5808 RES=0x00 SYN URGP=0 

Oct  3 22:42:51 [kernel] FIREWALL REJECT UNKNOWN:IN= OUT=ppp0 SRC=84.57.35.49 DST=66.218.71.6 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=30775 DF PROTO=TCP SPT=34173 DPT=11999 WINDOW=5808 RES=0x00 SYN URGP=0

```

thanx for any advice  :Smile: 

----------

## krunk

Allowing all ports above 1024 is like not having a firewall at all for about 55,000 of the 65,556 ports available. (not too advised)

The web games must use other ports besides http. The logs below indicate that ip 84.57.35.49 is attempted to connect from port 34173 to port 11999.

You don't have to open them all up, just those two and only going in one direction.

$IPT -A INPUT -s 84.57.35.49 --sport 34173 -p tcp --dport 11999 -j ACCEPT

(I think anyway, you may have to play around with the syntax)

----------

## woodm

This firewall script works flawlessly for me.  Which is fantastic.

However, I want to dig into it, and see exactly what's happening (damn curiosity.  Hey, wher's my cat?)  anyway, I can't seem to undo this monster at all.

I try: 

```

[doorman:~] > /sbin/iptables -F

[doorman:~] > /sbin/iptables -X

[doorman:~] > /sbin/iptables -L

Chain INPUT (policy DROP)

target     prot opt source               destination

Chain FORWARD (policy DROP)

target     prot opt source               destination

Chain OUTPUT (policy DROP)

target     prot opt source               destination

[doorman:~] > ssh (somewhere else known to work)

ssh: (location): Temporary failure in name resolution

[doorman:~] > ping yahoo.com

ping: unknown host yahoo.com

[doorman:~] > ping 128.138.240.1

PING 128.138.240.1 (128.138.240.1) 56(84) bytes of data.

ping: sendmsg: Operation not permitted

ping: sendmsg: Operation not permitted

```

I don't understand why that would happen at all.

I even try running the script from your FIRST HOW-TO which just kinda gets everything up and running.  Even if I completely shutdown the machine and make sure the iptables-restore is empty, I still can't get to the outside world.

I don't understand how that's possible, but then again, I don't understand what's happening within this script anyway.  It seems to me that the only non /sbin/iptables commands that are entered are the envirnment variables and echo 1/0 > /proc/**** commands.  I've tried matching these to other linux boxes I have, but nothing seems to work.  

Anyone have any ideas?

I mean, I do have a working firewall, but I can't really change it, and I don't understand what's going on.  These 2 things are bugging the crap out of me.    :Evil or Very Mad: 

[edit]

Oh, here may be a hint for those that know more than me (everyone): I ran your big script above with bash's debug flag (-x) on, and I noticed the following:

```

+ /sbin/iptables -N DROPl

+ /sbin/iptables -A DROPl -j LOG --log-prefix DROPl:

+ /sbin/iptables -A DROPl -j DROP

+ /sbin/iptables -N REJECTl

+ /sbin/iptables -A REJECTl -j LOG --log-prefix REJECTl:

+ /sbin/iptables -A REJECTl -j REJECT

iptables: No chain/target/match by that name

```

No chain by that name?  That seems strange.

BTW, I have read the above posts, but that doesn't necessarily mean that I haven't missed something ridiculously embarrassing.  You don't have to be gentle at all.    :Laughing: 

[/edit]

Anyway, thanks guys.  This is clearly the best forum in existence.  :Cool: 

----------

## krunk

In the first case, if you notice your default policies are 'DROP' this means if anything is not covered by a rule it is dropped. This is the first thing set by the script.

Secondly, you'll see this in the script:

```
$ECHO 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
```

which blocks all icmp type packets.....ping included.

cheers

btw you should check out the iptables howto at FrozenTux.net

FrozenTux

----------

## woodm

So the default policie for DROP isn't removed when I flush the system?  Do you just have to change the default to ACCEPT then?

Intersting.

/me goes and reads a LOT more how-tos.

----------

## kannX

 *krunk wrote:*   

> 
> 
> ```
> $ECHO 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
> ```
> ...

 

Well, i think it drops all incoming icmp send to the boradcast address.

Icmp with the right address (INTIP1, INTIP2) from clients int INTNET1, INTNET2 and icmp outgoing should work .

----------

## krunk

 *kannX wrote:*   

>  *krunk wrote:*   
> 
> ```
> $ECHO 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
> ```
> ...

 

Actually, I double checked and you are right. Wouldn't the default POLICY of DROP be at the root though?

----------

## jimbob0i0

I've been trying to get this script to work for me but have a problem....

I have an internal mailserver running imaps, smtp and smtp on port 2525 (girlfiriend's ISP blocks 25 for her so she can't connect on that)

I put in:

#Mail systems from the outside world to the internal server

$IPT -t nat -A PREROUTING -p tcp --dport 25 -i $EXTIF -j DNAT --to $CENTRAL

$IPT -t nat -A PREROUTING -p tcp --dport 993 -i $EXTIF -j DNAT --to $CENTRAL

$IPT -t nat -A PREROUTING -p tcp --dport 2525 -i $EXTIF -j DNAT --to $CENTRAL

Which I thought should have done it ($CENTRAL is defined as the IP address of the machine on the local network) but port scans show these ports as closed if I also put in a $IPT -A INPUT rule for those ports or stealthed if I try forward or forward&input

The logs show:

```
Nov 14 20:57:38 gateway DROPl:IN=eth1 OUT= MAC=00:09:5b:1b:72:09:00:0b:fc:43:c0:a8:08:00 SRC=204.1.226.228 DST=82.43.43.146 LEN=40 TOS=0x00 PREC=0x00 TTL=115 ID=32768 PROTO=TCP SPT=62263 DPT=2525 WINDOW=8192 RES=0x00 SYN URGP=0

Nov 14 20:57:05 gateway DROPl:IN=eth1 OUT= MAC=00:09:5b:1b:72:09:00:0b:fc:43:c0:a8:08:00 SRC=204.1.226.228 DST=82.43.43.146 LEN=40 TOS=0x00 PREC=0x00 TTL=115 ID=32768 PROTO=TCP SPT=62228 DPT=25 WINDOW=8192 RES=0x00 SYN URGP=0

Nov 14 19:46:34 gateway DROPl:IN=eth1 OUT= MAC=00:09:5b:1b:72:09:00:0b:fc:43:c0:a8:08:00 SRC=204.1.226.228 DST=82.43.43.146 LEN=40 TOS=0x00 PREC=0x00 TTL=115 ID=32768 PROTO=TCP SPT=56955 DPT=993 WINDOW=8192 RES=0x00 SYN URGP=0
```

Any ideas guys? I'd really like to lock down my firewall better than it is now.

----------

## Jerri

does anyone sufer from extremely huge log files?

I let my router run (using this script) for a week and a half, without checking on it.  /var/log/messages was over 25 MB.  That seems a touch excessive.  

I realise that its probably a good idea to review all the packets dropped.  But... something doesn't sit very well with me on that one.  I don't know.  

I guess what i'm interested in hearing from others, is whats your policy on logging every dropped packet?  what do you do with your log files?   i suppose i could run a cron job, to compress them every couple of days and store them somewhere.   The only problem is that my router is running out of space.  I mean, i have a 1.2 GB hard disk.  thats not a huge amount of room to work with.

Anyways.  The script works well.  Much obliged for the HOWTO :)

----------

## Maxwell

Hello

I have an Asus notebook and i use it in several networks, each of them using a different proxy. I'm thinking on setting all my icq, msn clients and firefox to use a direct connection to internet and use iptables to direct traffic to somewhere usefull (like the different proxies...).

But then i suppose i'll need a proxy running in my notebook...

So i ask for your advice: how should i configurate iptables to do this and do i need squid running? Light and fast solutions are appreciated!!   :Smile: 

Thans in advance

----------

## yaneurabeya

Interesting. Gotta try out this sometime soon cause I hate being unfirewalled (even though I do run Gentoo =\...).

----------

## mr.isomer

Ok I hope someone can help me out with this:

I use broadband to connect no ppp0... just eth0 ... how do I edit the script?

Do I set this:

EXTIF='eth0'

and get rid of INTIF ???

Great HOWTO BTW... I just hope it mentioned this

----------

## Jerri

Looking at this bit of code

```
# External interface

EXTIF=ppp0

# Internal interface

INTIF1=eth1

INTIF2=eth2 
```

we see that the external interface is configured for ppp0, and there are 2 ethernet cards used for the internal network.

If you are creating a router/firewall with broadband... using two network cards, one for external, one internal, you will want the following:

```
# External interface

EXTIF=etho

# Internal interface

INTIF1=eth1
```

then remove all instances of INTIF2 (unless of course, you wish to use multiple network cards for your internal network).

----------

## mr.isomer

 *Jerri wrote:*   

> Looking at this bit of code
> 
> ```
> # External interface
> 
> ...

 

thanks I'll try that... i only have 1 NIC tho... i guess this may not be for me...

----------

## Jerri

mr.isomer,

I modified the script so that I could use it on my web server (one nic - outside the firewall).  I'm not sure weather or not this was a useful thing to do, as far as security goes, since this script accepts connections from the internet (ssh, http, https).  However, I guess closing uneeded ports can't hurt.

```
#!/bin/sh

# ********** VARIABLE DEFINITIONS **********

#

# External interface

EXTIF="eth0"

# Loop device/localhost

LPDIF="lo"

LPDIP="127.0.0.1"

LPDMSK="255.0.0.0"

LPDNET="$LPDIP/$LPDMSK"

# Text tools variables

IPT="/sbin/iptables"

IFC="/sbin/ifconfig"

G="/bin/grep"

SED="/bin/sed"

AWK="/bin/awk"

# Setting up external interface environment variables

EXTIP="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":"); split(a[2],a," ");print a[1];exit}'`"

EXTBC="`$IFC $EXTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`"

EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"

EXTMSK="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"

EXTNET="$EXTIP/$EXTMSK"

echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"

# ********** INITIALIZATION **********

#

# Deny then accept: this keeps holes from opening up

# while we close ports and such

$IPT        -P INPUT       DROP

$IPT        -P OUTPUT      DROP

$IPT        -P FORWARD     DROP

# Flush all existing chains and erase personal chains

CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`

for i in $CHAINS;

do

    $IPT -t $i -F

done

for i in $CHAINS;

do

    $IPT -t $i -X

done

# enable syncookies & ignore icmp broadcasts

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

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

# Source Address Verification

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

        echo 1 > $f

done

# Disable IP source routing and ICMP redirects

for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do

        echo 0 > $f

done

for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do

        echo 0 > $f

done

# Log Martians

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

        echo 1 > $i

done

##################

# LOGGING CHAINS #

##################

# Do not complain if chain already exists (so restart is clean)

$IPT -N DROPl   2> /dev/null

$IPT -A DROPl   -m limit --limit 3/minute --limit-burst 10 -j LOG --log-prefix 'FIREWALL DROP BLOCKED:'

$IPT -A DROPl   -j DROP

$IPT -N REJECTl 2> /dev/null

$IPT -A REJECTl -m limit --limit 3/minute --limit-burst 10 -j LOG --log-prefix 'FIREWALL REJECT BLOCKED:'

$IPT -A REJECTl -j REJECT

# ********** SANE COMMON RULES **********

#

# Now we are going to accept all traffic from or to our loopback device

# if the IP matches any of our interfaces.

$IPT -A INPUT   -i $LPDIF -s   $LPDIP  -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $EXTIP  -j ACCEPT

$IPT -A OUTPUT  -o $LPDIF -d   $LPDIP  -j ACCEPT

$IPT -A OUTPUT  -o $LPDIF -d   $EXTIP  -j ACCEPT

# Allow to ping out

$IPT -A OUTPUT  -o $EXTIF -p icmp -s $EXTIP  --icmp-type 8 -m state --state NEW -j ACCEPT

#######################################

# ALLOWING INSIDE TO OUTSIDE SERVICES #

#######################################

# Add port numbers that you would like to open

# from localhost to the internet

NOIP="8245"

BITTORNADO="6881:6999"

EXTRA_SERV="nntp rsync"

EXTRA_PORT="8245 1863 5190 11371 10000 1046"

TCPSERV="$EXTRA_SERV $EXTRA_PORT domain ssh http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time"

UDPSERV="domain time"

echo "---------------------------------------------------------------------"

echo "FW: Allowing inside systems to use services (tcp): "

for i in $TCPSERV;

do

   echo -n "$i "

   $IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP  --dport $i --syn -m state --state NEW -j ACCEPT

done

echo ""

echo "---------------------------------------------------------------------"

echo "FW: Allowing inside systems to use services (udp): "

for i in $UDPSERV;

do

    echo -n "$i "

    $IPT -A OUTPUT  -o $EXTIF -p udp -s $EXTIP  --dport $i -m state --state NEW -j ACCEPT

done

echo ""

#################################

# ALLOWING EXTERNAL ACCESS TO   #

#    SERVICES ON FIREWALL       #

#                               #

#     !!! Security Risk !!!     #

#################################

#Allowing external systems to use tcp services on localhost:

$IPT -A INPUT -i $EXTIF -p tcp -d $EXTIP --dport "ssh"   --syn -m state --state NEW -j ACCEPT

$IPT -A INPUT -i $EXTIF -p tcp -d $EXTIP --dport "http"  --syn -m state --state NEW -j ACCEPT

$IPT -A INPUT -i $EXTIF -p tcp -d $EXTIP --dport "https" --syn -m state --state NEW -j ACCEPT

##############################

# allow existing connections #

##############################

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

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

#######################################

# block / log what me may have forgot #

#                                     #

#       useful for debugging          #

#######################################

#$IPT -A INPUT             -j DROPl

#$IPT -A OUTPUT            -j REJECTl

#$IPT -A FORWARD           -j DROPl

```

----------

## Nard`

This is proboably a stupid question, but read through all the posts and i'm trying to establish one thing:

Is the script written in the starting post meant to be run at boot (in which case i should rc-update del iptables) or just once? 

also, should this script/iptables init.d script be run after or before network devices being brought up? for security i'd say before but it might cause some problems referencing interfaces that aren't "up" yet

Thanks

EDIT: How are you transferring this script? I've been copying it from this into my router via ssh yet the md5sum is different every time I do it, don't know how to do it accurately...

----------

## krunk

The iptables init.d script should not be placed in your run time. (rc-update del iptables) 

You can create your own init script and put in local if you want it to start at boot.

It should be started after the interfaces are brought up or the dynamic interface parsing will not work ($INTNET, $EXTNET, etc).

The first thing the script does is set POLICY to deny, which serves as a safety net. It also does not enable ip_forwarding till the very end, so you are not actually forwarding any traffic till after the rules have been set.

----------

## Nard`

Thanks, possibly (you've proboably already thought of this...) found a few problems:

You drop all packets, but then immediately after that you flush everything! During the (admittedly short time) beetween when you do that and you set the rules up you have a time whereby packets are non filtered. I'm proboably missing something there...

Also, i've been looking through it (and granted haven't looked at in too much detail yet) i'm not seeing what advantages these rules offer over say denying all incoming connections except on specified ports (and maybye limit that to just some ip's?). Or maybye that's exactly what it does (and logs it, which is nice despite perhaps it being slightly annoying they get lumped along with the kernel log, but thats not your fault, and could be changed by using ulog)

Oh and:

```

# Last but not least, the users

JAMES=192.168.1.77

TERESA=192.168.2.77 

```

What's the point of that, it's only referenced once: in it's declaration

EDIT: forgot to mention, great tutorial  :Very Happy: 

----------

## krunk

Hehe,

--On the flushing, that is a very good point and oversight of mine. To be honest, I've switched platforms many months ago and stopped maintaining this tutorial after it was posted to the Gentoo Wiki where the community could easily improve as necessary. I have some vague memory that rule flushing does not remove the policies, but I could be completely off base on that.

---That's pretty much what it does....however it also has a good bit of egress filtering. Some would say this is an overkill security measure on a home system and they may be right. However, my philosophy was even in an uber secure network your 5 year old daughter can slap that floppy her teacher gave her in and circumvent it all. With this in mind, I always thought it made sense to place rules that would prevent such a worm or virus from sending itself out to the world from an infected network (if more admins practiced this, many worms viruses would be far less effective).

--Logging: Actually, I used syslog-ng (and metalog at one point) to place all the iptables rules into /var/log/iptables.log and when debugging placed all ACCEPT logs in /var/log/iptables-accept.log or some such. Since methods vary from logger to logger, I left that up to the user.

Thanks for the input, and please by all means check out the posting on the Wiki and improve on the script. I was a true iptables newbie when I started reading for this and I'm sure there's a lot of improvements that can be made and possible oversights as well.  :Smile: 

----------

## Nard`

On closer inspection, I think i'm wrong about the flushing, on my system at least:

```

chameleon# cat /proc/net/ip_tables_names 

nat

filter

```

so INPUT,OUTPUT,FORWARD, remain intact. Actually that raises the worrying question about whether rules already in iptables prior to running the script could overide the ones in the script, but in a good setup that shouldn't really happen.

----------

## krunk

Try this:

Run the script from a clean slate. 

Type: iptables -L > myrules.txt

Take only the top part (where the POLICY is set and the rules are flushed) and put it in a separate file named flush.sh

Run the flush.sh (make sure you have local access as this should kill all networking).

Than run iptables -L > flushed.txt

Now diff the two (or visually compare). You should have listings like

[INPUT POLICY: DENY]

[OUTPUT POLICY: DENY] 

or some such (I don't have a linux system to test on anymore). This would show that the rule flushing is working correctly. If you end up with POLICY: ALLOW or some such, than you have indeed spotted a small window/hole in the script.

-james

----------

## Morimando

mightbe i have done something completely wrong but i always get

```
root@Doomsday morimando # $IPT -A FORWARD -o $INTIF1 -d   $INTBC1  -j DROPl

bash: -A: command not found

root@Doomsday morimando # $IPT -A FORWARD -o $INTIF2 -d   $INTBC2  -j DROPl 

bash: -A: command not found

```

such errors when trying to follow your HowTo. However the first parts works smooth, its halfway through the 2nd where it starts, maybe i shouldn't have run all the code that you put in and did not explain how to run it in a scriptfile? i thought that would be okay?

----------

## krunk

You run a script file like so:

```

#./myscript.sh

```

or 

```

# sh myscript.sh

```

----------

## SerfurJ

Jerri,

for some reason after using your script, "iptables -F" messes up my internet connection.  any idea why?  is there anything else i need to do to reset my configuration?  i'm guessing 

```
echo 0 /proc/sys/net/ipv4/<file>
```

, but i don't know what the defaults were.

thanks.

----------

## krunk

In a pinch,  you can run /etc/init.d/iptables start than stop to reset everything.

But the loop at the top of my script that deletes all chains and rules should do it too.

----------

## SerfurJ

that did it.  but before it would let me start /etc/init.d/iptables, i had to save the rules myself

```
iptables-save > /var/lib/iptables/rules-save
```

  thanks.

----------

## woZa

Nice howto... Thanks.

Got things working well apart from printing. Clients can't access the cups server... anyone ever get this working???

----------

## woZa

```
# Allow clients to connect to CUPS server

$IPT -A INPUT   -i $INTIF -p tcp --dport 631 -j ACCEPT

$IPT -A OUTPUT  -o $INTIF -p tcp --sport 631 -j ACCEPT
```

seems to do the trick...

----------

## SerfurJ

krunk,

nice tutorial, thanks.  

suggestion: it would've been easier for me to follow your tutorial if there were three parts to the lesson.  the second would be getting your script up to this level of complexity:

```
#!/bin/bash

IPTABLES='/sbin/iptables'

# set interface values

INET_IFACE='eth0'

# flush rules and delete chains

$IPTABLES -F

$IPTABLES -X

# set default policies

$IPTABLES -P INPUT DROP

$IPTABLES -P FORWARD DROP

$IPTABLES -P OUTPUT ACCEPT

# block netbios noise (for windows networks)

$IPTABLES -A INPUT -p UDP -i $INET_IFACE --dport 135:139 -j DROP

### trusted hosts ###

$IPTABLES -A INPUT -i lo -j ACCEPT

$IPTABLES -A INPUT -s xxx.xxx.xxx.xxx -j ACCEPT

$IPTABLES -A INPUT -s xxx.xxx.xxx.xxx -j ACCEPT

# Allow traffic from established connections

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

### services available to subnets ###

# allow access to the HTTP server

$IPTABLES -A INPUT -s xxx.xxx.xxx.xxx/24 --protocol tcp --dport 80 -j ACCEPT

### services available to internet ###

# allow access to the SSH server

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

that way, someone like me (who doesn't need to build a complex router) would just stop after lesson two.

----------

## HriBB

If you are getting this error...

```
kernel: ip_conntrack: table full, dropping packet.
```

Do this...

```
echo "number" > /proc/sys/net/ipv4/ip_conntrack/ip_conntrack_max
```

Does anyone know how to flush /proc/net/ip_conntrack ?

----------

## nadamsieee

How do I basically undo this script entirely? I had a very simple, working config, then decided to try this.

Everything seemed great until I rebooted. Then I could not start KDE because the firewall wouldn't allow the connection, nmap no longer works because its not allowed to scan, and my simple little script that just enabled NAT now breaks the Internet connection completely.

You might want to add a disclaimer that these rules are a bit too strict for a desktop system...

----------

## SerfurJ

nadamsieee,

see my first posts on this thread:

https://forums.gentoo.org/viewtopic-p-2171669.html#2171669

----------

## Barshamm

Excellent work, this REALLY helps me a lot!

----------

## lost+found

i'm using the script (page2 of this thread) on a standalone pc by removing/commenting out lines, sections, things containing $INT*...

Bwa HA HA !!!

 :Laughing: 

P.S. i put the script in /etc/ppp/ip-up, to let pppd execute it every dialup.

P.P.S. test your TruStealth status here: ShieldsUP!!

----------

## beuselinck

great guide!

I'm learning a lot about firewalls.

But I'm having hard times understanding something:

How can a rule applying to the OUTPUT chain have a source address? eg in the script you have:

```
$IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP  --dport $i --syn -m state --state NEW -j ACCEPT
```

and in a rule from KannX in this thread

```
$IPT -A OUTPUT -o $INTIF1 -s $INTIP1 -d $INTNET1  -p udp --sport ntp -j ACCEPT
```

Aren't packets going through the output chain, packets that are created locally. If they are, then what is the source address?

Kinda lost on this...

thanks

----------

## Kazaza

Just wanted to say that this is a really great guide! Thanks for working with it...  :Very Happy: 

----------

## lost+found

@beuselinck

i think it's just an extra check: all packets got a source address anyway, spoofed or not, because they must be replied to actually start the connection.  See man:iptables, option --syn. $LPDIP isn't useful for other interfaces than lo, $EXTIP is.

@any firewall guru

i think i read somekind of problem with the "--state ESTABLISHED,RELATED" lines over here:  *Quote:*   

> Using the state module alone, INVALID will break protocols that use bi-directional connections or multiple connections or exchanges, unless an ALG is provided for the protocol. At this time, FTP and IRC are the only protocols with ALG support.

  is this what the ip_conntrack_ftp/irc modules are for  :Question:  ... and the cause of p2p like gnutella need separate rules  :Question: 

----------

## tscolari

This tutorial is very usefull  :Smile: 

but i got some problems here...

my iptables script do this:

```

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

#####################################

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

$IPTABLES -A INPUT --protocol tcp --dport 23    -j ACCEPT       #telnet

$IPTABLES -A INPUT --protocol tcp --dport 21    -j ACCEPT       #ftp

$IPTABLES -A INPUT --protocol tcp --dport 139   -j ACCEPT       #samba

$IPTABLES -A INPUT --protocol tcp --dport 177   -j ACCEPT       #XDMCP

$IPTABLES -A INPUT --protocol tcp --dport 2049  -j ACCEPT       #NFS

####################

$IPTABLES -A INPUT      -j DROP         

$IPTABLES -A FORWARD    -j DROP    

$IPTABLES -A OUTPUT     -j ACCEPT 

```

just want to block everything thats comming that is not one of the services i allow.

For ssh it works normal, but with ftp and telnet it doesnt :/

(i dont know about the others, havent been tested yet).

im using netkit-telnet and ftpd ebuilds, that seem to use xinetd, any special rule i should take then to make they work??

----------

## amzuk

 *Lepaca Kliffoth wrote:*   

> I was wondering if I can use this script. I've got a desktop connected to the internet through adsl and I want it to share the connection with a laptop. The laptop's conneted to my desktop with a cross-over cable. How should I modify the script?

 

no, this is exacctly what you need. except that you dont have $INTIF2

----------

## elestedt

hi

I've added som portforwardning by using 

```
$IPT -A FORWARD -j ACCEPT -p tcp --dport 80

$IPT -t nat -A PREROUTING -i $EXTIF -p tcp --dport 80 -j DNAT --to 192.168.0.1:80
```

to the script. and this works great as long as I'm not on the INTIF network. That is - it works as long as I'm on the internet even if I try to connect to the external IP from the internal network.

What I want is for that forwarding to work regardless of source (more or less). How do I have to modify the script to get that functionality?

Thanks in advance.

----------

## Stalione

I started out with the iptables script that is posted at the beginning of this thread.  I changed it quite a bit to match my needs (since I am not forwarding anything).  I have had very good success so far, except for getting NFS working.  All I am trying to do is restrict all outgoing and incoming traffic:

$IPT -A OUTPUT  -j REJECTl

But I would like to permit the host to be able to mount remote nfs shares.  Also I would like to the host to be able to serve nfs shares.  I edited the /etc/conf.d/nfs file to the following:

 *Quote:*   

> 
> 
> # Number of servers to be started up by default
> 
> RPCNFSDCOUNT=8
> ...

 

and also modified the sysctl.conf file to the following:

 *Quote:*   

> 
> 
> # TCP Port for lock manager
> 
> fs.nfs.nlm_tcpport = 32768
> ...

 

I have tried various rules to get the host to mount nfs shares and serve nfs shares but I cannot get it working for the life of me.

 *Quote:*   

> 
> 
> # NFS
> 
> $IPT -A OUTPUT --protocol tcp --dport 2049 -j ACCEPT
> ...

 

Keep in mind this host only has one network interface, and is NOT acting as a router/gateway.

When I attempt to mount nfs share I get the following error:

 *Quote:*   

> 
> 
> spduslishnode01 sysop # mount -t nfs -o mountport=955 10.55.58.143:/mnt /mnt/floppy
> 
> mount: RPC: Unable to send; errno = Operation not permitted
> ...

 

If I enable all outbound traffic, then it works.  I am not sure what else I need to allow outbound.  Any ideas?

----------

## MikeP

 *Stalione wrote:*   

> I am not sure what else I need to allow outbound.  Any ideas?

 

As i come across this, one suggestion that may help - you could try to use ethereal or something similar and check all packets that get send when you mount the share, when all outbound traffic may pass.

----------

## lost+found

This is how I do some sorting with the firewall log lines in OpenOffice (for analysis the ugly way  :Wink:  ).

<snip>

  THE SCRIPT MOVED HERE: https://forums.gentoo.org/viewtopic-p-2868355.html#2868355  :Laughing: 

-------Last edited by lost+found on Tue Dec 06, 2005 12:20 pm; edited 3 times in total

----------

## patrix_neo

First of all; thanks for a good guide! Needs more tallented writers like you.

Next I like to contribute, if no one else had. I've never seen it though, but made it work for me.

What I will do, is make the LANIP-var be calculated from LANIF (eth1) only. And I did like this:

```

LANIF="eth1"

LANIP="`ifconfig $LANIF|grep addr:|sed 's/.*addr:\([^ ]*\) .*/\1/'`"

LANBCAST="`ifconfig $LANIF|grep Bcast:|sed 's/.*Bcast:\([^ ]*\) .*/\1/'`"

```

I think it might be handy if you have to just enter your LANIF to get the LANIP parm, and LANBCAST parm automatically.

The same can ofcourse be done with your other  eth[n] interfaces.

I have not found out how to get the LANET="192.168.1.0/24" (for example) calculated from ifconfig-data. Which means it can be handy to have the actual LANIP, but now is hidden with this method.

----------

## namo

Just a side note : people with localized setups might find it useful to use

```
LC_ALL='C' /sbin/ifconfig
```

 instead of plain ifconfig, since its output is localized and this can break the sed filters. (and maybe include it in the main script ?)

----------

## parker.richie

Hi, 

Well firstly IPTables part 1 was real good and i have tried it out and havent faced any issues, as of now   :Smile:  .

However, I really would appreciate if I could know as to how do i configure two isp's using the iptables.  Say for example how do i do a Load Balance.  

Any documents which could guide me step-by-step??  

Thanx in advance

----------

## patrix_neo

 *parker.richie wrote:*   

> Hi, 
> 
> Well firstly IPTables part 1 was real good and i have tried it out and havent faced any issues, as of now   .
> 
> However, I really would appreciate if I could know as to how do i configure two isp's using the iptables.  Say for example how do i do a Load Balance.  
> ...

 

Hi. What you are looking for is the tc command for (traffic control) load balancing. Try this link http://www.lartc.org/howto/index.html Look at chapter 9. It works in conjunction with iptables. An other way to say it is - like symbiosis with eachother. You can que the traffic and with help of the MARK options in iptables you can use it in collaboration with tc. 

Worth a look at.

----------

## carpenike

Hello,

First of all, thank you VERY much for the informative guide! It definately got me going in the right direction...

Just have a quick question... Here's my current setup:

Cable Modem (5 Public IP Addresses) --> Gentoo Router (4 NICS).

Two of those NICS on my Gentoo Router are bridged together. When I don't have any IPTables settings on the box, I can easily pull DHCP addresses through the bridge.

I also have an IP address ontop of the bridge group that I use to NAT my other 2 interfaces (one wireless and one wired). 

My problem is that as soon as I turn on IPTables, DHCP broadcasts cannot traverse the bridge group, and I'm also not able to pass pings through to the box when it already has an IP address.

My config is pretty much the same as his, with the exception that instead of eth0 being my $EXTIF, br0 is my $EXTIF.

Can anybody give me advice? I'd like to be able to limit the ports that are accessible to those 5 public IPs by using IPTables like so. Any help would be most appreciated!

----------

## lost+found

Not necessarily in reply to carpenike, but here [ http://www.malibyte.net/iptables/scripts/firewall.iptables-generic ] are some nice iptables rules for use with a DHCP server and/or client. You can steal the relevant ones and paste them into the script of this thread.

For a client only (dhcpcd) and cable modem, I pasted the first set of 7 rules after the loopback interface section of our script (before blocking broadcasts). More* than enough imho. Plus this: 

```
DHCP_SERVER_IP=`grep DHCPSID /var/lib/dhcpc/dhcpcd-$EXTIF.info | sed 's:DHCPSID=\(.*\):\1:'`
```

For a server there's another section at the end.

* = /var/lib/iptables/rules-save shows that most of these rules are not/not often/only in some cases (offline modem) used in my/Gentoo's configuration...  :-sLast edited by lost+found on Fri Dec 29, 2006 4:00 pm; edited 1 time in total

----------

## lost+found

I guess this is a good place to start a firewall script...

/etc/conf.d/net:

```
postup() {

   [[ ${IFACE} != "lo" ]] && /root/scripts/firewall.sh

}
```

----------

