All graphics by The Gimp
Home IP Masq/NAT
Info & Apps
IPv6 @ aRDyNet Linux Links aRDy Music Eggdrop Scripts Whoami

IPTABLES NAT/Port Forwarding/Firewall

IPTABLES NAT/Port Forwarding/Firewall

[NAT/Masquerade] [Port Forwarding] [Firewall] [Top]

Page last updated on July 30, 2011, 03:29:48 PM


Simple IPTABLES NAT (masquerade) commands

Under Linux kernel 2.4 and 2.6, packet mangling has considerably changed. This includes the masquerading, firewalling, and port forwarding features. This document assumes you're using modules, if you're not, disregard the code in the following script that tests for the loaded module. The following is a self contained script that enables and sets basic masquerading (assuming kernel kernel support already exists) at boot time. You may use this example, or modify existing init scripts to include the code.

#!/bin/sh

# YOU MUST SET THE FOLLOWING THREE VARIABLES

# Set the full path to iptables
PROG=/path/to/iptables

# Set network interface to masquerade on. This will be the interface
# thats connected to the Internet. Possibilities include ppp0, eth0,
# eth1, etc.
IFACE=eth0

# Set machine or network to masquerade. This can be set as hostname, IP address,
# or network mask, examples:
# Hostname     your_hostname
# IP address   192.168.1.2
# Net mask     192.168.1.0/24 This masquerades ALL machines on 192.168.1.x
INTNET=192.168.1.2

# Enable IP Masquerading in the kernel
echo 1 > /proc/sys/net/ipv4/ip_forward

# Test if iptable_nat module is loaded, its boot time, not likely :)
if [ -z "`lsmod|grep iptable_nat`" ];
  then
  modprobe iptable_nat
fi

# Test if existing MASQ rules exist, its boot time, not likely :)
if [ -z "`$PROG -L -t nat|grep MASQUERADE`" ];
  then
  $PROG -t nat -A POSTROUTING -o $IFACE -s $INTNET -j MASQUERADE
fi

[NAT/Masquerade] [Port Forwarding] [Firewall] [Top]


Simple IPTABLES port forwarding

I have the following set in the same script that I run the above masquerading commands from.

# This forwards port 8080 on the gateway to port 80 on the internal machine

iptables -t nat -A PREROUTING -p tcp --dport 8080 -i $IFACE -j DNAT --to-destination 192.168.1.2:80

[NAT/Masquerade] [Port Forwarding] [Firewall] [Top]


Simple IPTABLES firewall

The following is a very simple firewall constructed with basic iptables commands. It is meant to be a guideline only, since any firewall is specific to the services the host offers, and the services the administrator permits local users to use. NOTE: As is, the script only allows ident (port 113) requests, ftp only works in PASV mode from the client side, IRC DCC sends and chats initiated from behind the firewall are blocked, but incoming DCC requests work (hint: to DCC chat from behind this firewall, use /ctcp nick chat). ICQ is also broken in a few ways, although you can send messages.

This is a self contained script, and it assumes kernel support, and modules.

#!/bin/sh

# iptables firewall script written by Rick Dicaire

# Script version 0.8

# Released under GPL. Alter it as you see fit.

# CONFIGURE THE IPTABLES PATH AND INTERFACE VARIABLES BEFORE RUNNING THIS SCRIPT.
# SEE "START CONFIGURATION SECTION" BELOW.

######################### START FUNCTIONS ##############################
scripthelp () {
cat << SCRIPTHELP

IPTABLES FIREWALL SCRIPT HELP
-----------------------------

This script requires one of the following arguments:

start, restart, refresh, or stop

start
-----

Loads the firewall.

restart
-------

Loads the firewall if not loaded. If one is already running, it verifies
that the current IP matches the one used by the currently loaded
firewall. If the IPs do not match, it dumps the old rules, then reloads
the firewall using the new IP address. This argument is used if you want
to use this script in a cron job to test the firewall to make sure its 
using your current IP, and update the firewall if it isn't, great for 
dialups and other connection types that dynamically assign addresses.
crontab examples:

Every 15 minutes
*/15 * * * * /path/to/this/script restart > /dev/null 2>&1

Every 5 minutes
*/5 * * * * /path/to/this/script restart > /dev/null 2>&1

refresh
-------

Dumps current rules and reloads them.

stop
----

Dumps current rules and halts firewall.
---------------------------------------------------------

Usage: $0 [start|restart|refresh|stop]

SCRIPTHELP
}

fireme () {
if [ -z "`lsmod|grep iptable_filter`" ];
then
modprobe iptable_filter
fi

########################################################
#---------- Start predefined target rulesets ----------#
########################################################

# On the fly
$PROG -N ONTHEFLY
$PROG -A ONTHEFLY -j LOG --log-level 5 --log-prefix "TL0G_ONTHEFLY: "
$PROG -A ONTHEFLY -j DROP

# DENIED PORTS Privileged (1-1023) Target Ruleset
$PROG -N DENIED_PORT_PRIV
$PROG -A DENIED_PORT_PRIV -m state --state RELATED,ESTABLISHED -j ACCEPT
$PROG -A DENIED_PORT_PRIV -j LOG --log-level 5 --log-prefix "TL0G_DENIED_PORT_PRIV: "
$PROG -A DENIED_PORT_PRIV -j DROP

# DENIED PORTS Unprivileged TCP (1024+) Target Ruleset
$PROG -N DENIED_PORT_UNPRIV_TCP
$PROG -A DENIED_PORT_UNPRIV_TCP -m state --state RELATED,ESTABLISHED -j ACCEPT
$PROG -A DENIED_PORT_UNPRIV_TCP -j LOG --log-level 5 --log-prefix "TL0G_DENIED_PORT_T-UNPRIV: "
$PROG -A DENIED_PORT_UNPRIV_TCP -m state --state NEW,INVALID -j DROP

# DENIED PORTS Unprivileged UDP (1024+) Target Ruleset
$PROG -N DENIED_PORT_UNPRIV_UDP
$PROG -A DENIED_PORT_UNPRIV_UDP -m state --state RELATED,ESTABLISHED -j ACCEPT
$PROG -A DENIED_PORT_UNPRIV_UDP -j LOG --log-level 5 --log-prefix "TL0G_DENIED_PORT_U-UNPRIV: "
$PROG -A DENIED_PORT_UNPRIV_UDP -j DROP

######################################################
#---------- End predefined target rulesets ----------#
######################################################

######################################################
# Services

# The default for this script allows only ident
# tcp port 113, aka identd

######################################################
######### start permitted services incoming ##########
######################################################

# To open additional ports, you can put ACCEPT rules
# in this section, example to allow port 80 if you
# run a webserver:

#$PROG -A INPUT -p tcp --dport 80 -s 0/0 -d $IP -i $IFACE -j ACCEPT

######################################################
########## end permitted services incoming ###########
######################################################

$PROG -A INPUT -p tcp --dport 0:112 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_PRIV
$PROG -A INPUT -p udp --dport 0:112 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_PRIV

$PROG -A INPUT -p tcp --dport 114:1023 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_PRIV
$PROG -A INPUT -p udp --dport 114:1023 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_PRIV

# NFS
$PROG -A INPUT -p tcp --dport 2049 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_UNPRIV_TCP
$PROG -A INPUT -p udp --dport 2049 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_UNPRIV_UDP

# X11
$PROG -A INPUT -p tcp --dport 6000:6005 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_UNPRIV_TCP
$PROG -A INPUT -p udp --dport 6000:6005 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_UNPRIV_UDP

# Netbus
$PROG -A INPUT -p tcp --dport 12345:12346 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_UNPRIV_TCP
$PROG -A INPUT -p udp --dport 12345:12346 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_UNPRIV_UDP

# Deny all else on TCP unless initiated from local machine/network.
# This rule covers NFS, X11, and Netbus listed above, its a catch-all for any TCP
# ports you may have services running on, but don't know what ports they use.
# Prevents an accidental crack attempt via TCP services.
# If you wish to allow any services, or alter the existing rules, they must be
# added BEFORE the rule below.

$PROG -A INPUT -p tcp --dport 1024:65535 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_UNPRIV_TCP
$PROG -A INPUT -p udp --dport 1024:65535 -s 0/0 -d $IP -i $IFACE -j DENIED_PORT_UNPRIV_UDP

echo "OK"
echo "rc.firewall loaded with IP: $IP and interface: $IFACE."
}

########################### END FUNCTIONS ##########################

####################################################################
#----------------- START CONFIGURATION SECTION --------------------#
####################################################################
# Set path to iptables program

PROG=/path/to/iptables

# Set interface type, ie; eth0, ppp0

IFACE=""

####################################################################
#------------------ END CONFIGURATION SECTION ---------------------#
####################################################################

# Test to make sure configuration variables are set, die if not.

if [ ! -x "$PROG" ] || [ -z "$IFACE" ];
  then
  echo "$PROG is not executable, or interface is not set, exiting."
  exit 0
  else

# Get current IP address

IP=`ifconfig $IFACE| grep inet| cut -f2 -d:| cut -f1 -d" "`

# Get old IP from last firewall load (if any).
# The purpose of getting OLDIP is so you can use this script in a cron
# job to update the firewall with the current IP, great for dialups 
# and other dynamic connections.
# Examples:
# Check every 15 minutes:
# */15 * * * * /path/to/this/script restart > /dev/null 2>&1
# Check every 5 minutes:
# */5 * * * * /path/to/this/script restart > /dev/null 2>&1

OLDIP=`$PROG -n -L INPUT| grep 6005|grep udp| cut -b55-|cut -f1 -d u`

case $1 in

  start)
  if [ -z "$OLDIP" ];
    then
    echo -n "Starting firewall..."
    fireme
    elif [ $IP = $OLDIP ];
    then
    echo "FIREWALL IS UPDATED."
  fi
;;
  restart)
echo -n "Restarting firewall..."
if [ -z "`$PROG -n -L INPUT| grep 6005`" ]; 
  then 
  fireme
  elif [ $IP = $OLDIP ];
  then
  echo "FIREWALL IS UPDATED."
  else 

  $PROG -F INPUT
  $PROG -F FORWARD

  for i in DENIED_PORT_PRIV DENIED_PORT_UNPRIV_TCP DENIED_PORT_UNPRIV_UDP ONTHEFLY
  do 
  $PROG -F $i
  $PROG -X $i
  done
  fireme
fi
;;
  refresh)
echo -n "Resetting firewall..."
if [ -z "`$PROG -n -L INPUT| grep 6005`" ];
then
   fireme
   else

  $PROG -F INPUT
  $PROG -F FORWARD

  for i in DENIED_PORT_PRIV DENIED_PORT_UNPRIV_TCP DENIED_PORT_UNPRIV_UDP ONTHEFLY
  do
  $PROG -F $i
  $PROG -X $i
  done
  fireme
fi
;;
  stop)

  $PROG -F INPUT
  $PROG -F FORWARD

  for i in DENIED_PORT_PRIV DENIED_PORT_UNPRIV_TCP DENIED_PORT_UNPRIV_UDP ONTHEFLY
  do
  $PROG -F $i
  $PROG -X $i
  done
  echo "Firewall stopped...[OK]"
;;
  *)
  echo
  scripthelp
;;
esac
fi

Download this script

rc_firewall.iptables-0.8.tgz

Contrary to popular belief, if you filter out ICMP, this does not protect you from being flooded. The packets still arrive, the kernel just doesn't respond to them. If you're on a T3 or better you MAY have the bandwidth to sustain an ICMP flood or smurf, this is merely speculation though. Dialups can still be easily killed with ICMP filtering in place.

[NAT/Masquerade] [Port Forwarding] [Firewall] [Top]