Difference between revisions of "Iptables"

From Noah.org
Jump to navigationJump to search
 
(32 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[Category:Engineering]]
 
[[Category:Engineering]]
 +
[[Category: Networking]]
  
 
== Linux iptables Basic Examples ==
 
== Linux iptables Basic Examples ==
  
The following are simple iptables firewalls for Linux. I use these as starter firewalls when I setup a machine... I don't like using iptables-restore. I prefer
+
The following are simple iptables firewalls for Linux. I use these as starter firewalls when I setup a machine. I don't like using iptables-restore. I prefer to simply script the iptables commands that I would type at the command line.
to simply script the iptables commands that I would otherwise type at the command line.
+
 
 +
Most of these scripts start by reinitializing iptables, so you will loose any rules, chains, or accounting information that iptables knows about. For example, this deletes any policies, chains, and rules in place.
  
Most of these scripts start by reinitializing iptables, so you will loose
 
any rules, chains, or accounting information that iptables knows about.
 
For example, this deletes any policies, chains, and rules in place.
 
 
<pre>
 
<pre>
 
iptables -P INPUT ACCEPT    # open up default policy on built-in chain
 
iptables -P INPUT ACCEPT    # open up default policy on built-in chain
Line 17: Line 16:
 
</pre>
 
</pre>
  
=== Block everything ===
+
=== Block everything firewall ===
  
This blocks everything. You will only be able to access the machine from the console. Don't do this if you are working remotely because your connection will instantly be dropped. Another way to do this would be to disable the network interface. The advantage of blocking everything with iptables instead of shutting down a network interface is that this leaves the kernel network layer still running. Running apps will not complain about the network being unavailable. This also blocks all network interfaces at once, so if you have a machine with multiple interfaces this will take care of them all.
+
This blocks everything. You will only be able to access the machine from the console. Don't do this if you are working remotely because your connection will instantly be dropped. Another way to do this would be to disable the network interface. The advantage of blocking everything with iptables instead of shutting down a network interface is that this leaves the kernel network layer still running. Applications will not complain about the network being unavailable. This also blocks all network interfaces at once, so if you have a machine with multiple interfaces this will take care of them all.
  
 
<pre>
 
<pre>
Line 33: Line 32:
 
</pre>
 
</pre>
  
=== Wide Open Firewall ===
+
=== Allow everything firewall ===
  
This opens up everything. It's the exact opposite of [[#Block everything|Block everything]].  
+
This opens up everything. It's the exact opposite of [[#Block everything|Block everything]]. The firewall is still technically running, but every packet is allowed through. This is the safe way to open the firewall without accidentally locking yourself out.
The firewall is still technically running, but every packet is allowed through.
 
This is the safe way to open the firewall without accidentally locking yourself out.
 
  
 
<pre>
 
<pre>
Line 52: Line 49:
 
I use this to shut down everything except SSH port 22. This is my panic script. If something seems suspicious then I use this script to put a machine into as safe a state as possible while still allowing remote SSH connections.
 
I use this to shut down everything except SSH port 22. This is my panic script. If something seems suspicious then I use this script to put a machine into as safe a state as possible while still allowing remote SSH connections.
  
Note that a machine with these rules won't even be visible on the network. If you want to scan it with nmap you will have to use "nmap -P0" which scans without first checking with ICMP (ping).
+
Note that a machine with these rules won't be visible on the network with ping. Nmap by default does a ping test before mapping a machine. If you want to scan it with nmap you will have to use "nmap -P0" to scan without first checking ping.
  
 
<pre>
 
<pre>
Line 64: Line 61:
 
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
 
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
 
iptables -P INPUT DROP
 
iptables -P INPUT DROP
 +
iptables -A OUTPUT -p tcp -m tcp --sport 22 -j ACCEPT
 +
iptables -P OUTPUT DROP
 
</pre>
 
</pre>
  
=== Basic firewall ===
+
=== A practical, simple iptables firewall init.d script ===
  
This example is a little more practical. This will block bad packets; it will allow friendly ICMP (ping requests); it will allow SSH, HTTP, HTTPS; and it will allow established and related connections, so you can use applications such as outbound ftp clients.
+
For my real firewall I use an init.d script to store the configuration and to load the rules when the system boots. RedHat has a similar mechanism setup by default. Oddly, Ubuntu has no standard for restoring iptables rules on boot which is why I wrote this script to begin with. It turned out that I liked storing the rules this way better than I liked the RedHat style anyway.
  
<pre>
+
To restore rules on boot, copy this script to /etc/init.d/firewall. On Ubuntu or Debian systems, run "update-rc.d firewall defaults" and the system will from then on start loading the firewall rules on boot. On RedHat systems, run "chkconfig --add firewall" and the system will run the script on boot.
#!/bin/sh
 
  
# Flush any old policies and rules.
+
This script includes options to start, stop, and show the status of iptables. The "stop" command doesn't really stop iptables (it is not a daemon). In this case, "stop" just flushes all policies and rules which opens networking to all traffic.
iptables -P INPUT ACCEPT
 
iptables -P OUTPUT ACCEPT
 
iptables -P FORWARD ACCEPT
 
iptables -F
 
iptables -X
 
  
#
+
Click here to download: [http://www.noah.org/engineering/src/shell/firewall firewall]
# Accept some remote connections.
+
<include src="http://www.noah.org/engineering/src/shell/firewall" highlight="sh" />
#
 
# SSH
 
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
 
# HTTP
 
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
 
# HTTPS
 
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
 
# SMTP
 
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
 
# DNS
 
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
 
# VMware
 
iptables -A INPUT -p tcp --dport 902 -j ACCEPT
 
  
#
+
=== Funny story ===
# Accept some localhost connections.
 
#
 
# IMAP
 
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 143 -j ACCEPT
 
# MySQL
 
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 3306 -j ACCEPT
 
# PostgreSQL
 
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 5432 -j ACCEPT
 
# BIND RNDC
 
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 953 -j ACCEPT
 
# VNC -- You should use an SSH tunnel to expose this to remote connections.
 
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 5900 -j ACCEPT
 
# Subversion svnserve (you should probably just use the svn+ssh: URL scheme)
 
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 3690 -j ACCEPT
 
  
# Drop illegal packets
+
At one time I had an iptables rule on all my machines that limited pings to 1 per second. By default the ping command sends 1 ICMP packet per second. Everything was fine and eventually I forgot about the rule. Months later I noticed that mtr was reporting high packet loss to a machine. A co-worker helped me investigate and the packet loss only got worse. Then the machine would intermittently stop accepting new SSH connections. All outside connections go through a load balancer. The load balancer is setup to probe each cluster and if a machine does not respond to a ping every 10 minutes then the load balancer removes that machine from rotation (even if there is only one machine in a cluster). So as we tried to debug our packet loss with ping and mtr it would cause iptables to block ICMP and if the load balancer happened to be doing a probe then it would take the machine off the network. We thought things were really bad because we couldn't even connect to the server through through the load balancer interface. Huge packet loss and dropped SSH connections -- we were thinking to check for bad cables, bad switch, or a bad load balancer. Then we checked the load balancer logs and saw that it had removed the machine because of failed ping probes. Eventually I tried shutting off iptables and the problem went away. Finally we decided to look at the iptables rules which revealed the rule that was causing all the grief. This will cause apparent packet loss if two engineers both ping at the same time:
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
 
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
 
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP # NULL packets
 
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
 
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP #XMAS
 
iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP # FIN packet scans
 
iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
 
  
# Allow some ICMP (ping)
+
<pre>
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
 
iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
 
iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT
 
 
iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT
 
iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT
iptables -A INPUT -p icmp -j DROP
 
 
# Match related and established state connections.
 
# This allows client-side connections such as ftp work properly.
 
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 
 
# Default policies to handle everything not covered by a rule.
 
iptables -P INPUT DROP
 
iptables -P OUTPUT ACCEPT
 
iptables -P FORWARD ACCEPT
 
 
</pre>
 
</pre>
  
 
== Load firewall on boot ==
 
== Load firewall on boot ==
When you shutdown your server all the iptables rules will be lost.
+
 
You need to run a firewall script every time you boot.
+
When you shutdown your server all the iptables rules will be lost. You need to run a firewall script every time you boot.
Some people use [http://www.fs-security.com/ firestarter], but I prefer edit  
+
Some people use [http://www.fs-security.com/ firestarter], but I prefer edit my own simple init script.
my own simple init script.
 
  
 
=== RedHat ===
 
=== RedHat ===
 +
 
For RedHat you need to edit:
 
For RedHat you need to edit:
    <pre>/etc/sysconfig/iptables</pre>
+
 
Don't confuse this with /etc/sysconfig/iptables-config.
+
<pre>/etc/sysconfig/iptables</pre>
Also note that RedHat has a tool called system-security-level that
+
 
overwrites /etc/sysconfig/iptables, so if you run system-security-level  
+
Don't confuse this with /etc/sysconfig/iptables-config. Also note that RedHat has a tool called system-security-level that overwrites /etc/sysconfig/iptables, so if you run system-security-level you will loose your changes. You can edit the file manually or you can use system-security-level. Choose one or the other, not both.
you will loose your changes. You can edit the file manually or you can
+
 
use system-security-level. Choose one or the other, not both.
+
You can also setup the firewall the way you want using the iptables command and then save the settings using RedHat's inti.d script:
 +
 
 +
<pre>/etc/init.d/iptables save</pre>
  
 
=== Ubuntu/Debian ===
 
=== Ubuntu/Debian ===
 +
 
For Ubuntu/Debian you can put an init script into /etc/init.d then link to an 'S' file in /etc/rc2.d
 
For Ubuntu/Debian you can put an init script into /etc/init.d then link to an 'S' file in /etc/rc2.d
 +
 
<pre>
 
<pre>
 
cp firewall /etc/init.d/firewall
 
cp firewall /etc/init.d/firewall
Line 160: Line 110:
 
cd /etc/rc2.d/
 
cd /etc/rc2.d/
 
ln -s ../init.d/firewall S99firewall
 
ln -s ../init.d/firewall S99firewall
</pre>
 
=== init.d script ===
 
The following init script is based on the scripts given previously.
 
Save this in /etc/init.d/firewall. This includes options to start, stop, or
 
show the status of iptables. This doesn't really stop iptables. It just
 
deletes all firewall rules.
 
<pre>
 
#!/bin/sh
 
 
N=/etc/init.d/firewall
 
 
set -e
 
 
case "$1" in
 
  start)
 
    # Flush any old policies and rules.
 
    iptables -P INPUT ACCEPT
 
    iptables -P OUTPUT ACCEPT
 
    iptables -P FORWARD ACCEPT
 
    iptables -F
 
    iptables -X
 
 
    #
 
    # Accept some remote connections.
 
    #
 
    # SSH
 
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
 
    # HTTP
 
    iptables -A INPUT -p tcp --dport 80 -j ACCEPT
 
    # HTTPS
 
    iptables -A INPUT -p tcp --dport 443 -j ACCEPT
 
    # SMTP
 
    iptables -A INPUT -p tcp --dport 25 -j ACCEPT
 
    # DNS
 
    iptables -A INPUT -p tcp --dport 53 -j ACCEPT
 
    # VMware
 
    iptables -A INPUT -p tcp --dport 902 -j ACCEPT
 
 
    #
 
    # Accept some localhost connections.
 
    #
 
    # IMAP
 
    iptables -A INPUT -p tcp -s 127.0.0.1 --dport 143 -j ACCEPT
 
    # MySQL
 
    iptables -A INPUT -p tcp -s 127.0.0.1 --dport 3306 -j ACCEPT
 
    # PostgreSQL
 
    iptables -A INPUT -p tcp -s 127.0.0.1 --dport 5432 -j ACCEPT
 
    # BIND RNDC
 
    iptables -A INPUT -p tcp -s 127.0.0.1 --dport 953 -j ACCEPT
 
    # VNC -- You should use an SSH tunnel to expose this to remote connections.
 
    iptables -A INPUT -p tcp -s 127.0.0.1 --dport 5900 -j ACCEPT
 
    # Subversion svnserve (you should probably just use the svn+ssh: URL scheme)
 
    iptables -A INPUT -p tcp -s 127.0.0.1 --dport 3690 -j ACCEPT
 
 
    # Drop illegal packets
 
    iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
 
    iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
 
    iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP # NULL packets
 
    iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
 
    iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP #XMAS
 
    iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP # FIN packet scans
 
    iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
 
 
    # Allow some ICMP (ping)
 
    iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
 
    iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
 
    iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT
 
    iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/second -j ACCEPT
 
    iptables -A INPUT -p icmp -j DROP
 
 
    # Match related and established state connections.
 
    # This allows client-side connections such as ftp work properly.
 
    iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 
 
    # Default policies to handle everything not covered by a rule.
 
    iptables -P INPUT DROP
 
    iptables -P OUTPUT ACCEPT
 
    iptables -P FORWARD ACCEPT
 
    ;;
 
  stop)
 
    iptables -P INPUT ACCEPT
 
    iptables -P OUTPUT ACCEPT
 
    iptables -P FORWARD ACCEPT
 
    iptables -F
 
    iptables -X
 
    ;;
 
  status)
 
    iptables -L -v
 
    ;;
 
  *)
 
    echo "Usage: $N {start|stop|status}" >&2
 
    exit 1
 
    ;;
 
esac
 
 
exit 0
 
 
</pre>
 
</pre>
  
 
== Traffic shaping ==
 
== Traffic shaping ==
 +
 
Most iptables installs come with the "TOS" module (Type Of Service):
 
Most iptables installs come with the "TOS" module (Type Of Service):
 +
 
<pre>
 
<pre>
 
iptables -m tos -h
 
iptables -m tos -h
 
</pre>
 
</pre>
This lets you set priority options for packets.
 
  
This is a complex topic. I need to expand this with a simple setup that
+
The TOS module lets you flag packets for different processing based on the IP packet header's TOS (now called Differentiated Services Code Point -- DSCP). IP packet headers contain an 8 bit field called DSCP (previously TOS) which can be used by the user application to indicate the priority of traffic. OpenSSH marks its packets depending on whether they originate from `ssh` or `scp`. The `ssh` packets are marked as "low delay" which denotes interactive traffic whereas `scp` packets are marked as "throughput" which denotes bulk traffic that is not sensitive to delays or latency.
shows how to boost priority of interactive applications like SSH and
+
 
possibly HTTP, while lowering priority for everything else.
+
Iptables also has a "DSCP" module. It's not clear which one to use for traffic shaping of SSH traffic. It seems that OpenSSH is still using the old TOS values, so it may be that the "TOS" module is the better choice at the moment.
[http://gentoo-wiki.com/HOWTO_Packet_Shaping | Gentoo Wiki] is one of the better
+
 
 +
This is a complex topic. I need to expand this with a simple setup that shows how to boost priority of interactive applications like SSH and
 +
possibly HTTP, while lowering priority for everything else. [http://gentoo-wiki.com/HOWTO_Packet_Shaping | Gentoo Wiki] is one of the better
 
documentation sources I have found.
 
documentation sources I have found.
  
 
TCNG seems interesting. I have yet to try it:
 
TCNG seems interesting. I have yet to try it:
 +
 
http://tcng.sourceforge.net/
 
http://tcng.sourceforge.net/
  
 
I tried this without much luck:
 
I tried this without much luck:
 +
 
http://lartc.org/howto/lartc.cookbook.ultimate-tc.html#AEN2210
 
http://lartc.org/howto/lartc.cookbook.ultimate-tc.html#AEN2210
  
Line 281: Line 140:
 
== Handy commands ==
 
== Handy commands ==
  
=== Block an annoying machine from reaching your server ===
+
=== Ban -- block an annoying machine ===
This blocks a specific IP address from your server.
+
 
This is useful if you are getting annoying traffic from
+
This blocks a specific IP address from reaching your server. This is useful if you are getting annoying traffic from another machine and you want to get rid of them. Replace 255.255.255.255 with the IP address you want to drop.
another machine and you want to get rid of them.
+
 
Replace 255.255.255.255 with the IP address you want to drop.
+
<pre>
 +
iptables -I INPUT -j DROP -s 255.255.255.255
 +
</pre>
 +
 
 +
I set these aliases in my .bash_aliases file (sourced by .bashrc):
 
<pre>
 
<pre>
iptables -I INPUT -s 255.255.255.255 -j DROP
+
alias ban='iptables -I INPUT -j DROP -s'
 +
alias unban='iptables -D INPUT -j DROP -s'
 
</pre>
 
</pre>
 +
 +
A very useful tool to do this automatically is [http://www.fail2ban.org/ fail2ban].
  
 
=== Show packet and byte counts ===
 
=== Show packet and byte counts ===
This shows the counters for each rule in a chain.
+
 
This shows the number of packets and bytes that have
+
This shows the counters for each rule in a chain. This shows the number of packets and bytes that have gone through a specific chain. You can use this to measure traffic.
gone through a specific chain. You can use this to
+
 
measure traffic.
 
 
<pre>
 
<pre>
 
iptables -L INPUT -v
 
iptables -L INPUT -v
 
</pre>
 
</pre>

Latest revision as of 16:34, 24 March 2014


Linux iptables Basic Examples

The following are simple iptables firewalls for Linux. I use these as starter firewalls when I setup a machine. I don't like using iptables-restore. I prefer to simply script the iptables commands that I would type at the command line.

Most of these scripts start by reinitializing iptables, so you will loose any rules, chains, or accounting information that iptables knows about. For example, this deletes any policies, chains, and rules in place.

iptables -P INPUT ACCEPT    # open up default policy on built-in chain
iptables -P OUTPUT ACCEPT   # open up default policy on built-in chain
iptables -P FORWARD ACCEPT  # open up default policy on built-in chain
iptables -F                 # delete all rules from all chains
iptables -X                 # delete all user chains (non built-in chains)

Block everything firewall

This blocks everything. You will only be able to access the machine from the console. Don't do this if you are working remotely because your connection will instantly be dropped. Another way to do this would be to disable the network interface. The advantage of blocking everything with iptables instead of shutting down a network interface is that this leaves the kernel network layer still running. Applications will not complain about the network being unavailable. This also blocks all network interfaces at once, so if you have a machine with multiple interfaces this will take care of them all.

#!/bin/sh
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -X
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

Allow everything firewall

This opens up everything. It's the exact opposite of Block everything. The firewall is still technically running, but every packet is allowed through. This is the safe way to open the firewall without accidentally locking yourself out.

#!/bin/sh
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -X

Minimal emergency firewall

I use this to shut down everything except SSH port 22. This is my panic script. If something seems suspicious then I use this script to put a machine into as safe a state as possible while still allowing remote SSH connections.

Note that a machine with these rules won't be visible on the network with ping. Nmap by default does a ping test before mapping a machine. If you want to scan it with nmap you will have to use "nmap -P0" to scan without first checking ping.

#!/bin/sh
# Minimal emergency firewall (block everything except SSH).
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -X
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
iptables -P INPUT DROP
iptables -A OUTPUT -p tcp -m tcp --sport 22 -j ACCEPT
iptables -P OUTPUT DROP

A practical, simple iptables firewall init.d script

For my real firewall I use an init.d script to store the configuration and to load the rules when the system boots. RedHat has a similar mechanism setup by default. Oddly, Ubuntu has no standard for restoring iptables rules on boot which is why I wrote this script to begin with. It turned out that I liked storing the rules this way better than I liked the RedHat style anyway.

To restore rules on boot, copy this script to /etc/init.d/firewall. On Ubuntu or Debian systems, run "update-rc.d firewall defaults" and the system will from then on start loading the firewall rules on boot. On RedHat systems, run "chkconfig --add firewall" and the system will run the script on boot.

This script includes options to start, stop, and show the status of iptables. The "stop" command doesn't really stop iptables (it is not a daemon). In this case, "stop" just flushes all policies and rules which opens networking to all traffic.

Click here to download: firewall <include src="http://www.noah.org/engineering/src/shell/firewall" highlight="sh" />

Funny story

At one time I had an iptables rule on all my machines that limited pings to 1 per second. By default the ping command sends 1 ICMP packet per second. Everything was fine and eventually I forgot about the rule. Months later I noticed that mtr was reporting high packet loss to a machine. A co-worker helped me investigate and the packet loss only got worse. Then the machine would intermittently stop accepting new SSH connections. All outside connections go through a load balancer. The load balancer is setup to probe each cluster and if a machine does not respond to a ping every 10 minutes then the load balancer removes that machine from rotation (even if there is only one machine in a cluster). So as we tried to debug our packet loss with ping and mtr it would cause iptables to block ICMP and if the load balancer happened to be doing a probe then it would take the machine off the network. We thought things were really bad because we couldn't even connect to the server through through the load balancer interface. Huge packet loss and dropped SSH connections -- we were thinking to check for bad cables, bad switch, or a bad load balancer. Then we checked the load balancer logs and saw that it had removed the machine because of failed ping probes. Eventually I tried shutting off iptables and the problem went away. Finally we decided to look at the iptables rules which revealed the rule that was causing all the grief. This will cause apparent packet loss if two engineers both ping at the same time:

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

Load firewall on boot

When you shutdown your server all the iptables rules will be lost. You need to run a firewall script every time you boot. Some people use firestarter, but I prefer edit my own simple init script.

RedHat

For RedHat you need to edit:

/etc/sysconfig/iptables

Don't confuse this with /etc/sysconfig/iptables-config. Also note that RedHat has a tool called system-security-level that overwrites /etc/sysconfig/iptables, so if you run system-security-level you will loose your changes. You can edit the file manually or you can use system-security-level. Choose one or the other, not both.

You can also setup the firewall the way you want using the iptables command and then save the settings using RedHat's inti.d script:

/etc/init.d/iptables save

Ubuntu/Debian

For Ubuntu/Debian you can put an init script into /etc/init.d then link to an 'S' file in /etc/rc2.d

cp firewall /etc/init.d/firewall
chmod 755 /etc/init.d/firewall
cd /etc/rc2.d/
ln -s ../init.d/firewall S99firewall

Traffic shaping

Most iptables installs come with the "TOS" module (Type Of Service):

iptables -m tos -h

The TOS module lets you flag packets for different processing based on the IP packet header's TOS (now called Differentiated Services Code Point -- DSCP). IP packet headers contain an 8 bit field called DSCP (previously TOS) which can be used by the user application to indicate the priority of traffic. OpenSSH marks its packets depending on whether they originate from `ssh` or `scp`. The `ssh` packets are marked as "low delay" which denotes interactive traffic whereas `scp` packets are marked as "throughput" which denotes bulk traffic that is not sensitive to delays or latency.

Iptables also has a "DSCP" module. It's not clear which one to use for traffic shaping of SSH traffic. It seems that OpenSSH is still using the old TOS values, so it may be that the "TOS" module is the better choice at the moment.

This is a complex topic. I need to expand this with a simple setup that shows how to boost priority of interactive applications like SSH and possibly HTTP, while lowering priority for everything else. | Gentoo Wiki is one of the better documentation sources I have found.

TCNG seems interesting. I have yet to try it:

http://tcng.sourceforge.net/

I tried this without much luck:

http://lartc.org/howto/lartc.cookbook.ultimate-tc.html#AEN2210

This page also has some notes: http://www.void.gr/kargig/blog/2005/07/27/traffic-shaping-a-dsl-line-with-linux/

Handy commands

Ban -- block an annoying machine

This blocks a specific IP address from reaching your server. This is useful if you are getting annoying traffic from another machine and you want to get rid of them. Replace 255.255.255.255 with the IP address you want to drop.

iptables -I INPUT -j DROP -s 255.255.255.255

I set these aliases in my .bash_aliases file (sourced by .bashrc):

alias ban='iptables -I INPUT -j DROP -s'
alias unban='iptables -D INPUT -j DROP -s'

A very useful tool to do this automatically is fail2ban.

Show packet and byte counts

This shows the counters for each rule in a chain. This shows the number of packets and bytes that have gone through a specific chain. You can use this to measure traffic.

iptables -L INPUT -v