Add port knocking and support save and load rules

* Support port knocking
 * Add a test option
 * Add save and load of the rules
 * Modify states to support last iptables version
 * Add logrotate support for the Debian packages
This commit is contained in:
Jérôme Schneider 2011-06-21 14:21:52 +02:00
parent b4601423a0
commit 6a34b1697e
6 changed files with 96 additions and 26 deletions

View File

@ -14,6 +14,6 @@ all:
install:
install -d -m 0755 -o root -g root $(DESTDIR)/etc/init.d $(DESTDIR)/etc/rsyslog.d/
install -m 0640 -o root -g root $(NAME).conf $(DESTDIR)/etc/
install -m 0640 -o root -g root iptables.conf $(DESTDIR)/etc/rsyslog.d
install -m 0640 -o root -g root rsyslog.conf $(DESTDIR)/etc/rsyslog.d
install -m 0755 -o root -g root $(NAME) $(DESTDIR)/etc/init.d

16
README
View File

@ -1,4 +1,14 @@
= INSTALLATION =
* Install rsyslog
= Installation =
* Requrie: rsyslog, logrotate and iptables
* make install
* use /etc/init.d/firewall [stop | start | restart]
= Usage =
First launch test your configuration:
/etc/init.d/firewall test
Second save this change (this will load your rules and save it):
/etc/init.d/firewall save
You need to use save at least one time.
/etc/init.d/firewall stop: will flush your rules
/etc/init.d/firewall start|restore: will load your saved rules

9
debian/eofirewall.logrotate vendored Normal file
View File

@ -0,0 +1,9 @@
/var/log/iptables.log {
weekly
rotate 6
compress
delaycompress
missingok
create 640 root adm
}

View File

@ -12,14 +12,6 @@
NAME="firewall"
if [ -f "/etc/firewall.conf" ]; then
source /etc/firewall.conf
else
echo "No configuration file /etc/firewall.conf"
exit 1
fi
abort()
{
message=$@
@ -29,6 +21,12 @@ abort()
exit 1
}
if [ -f "/etc/firewall.conf" ]; then
source /etc/firewall.conf
else
abort "No configuration file /etc/firewall.conf"
fi
clean()
{
$IPTABLES -F
@ -76,7 +74,7 @@ forward_port()
echo "!! WARNING you must add a LAN interface (LAN_INT) for a port forward"
else
echo "+ Forward $port to $destination for protocol $proto"
$IPTABLES -A FORWARD -i $WAN_INT -o $LAN_INT -p $proto -s $source -d $dest_ip --dport $dest_port -m state ! --state INVALID -j ACCEPT
$IPTABLES -A FORWARD -i $WAN_INT -o $LAN_INT -p $proto -s $source -d $dest_ip --dport $dest_port -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i $WAN_INT -p $proto -s $source -d $IP --dport $port -j DNAT --to $destination
fi
fi
@ -100,7 +98,7 @@ open_port()
source=$1
for port in $(echo $ports | sed 's/,/ /g'); do
echo "+ Open port $port from $source to $destination for protocol $proto"
$IPTABLES -A INPUT -i $WAN_INT -p $proto -s $source -d $destination --dport $port -m state ! --state INVALID -j ACCEPT
$IPTABLES -A INPUT -i $WAN_INT -p $proto -s $source -d $destination --dport $port -m state --state NEW -j ACCEPT
critical_return
done
}
@ -111,7 +109,7 @@ port_redirection()
echo "! Bad syntax for port redirection : $*"
return
fi
if=$1
proto=$2
srcport=$3
@ -121,6 +119,28 @@ port_redirection()
iptables -t nat -A PREROUTING -i $if -p $proto --dport $srcport -j REDIRECT --to-port $destport
}
port_knocking()
{
if [ $# != 2 ]; then
echo "! Bad syntax for port knocking : $*"
return
fi
port=$1
knock_ports=$2
iptables -N toc2
iptables -A toc2 -m recent --name toc1 --remove
iptables -A toc2 -m recent --name toc2 --set
iptables -N toc3
iptables -A toc3 -m recent --name toc2 --remove
iptables -A toc3 -m recent --name toc3 --set
for port in $(echo $knock_ports | sed 's/,/ /g'); do
iptables -A INPUT -i $WAN_INT -p tcp --dport $port -m recent --set --name toc1
done
iptables -A INPUT -i $WAN_INT -p tcp --dport $port -m recent --rcheck --seconds 15 --name toc3 -m state --state NEW -j ACCEPT
}
start()
{
echo "Starting: Firewall"
@ -139,14 +159,14 @@ start()
$IPTABLES -A OUTPUT -o lo -j ACCEPT
echo "+ Allow WAN outgoing traffic"
$IPTABLES -A OUTPUT -o $WAN_INT -p all -m state ! --state INVALID -j ACCEPT
$IPTABLES -A INPUT -i $WAN_INT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -o $WAN_INT -p all -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
$IPTABLES -A INPUT -i $WAN_INT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
critical_return
if [ $LAN == 1 ]; then
echo "+ Allow WAN outgoing traffic from lan"
$IPTABLES -A FORWARD -i $LAN_INT -o $WAN_INT -p all -m state ! --state INVALID -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_INT -o $WAN_INT -p all -m state ESTABLISHED,RELATED,NEW -j ACCEPT
$IPTABLES -A FORWARD -i $WAN_INT -o $LAN_INT -p all -m state --state RELATED,ESTABLISHED -j ACCEPT
echo "+ Allow local network"
@ -154,7 +174,7 @@ start()
$IPTABLES -A INPUT -i $LAN_INT -p all -j ACCEPT
for ALLOW_INT in $ALLOW_INTS; do
echo "+ Allow WAN outgoing traffic for interface $ALLOW_INT"
$IPTABLES -A FORWARD -i $ALLOW_INT -o $WAN_INT -p all -m state ! --state INVALID -j ACCEPT
$IPTABLES -A FORWARD -i $ALLOW_INT -o $WAN_INT -p all -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
$IPTABLES -A FORWARD -i $WAN_INT -o $ALLOW_INT -p all -m state --state RELATED,ESTABLISHED -j ACCEPT
echo "+ Allow local network"
@ -222,6 +242,11 @@ start()
open_port $args
done
## Port knocking
for args in "${PORT_KNOCK[@]}"; do
port_knocking $args
done
## Port forwading
for args in "${TRAFFICS[@]}"; do
forward_port $args
@ -279,19 +304,39 @@ stop()
}
case "$1" in
start)
start || exit 1
start|restore)
if [ -f /etc/network/iptables-save ]; then
iptables-restore < /etc/network/iptables-save
echo "Firewall: rules loaded"
else
abort "!! No iptables rules saved please use test and save script options"
fi
;;
stop)
stop || exit 1
stop || exit 1
;;
restart|force-reload)
test)
echo "You have 30 seconds to test your new rules"
start || exit 1
echo "... Please test your rules"
sleep 30
echo "---- The test is finished ----"
if [ -f /etc/network/iptables-save ]; then
iptables-restore < /etc/network/iptables-save
echo "Old rules restored"
else
stop
start || exit 1
echo "Rules flushed"
fi
echo "If you are happy with this new rules please use save option"
;;
save)
start || exit 1
iptables-save > /etc/network/iptables-save
;;
*)
N=/etc/init.d/$NAME
abort "Usage: $N {start|stop|restart|force-reload}" >&2
abort "Usage: $N {start|restore|save|test|stop}" >&2
;;
esac

View File

@ -20,9 +20,15 @@ ALLOW_INTS=''
## Open ports
# "source [destination] protocole {porta|portx:porty},[portx:porty,porta,portb,...]" ...
# The default destination is the IP !
# example : OPEN_PORTS=("0.0.0.0/0 tcp 22" "42.42.42.0/24 42.42.42.42 tcp ssh,imap,imaps,1024:2048,32")
# example : OPEN_PORTS=("0.0.0.0/0 tcp 22"
# "42.42.42.0/24 42.42.42.42 tcp ssh,imap,imaps,1024:2048,32")
OPEN_PORTS=("0.0.0.0/0 tcp ssh")
## Port knocking
# "port knock_ports_combinaison"
# example : PORT_KNOCK("22 121,4353,4242,111")
PORT_KNOCK=()
## Port forwarding
# "source port destination:port protocol" "source port destination:port protocol" ...
# example : TRAFFICS=("0.0.0.0/0 80 192.168.0.42:80 tcp" "42.42.42.42 4242 192.168.0.43:22 tcp")