Simple iptables firewall script with NAT and SFQ sceduling
I have been working with firewalls and security for quite many years at this point. Therefore friends and people I know ask me every now and then to write a firewall script for them. So instead of basically writing the same script over and over again I decided to write this article that explains how you can set up a basic iptables box by yourself.
If you do not know what iptables is the best way to start is to do some reading:
Wikipedia about iptables
Home of iptables/netfilter
In its most basic form iptables has three (3) built in tables. These tables are INPUT, OUTPUT and FORWARD
INPUT: Packets that are destined to a interface and/or address of your host
OUTPUT: Packets that origin from a interface and/or address of your host
FORWARD: Packets that pass through your hosts interfaces and/or addresses
To set up a linux router/firewall/NAT box you need a computer with at least two network interfaces. One interface for the internal network and one for the external network (usually the internet). You also need to install linux on that computer
There are many networking features besides firewall and NAT in Linux. There are things like TC. With the tc command your can configure the packet queuing mechanism of your network interfaces. The default mechanism is FIFO which stands for FirstInFirstOut. I recommend that you change the queuing mechanism of your external network interface from FIFO to SFQ.
Stochastic Fairness Queueing reorders queued traffic so each ’session’ gets to send a packet in turn.
You can enable SFQ by entering the following into a terminal as root: tc qdisc add dev <your external NIC here> root sfq perturb 10
You can put the example above into your /etc/rc.local or some other start up file in order for it to be run at each boot.
Now you just need a small shell script which configures iptables for you. It is a good idea to execute this script on boot via the init procedure of your Linux distribution.
I hope that the script is somewhat self explaining. If you have questions about it please feel free to comment this post.
#!/bin/bash #Setting up some Variables ##################################################### EXTIP="<your external ip goes here>" # Example 1.2.3.4 INTNET="<your internal network goes here>" # Example 192.168.1.0/24 EXTIF="<your external NIC>" # Example eth0 INTIF="<your internal NIX>" # Example eth1 #Disabling ipforwarding aka routing ############################################ echo 0 > /proc/sys/net/ipv4/ip_forward #Flushing tables and setting policys ########################################### iptables -F iptables -t nat -F PREROUTING iptables -t nat -F POSTROUTING iptables -t mangle -F iptables -P FORWARD DROP iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -A OUTPUT -o lo -j ACCEPT iptables -A INPUT -i lo -j ACCEPT # INPUT from local network ##################################################### iptables -A INPUT -i $INTIF -s $INTNET -j ACCEPT iptables -A INPUT -i $INTIF -p udp --dport 67 --sport 68 -j ACCEPT # Dropping private addresses on the external interface ######################## iptables -A INPUT -i $EXTIF -s 10.0.0.0/8 -j DROP iptables -A INPUT -i $EXTIF -s 172.16.0.0/12 -j DROP iptables -A INPUT -i $EXTIF -s 192.168.0.0/16 -j DROP iptables -A INPUT -i $EXTIF -s 169.254.0.0/16 -j DROP iptables -A INPUT -i ! lo -s 127.0.0.0/8 -j DROP # INPUT from external networks ################################################# # The example below allows traffic to a webserver that runs on your NAT box # iptables -A INPUT -d $EXTIP -p tcp --dport 80 --sport 1024:65535 -j ACCEPT # ICMP from external networks ################################################## iptables -A INPUT -i $EXTIF -d $EXTIP -p icmp --icmp-type \ destination-unreachable -j ACCEPT iptables -A INPUT -i $EXTIF -d $EXTIP -p icmp --icmp-type \ source-quench -j ACCEPT iptables -A INPUT -i $EXTIF -d $EXTIP -p icmp --icmp-type \ time-exceeded -j ACCEPT iptables -A INPUT -i $EXTIF -d $EXTIP -p icmp --icmp-type \ parameter-problem -j ACCEPT iptables -A INPUT -i $EXTIF -d $EXTIP -p icmp --icmp-type \ echo-request -m limit --limit 2/second --limit-burst 5 -j ACCEPT # Allowing all traffic that is related to our traffic :) aka STATEFUL ########## iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # FORWARD between internal and external network ################################ iptables -A FORWARD -i $INTIF -o $EXTIF -s $INTNET -d ! $INTNET -j ACCEPT iptables -A FORWARD -i $EXTIF -s ! $INTNET -d $INTNET \ -m state --state RELATED,ESTABLISHED -j ACCEPT # MASQUERADING aka NAT ######################################################### iptables -t nat -A POSTROUTING -o $EXTIF -s $INTNET -d ! $INTNET -j MASQUERADE # Enabling stuff in /proc ###################################################### echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 1 > /proc/sys/net/ipv4/conf/$EXTIF/log_martians echo 0 > /proc/sys/net/ipv4/conf/$EXTIF/accept_redirects echo 0 > /proc/sys/net/ipv4/conf/$EXTIF/accept_source_route # Enabling anti Spoofing ####################################################### if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f done else echo echo "PROBLEMS SETTING UP IP SPOOFING PROTECTION. BE WORRIED." echo fi # Enabling ipforwarding aka routing ############################################ echo 1 > /proc/sys/net/ipv4/ip_forward # Linsing rules ################################################################ iptables -L -n -v iptables -t nat -L -n -v
Recent Comments