This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
eofirewall/firewall

347 lines
10 KiB
Bash
Executable File

#!/bin/bash
### BEGIN INIT INFO
# Provides: firewall
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Iptables firewall
# Description: An iptables firewall
### END INIT INFO
NAME="firewall"
abort()
{
message=$@
echo >&2
echo -e "$message" >&2
echo >&2
exit 1
}
if [ -f "/etc/firewall.conf" ]; then
source /etc/firewall.conf
else
abort "No configuration file /etc/firewall.conf"
fi
clean()
{
$IPTABLES -F
$IPTABLES -F INPUT
$IPTABLES -F OUTPUT
$IPTABLES -F FORWARD
$IPTABLES -F -t mangle
$IPTABLES -F -t nat
$IPTABLES -X
}
test_config()
{
if [ ! "$WAN_INT" -o ! "$IP" ]; then
echo "Bad configuration please check your /etc/firewall.conf"
exit 1
fi
}
critical_return()
{
if [ `echo $?` != 0 ]; then
echo "!!! CRITICAL error on the last command firewall will be stop"
stop
exit 1
fi
}
forward_port()
{
if [ $# != 4 ]; then
echo "! Bad syntax for port forward : $*"
return
fi
source=$1
port=$2
destination=$3
proto=$4
if echo "$destination" | grep -q ":"; then
dest_ip=$(echo $destination | cut -d ":" -f1)
dest_port=$(echo $destination | cut -d ":" -f2)
if [ ! "$LAN_INT" ]; then
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 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
}
open_port()
{
if [ $# == 4 ]; then
destination=$2
proto=$3
ports=$4
elif [ $# == 3 ]; then
destination=$IP
proto=$2
ports=$3
else
echo "!!! CRITICAL Open port bad syntax : $*"
stop && exit 1
fi
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 NEW -j ACCEPT
critical_return
done
}
port_redirection()
{
if [ $# != 4 ]; then
echo "! Bad syntax for port redirection : $*"
return
fi
if=$1
proto=$2
srcport=$3
destport=$4
echo "+ Redirect $if port $srcport to $destport for portocol $proto"
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
i=0
for kport in $(echo $knock_ports | sed 's/,/ /g'); do
((i++))
if [ $i -gt 1 ]; then
iptables -N toc$i
iptables -A toc$i -m recent --name toc$(($i-1)) --remove
iptables -A toc$i -m recent --name toc$i --set
iptables -A INPUT -i $WAN_INT -p tcp --dport $kport -m recent --rcheck --name toc$(($i-1)) -j toc$i
else
iptables -A INPUT -i $WAN_INT -p tcp --dport $kport -m recent --set --name toc$i
fi
done
iptables -A INPUT -i $WAN_INT -p tcp --dport $port -m recent --rcheck --seconds 15 --name toc$i -m state --state NEW -j ACCEPT
}
start()
{
echo "Starting: Firewall"
modprobe ip_conntrack
clean
test_config
# default policies
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP
## allow packets coming from the machine
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
echo "+ Allow WAN outgoing traffic"
$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 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"
$IPTABLES -A OUTPUT -o $LAN_INT -p all -j ACCEPT
$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 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"
$IPTABLES -A OUTPUT -o $ALLOW_INT -p all -j ACCEPT
$IPTABLES -A INPUT -i $ALLOW_INT -p all -j ACCEPT
done
fi
## block spoofing
echo "+ Block spoofing"
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
## NMAP FIN/URG/PSH
echo "+ Block scan ports"
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix 'iptables: Port scan: ' --log-level 4
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
## stop Xmas Tree type scanning
echo "+ Block Xmas Tree"
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "iptables: Xmas tree: " --log-level 4
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags ALL ALL -j DROP
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "iptables: Xmas tree: " --log-level 4
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
## stop null scanning
echo "+ Block null scanning"
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "iptables: Null scanning: " --log-level 4
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags ALL NONE -j DROP
## SYN/RST
echo "+ Block SYN/RST"
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "iptables: SYN/RST: " --log-level 4
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
## SYN/FIN
echo "+ Block SYN/FIN"
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "iptables: SYN/FIN: " --log-level 4
$IPTABLES -A INPUT -i $WAN_INT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
## stop sync flood
echo "+ Block Syn flood"
echo "1" >/proc/sys/net/ipv4/tcp_syncookies
echo "1024" > /proc/sys/net/ipv4/tcp_max_syn_backlog
if [ $PING == 1 ]; then
echo "+ PING allowed"
iptables -A INPUT -p icmp --icmp-type ping -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type ping -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type ping -j ACCEPT
fi
if [ $FTP == 1 ]; then
echo "+ FTP allowed"
modprobe ip_conntrack_ftp
$IPTABLES -A INPUT -i $WAN_INT -d $IP -p tcp --dport ftp -m state --state NEW,ESTABLISHED -j ACCEPT
$IPTABLES -A OUTPUT -o $WAN_INT -s $IP -p tcp --sport ftp -m state --state ESTABLISHED -j ACCEPT
# Data
$IPTABLES -A INPUT -i $WAN_INT -d $IP -p tcp --dport ftp-data -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -A OUTPUT -o $WAN_INT -s $IP -p tcp --sport ftp-data -m state --state ESTABLISHED,RELATED -j ACCEPT
# Passive mod
$IPTABLES -A INPUT -i $WAN_INT -d $IP -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -A OUTPUT -o $WAN_INT -s $IP -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT
fi
## Open Ports
for args in "${OPEN_PORTS[@]}"; do
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
done
## Port redirection
for args in "${REDIRECTIONS[@]}"; do
port_redirection $args
done
## NAT
if [ $NAT == 1 ]; then
echo "+ Activate nat"
for proto in ftp irc sip h323; do modprobe nf_nat_$proto; done
$IPTABLES -t nat -A POSTROUTING -o $WAN_INT -s $LAN_NETWORK -j SNAT --to-source $IP
fi
ipt_hook
## LOG
## Create a LOGDROP chain to log and drop packets
$IPTABLES -N LOGDROP
$IPTABLES -A LOGDROP -j LOG --log-prefix "iptables: " --log-level 4
$IPTABLES -A LOGDROP -j DROP
$IPTABLES -A INPUT -j LOGDROP
$IPTABLES -A OUTPUT -j LOGDROP
$IPTABLES -A FORWARD -j LOGDROP
}
stop()
{
echo "+ Firewall stoped"
$IPTABLES -t filter -F
$IPTABLES -t filter -X
$IPTABLES -t filter -P INPUT ACCEPT
$IPTABLES -t filter -P FORWARD ACCEPT
$IPTABLES -t filter -P OUTPUT ACCEPT
$IPTABLES -t nat -F
$IPTABLES -t nat -X
$IPTABLES -t nat -P PREROUTING ACCEPT
$IPTABLES -t nat -P OUTPUT ACCEPT
$IPTABLES -t nat -P POSTROUTING ACCEPT
$IPTABLES -t mangle -F
$IPTABLES -t mangle -X
$IPTABLES -t mangle -P PREROUTING ACCEPT
$IPTABLES -t mangle -P INPUT ACCEPT
$IPTABLES -t mangle -P FORWARD ACCEPT
}
case "$1" in
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
;;
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
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|restore|save|test|stop}" >&2
;;
esac
exit 0