#! /bin/bash ## configure iptables version 1.1 ## (c) 2002, Luciano Rocha ## Licence: GPL v2, ## BUGS: # can't use hostnames in rules, they are created before DNS lookups are # allowed (if allowed at all) # extra configuration goes to this file. it will be sourced by this # executable so it should change the values of configuration variables EXTRACONFFILE="/etc/sysconfig/iptables" # general configuration # set this to something to see how iptables is called DEBUG="$1" # file to run after the ip tables have been set RUNAFTER="" # TRUSTED: what interfaces are trusted: all input from, output to and # forward from are allowed. format: TRUSTED="if0 if1 lo" TRUSTED="lo" # EXTERNAL: external interfaces, not to be trusted. format same as above EXTERNAL="eth0" # FORWARD: whether to forward or not. valid values are: # no: deny all packets # allowed: allow all packets # restricted: allow all packets from trusted interfaces and related FORWARD="no" # NAT: whether to do NAT of packets going through external interface # valid values are "yes" or "no" NAT="yes" # NATDEST: what to do with nated packets. # valid values are "MASQUERADE" or "SNAT --to-source some-source" NATDEST="MASQUERADE" # INPUT: whether to allow input packets or not. valid values are: # no: deny all packets # allowed: allow all packets # restricted: allow all related packets, all packets from trusted # interfaces, and all connections to specified allowed # ports or from specified hosts INPUT="restricted" # OUTPUT: same as above, but for output packets OUTPUT="restricted" # INPUT and OUTPUT rules # ALLOW_TCP_IN: specifies what new connections to this host are allowed # ALLOW_UDP_IN: specifies what input udp packets to this host are allowed # ALLOW_TCP_OUT: specifies what new connections to the outside are allowd # ALLOW_UDP_OUT: specifies what output udp packets to the outside are allowed # DENY_*_*: as above, but denies the packets # format: [host][:port] # host packets from/to this host # :port packets to this port (remote or local) # host:port packets from/to this host *and* to this port # - any packet ALLOW_TCP_IN=":ssh :imaps :pop3s :www :9999 :ftp :domain :smtp :https :500 192.168.1.2" ALLOW_TCP_OUT="-" ALLOW_UDP_IN=":67 :68 :53 :500 :161 :162": ALLOW_UDP_OUT=":53" DENY_TCP_IN=":auth" DENY_TCP_OUT="192.168.1.1:22" DENY_UDP_IN="" DENY_UDP_OUT="" # rate for some rules: new connections, udp packets, reject packets and # logging # rate must be of acceptable format to the "limit" module, like 10/second, # 3/hour, 2/minute, etc., or empty, in which case no limit will be applied LOG_RATE="5/minute" TCP_REJECT_RATE="20/minute" UDP_REJECT_RATE="20/minute" TCP_IN_RATE="16/second" UDP_IN_RATE="32/second" TCP_OUT_RATE="32/second" UDP_OUT_RATE="64/second" # path to binaries MD="/sbin/modprobe" IPT="/sbin/iptables" ######################################################################### [ "$EXTRACONFFILE" -a -f "$EXTRACONFFILE" ] && \ echo "loading configuration from $EXTRACONFFILE" && \ source "$EXTRACONFFILE" LR="${LOG_RATE:+"-m limit --limit $LOG_RATE"}" TRR="${TCP_REJECT_RATE:+"-m limit --limit $TCP_REJECT_RATE"}" URR="${UDP_REJECT_RATE:+"-m limit --limit $UDP_REJECT_RATE"}" TIR="${TCP_IN_RATE:+"-m limit --limit $TCP_IN_RATE"}" UIR="${UDP_IN_RATE:+"-m limit --limit $UDP_IN_RATE"}" TOR="${TCP_OUT_RATE:+"-m limit --limit $TCP_OUT_RATE"}" UOR="${UDP_OUT_RATE:+"-m limit --limit $UDP_OUT_RATE"}" ipt() { [ "$DEBUG" ] && echo "$IPT $*" $IPT "$@" } build_input() { ipt -F check_tcp_input &> /dev/null ipt -X check_tcp_input &> /dev/null ipt -N check_tcp_input for conf in $DENY_TCP_IN do CNF="" [ "$conf" != "-" ] && { HOST="$(echo $conf | cut -s -f1 -d:)" PORT="$(echo $conf | cut -s -f2 -d:)" [ ! "$HOST" -a ! "$PORT" ] && CNF="-s $conf" [ "$HOST" ] && CNF="-s $HOST" [ "$PORT" ] && CNF="$CNF --dport $PORT" } ipt -A check_tcp_input -p TCP $CNF -j RETURN done for conf in $ALLOW_TCP_IN do CNF="" [ "$conf" != "-" ] && { HOST="$(echo $conf | cut -s -f1 -d:)" PORT="$(echo $conf | cut -s -f2 -d:)" [ ! "$HOST" -a ! "$PORT" ] && CNF="-s $conf" [ "$HOST" ] && CNF="-s $HOST" [ "$PORT" ] && CNF="$CNF --dport $PORT" } ipt -A check_tcp_input -p TCP $CNF -j ACCEPT done ipt -F check_udp_input &> /dev/null ipt -X check_udp_input &> /dev/null ipt -N check_udp_input for conf in $DENY_UDP_IN do CNF="" [ "$conf" != "-" ] && { HOST="$(echo $conf | cut -s -f1 -d:)" PORT="$(echo $conf | cut -s -f2 -d:)" [ ! "$HOST" -a ! "$PORT" ] && CNF="-s $conf" [ "$HOST" ] && CNF="-s $HOST" [ "$PORT" ] && CNF="$CNF --dport $PORT" } ipt -A check_udp_input -p UDP $CNF -j RETURN done for conf in $ALLOW_UDP_IN do CNF="" [ "$conf" != "-" ] && { HOST="$(echo $conf | cut -s -f1 -d:)" PORT="$(echo $conf | cut -s -f2 -d:)" [ ! "$HOST" -a ! "$PORT" ] && CNF="-s $conf" [ "$HOST" ] && CNF="-s $HOST" [ "$PORT" ] && CNF="$CNF --dport $PORT" } ipt -A check_udp_input -p UDP $CNF -j ACCEPT done } build_output() { ipt -F check_tcp_output &> /dev/null ipt -X check_tcp_output &> /dev/null ipt -N check_tcp_output for conf in $DENY_TCP_OUT do CNF="" [ "$conf" != "-" ] && { HOST="$(echo $conf | cut -s -f1 -d:)" PORT="$(echo $conf | cut -s -f2 -d:)" [ ! "$HOST" -a ! "$PORT" ] && CNF="-d $conf" [ "$HOST" ] && CNF="-d $HOST" [ "$PORT" ] && CNF="$CNF --dport $PORT" } ipt -A check_tcp_output -p TCP $CNF -j RETURN done for conf in $ALLOW_TCP_OUT do CNF="" [ "$conf" != "-" ] && { HOST="$(echo $conf | cut -s -f1 -d:)" PORT="$(echo $conf | cut -s -f2 -d:)" [ ! "$HOST" -a ! "$PORT" ] && CNF="-d $conf" [ "$HOST" ] && CNF="-d $HOST" [ "$PORT" ] && CNF="$CNF --dport $PORT" } ipt -A check_tcp_output -p TCP $CNF -j ACCEPT done ipt -F check_udp_output &> /dev/null ipt -X check_udp_output &> /dev/null ipt -N check_udp_output for conf in $DENY_UDP_OUT do CNF="" [ "$conf" != "-" ] && { HOST="$(echo $conf | cut -s -f1 -d:)" PORT="$(echo $conf | cut -s -f2 -d:)" [ ! "$HOST" -a ! "$PORT" ] && CNF="-d $conf" [ "$HOST" ] && CNF="-d $HOST" [ "$PORT" ] && CNF="$CNF --dport $PORT" } ipt -A check_udp_output -p UDP $CNF -j RETURN done for conf in $ALLOW_UDP_OUT do CNF="" [ "$conf" != "-" ] && { HOST="$(echo $conf | cut -s -f1 -d:)" PORT="$(echo $conf | cut -s -f2 -d:)" [ ! "$HOST" -a ! "$PORT" ] && CNF="-d $conf" [ "$HOST" ] && CNF="-d $HOST" [ "$PORT" ] && CNF="$CNF --dport $PORT" } ipt -A check_udp_output -p UDP $CNF -j ACCEPT done } allow_nat() { ipt -t nat -A POSTROUTING -o "$EXTERNAL" -j "$NATDEST" } init() { $MD ipt_LOG &> /dev/null $MD ipt_REJECT &> /dev/null $MD ipt_MASQUERADE &> /dev/null $MD ip_conntrack_ftp &> /dev/null $MD ip_conntrack_irc &> /dev/null ipt -F ipt -t nat -F ipt -X ipt -P INPUT DROP ipt -P OUTPUT DROP ipt -P FORWARD DROP [ -e "/proc/sys/net/ipv4/ip_dynaddr" ] && \ echo "1" > /proc/sys/net/ipv4/ip_dynaddr [ -e "/proc/sys/net/ipv4/tcp_syncookies" ] && \ echo "1" > /proc/sys/net/ipv4/tcp_syncookies [ -e "/proc/sys/net/ipv4/tcp_syncookies" ] && \ echo "1" > /proc/sys/net/ipv4/ip_forward } restrict_forward() { ipt -A FORWARD -p all -m state --state ESTABLISHED,RELATED -j ACCEPT for i in $TRUSTED do ipt -A FORWARD -i "$i" -o "$EXTERNAL" -j ACCEPT done } restrict_input() { build_input ipt -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT for i in $TRUSTED do ipt -A INPUT -i "$i" -j ACCEPT done ipt -A INPUT -p ICMP --icmp-type echo-reply -j ACCEPT ipt -A INPUT -p ICMP --icmp-type echo-request -j ACCEPT ipt -A INPUT -p ICMP --icmp-type destination-unreachable -j ACCEPT ipt -A INPUT -p ICMP --icmp-type time-exceeded -j ACCEPT ipt -A INPUT -p TCP --syn $TIR -j check_tcp_input ipt -A INPUT -p UDP $UIR -j check_udp_input ipt -A INPUT $LR -j LOG --log-level INFO --log-prefix "input: " ipt -A INPUT -p TCP $TRR -j REJECT --reject-with tcp-reset ipt -A INPUT -p UDP $URR -j REJECT --reject-with icmp-port-unreachable } restrict_output() { build_output ipt -A OUTPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT for i in $TRUSTED do ipt -A OUTPUT -o "$i" -j ACCEPT done ipt -A OUTPUT -p ICMP --icmp-type echo-reply -j ACCEPT ipt -A OUTPUT -p ICMP --icmp-type echo-request -j ACCEPT ipt -A OUTPUT -p ICMP --icmp-type destination-unreachable -j ACCEPT ipt -A OUTPUT -p ICMP --icmp-type time-exceeded -j ACCEPT ipt -A OUTPUT -p TCP --syn $TOR -j check_tcp_output ipt -A OUTPUT -p UDP $UOR -j check_udp_output ipt -A OUTPUT $LR -j LOG --log-level INFO --log-prefix "output: " ipt -A OUTPUT -p TCP -j REJECT --reject-with tcp-reset ipt -A OUTPUT -p UDP -j REJECT --reject-with icmp-port-unreachable } init [ "$FORWARD" = "allowed" ] && ipt -P "FORWARD" ACCEPT [ "$OUTPUT" = "allowed" ] && ipt -P "OUTPUT" ACCEPT [ "$INPUT" = "allowed" ] && ipt -P "INPUT" ACCEPT [ "$FORWARD" = "restricted" ] && restrict_forward [ "$INPUT" = "restricted" ] && restrict_input [ "$OUTPUT" = "restricted" ] && restrict_output [ "$FORWARD" != "no" -a "$NAT" = "yes" ] && allow_nat [ "$RUNAFTER" -a -x "$RUNAFTER" ] && \ echo "post executing $RUNAFTER" && \ "$RUNAFTER" exit 0