451 lines
13 KiB
Bash
451 lines
13 KiB
Bash
|
#!/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
|
||
|
|
||
|
|