#!/bin/sh
#
# ********** VARIABLE DEFINITIONS **********
#
# External interface
EXTIF="eth1"
# Internal interface
INTIF="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
# 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="root"
# ********** 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
Secure_SMTP=465
# All services ports are read from /etc/services
TCPSERV="domain ssh ntp http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE $IRC $OpenPGP_HTTP_Keyserver $Secure_SMTP 5154 2401"
UDPSERV="domain time ntp 5154"
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 67 microsoft-ds"
EXTUDPDAEMONS=""
INTUDPDAEMONS="$EXTUDPDAEMONS 67 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 ""
echo "FW: Allowing broadcasts to go out on ntp & microsoft-ds ports "
$IPT -A OUTPUT -s $INTIP -d $INTBC -p udp --sport ntp -j ACCEPT
$IPT -A OUTPUT -o $INTIF -s $INTIP -d $INTBC -p udp --sport microsoft-ds -j ACCEPT
#
# 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