#!/bin/sh
#
# This will be universal firewalling script for Linux kernel (iptables) in near future
# Can be started by init or by hand.
#
# Developed by Lubomir Host 'rajo' <rajo AT platon.sk>
# Copyright (c) 2003-2005 Platon SDG, http://platon.sk/
# Licensed under terms of GNU General Public License.
# All rights reserved.
#
# $Platon: scripts/shell/firewall/fw-universal.sh,v 2.30 2005/11/01 00:36:24 rajo Exp $
#
# Changelog:
# 2003-10-24 - created
#
DESC="firewall"
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DEFAULT_FIREWALL_CONFIG="${DEFAULT_FIREWALL_CONFIG:=/etc/default/firewall}"
DEFAULT_CACHE_DIR="${DEFAULT_CACHE_DIR:=/var/cache/firewall}"
if [ -f "$DEFAULT_FIREWALL_CONFIG" ]; then
echo "Reading config file $DEFAULT_FIREWALL_CONFIG"
. $DEFAULT_FIREWALL_CONFIG
fi
#
# Default configuration values:
#
DEFAULT_POLICY="${DEFAULT_POLICY:=DROP}"
# which modules to load
MODULES="${MODULES:=}"
MODULES_LOADING="${MODULES_LOADING:=yes}"
MODULES_REMOVING="${MODULES_REMOVING:=no}"
LOG_LIMIT="${LOG_LIMIT:=-m limit --limit 12/h --limit-burst 10 -j LOG --log-level notice --log-prefix}"
# Paths:
#IPTABLES=":" # for testing only - does nothing
IPTABLES="${IPTABLES:=$DEBUG/sbin/iptables}"
IPTABLES_SAVE="${IPTABLES_SAVE:=$DEBUG/sbin/iptables-save}"
IPTABLES_RESTORE="${IPTABLES_RESTORE:=$DEBUG/sbin/iptables-restore}"
if [ "x$LOGGING" = "xoff" ]; then
IPTABLES_LOG=": log turned off"
else
IPTABLES_LOG="${IPTABLES_LOG:=$DEBUG/sbin/iptables}"
fi
IFCONFIG="${IFCONFIG:=/sbin/ifconfig}"
DEPMOD="${DEPMOD:=/sbin/depmod}"
MODPROBE="${MODPROBE:=/sbin/modprobe}"
RMMOD="${RMMOD:=/sbin/rmmod}"
AWK="${AWK:=/usr/bin/awk}"
# loopback interface
LO_IFACE="${LO_IFACE:=lo}"
#
# CONSTANTS - Do not edit
#
ANYWHERE="0.0.0.0/0" # Match any IP address
BROADCAST_SRC="0.0.0.0" # Broadcast Source Address
BROADCAST_DEST="255.255.255.255" # Broadcast Destination Address
CLASS_A="10.0.0.0/8" # Class-A Private (RFC-1918) Networks
CLASS_B="172.16.0.0/12" # Class-B Private (RFC-1918) Networks
CLASS_C="192.168.0.0/16" # Class-C Private (RFC-1918) Networks
CLASS_D_MULTICAST="224.0.0.0/4" # Class-D Multicast Addresses
CLASS_E_RESERVED_NET="240.0.0.0/5" # Class-E Reserved Addresses
PRIVPORTS="0:1023" # Well-Known, Privileged Port Range
UNPRIVPORTS="1024:65535" # Unprivileged Port Range
TRACEROUTE_SRC_PORTS="32769:65535" # Traceroute Source Ports
TRACEROUTE_DEST_PORTS="33434:33523" # Traceroute Destination Ports
# allow some ICMP packets - needed for ping etc.
ACCEPT_ICMP_PACKETS="${ACCEPT_ICMP_PACKETS:=echo-reply destination-unreachable echo-request time-exceeded}"
# load necessary modules from $MODULES variable
load_modules()
{ # {{{
if [ "e$MODULES_LOADING" = "eyes" ]; then
echo "# Loading modules"
for mod in $MODULES; do
echo " $MODPROBE $mod"
$MODPROBE $mod
done
fi
} # }}}
load_cache()
{ # {{{
if [ ! -d "$DEFAULT_CACHE_DIR" ]; then
mkdir -p "$DEFAULT_CACHE_DIR";
fi
config=`cat $DEFAULT_FIREWALL_CONFIG`;
md5key=`echo "config = '$config' parsed_interfaces ='$parsed_interfaces' parsed_routes='$parsed_routes'" | md5sum | awk '{ print $1; }'`;
CACHE_FILE="$DEFAULT_CACHE_DIR/$md5key"
#echo "CACHE_FILE=$CACHE_FILE"
if [ -f "$CACHE_FILE" ]; then
echo "Loading rules from cache file $CACHE_FILE"
$IPTABLES_RESTORE -c < $CACHE_FILE;
forward_on # this has nothing to do with IPtables rules, we need to run them explicitly
exit 0;
fi
} # }}}
# unload necessary modules from $MODULES variable
unload_modules()
{ # {{{
# reverse modules
if [ "e$MODULES_REMOVING" = "eyes" ]; then
echo "# Removing modules"
R_MODULES=`echo "$MODULES" | tr ' ' '\012' | tac | tr '\012' ' '`
for mod in $R_MODULES; do
echo " $RMMOD $mod"
$RMMOD $mod
done
fi
} # }}}
# print status of detected interfaces
print_iface_status()
{ # {{{
# Print interfaces:
echo "# iface | IP addr | Gateway | broadcast | netmask | HW addr"
for iface in $interfaces; do
IP="IP_$iface"; Gateway="Gateway_$iface"; Bcast="Bcast_$iface"; Mask="Mask_$iface"; HWaddr="HWaddr_$iface";
echo "$iface | ${!IP} | ${!Gateway} | ${!Bcast} | ${!Mask} | ${!HWaddr}"
done
} # }}}
# set default policy (variable $DEFAULT_POLICY)
set_default_policy()
{ # {{{
# Set default policy
for chain in INPUT OUTPUT FORWARD; do
$IPTABLES -P $chain $DEFAULT_POLICY
done
} # }}}
antispoof_on()
{ # {{{
for interface in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo "1" > ${interface}
done
} # }}}
# Turn on IP packets forwarding
forward_on()
{ # {{{
# NAT requires turn on IP forwarding
if [ ! -z "$NAT_LAN_IFACE" ]; then
echo -en "NAT: Enabling packet forwarding..."
echo 1 > /proc/sys/net/ipv4/ip_forward
echo " done."
fi
} # }}}
forward_off()
{ # {{{
echo -en "NAT: Disabling packet forwarding..."
echo 0 > /proc/sys/net/ipv4/ip_forward
echo " done."
} # }}}
# clear status of iptable chains
remove_chains()
{ # {{{
for table in filter nat mangle; do
$IPTABLES -t $table -F # clear all chains
$IPTABLES -t $table -X # remove all chains
$IPTABLES -t $table -Z # zero counts
done
} # }}}
# DROP packages from nmap(1)
nmap_scan_filter()
{ # {{{
echo -en "Turning on nmap scan filter "
for chain in INPUT FORWARD; do
# Nie je nastaveny ziaden bit
$IPTABLES_LOG -A $chain -p TCP --tcp-flags ALL NONE $LOG_LIMIT "nmap scan $chain ALL NONE: "
echo -en "."
$IPTABLES -A $chain -p TCP --tcp-flags ALL NONE -j DROP
echo -en "."
# dva odporujuuce si flagy su nastavene:
for flags in SYN,FIN SYN,RST FIN,RST ; do
$IPTABLES_LOG -A $chain -p TCP --tcp-flags $flags $flags $LOG_LIMIT "nmap scan $chain $flags: "
echo -en "."
$IPTABLES -A $chain -p TCP --tcp-flags $flags $flags -j DROP
echo -en "."
done
# je nastavene len $flags bez predpokladaneho ACK
for flags in FIN PSH URG ; do
$IPTABLES_LOG -A $chain -p TCP --tcp-flags ACK,$flags $flags $LOG_LIMIT "nmap scan $chain ACK,$flags: "
echo -en "."
$IPTABLES -A $chain -p TCP --tcp-flags ACK,$flags $flags -j DROP
echo -en "."
done
done
echo " done."
} # }}}
# drop packets in state INVALID
invalid_packet_filter()
{ # {{{
echo -en "Turning on INVALID packet filter "
for chain in INPUT OUTPUT FORWARD; do
$IPTABLES_LOG -A $chain -m state --state INVALID $LOG_LIMIT "INVALID $chain: "
echo -en "."
$IPTABLES -A $chain -m state --state INVALID -j DROP
echo -en "."
done
echo " done."
} # }}}
syn_flood()
{ # {{{
$IPTABLES -N syn-flood
$IPTABLES -A syn-flood -m limit --limit 1/s --limit-burst 4 -j RETURN
$IPTABLES -A syn-flood -j DROP
for iface in $INTERFACES; do
$IPTABLES -A INPUT -i $iface -p TCP --syn -j syn-flood
# packet is marked az NEW, but doesn't have SYN flag - drop it
$IPTABLES -A INPUT -i $iface -p TCP ! --syn -m state --state NEW -j DROP
done
} # }}}
anti_spoof_filter()
{ # {{{
# http://www.iana.com/assignments/ipv4-address-space
if [ ! -z "$ANTISPOOF_IFACE" ]; then
echo -en "Turning on antispoof filter for interfaces: "
$IPTABLES -N spoof
# Ochrana proti Spoogingu zo spatnej slucky
$IPTABLES_LOG -A spoof -s 127.0.0.0/8 $LOG_LIMIT "RESERVED:127.0.0.0/8 src"
$IPTABLES -A spoof -s 127.0.0.0/8 -j DROP
$IPTABLES_LOG -A spoof -d 127.0.0.0/8 $LOG_LIMIT "RESERVED:127.0.0.0/8 dest"
$IPTABLES -A spoof -d 127.0.0.0/8 -j DROP
# Ochrana proti Spoofingu Internetu z adries urcenych pre lokalne siete
$IPTABLES_LOG -A spoof -s 192.168.0.0/16 $LOG_LIMIT "RESERVED:192.168.0.0/16 src"
$IPTABLES -A spoof -s 192.168.0.0/16 -j DROP # RFC1918
$IPTABLES_LOG -A spoof -s 172.16.0.0/12 $LOG_LIMIT "RESERVED:172.16.0.0/12 src"
$IPTABLES -A spoof -s 172.16.0.0/12 -j DROP # RFC1918
$IPTABLES_LOG -A spoof -s 10.0.0.0/8 $LOG_LIMIT "RESERVED:10.0.0.0/8 src"
$IPTABLES -A spoof -s 10.0.0.0/8 -j DROP # RFC1918 len pre sietovy interface do Internetu, kedze 10.0.0.0 je adresa LAN
$IPTABLES_LOG -A spoof -s 96.0.0.0/4 $LOG_LIMIT "RESERVED:96.0.0.0/4 src"
$IPTABLES -A spoof -s 96.0.0.0/4 -j DROP # IANA
for iface in $ANTISPOOF_IFACE; do
echo -en " $iface"
$IPTABLES -A FORWARD -i $iface -j spoof
$IPTABLES -A INPUT -i $iface -j spoof
done
echo " done."
fi
} # }}}
mangle_prerouting()
{ # {{{
echo -en "Optimizing PREROUTING TOS: "
# TOS flagy slouzi k optimalizaci datovych cest. Pro ssh, ftp a telnet
# pozadujeme minimalni zpozdeni. Pro ftp-data zase maximalni propostnost
$IPTABLES -t mangle -A PREROUTING -p TCP --sport ssh -j TOS --set-tos Minimize-Delay
echo -en "."
$IPTABLES -t mangle -A PREROUTING -p TCP --dport ssh -j TOS --set-tos Minimize-Delay
echo -en "."
$IPTABLES -t mangle -A PREROUTING -p TCP --sport ftp -j TOS --set-tos Minimize-Delay
echo -en "."
$IPTABLES -t mangle -A PREROUTING -p TCP --dport ftp -j TOS --set-tos Minimize-Delay
echo -en "."
$IPTABLES -t mangle -A PREROUTING -p TCP --dport telnet -j TOS --set-tos Minimize-Delay
echo -en "."
$IPTABLES -t mangle -A PREROUTING -p TCP --sport ftp-data -j TOS --set-tos Maximize-Throughput
echo -en "."
echo " done."
} # }}}
mangle_output()
{ # {{{
echo -en "Optimizing OUTPUT TOS:"
# TOS flagy slouzi k optimalizaci datovych cest. Pro ssh, ftp a telnet
# pozadujeme minimalni zpozdeni. Pro ftp-data zase maximalni propostnost
for iface in $INTERFACES; do
echo -en " $iface";
$IPTABLES -t mangle -A OUTPUT -o $iface -p TCP --sport ssh -j TOS --set-tos Minimize-Delay
$IPTABLES -t mangle -A OUTPUT -o $iface -p TCP --dport ssh -j TOS --set-tos Minimize-Delay
$IPTABLES -t mangle -A OUTPUT -o $iface -p TCP --sport ftp -j TOS --set-tos Minimize-Delay
$IPTABLES -t mangle -A OUTPUT -o $iface -p TCP --dport ftp -j TOS --set-tos Minimize-Delay
$IPTABLES -t mangle -A OUTPUT -o $iface -p TCP --dport telnet -j TOS --set-tos Minimize-Delay
$IPTABLES -t mangle -A OUTPUT -o $iface -p TCP --sport ftp-data -j TOS --set-tos Maximize-Throughput
done
echo " done."
} # }}}
# Masquerade local subnet
masquerade()
{ # {{{
if [ ! -z "$NAT_LAN_IFACE" ]; then
echo -en "NAT: Enabling packet forwarding..."
echo 1 > /proc/sys/net/ipv4/ip_forward
echo " done."
echo -en "NAT: Masquerading local subnet: $NAT_SUBNET_IFACE --> $NAT_LAN_IFACE"
ip="IP_$NAT_SUBNET_IFACE";
netmask="Mask_$NAT_SUBNET_IFACE"
localnet="${!ip}/${!netmask}"
lan_ip="IP_$NAT_LAN_IFACE"
# alow packets from private subnet
$IPTABLES -A FORWARD -s ! $localnet -i $NAT_SUBNET_IFACE -j DROP
for client_ip in $NAT_CLIENT_DROP; do
echo -en " !$client_ip";
$IPTABLES -A FORWARD -s $client_ip -i $NAT_SUBNET_IFACE -j DROP
done
for redirect in $NAT_TCP_PORT_REDIRECT; do
eval `echo $redirect | awk -v FS=: '{ printf "remote_port=%s; local_port=%s;", $1, $2; }'`
echo -en " $remote_port:$local_port"
$IPTABLES -t nat -A PREROUTING -p TCP \
-i ! $NAT_LAN_IFACE -d ! ${!lan_ip} \
--dport $remote_port -j REDIRECT --to-port $local_port
done
#$IPTABLES -t nat -A POSTROUTING -s $localnet -o $NAT_LAN_IFACE -j MASQUERADE
$IPTABLES -t nat -A POSTROUTING -o $NAT_LAN_IFACE -j MASQUERADE
echo " done."
# don't forward Miscrosoft protocols - NOT RFC compliant packets
if [ ! -z "$NAT_FORWARD_MICROSOFT" ]; then
if [ "x$NAT_FORWARD_MICROSOFT" = "xno" ]; then
$IPTABLES -A FORWARD -p TCP ! --syn -m state --state NEW -j DROP
for port in 69 135 445 1434 6667; do
$IPTABLES -A FORWARD -p TCP --dport $port -j DROP
$IPTABLES -A FORWARD -p UDP --dport $port -j DROP
done
fi
fi
if [ ! -z "$NAT_FORWARD_TCP_PORTS" ]; then
echo -en "\tAccepting FORWARD TCP ports:"
for port in $NAT_FORWARD_TCP_PORTS; do
echo -en " $port"
$IPTABLES -A FORWARD -p TCP --dport $port -m state --state NEW -j ACCEPT
done
echo " done."
fi
if [ ! -z "$NAT_FORWARD_UDP_PORTS" ]; then
echo -en "\tAccepting FORWARD UDP ports:"
for port in $NAT_FORWARD_UDP_PORTS; do
echo -en " $port"
$IPTABLES -A FORWARD -p UDP --dport $port -m state --state NEW -j ACCEPT
done
echo " done."
fi
echo -en "\tAccepting ICMP packets:"
for type in $ACCEPT_ICMP_PACKETS; do
echo -en " $type"
$IPTABLES -A FORWARD -p ICMP --icmp-type $type -j ACCEPT
done
#$IPTABLES_LOG -A FORWARD -p ICMP -j LOG --log-prefix "FWD ICMP: "
echo " done."
# Port forwarding to local machines
if [ ! -z "$NAT_TCP_PORT_FORWARD" ]; then
echo -en "\tForwarding ports to local machines:"
for redirect in $NAT_TCP_PORT_FORWARD; do
eval `echo $redirect | awk -v FS=: '{ printf "src_port=%s; local_machine=%s; dest_port=%s;", $1, $2, $3; }'`
echo -en " $src_port -> $local_machine:$dest_port"
$IPTABLES -t nat -A PREROUTING -p TCP -i $NAT_LAN_IFACE -d ${!lan_ip} \
--dport $src_port -j DNAT --to $local_machine:$dest_port
$IPTABLES -A FORWARD -p TCP -i eth0 -d $local_machine --dport $dest_port -j ACCEPT
done
echo " done."
fi
# Keep state of connections from private subnets
$IPTABLES -A OUTPUT -m state --state NEW -o $NAT_LAN_IFACE -j ACCEPT
#$IPTABLES -A FORWARD -m state --state NEW -o $NAT_LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
fi
} # }}}
log_new_connections()
{ # {{{
if [ ! -z "$NAT_LOG_NEW_CONNECTIONS" ]; then
if [ "x$NAT_LOG_NEW_CONNECTIONS" = "xyes" ]; then
if [ "x$NAT_LOG_NEW_CONNECTIONS" = "xyes" ]; then
NAT_LOG_NEW_CONNECTIONS="TCP UDP"
fi
echo -en "Logging new connections $NAT_LOG_NEW_CONNECTIONS:"
for proto in $NAT_LOG_NEW_CONNECTIONS; do
$IPTABLES_LOG -A INPUT -m state --state NEW -p $proto -j LOG --log-prefix "IN connection: "
$IPTABLES_LOG -A OUTPUT -m state --state NEW -p $proto -j LOG --log-prefix "OUT connection: "
$IPTABLES_LOG -A FORWARD -m state --state NEW -p $proto -j LOG --log-prefix "FWD connection: "
done
echo " done."
fi
fi
} # }}}
drop_output()
{ # {{{
for iface in $INTERFACES; do
ip="IP_$iface";
drop_output_tcp="${iface}_DROP_OUTPUT_TCP"
DROP_OUTPUT_TCP="${!drop_output_tcp}"
drop_output_udp="${iface}_DROP_OUTPUT_UDP"
DROP_OUTPUT_UDP="${!drop_output_udp}"
if [ ! -z "$DROP_OUTPUT_TCP" ]; then
echo -en "$iface: Dropping outgoing packets from ports:"
for port in $DROP_OUTPUT_TCP; do
echo -en " $port"
$IPTABLES -A FORWARD -p TCP --sport $port -o $iface -j DROP
$IPTABLES -A OUTPUT -p TCP --sport $port -o $iface -j DROP
done
echo " done."
fi
if [ ! -z "$DROP_OUTPUT_UDP" ]; then
echo -en "$iface: Dropping outgoing packets from ports:"
for port in $DROP_OUTPUT_UDP; do
echo -en " $port"
$IPTABLES -A FORWARD -p UDP --sport $port -o $iface -j DROP
$IPTABLES -A OUTPUT -p UDP --sport $port -o $iface -j DROP
done
echo " done."
fi
done
} # }}}
bann_ip_adresses()
{ # {{{
#
# This feature has been developed for following reason:
# UbiCrawler spam our website with many requests (they are duplicit requests of the same page!)
# And this web robot doesn't accept HTTP META tags (http://www.robotstxt.org/wc/faq.html#extension)
#
# Bann them too!
#
#IP address is: 146.48.97.11 146.48.97.13
# User Agent: "UbiCrawler/v0.4beta (http://ubi.iit.cnr.it/projects/ubicrawler/)"
#
if [ ! -z "$BANNED_IP" ]; then
echo -en "Dropping ALL packets from IP:"
for banned_ip in $BANNED_IP; do
echo -en " $banned_ip"
$IPTABLES -A INPUT -s $banned_ip -j DROP
$IPTABLES -A FORWARD -s $banned_ip -j DROP
done
echo " done."
fi
} # }}}
allow_accept_all()
{ # {{{
if [ ! -z "$IFACE_ACCEPT_ALL" ]; then
echo -en "Accepting ALL packets on interfaces:"
for iface in $IFACE_ACCEPT_ALL; do
echo -en " $iface"
$IPTABLES -A INPUT -i $iface -j ACCEPT
$IPTABLES -A FORWARD -i $iface -j ACCEPT
$IPTABLES -A OUTPUT -o $iface -j ACCEPT
done
echo " done."
fi
} # }}}
allow_input()
{ # {{{
if [ ! -z "$NAT_LAN_IFACE" ]; then
for client_ip in $NAT_CLIENT_DROP; do
echo -en " !$client_ip";
$IPTABLES -A INPUT -s $client_ip -i $NAT_SUBNET_IFACE -j DROP
done
fi
if [ ! -z "$ALL_ACCEPT_INPUT_TCP" ]; then
echo -en "Accepting ALL INPUT TCP connections on ports:"
for port in $ALL_ACCEPT_INPUT_TCP; do
for iface in $INTERFACES; do
ip="IP_$iface";
echo -en " $port($iface)"
$IPTABLES -A INPUT -i $iface -d ${!ip} -p TCP --dport $port -j ACCEPT
done
done
echo " done."
fi
if [ ! -z "$ALL_ACCEPT_INPUT_UDP" ]; then
echo -en "Accepting ALL INPUT UDP connections on ports:"
for port in $ALL_ACCEPT_INPUT_UDP; do
for iface in $INTERFACES; do
ip="IP_$iface";
echo -en " $port($iface)"
$IPTABLES -A INPUT -i $iface -p UDP --dport $port -j ACCEPT
done
done
echo " done."
fi
for iface in $INTERFACES; do
ip="IP_$iface";
accept_input_tcp="${iface}_ACCEPT_INPUT_TCP"
ACCEPT_INPUT_TCP="${!accept_input_tcp}"
accept_input_udp="${iface}_ACCEPT_INPUT_UDP"
ACCEPT_INPUT_UDP="${!accept_input_udp}"
if [ ! -z "$ACCEPT_INPUT_TCP" ]; then
echo -en "$iface: Accepting INPUT TCP connections on ports:"
for port in $ACCEPT_INPUT_TCP; do
echo -en " $port"
$IPTABLES -A INPUT -i $iface -d ${!ip} -p TCP --dport $port -j ACCEPT
done
echo " done."
fi
if [ ! -z "$ACCEPT_INPUT_UDP" ]; then
echo -en "$iface: Accepting INPUT UDP connections on ports:"
for port in $ACCEPT_INPUT_UDP; do
echo -en " $port"
#$IPTABLES -A INPUT -i $iface -d ${!INET_IP} -p UDP --dport $port -j ACCEPT
#$IPTABLES -A INPUT -i $iface --source 192.168.1.0/16 -p UDP --dport $port -j ACCEPT
$IPTABLES -A INPUT -i $iface -p UDP --dport $port -j ACCEPT
done
echo " done."
fi
done
# Enable outgoing TRACEROUTE requests (required e.g. by Skype, http://www.skype.com)
if [ ! -z "$TRACEROUTE_IFACE" ]; then
ip="IP_$ANTISPOOF_IFACE";
echo -en "Accepting traceroute:"
$IPTABLES -A OUTPUT -o $ANTISPOOF_IFACE -p UDP \
--sport $TRACEROUTE_SRC_PORTS --dport $TRACEROUTE_DEST_PORTS \
-s ${!ip} -d $ANYWHERE -j ACCEPT
for iface in $TRACEROUTE_IFACE; do
$IPTABLES -A FORWARD -p UDP -i $iface --sport $TRACEROUTE_SRC_PORTS \
--dport $TRACEROUTE_DEST_PORTS -j ACCEPT
done
echo " done."
fi
} # }}}
# ACCEPT all packets from our IP address
allow_output()
{ # {{{
# Povolíme odchozí pakety, které mají naše IP adresy
echo -en "Accepting OUTPUT packets from"
for iface in $INTERFACES; do
ip="IP_$iface";
echo -en " ${!ip}($iface)"
$IPTABLES -A OUTPUT -o $iface -s ${!ip} -j ACCEPT
done;
echo " done.";
} # }}}
allow_icmp()
{ # {{{
echo -en "Accepting ICMP packets:"
# Službu AUTH není dobré filtrovat pomocí DROP, protože to může
# vést k prodlevám při navazování některých spojení. Proto jej
# sice zamítneme, ale vygenerujeme korektní ICMP chybovou zprávu
$IPTABLES -A INPUT -p TCP --dport 113 -j REJECT --reject-with tcp-reset #AUTH server
# accept only allowed ICMP packets
for type in $ACCEPT_ICMP_PACKETS; do
echo -en " $type"
for iface in $INTERFACES; do
ip="IP_$iface";
$IPTABLES -A INPUT -i $iface -d ${!ip} -p ICMP --icmp-type $type -j ACCEPT
done
done
#$IPTABLES_LOG -A INPUT -p ICMP -j LOG --log-prefix "IN ICMP: "
#$IPTABLES_LOG -A OUTPUT -p ICMP -j LOG --log-prefix "OUT ICMP: "
echo " done."
} # }}}
log_input_drop()
{ # {{{
if [ ! "x$LOGGING" = "xoff" ]; then
prefix="input drop: "
echo "Input drop is logged with prefix '$prefix'"
$IPTABLES_LOG -A INPUT $LOG_LIMIT "$prefix"
fi
} # }}}
log_output_drop()
{ # {{{
if [ ! "x$LOGGING" = "xoff" ]; then
prefix="output drop: "
echo "Output drop is logged with prefix '$prefix'"
$IPTABLES_LOG -A OUTPUT $LOG_LIMIT "$prefix"
fi
} # }}}
log_forward_drop()
{ # {{{
if [ ! "x$LOGGING" = "xoff" ]; then
prefix="forward drop: "
echo "Forward drop is logged with prefix '$prefix'"
$IPTABLES_LOG -A FORWARD $LOG_LIMIT "$prefix"
fi
} # }}}
accept_related()
{ # {{{
echo -en "Accepting ESTABLISHED, RELATED packets for IP:"
for iface in $INTERFACES; do
ip="IP_$iface";
echo -en " ${!ip}($iface)"
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
done
echo " done."
} # }}}
accept_loopback()
{ # {{{
# Loopback není radno omezovat
echo -en "Accepting loopback:"
$IPTABLES -A INPUT -i $LO_IFACE -j ACCEPT
$IPTABLES -A OUTPUT -o $LO_IFACE -j ACCEPT
echo " done."
} # }}}
# Parse output from ifconfig: - tested on Linux and FreeBSD
# http://platon.sk/cvs/cvs.php/scripts/shell/firewall/ifconfig-parse.sh
parse_ifconfig()
{ # {{{
# Parse output from ifconfig:
parsed_interfaces=`$IFCONFIG | \
$AWK 'BEGIN { interfaces=""; }
/^[a-zA-Z0-9]+[ \t]+/ { # Linux
iface=$1;
interfaces = sprintf("%s %s", interfaces, iface);
printf "\nIFACE_%s=\"%s\"; export IFACE_%s;\n", iface, iface, iface;
printf "HWaddr_%s=\"%s\"; export HWaddr_%s;\n", iface, $5, iface;
}
/^[ \t]+inet addr:/ { # Linux
split($0, fields, "[ \t:]+");
printf "IP_%s=\"%s\"; export IP_%s;\n", iface, fields[4], iface;
printf "Bcast_%s=\"%s\"; export Bcast_%s;\n", iface, fields[6], iface;
printf "Mask_%s=\"%s\"; export Mask_%s;\n", iface, fields[8], iface;
}
/^[a-zA-Z0-9]+:/ { # FreeBSD
iface = $1;
sub(":", "", iface);
interfaces = sprintf("%s %s", interfaces, iface);
printf "\nIFACE_%s=\"%s\"; export IFACE_%s;\n", iface, iface, iface;
}
/^[ \t]+inet [0-9]+/ { # FreeBSD
printf "IP_%s=\"%s\"; export IP_%s;\n", iface, $2, iface;
printf "Bcast_%s=\"%s\"; export Bcast_%s;\n", iface, $6, iface;
printf "Mask_%s=\"%s\"; export Mask_%s;\n", iface, $4, iface;
}
/^[ \t]+ether/ { # FreeBSD
printf "HWaddr_%s=\"%s\"; export HWaddr_%s;\n", iface, $2, iface;
}
END { printf "\ninterfaces=\"%s\"; export interfaces;\n", interfaces; }
'`
eval "$parsed_interfaces";
parsed_routes=`perl -e '
$\ = "\n";
open(FILE, "/proc/net/route") or die "Can not open /proc/net/route: $!";
my @columns = split(/\s+/, <FILE>);
while (my $line = <FILE>) {
my $iface;
my @vals = split(/\s+/, $line);
foreach my $key (@columns) {
$iface->{$key} = shift @vals;
}
foreach my $key (qw( Gateway Destination )) {
print "${key}_$iface->{Iface}=",
qw("), hex2ip($iface->{$key}), qw("),
"; export ${key}_$iface->{Iface};";
}
foreach my $key (qw( Flags MTU Metric Window IRTT )) {
print "${key}_$iface->{Iface}=",
qw("), $iface->{$key}, qw("),
"; export ${key}_$iface->{Iface};";
}
}
close(FILE);
sub hex2ip
{ # {{{
my ($str) = @_;
my @block;
my $hex = uc($str);
while (length($hex)) {
my $x = ord(substr($hex, 0, 1));
my $y = ord(substr($hex, 1, 1));
$x = $x > 64 ? $x - 55 : $x - 48;
$y = $y > 64 ? $y - 55 : $y - 48;
push @block, 16 * $x + $y;
$hex = substr($hex, 2);
}
return join(".", reverse @block);
} # }}}
'`
eval "$parsed_routes";
# Now we have defined variables like this:
# IFACE_eth0 HWaddr_eth0 IP_eth0 Bcast_eth0 Mask_eth0
# IFACE_lo HWaddr_lo IP_lo Bcast_lo Mask_lo
# interfaces
} # }}}
parse_ifconfig
print_iface_status
#
# Split interfaces into 2 groups:
#
# $INTERFACES_ACCEPT_ALL - interfaces withouth restrictions
#
# $INTERFACES - all interfaces withouth loopback
# and devices without restrictions (e.g. tun0 tun1 tap0 ...)
#
# list of all interfaces is in $interfaces variable
#
INTERFACES=""
INTERFACES_ACCEPT_ALL=""
regexp='^\('`echo $IFACE_ACCEPT_ALL | sed 's/ /\\\|/g; s/+/.*/g;'`'\)$'
for iface in $interfaces; do
#if [ "o$iface" = "olo" ]; then continue; fi
echo $iface | grep -q -e "$regexp"
if [ $? = 0 ] || [ "o$iface" = "olo" ]; then # lo interface is always here
INTERFACES_ACCEPT_ALL="$INTERFACES_ACCEPT_ALL $iface";
else
INTERFACES="$INTERFACES $iface";
fi
done
INTERFACES_ACCEPT_ALL="$IFACE_ACCEPT_ALL"
case "$1" in
start)
echo -n "Starting $DESC: "
# Inicialize modules
#$DEPMOD -a
load_modules
load_cache
set_default_policy
remove_chains
#
# (un)commnet next lines as needed
#
bann_ip_adresses
allow_accept_all
nmap_scan_filter
invalid_packet_filter
anti_spoof_filter
syn_flood
mangle_prerouting
mangle_output
log_new_connections
drop_output
allow_input
allow_output
allow_icmp
accept_related
accept_loopback
masquerade
log_input_drop
log_output_drop
log_forward_drop
forward_on
$IPTABLES_SAVE -c > $CACHE_FILE
;;
stop)
echo -n "Stopping $DESC: "
set_default_policy
remove_chains
unload_modules
forward_off
accept_related
;;
really-off)
echo -n "Stopping $DESC: removing ALL rules, all packets are dropped !!"
set_default_policy
remove_chains
unload_modules
forward_off
;;
status)
print_iface_status; echo
$IPTABLES -L -nv
;;
purge)
find $DEFAULT_CACHE_DIR -type f -ls -exec rm -f {} \;
;;
*)
echo "Usage: $0 {start|stop|really-off|status|purge}" >&2
exit 1
;;
esac
exit 0
# vim600: fdm=marker fdl=0 fdc=3
Platon Group <platon@platon.org> http://platon.org/
|