#! /bin/sh # # firewall+masq TCP/IP firewalling + masquerading. # # Author: Peter Bieringer # # description: This script sets various firewall rules # # chkconfig: 345 12 89 # # processname: firewall+masq # Changes to # 19990205: ipchains/kernel 2.1+2.2 ready # Quick merge from my old DLD 5.4 compatible script # 1.00: initial merging # 1.01: option for selecting specific masquerading modules (not load all) # 1.02: some basic outgoing blocking (firewalling) to prevent dial-on-demand # 1.03: major incoming blocking (firewalling) # 1.04: add new FW rule for time-exceeded (used by traceroute) # 1.05: add new FW and options to allow IDENT (auth) connections # 1.06: add new FW rule against routed # 1.07: modify masq timeouts, add some logging toggles and an udp logger # 20000108: Review for RedHat 6.1, remove obsolete "ipfwadm" # 20000109: Add option "unsecure" # 20000205: Block broadcasts to dialup # 20000423: Fix ippp dialin # 20000702: Allow DHCP # 20000721: Allow tunneled IPv6 # 20000722: Allow ICMP echo reply out to IPv6 tunnel host # 20000816: Allow all on interface lo # 20000923: Block IGMP # 20001029: Change dialup interface, enable incoming RealAudio UDP # 20001031: Redesign to use with different dialup interfaces (ADSL+ISDN) # 20001101: Hardening dedicated port filter rules, add some special ones # 20001104: Renaming user chains, adjust RTP/UDP, add sysctl, some switches # 20001108: Allow local ICMP #set -x # Source function library. . /etc/rc.d/init.d/functions # Get config. . /etc/sysconfig/network # Check that networking is up. if [ ${NETWORKING} = "no" ] then exit 0 fi IPFW=/sbin/ipchains [ -f $IPFW ] || exit 0 [ -f /sbin/insmod ] || exit 0 [ -f /sbin/rmmod ] || exit 0 [ -f /sbin/lsmod ] || exit 0 RETVAL=0 subsys_parameter=$1 LOCKDIR=/var/lock/subsys ALL="0.0.0.0/0" LocalNet="192.168.0.0/22" DialInNet="192.168.3.0/24" # Specify IPv4 masquerading modules (7 at the moment (2.2.1)) IPMASQALLMODULES="ip_masq*" # matches all modules for removing #IPMASQMODULES="ip_masq*" # all existing modules IPMASQMODULES="ip_masq_ftp ip_masq_raudio" # only selected ones # Firewalling? #FW_OUTGOING=no FW_OUTGOING=yes #FW_INTERFACES="ippp+" #FW_INTERFACES="ppp+" FW_INTERFACES="ppp+ ippp+" # Given IPv4 addresses for pppoe startup configuration FW_PPPoEINITIAL="yes" FW_PPPoELOCALINITAL="10.112.112.112" # Allow incoming IPv6 packets through an IPv6-in-IPv4 tunnel FW_ALLOWTUNNELEDIPV6=yes IPv4_TUNNELIP=195.226.187.50 FW_LOGDEFAULTINCOMINGDENY="yes" #FW_LOGDEFAULTINCOMINGDENY="no" # Allow incoming Real Audio (UDP 6970-6999) FW_ENABLE_REALAUDIO="yes" # Enable active FTP (not recommended, because all local binded daemons, such # as 0.0.0.0:port are reachable from outside using source port 20) FW_ENABLE_ACTIVE_FTP="no" # If active FTP is enabled, you should block several ports # Fill here in all listening ports >1023 you found with # netstat -lnp --ip | grep ^tcp |awk '{ print $4 "\t" $6 }' | grep ^0.0.0.0 # 3128 8080 8081 8082: squid, junkbuster # 6105 6106 20011: isdninfo FW_INCOMING_PORTBLOCK="3128 8080 8081 8082 6105 6106 20011" ######-------nothing to be changed here-------- # Test if masquerading is enabled in kernel if ! [ -f /proc/net/ip_masq -o -f /proc/net/ip_masquerade ]; then echo -e "\a Error: Kernel doesn't support masquerading!" echo " You have to compile a new one, don't forget to enable this feature." exit $STARTUP_FAIL fi #Get Kernel Version for module loading VERSION=`cat /proc/version | awk '{ print $3 }' ` ## Switch on forwarding in the kernel (Name of the file is different between 2.0.x and 2.1.x) PROC_IPFORWARD="`ls /proc/sys/net/ipv4/ip_forward* 2>/dev/null`" # Following switches on forwarding for all devices, perhaps against security... # if [ -f /proc/sys/net/ipv4/conf/all/forwarding ]; then # # for kernel 2.1.90+ # for i in /proc/sys/net/ipv4/conf/*/forwarding; do # if ! [ "`cat $i`" = "1" ]; then # device=`echo $i | cut -d / -f 7` # echo " Switch on IPv4 forwarding for device '$device' in the kernel" # echo "1" > $i # fi # done # fi showinfo() { ipchains -n -L -v } fwrules_insert() { echo " Switch on IP forwarding" echo "1" >$PROC_IPFORWARD # Forward policy: REJECT ipchains -P forward REJECT # Input policy: REJECT ipchains -P output REJECT # Input policy: DENY ipchains -P input DENY # Create new chains for Internet connection ipchains -N extOUT ipchains -N extIN echo " Bypass local dialin addresses" ipchains -A input -s $DialInNet -j ACCEPT ipchains -A output -d $DialInNet -j ACCEPT ipchains -A forward -d $DialInNet -j ACCEPT if [ "$FW_PPPoEINITIAL" = "yes" ]; then echo " Bypass PPPoE local interface IP (for startup issues)" ipchains -A extOUT -s $FW_PPPoELOCALINITAL -j ACCEPT fi # Put all traffic relating Internet connections into that interfaces echo -n " Add defined interfaces to Internet chains: " for iface in $FW_INTERFACES; do echo -n "$iface " ipchains -A input -i $iface -j extIN ipchains -A output -i $iface -j extOUT ipchains -A forward -j MASQ -p all -s $LocalNet -i $iface done echo # Masquerading parameters ipchains -M -S 7200 120 180 echo " Allow local addresses" ipchains -A input -s $LocalNet -j ACCEPT ipchains -A output -d $LocalNet -j ACCEPT ipchains -A forward -d $LocalNet -j ACCEPT ipchains -A input -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT ipchains -A output -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT ipchains -A input -i lo -j ACCEPT ipchains -A output -i lo -j ACCEPT echo " FW rule to prevent outgoing and incoming RfC 1822 addresses" ipchains -A extOUT -s 10.0.0.0/8 -j REJECT -l ipchains -A extOUT -s 172.16.0.0/12 -j REJECT -l ipchains -A extOUT -s 192.168.0.0/16 -j REJECT -l ipchains -A extIN -d 10.0.0.0/8 -j DENY -l ipchains -A extIN -d 172.16.0.0/12 -j DENY -l ipchains -A extIN -d 192.168.0.0/16 -j DENY -l if [ "$FW_OUTGOING" = "yes" ]; then echo " FW rules to prevent netbios dial-on-demand (block all outgoing NetBIOS traffic)" ipchains -A extOUT -p tcp --dport 135 -j REJECT ipchains -A extOUT -p udp --dport 135 -j REJECT ipchains -A extOUT -p tcp --dport netbios-ns -j REJECT ipchains -A extOUT -p udp --dport netbios-ns -j REJECT ipchains -A extOUT -p tcp --dport netbios-dgm -j REJECT ipchains -A extOUT -p udp --dport netbios-dgm -j REJECT ipchains -A extOUT -p tcp --dport netbios-ssn -j REJECT ipchains -A extOUT -p udp --dport netbios-ssn -j REJECT ipchains -A extOUT -p tcp --dport 445 -j REJECT ipchains -A extOUT -p udp --dport 445 -j REJECT echo " FW rules to prevent broadcast/anycast dialouts" ipchains -A extOUT -d 0.0.0.0/255.255.255.255 -j REJECT ipchains -A extOUT -d 0.0.0.255/0.0.0.255 -j REJECT ipchains -A extOUT -d 0.0.255.255/0.0.255.255 -j REJECT ipchains -A extOUT -d 0.255.255.255/0.255.255.255 -j REJECT echo " FW rules to prevent routed" ipchains -A extOUT -p udp --sport router -j REJECT fi echo " FW rules to block incoming (unwanted) NetBIOS traffic" ipchains -A extIN -p tcp --dport 135 -j DENY -l ipchains -A extIN -p udp --dport 135 -j DENY -l ipchains -A extIN -p tcp --dport netbios-ns -j DENY -l ipchains -A extIN -p udp --dport netbios-ns -j DENY -l ipchains -A extIN -p tcp --dport netbios-dgm -j DENY -l ipchains -A extIN -p udp --dport netbios-dgm -j DENY -l ipchains -A extIN -p tcp --dport netbios-ssn -j DENY -l ipchains -A extIN -p udp --dport netbios-ssn -j DENY -l ipchains -A extIN -p tcp --dport 445 -j DENY -l ipchains -A extIN -p udp --dport 445 -j DENY -l # Reject incoming auth/ident (mostly from foreign FTP or SMTP servers) echo " FW rule to reject incoming TCP auth/ident requests" ipchains -A extIN -p tcp --dport auth -j REJECT if [ "$FW_ALLOWTUNNELEDIPV6" = "yes" ]; then # IPv6-in-IPv4 tunnel ipchains -A extIN -p ipv6 -s $IPv4_TUNNELIP -j ACCEPT ipchains -A extOUT -p ipv6 -d $IPv4_TUNNELIP -j ACCEPT # Ping (dynamic tunnel tester) ipchains -A extIN -p icmp -s $IPv4_TUNNELIP --icmp-type echo-request -j ACCEPT ipchains -A extOUT -p icmp -d $IPv4_TUNNELIP --icmp-type echo-reply -j ACCEPT fi # Block TCP ports for incoming connections (safety) if [ ! -z "$FW_INCOMING_PORTBLOCK" ]; then echo " FW rule to block listening TCP ports (because the later active FTP data connection rule is able to allow connections with source port 20)" for port in $FW_INCOMING_PORTBLOCK; do ipchains -A extIN -p tcp --dport $port -j DENY -l done fi if [ "$FW_ENABLE_ACTIVE_FTP" = "yes" ]; then echo " FW rule to allow active FTP data connections (SYN set)" ipchains -A extIN -p tcp --sport ftp-data --dport 1024: -j ACCEPT fi echo " FW rule to block listening UDP ports (because the later DNS rule is able to allow connections with source port 53)" # Fill here in all listening ports >1023 you found with # netstat -lnp --ip | grep ^udp |awk '{ print $4 "\t" $6} ' | grep ^0.0.0.0 | egrep -v "named|squid" # FYI: named & squid are binding on startup an UDP port >1023 for DNS lookups to the Internet - this ports should'nt be blocked!" # Nothing >1023 found on my system at the moment echo " FW rule to allow incoming UDP/DNS response" ipchains -A extIN -p udp --sport domain --dport 1024: -j ACCEPT if [ "$FW_ENABLE_REALAUDIO" = "yes" ]; then echo " FW rule to enable incoming RealAudio UDP" ipchains -A extIN -p udp --sport 1024: --dport 6970:6999 -j ACCEPT fi echo " FW rule to allow only a few outgoing ICMP packets" ipchains -A extOUT -p icmp --icmp-type echo-request -j ACCEPT ipchains -A extOUT -p icmp --icmp-type destination-unreachable -j ACCEPT ipchains -A extOUT -p icmp --icmp-type time-exceeded -j ACCEPT echo " FW rule to allow some incoming ICMP packets" #ipchains -A extIN -p icmp --icmp-type echo-request -j ACCEPT ipchains -A extIN -p icmp --icmp-type echo-reply -j ACCEPT ipchains -A extIN -p icmp --icmp-type destination-unreachable -j ACCEPT ipchains -A extIN -p icmp --icmp-type time-exceeded -j ACCEPT echo " FW rule for Cisco packages, but don't log" ipchains -A extIN -p 88 -j REJECT echo " FW rule to block IGMP" ipchains -A extIN -p igmp -j REJECT ipchains -A extOUT -p igmp -j REJECT echo " FW rule to allow incoming TCP response (SYN not set)" ipchains -A extIN -p tcp ! -y -j ACCEPT if [ "$FW_LOGDEFAULTINCOMINGDENY" = "yes" ]; then echo " FW default policies (DENY all incoming from the Internet and log)" ipchains -A extIN -j DENY -l else echo " FW default policies (DENY all incoming from the Internet)" ipchains -A extIN -j DENY fi echo " FW default policies (ACCEPT all outgoing TCP/UDP to the Internet)" ipchains -A extOUT -p tcp -j ACCEPT ipchains -A extOUT -p udp -j ACCEPT echo " FW default policies (REJECT the rest and log)" ipchains -A extOUT -j REJECT -l echo " FW default policies (log rules)" ipchains -A input -j DENY -l ipchains -A output -j REJECT -l ipchains -A forward -j REJECT -l } # Enable kernel security function proc_ipv4_dosecure () { echo " Set some /proc switches to enable security features provided by k ernel" sysctl -w net.ipv4.ip_always_defrag=1 sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1 sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 sysctl -w net.ipv4.conf.default.log_martians=1 sysctl -w net.ipv4.conf.all.log_martians=1 sysctl -w net.ipv4.conf.default.accept_source_route=0 sysctl -w net.ipv4.conf.all.accept_source_route=0 sysctl -w net.ipv4.conf.default.accept_redirects=0 sysctl -w net.ipv4.conf.all.accept_redirects=0 sysctl -w net.ipv4.conf.default.rp_filter=1 sysctl -w net.ipv4.conf.all.rp_filter=1 } # Disable kernel security function proc_ipv4_dounsecure () { echo " Set some /proc switches to DISABLE some security features provide d by kernel" sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=0 sysctl -w net.ipv4.conf.default.log_martians=0 sysctl -w net.ipv4.conf.all.log_martians=0 sysctl -w net.ipv4.conf.default.accept_redirects=1 sysctl -w net.ipv4.conf.all.accept_redirects=1 sysctl -w net.ipv4.conf.default.rp_filter=0 sysctl -w net.ipv4.conf.all.rp_filter=0 } fwrules_remove() { echo " Remove all FW rules" ipchains -F forward ipchains -F output ipchains -F input # Delete user chains ipchains -F extOUT ipchains -F extIN ipchains -X extOUT ipchains -X extIN echo " Switch off IP forwarding" echo "0" >$PROC_IPFORWARD } case "$1" in start) echo "Start firewalling..." if [ -f $LOCKDIR/firewall+masq ]; then echo -e "\a Alredy running, stop first!" fi echo " Load IP-Masquerading Modules:" cd /lib/modules/$VERSION/ipv4 for i in $IPMASQMODULES; do echo -n " $i: " insmod $i; done echo proc_ipv4_dosecure fwrules_insert touch $LOCKDIR/firewall+masq ;; stop) echo "Stop firewalling..." fwrules_remove # unload ip_masquerading modules echo -n " Unload IP-Masquerading Modules:" lsmod | grep ^$IPMASQALLMODULES | while read mname rest; do echo -n " $mname" rmmod $mname done echo rm -f $LOCKDIR/firewall+masq ;; unsecure) $0 stop echo "Reset default policies to ACCEPT" ipchains -P input ACCEPT ipchains -P forward ACCEPT ipchains -P output ACCEPT proc_ipv4_dounsecure ;; restart) $0 stop $0 start exit $? ;; status) showinfo exit $STARTUP_OK ;; *) echo "Usage: firewall {start|stop|restart|status|unsecure}" exit $STARTUP_FAIL ;; esac exit $STARTUP_OK