Just starting to write an iptables script and would like someone to take a look at it and see if i'm on the right track. Maybe make some suggestions on how I could improve or add to the script.
The script is written for a static IP, and to allow all internal traffic to the internet. I have written some of it myself, and grab some snippets from samples on the internet.
#!/bin/bash
#
#==============================================================
# SECTION 1
# Set the ethernet cards to the network and internet sides
INET_IP="35.35.35.35"
INET_IFACE="eth0"
LAN_IP="192.168.0.1"
LAN_IFACE="eth1"
INTERNAL_ADDRESS_RANGE="192.168.0.0/24"
LAN_BCAST_ADDRESS="192.168.0.255"
LO_IP="127.0.0.1"
LO_IFACE="lo"
ifdown $INET_IFACE
ifdown $LAN_IFACE
ifconfig $INET_IFACE 0.0.0.0
ifconfig $LAN_IFACE 0.0.0.0
#===============================================================================
# SECTION 2
# Load the netfilter modules
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state
# Load Non-Required modules
/sbin/modprobe ipt_owner
/sbin/modprobe ipt_REJECT
/sbin/modprobe ipt_MASQUERADE
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_conntrack_irc
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ip_nat_irc
#=================================================================================
# SECTION 3
# Set iptables variable path
iptables=/sbin/iptables
# Allow internal machines to forward packets to the internet
echo "1" > /proc/sys/net/ipv4/ip_forward
# Prevent SYN floods from cosuming to much resources
echo "1" > /proc/sys/net/ipv4/tcp_syncookies
# Disable response to ping
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
# Disable response to broadcasts
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# Don't accept source routed packets
echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route
# Disable ICMP redirect acceptance
for interface in /proc/sys/net/ipv4/conf/*/accept_redirects; do
/bin/echo "0" > ${interface}
done
# Turn on reverse path filtering. This helps make sure that packets use
# legitimate source addresses
for interface in /proc/sys/net/ipv4/conf/*/rp_filter; do
/bin/echo "1" > ${interface}
done
# Log spoofed packets, source routed packets, redirect packets.
/bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
# Enable bad error message protection.
/bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
#================================================================================
# SECTION 4
# Flush all existing rule
$IPTABLES -F INPUT
$IPTABLES -F OUTPUT
$IPTABLES -F FORWARD
$IPTABLES -F -t nat
$IPTABLES -X
# Set the default policy for FORWARD, INPUT and OUTPUT rules to drop all packets
$IPTABLES -P FORWARD DROP
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
# Create separate chains for ICMP, TCP and UDP to traverse
# Sourced from internet sample script
$IPTABLES -N allowed
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets
# Create a chain for bad TCP packets
$IPTABLES -N bad_tcp_packets
#=========================================================================================
# SECTION 5
# First line to accept packets on the Internal network interface first ($LAN_IFACE)
# Second then forwards all packets from $LAN_IFACE (Internal Network) to $INET_IFACE (Internet)
# Third line then allows the ($INET_IFACE) to accept the packets to pass out into the internet
$IPTABLES -A INPUT -i $LAN_IFACE -s 0/0 -d 0/0 -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -o $INET_IFACE -j ACCEPT
$IPTABLES -A OUTPUT -o $INET_IFACE -s 0/0 -d 0/0 -j ACCEPT
# These 2 lines are to accept packets on the Internal network ($LAN_IFACE loopback)
# And also NAT loopback as well, may not be needed but wont hurt to have it
$IPTABLES -A INPUT -i lo -s 0/0 -d 0/0 -j ACCEPT
$IPTABLES -A OUTPUT -o lo -s 0/0 -d 0/0 -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i lo -j ACCEPT
$IPTABLES -t nat -A POSTROUTING -o lo -j ACCEPT
# First we need to allow the firewall to accept existing and related connections from the internet ($INET_IFACE)
# Then forward those connections to the Internal Network ($LAN_IFACE), so ($LAN_IFACE) can then allow packets to travel into
# the network to their destination
$IPTABLES -A INPUT -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $INET_IFACE -o $LAN_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -o $LAN_IFACE -j ACCEPT
# Enable SNAT on the Internet Interface ($INET_IFACE) this is used for Accounts that have a static IP
# All data from the Internal network ID will be give the static IP address as it passes through
# to the internet. 35.35.35.35 replace with your static IP address assigned by your ISP
$IPTABLES -A POSTROUTING -t nat -s 192.168.0.0/24 -o $INET_IFACE -j SNAT --to -source 35.35.35.35
# If you have a dynamic IP address (DHCP) assigned to you by your ISP, you will need to use
# Masquerade, just comment out the above SNAT line, an uncomment the MASQUERADE line
# below
# $IPTABLES -A POSTROUTING -t nat -s 192.168.0.0/24 -o $INET_IFACE -j MASQUERADE
#==================================================================================
# SECTION 6
# Need to block a specific internal IP address from accessing the internet
#$IPTABLES -A OUTPUT -o $INET_IFACE -s 192.168.1.10 -j DROP
# Need to block a specific port on an internal IP address
#$IPTABLES -A OUTPUT -o $INET_IFACE -s 192.168.1.10 --sport 80 --dport 80 -j DROP
# Need to block a specific IP address and log any attemps from accessing the firewall from the internet
#$IPTABLES -A INPUT -i $INET_IFACE -s 210.210.210.210 -m limit --limit 6/h --limit-burst 5 -j LOG --log-prefix "BLOCKED IP ALERT: "
#$IPTABLES -A INPUT -i $INET_IFACE -s 210.210.210.210 -j DROP
# To block a machine by its physical address (MAC) from accessing the internet
#$IPTABLES -A OUTPUT -o $INET_IFACE --mac-source 00:0B
B:45:56:42 -j DROP
# To allow only specified (MAC) addresses to pass through the firewall
# To use this feature, you will need to comment-out the default FORWARD rule (SECTION 5) allowing all internal network
# packets to pass from ($LAN_IFACE) to ($INET_IFACE), an then un-comment this line.
#$IPTABLES -A FORWARD -i $LAN_IFACE -o $INET_IFACE --mac-source 00:0B
B:45:56:42 -j ACCEPT
# Need to FORWARD packets to a specified IP address behind the firewall on the internal network
#$IPTABLES -A INPUT -p TCP -i $INET_IFACE -s 0/0 -d 192.168.0.10 -sport 80 -dport 80 -j ACCEPT
#$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -o $LAN_IFACE -s 0/0 -d 192.168.0.10 -sport 80 -dport 80 -j ACCEPT
#===================================================================================
# SECTION 7
# All below the hash line come from internet sample scripts
# Rules for incoming packets from anywhere.
$IPTABLES -A INPUT -p TCP -j tcp_packets
$IPTABLES -A INPUT -p UDP -j udp_packets
$IPTABLES -A INPUT -p ICMP -j icmp_packets
# allowed chain
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP
# bad_tcp_packets chain
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -m limit --limit 6/h --limit-burst 5 -j LOG --log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
# Do some checks for obviously spoofed IP's
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 192.168.0.0/24 -j DROP
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 10.0.0.0/8 -j DROP
$IPTABLES -A bad_tcp_packets -i $INET_IFACE -s 172.16.0.0/12 -j DROP
# Take care of bad TCP packets that we don't want.
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets
$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets
$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
#===================================================================================
# SECTION 8
# This section came from sample scripts on the internet
# Log weird packets that don't match any rules above.
$IPTABLES -A INPUT -m limit --limit 6/h --limit-burst 5 -j LOG --log-level DEBUG --log-prefix "IPT INPUT packet died: "
# Any udp not already allowed is logged and then dropped.
$IPTABLES -A INPUT -i $INET_IFACE -p udp -m limit --limit 6/h --limit-burst 5 -j LOG --log-prefix "IPTABLES UDP-IN: "
$IPTABLES -A INPUT -i $INET_IFACE -p udp -j DROP
# Any icmp not already allowed is logged and then dropped.
$IPTABLES -A INPUT -i $INET_IFACE -p icmp -m limit --limit 6/h --limit-burst 5 -j LOG --log-prefix "IPTABLES ICMP-IN: "
$IPTABLES -A INPUT -i $INET_IFACE -p icmp -j DROP
# Any tcp not already allowed is logged and then dropped.
$IPTABLES -A INPUT -i $INET_IFACE -p tcp -m limit --limit 6/h --limit-burst 5 -j LOG --log-prefix "IPTABLES TCP-IN: "
$IPTABLES -A INPUT -i $INET_IFACE -p tcp -j DROP
# Anything else not already allowed is logged and then dropped.
# It will be dropped by the default policy anyway ........ but let's be paranoid.
$IPTABLES -A INPUT -i $INET_IFACE -m limit --limit 6/h --limit-burst 5 -j LOG --log-prefix "IPTABLES PROTOCOL-X-IN: "
$IPTABLES -A INPUT -i $INET_IFACE -j DROP
###################################################################################