diff --git a/firewall-forward.conf b/firewall-forward.conf new file mode 100644 index 0000000..4d7177c --- /dev/null +++ b/firewall-forward.conf @@ -0,0 +1,22 @@ +# /etc/sysconfig/firewall-forward.conf +# +# [destport[:destport]] +# +# Wenn IP = 127.0.0.1, wird der Port nur in der +# Firewall geoeffnet, kein Forwarding eingerichtet. + +# lokal +127.0.0.1 tcp 21 +127.0.0.1 tcp 22 +127.0.0.1 tcp 25 +127.0.0.1 tcp 80 +127.0.0.1 tcp 113 +127.0.0.1 tcp 443 +127.0.0.1 tcp 6881:6889 +127.0.0.1 tcp 465 5000 + +10.10.1.100 tcp 122 22 +10.10.1.100 tcp 180 80 + +# honeypot forward +#192.168.0.2 tcp 22 diff --git a/firewall-masquerade.conf b/firewall-masquerade.conf new file mode 100644 index 0000000..d5139de --- /dev/null +++ b/firewall-masquerade.conf @@ -0,0 +1,14 @@ +# /etc/sysconfig/firewall-masquerade.conf +# +# +# +# all + +10.10.0.100 all +10.10.0.200 all +10.10.0.254 all +10.10.250.133 all +10.10.250.134 all +10.10.250.248 all +10.10.1.0/24 all +192.168.1.254 all diff --git a/firewall-qos.conf b/firewall-qos.conf new file mode 100644 index 0000000..0af17d3 --- /dev/null +++ b/firewall-qos.conf @@ -0,0 +1,12 @@ +#mark proto sport dport +21 tcp 22 any +21 tcp any 22 +21 udp +21 icmp +21 41 +23 tcp 21 any +23 tcp any 21 +23 tcp 4661:4669 any +23 tcp any 4661:4669 +23 tcp 6881:6889 any +23 tcp any 6881:6889 diff --git a/firewall.sh b/firewall.sh new file mode 100644 index 0000000..cdb248c --- /dev/null +++ b/firewall.sh @@ -0,0 +1,450 @@ +#!/bin/bash +# chkconfig: - 16 84 +# description: Automates a packet filtering firewall with iptables. + +# File: /etc/init.d/firewall + +. /etc/init.d/functions +. /etc/sysconfig/firewall.conf + +MASQCONF="/etc/sysconfig/firewall-masquerade.conf" +FWDCONF="/etc/sysconfig/firewall-forward.conf" +QOSCONF="/etc/sysconfig/firewall-qos.conf" + +# erlaubt immer SSH zugriff aus internen netzen +DEBUG="no" + +modprobe=`which modprobe` +ipt=`which iptables` +tc=`which tc` + +# ulog target +ULOG="ULOG --ulog-cprange 128 --ulog-prefix" + +case "$1" in + start) + echo "Setting up firewall" + touch /var/lock/subsys/firewall + + # Flush all tables and delete user chains + $ipt -F -t filter + $ipt -F -t nat + $ipt -F -t mangle + $ipt -X -t filter + $ipt -X -t nat + $ipt -X -t mangle + + # user chains + $ipt -N ext-in + $ipt -N fwd-out + $ipt -N ext-out + $ipt -t nat -N ext-in + $ipt -t mangle -N ext-in + $ipt -t mangle -N ext-out + + # USER-CHAIN: drop/reject unwanted packets from inet + $ipt -N droprej + $ipt -A droprej -p tcp -j REJECT --reject-with tcp-reset + $ipt -A droprej -p udp -j REJECT + $ipt -A droprej -j DROP + + # USER-CHAIN: log & drop private IPs from/to inet + $ipt -t mangle -N logdrop + $ipt -t mangle -A logdrop -j $ULOG ext-drop + $ipt -t mangle -A logdrop -j DROP + + # Allow loopback + $ipt -A INPUT -i lo -j ACCEPT + $ipt -A OUTPUT -o lo -j ACCEPT + + # debugging + if [ "$DEBUG" == "yes" ]; then + $ipt -A INPUT -p tcp --dport 22 -j ACCEPT + $ipt -A OUTPUT -p tcp --sport 22 -j ACCEPT + fi + + # already accepted traffic + $ipt -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT + + # internal nets + for i in $INT_NUMS; do + eval dev=\${INT_DEV_${i}} + eval nets=\${INT_NET_${i}} + eval opts=\${INT_OPT_${i}} + realdev=`echo $dev | cut -d":" -f1` + + # options parsing + for opt in $opts; do + case "$opt" in + # Allow bridging + BRIDGE) + $ipt -A FORWARD -i $dev -o $dev -j ACCEPT + ;; + + # allow traffic on internal net + INTERNAL) + for net in $nets; do + $ipt -A INPUT -i $realdev -s $net -j ACCEPT + $ipt -A OUTPUT -o $realdev -d $net -j ACCEPT + done + ;; + + # Allow traffic to external net + EXTERNAL) + for net in $nets; do + $ipt -A FORWARD -i $dev -s $net -j fwd-out + done + ;; + + # Allow Routing to other internal nets + ROUTE) + for i2 in $INT_NUMS; do + eval dev2=\${INT_DEV_${i2}} + eval nets2=\${INT_NET_${i2}} + realdev2=`echo $dev2 | cut -d":" -f1` + + for net in $nets; do + for net2 in $nets2; do + if [ "$net" != "$net2" ] || [ "$realdev" != "$realdev2" ]; then + $ipt -A FORWARD -i $realdev -o $realdev2 -s $net -d $net2 -j ACCEPT + fi + done + done + done + ;; + + # Masquerade all connections through this interface and allow external portforwardings + MASQ) + for net in $nets; do + $ipt -t nat -A PREROUTING -i $dev -j ext-in + $ipt -A INPUT -i $dev -s $net -j ext-in + $ipt -A OUTPUT -o $dev -d $net -j ext-out + $ipt -A FORWARD -i $dev -s $net -m conntrack --ctstate SNAT -j ACCEPT + $ipt -t nat -A POSTROUTING -o $dev -j MASQUERADE + done + ;; + + # redirect web traffic to squid + TSQUID) + if [ -z "$squid_table" ]; then + squid_table=ok + + # squid table + $ipt -t nat -N squid + fi + + $ipt -t nat -A PREROUTING -i $dev -p tcp --dport 80 -j squid + # no squid between nets on this interface + for neta in $nets; do + for netb in $nets; do + $ipt -t nat -A squid -i $dev -s $neta -d $netb -j ACCEPT + done + done + $ipt -t nat -A squid -i $dev -p tcp -j REDIRECT --to-ports 3128 + ;; + + # Allow dhcpd traffic + DHCP) + $ipt -A INPUT -i $dev -p udp --sport 67:68 --dport 67:68 -j ACCEPT + $ipt -A OUTPUT -o $dev -p udp --sport 67:68 --dport 67:68 -j ACCEPT + ;; + + # honeypot target/net + HONEYPOT) + if [ -z "$hpot_table" ]; then + hpot_table=ok + + # Allow nothing + $ipt -N hpot-in + $ipt -A hpot-in -j droprej + + # Allow ftp and dns to external net + $ipt -N hpot-fwd + $ipt -A hpot-fwd -p udp --dport 53 -j ACCEPT + $ipt -A hpot-fwd -p tcp --dport 21 -j ACCEPT + $ipt -A hpot-fwd -j droprej + + # Allow icmp, tcp-rst from localhost (answer to drop-rej in hpot-fwd) + $ipt -N hpot-out + $ipt -A hpot-out -p tcp --tcp-flags RST RST -j ACCEPT + $ipt -A hpot-out -p icmp -j ACCEPT + $ipt -A hpot-out -j DROP + + # ratelimit everything + $ipt -t mangle -N hpot-in + $ipt -t mangle -A hpot-in -m limit --limit $HONEYPOT_RATE_TO -j ACCEPT + $ipt -t mangle -A hpot-in -j DROP + + $ipt -t mangle -N hpot-out + $ipt -t mangle -A hpot-out -m limit --limit $HONEYPOT_RATE_FROM -j ACCEPT + $ipt -t mangle -A hpot-out -j DROP + fi + + for net in $nets; do + $ipt -t mangle -A PREROUTING -i $dev -s $net -j hpot-in + $ipt -A INPUT -i $dev -s $net -j hpot-in + $ipt -A FORWARD -i $dev -s $net -j hpot-fwd + $ipt -A OUTPUT -o $dev -d $net -j hpot-out + $ipt -t mangle -A POSTROUTING -o $dev -d $net -j hpot-out + done + ;; + + esac + done + done + + # external nets + for dev in $EXT_DEVS; do + $ipt -A INPUT -i $dev -j ext-in + $ipt -A FORWARD -i $dev -m conntrack --ctstate DNAT -j ACCEPT + $ipt -A OUTPUT -o $dev -j ext-out + + # external in/out (dropping internal nets) + $ipt -t mangle -A PREROUTING -i $dev -j ext-in + $ipt -t mangle -A POSTROUTING -o $dev -j ext-out + + # external in/out (portforwarding) + $ipt -t nat -A PREROUTING -i $dev -j ext-in + + # used to overcome criminally brain-dead ISPs or servers which block ICMP Fragmentation Needed packets + $ipt -t mangle -A FORWARD -o $dev -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + + # masquerade everything passing ext device + $ipt -t nat -A POSTROUTING -o $dev -j MASQUERADE + done + + + # reject the rest + $ipt -A INPUT -j $ULOG input + $ipt -A INPUT -j droprej + $ipt -A FORWARD -j $ULOG forward + $ipt -A FORWARD -j droprej + $ipt -A OUTPUT -j $ULOG output + $ipt -A OUTPUT -j droprej + + # drop restriced nets + for net in $EXT_DENIED; do + $ipt -t mangle -A ext-in -s $net -j logdrop + $ipt -t mangle -A ext-out -d $net -j logdrop + done + + # allow own traffic + $ipt -A ext-in -m state --state ESTABLISHED,RELATED -j ACCEPT + + # block windows traffic + if [ "$EXT_BLOCK_WINDOWS" == "yes" ]; then + for chain in ext-in fwd-out ext-out; do + $ipt -A $chain -p tcp --dport 135:139 -j droprej + $ipt -A $chain -p udp --dport 135:139 -j droprej + $ipt -A $chain -p tcp --dport 445 -j droprej + done + fi + + # masqerading list (masquerade.conf) + grep '^[^#]' $MASQCONF | while read ip proto port; do + if [ "$proto" == "all" ]; then + $ipt -A fwd-out -s $ip -j ACCEPT + + elif [ "$proto" == "tcp" -o "$proto" == "udp" ]; then + $ipt -A fwd-out -s $ip -p $proto --dport $port -j ACCEPT + + else + $ipt -A fwd-out -s $ip -p $proto -j ACCEPT + fi + done + + # log & drop/reject unwanted packets from internal to inet + $ipt -A fwd-out -j $ULOG fwd-out + $ipt -A fwd-out -j droprej + + # allow ipv6 proto (tunnel) + for ip in "$EXT_SIT_TUNNEL_IP"; do + $ipt -A ext-in -p 41 -s $ip -j ACCEPT + $ipt -A ext-out -p 41 -d $ip -j ACCEPT + done + + # port-forwarding list (forward.conf) + grep '^[^#]' $FWDCONF | while read ip proto port dport; do + # if ip=127.0.0.1 then do not forwarding + if [ "$ip" == "127.0.0.1" ]; then + if [ -z "$dport" ]; then + dport=$port + else + $ipt -t nat -A ext-in -p $proto --dport $port -j REDIRECT --to-ports $dport + fi + $ipt -A ext-in -p $proto --dport $dport -j ACCEPT + + else + # if no dport is given, dport = port + if [ -z "$dport" ]; then + dport=`echo $port | tr ':' '-'` + else + dport=`echo $dport | tr ':' '-'` + fi + $ipt -t nat -A ext-in -p $proto --dport $port -j DNAT --to ${ip}:${dport} + fi + done + + # allow some icmp-echo-requests + $ipt -A ext-in -p icmp --icmp-type echo-request -m limit --limit 5/s -m length --length 0:128 -j ACCEPT + $ipt -A ext-in -p icmp --icmp-type echo-request -j DROP + + # log low ports and block the rest + $ipt -A ext-in -p tcp --dport 1024:65535 -j droprej + $ipt -A ext-in -p udp --dport 1024:65535 -j droprej + $ipt -A ext-in -j $ULOG ext-in + $ipt -A ext-in -j droprej + + # final catch ext-out + $ipt -A ext-out -p tcp -j ACCEPT + $ipt -A ext-out -p udp -j ACCEPT + $ipt -A ext-out -p icmp -j ACCEPT + $ipt -A ext-out -j $ULOG ext-out + $ipt -A ext-out -j droprej + + # qos-stuff + $ipt -t mangle -N qosmark + $ipt -t mangle -A qosmark -j MARK --set-mark 22 + + # qos-regeln + grep '^[^#]' $QOSCONF | while read mark proto sport dport; do + if [ "$proto" == "tcp" -o "$proto" == "udp" ]; then + if [ -z "$sport" -o "$sport" == "any" ]; then + sport="0:65535" + fi + if [ -z "$dport" -o "$dport" == "any" ]; then + dport="0:65535" + fi + $ipt -t mangle -A qosmark -p $proto --sport $sport --dport $dport -j MARK --set-mark $mark + + else + $ipt -t mangle -A qosmark -p $proto -j MARK --set-mark $mark + fi + done + + # safe mark + $ipt -t mangle -A qosmark -j CONNMARK --save-mark + $ipt -t mangle -A qosmark -j RETURN + + # call qosmark from prerouting and postrouting for new connections only + $ipt -t mangle -A ext-in -j CONNMARK --restore-mark + $ipt -t mangle -A ext-in -m mark --mark 0 -j qosmark + $ipt -t mangle -A ext-out -j CONNMARK --restore-mark + $ipt -t mangle -A ext-out -m mark --mark 0 -j qosmark + + # small acks must be fast (per packet, not per flow) + $ipt -t mangle -A ext-in -p tcp --tcp-flags ACK ACK -m length --length 0:65 -j MARK --set-mark 20 + $ipt -t mangle -A ext-out -p tcp --tcp-flags ACK ACK -m length --length 0:65 -j MARK --set-mark 20 + + # kernel tweaks + echo 1 > /proc/sys/net/ipv4/ip_forward + echo 1 > /proc/sys/net/ipv4/netfilter/ip_conntrack_log_invalid > /dev/null 2>&1 + + # add. modules + $modprobe ip_nat_ftp + + success "Setting up firewall" + echo + ;; + + stop) + echo -n "Shutting down firewall" + + rm /var/lock/subsys/firewall + + # Flush all tables + iptables -F -t filter + iptables -F -t nat + iptables -F -t mangle + iptables -X -t filter + iptables -X -t nat + iptables -X -t mangle + + success "Shutting down firewall" + echo + ;; + + restart) + $0 stop + $0 start + ;; + + status) + { + echo "===============================================" + echo "FILTER:" + $ipt -L -nv -t filter + echo + + echo "===============================================" + echo "NAT:" + $ipt -L -nv -t nat + echo + + echo "===============================================" + echo "MANGLE:" + $ipt -L -nv -t mangle + echo + } | less -S -#4 + ;; + + start-qos) + $0 stop-qos + echo -n "Setting up QoS" + + $tc qdisc add dev $QOS_DEV root handle 1: htb default 22 + + $tc class add dev $QOS_DEV parent 1: classid 1:1 htb rate ${QOS_RATEUP}kbit + $tc class add dev $QOS_DEV parent 1:1 classid 1:20 htb rate $[$QOS_RATEUP/10]kbit ceil $[$QOS_RATEUP/10*3]kbit prio 4 + $tc class add dev $QOS_DEV parent 1:1 classid 1:21 htb rate $[$QOS_RATEUP/10]kbit ceil $[$QOS_RATEUP/10*5]kbit prio 2 + $tc class add dev $QOS_DEV parent 1:1 classid 1:22 htb rate $[$QOS_RATEUP/10]kbit ceil $[$QOS_RATEUP/10*5]kbit prio 1 + $tc class add dev $QOS_DEV parent 1:1 classid 1:23 htb rate $[$QOS_RATEUP/10]kbit ceil $[$QOS_RATEUP/10*8]kbit prio 0 + + $tc qdisc add dev $QOS_DEV parent 1:20 handle 20: sfq perturb 10 + $tc qdisc add dev $QOS_DEV parent 1:21 handle 21: sfq perturb 10 + $tc qdisc add dev $QOS_DEV parent 1:22 handle 22: sfq perturb 10 + $tc qdisc add dev $QOS_DEV parent 1:23 handle 23: sfq perturb 10 + + $tc filter add dev $QOS_DEV parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20 + $tc filter add dev $QOS_DEV parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21 + $tc filter add dev $QOS_DEV parent 1:0 prio 0 protocol ip handle 22 fw flowid 1:22 + $tc filter add dev $QOS_DEV parent 1:0 prio 0 protocol ip handle 23 fw flowid 1:23 + + success "Setting up QoS" + echo + ;; + + stop-qos) + echo -n "Shutting down QoS" + $tc qdisc del dev $QOS_DEV root 2> /dev/null + + success "Shutting down QoS" + echo + ;; + + status-qos) + { + echo "===============================================" + echo "QDISC:" + $tc -s -d qdisc show dev $QOS_DEV + echo + + echo "===============================================" + echo "CLASS:" + $tc -s -d class show dev $QOS_DEV + echo + + echo "===============================================" + echo "FILTER:" + $tc -s -d filter show dev $QOS_DEV + echo + } | less -S -#4 + ;; + + *) + echo "Usage: $0 {start|stop|restart|status|start-qos|stop-qos|status-qos}" + exit 1 + ;; +esac + +