All pastes #3618 Raw Edit

Chaosite Firewall Script

public text v1 · immutable
#3618 ·published 2004-12-31 09:00 UTC
rendered paste body
#!/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