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/eofirewall

425 lines
13 KiB
Bash
Executable File

#!/bin/bash
. /lib/lsb/init-functions
NAME="eofirewall"
abort()
{
message=$@
log_failure_msg "$message"
exit 1
}
chain_exists()
{
local chain_name="$1" ; shift
[ $# -eq 1 ] && local table="--table $1"
$IPTABLES $table -n --list "$chain_name" >/dev/null 2>&1
}
if [ -f "/etc/firewall/firewall.conf" ]; then
source /etc/firewall/firewall.conf
else
abort "No configuration file /etc/firewall/firewall.conf"
fi
flush()
{
$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
}
clean()
{
$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 mangle -F
$IPTABLES -t mangle -X
if chain_exists EO-INPUT; then
$IPTABLES -D INPUT -j EO-INPUT
$IPTABLES -D OUTPUT -j EO-OUTPUT
$IPTABLES -D FORWARD -j EO-FORWARD
$IPTABLES -D INPUT -j EO-LOGDROP
$IPTABLES -D OUTPUT -j EO-LOGDROP
$IPTABLES -D FORWARD -j EO-LOGDROP
fi
for chain in `$IPTABLES --list -n | grep '^Chain EO' | cut -f2 -d ' '`; do
$IPTABLES -F $chain
$IPTABLES -X $chain
done
}
init()
{
clean
test_config
modprobe ip_conntrack
$IPTABLES -N EO-INPUT
$IPTABLES -N EO-OUTPUT
$IPTABLES -N EO-FORWARD
$IPTABLES -N EO-LOGDROP
# default policies
log_action_msg "DROP Input, Forward and Output by default"
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP
}
test_config()
{
# FIXME: test if the interface and the ip exist
if [ ! "$WAN_INT" -o ! "$IP" ]; then
abort "Bad configuration please check /etc/firewall/firewall.conf"
fi
}
critical_return()
{
if [ `echo $?` != 0 ]; then
log_failure_msg "Error on the last command firewall will be stop"
clean
exit 1
fi
}
forward_port()
{
if [ $# != 4 ]; then
log_warning_msg "Bad syntax for port forward : $*"
return
fi
local source=$1
local port=$2
local destination=$3
local 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
log_warning_msg "You must add a LAN interface (LAN_INT) for a port forward"
else
log_action_msg "Forward $port to $destination for protocol $proto"
$IPTABLES -A EO-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_input_port()
{
if [ $# == 4 ]; then
local destination=$2
local proto=$3
local ports=$4
elif [ $# == 3 ]; then
local destination=$IP
local proto=$2
local ports=$3
else
log_warning_msg "Open port bad syntax : $*"
fi
source=$1
log_action_msg "Open port(s) $ports from $source to $destination for protocol $proto"
$IPTABLES -A EO-INPUT -i $WAN_INT -p $proto -s $source -d $destination -m multiport --dports $ports -m state --state NEW -j ACCEPT
critical_return
}
open_output_port()
{
if [ $# == 4 ]; then
local source=$2
local proto=$3
local ports=$4
elif [ $# == 3 ]; then
local source=$IP
local proto=$2
local ports=$3
else
log_warning_msg "Open output port bad syntax : $*"
fi
destination=$1
log_action_msg "Open output port(s) $ports from $source to $destination for protocol $proto"
$IPTABLES -A EO-OUTPUT -o $WAN_INT -p $proto -s $source -d $destination -m multiport --dports $ports -m state --state NEW -j ACCEPT
critical_return
}
port_redirection()
{
if [ $# != 4 ]; then
log_warning_msg "Bad syntax for port redirection : $*"
return
fi
local if=$1
local proto=$2
local srcport=$3
local destport=$4
log_action_msg "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 [ $# != 3 ]; then
log_warning_msg "Bad syntax for port knocking : $*"
return
fi
local ports=$1
local knock_ports=$2
local knock_number=$3
local i=0
for kport in $(echo $knock_ports | sed 's/,/ /g'); do
((i++))
tock_number=$knock_number$i
if [ $i -gt 1 ]; then
$IPTABLES -N EO-TOC${tock_number}
$IPTABLES -A EO-TOC${tock_number} -m recent --name EO-TOC$((${tock_number}-1)) --remove
$IPTABLES -A EO-TOC${tock_number} -m recent --name EO-TOC${tock_number} --set
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --dport $kport -m recent --rcheck --name EO-TOC$((${tock_number}-1)) -j EO-TOC${tock_number}
else
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --dport $kport -m recent --set --name EO-TOC${tock_number}
fi
done
log_action_msg "Port knocking for $ports with combinaison $knock_ports on $WAN_INT"
for port in $(echo $ports | sed 's/,/ /g'); do
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --dport $port -m recent --rcheck --seconds 15 --name EO-TOC${tock_number} -m state --state NEW -j ACCEPT
done
}
start()
{
init
## allow packets coming from the machine
log_action_msg "Accept lo interface"
$IPTABLES -A EO-INPUT -i lo -j ACCEPT
$IPTABLES -A EO-OUTPUT -o lo -j ACCEPT
$IPTABLES -A EO-INPUT -i $WAN_INT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
if [ $ALLOW_WAN_OUTOUT_EVERYWHERE -eq 0 ]; then
$IPTABLES -A EO-OUTPUT -o $WAN_INT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
else
log_action_msg "Allow WAN outgoing traffic to everywhere"
$IPTABLES -A EO-OUTPUT -o $WAN_INT -p all -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
fi
critical_return
if [ $LAN == 1 ]; then
log_action_msg "Allow WAN outgoing traffic from lan"
$IPTABLES -A EO-FORWARD -i $WAN_INT -o $LAN_INT -p all -d $LAN_NETWORK -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A EO-FORWARD -i $LAN_INT -o $WAN_INT -p all -s $LAN_NETWORK -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
log_action_msg "Allow local network"
$IPTABLES -A EO-OUTPUT -o $LAN_INT -s $LAN_NETWORK -p all -j ACCEPT
$IPTABLES -A EO-INPUT -i $LAN_INT -d $LAN_NETWORK -p all -j ACCEPT
fi
## block spoofing
log_action_msg "Block spoofing, scan port, Xmas Tree, null scanning, SYN/RST and SYN/FIN"
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
## NMAP FIN/URG/PSH
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix 'iptables: Port scan: ' --log-level 4
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
## stop Xmas Tree type scanning
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "iptables: Xmas tree: " --log-level 4
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags ALL ALL -j DROP
$IPTABLES -A EO-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 EO-INPUT -i $WAN_INT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
## stop null scanning
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "iptables: Null scanning: " --log-level 4
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags ALL NONE -j DROP
## SYN/RST
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "iptables: SYN/RST: " --log-level 4
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
## SYN/FIN
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "iptables: SYN/FIN: " --log-level 4
$IPTABLES -A EO-INPUT -i $WAN_INT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
## stop sync flood
log_action_msg "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
log_action_msg "PING allowed"
$IPTABLES -A EO-INPUT -p icmp --icmp-type ping -j ACCEPT
$IPTABLES -A EO-OUTPUT -p icmp --icmp-type ping -j ACCEPT
$IPTABLES -A EO-FORWARD -p icmp --icmp-type ping -j ACCEPT
fi
if [ $FTP == 1 ]; then
log_action_msg "FTP allowed"
modprobe ip_conntrack_ftp
$IPTABLES -A EO-INPUT -i $WAN_INT -d $IP -p tcp --dport ftp -m state --state NEW,ESTABLISHED -j ACCEPT
$IPTABLES -A EO-OUTPUT -o $WAN_INT -s $IP -p tcp --sport ftp -m state --state ESTABLISHED -j ACCEPT
# Data
$IPTABLES -A EO-INPUT -i $WAN_INT -d $IP -p tcp --dport ftp-data -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -A EO-OUTPUT -o $WAN_INT -s $IP -p tcp --sport ftp-data -m state --state ESTABLISHED,RELATED -j ACCEPT
# Passive mod
$IPTABLES -A EO-INPUT -i $WAN_INT -d $IP -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED -j ACCEPT
$IPTABLES -A EO-OUTPUT -o $WAN_INT -s $IP -p tcp --sport 1024: --dport 1024: -m state --state ESTABLISHED,RELATED -j ACCEPT
fi
## Open input ports
for args in "${OPEN_PORTS[@]}"; do
open_input_port $args
done
## Open ouput ports
for args in "${OUPUT_DESTINATIONS[@]}"; do
open_output_port $args
done
## Port knocking
local i=1
for args in "${PORT_KNOCK[@]}"; do
port_knocking $args $i
((i++))
done
## Port forwading
for args in "${TRAFFICS[@]}"; do
forward_port $args
done
## Port redirection
for args in "${REDIRECTIONS[@]}"; do
port_redirection $args
done
## Old: Whitelist
for arg in "${WHITELIST_SSH[@]}"; do
log_warning_msg "WHITELIST_SSH is obsolete: this option will be removed in next version"
open_input_port $arg tcp ssh
done
for ip in "${WHITELIST[@]}"; do
for args in "${WHITELIST_OPEN_PORTS[@]}"; do
open_input_port $ip $args
done
done
## NAT
if [ $NAT == 1 ]; then
log_action_msg "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
$IPTABLES -A INPUT -j EO-INPUT
$IPTABLES -A OUTPUT -j EO-OUTPUT
$IPTABLES -A FORWARD -j EO-FORWARD
## LOG
## Create a EO-LOGDROP chain to log and drop packets
$IPTABLES -A EO-LOGDROP -p tcp -m limit --limit 1/min -j LOG --log-prefix "iptables: denied tcp: " --log-level 4
$IPTABLES -A EO-LOGDROP -p udp -m limit --limit 1/min -j LOG --log-prefix "iptables: denied udp: " --log-level 4
$IPTABLES -A EO-LOGDROP -p icmp -m limit --limit 1/min -j LOG --log-prefix "iptables: denied icmp: " --log-level 4
$IPTABLES -A EO-LOGDROP -j DROP
$IPTABLES -A INPUT -j EO-LOGDROP
$IPTABLES -A OUTPUT -j EO-LOGDROP
$IPTABLES -A FORWARD -j EO-LOGDROP
}
load()
{
log_daemon_msg "Loading old rules from /etc/network/iptables-save"
log_daemon_msg "If you want to load new rules please use test and then start"
if [ -f /etc/network/iptables-save ]; then
iptables-restore < /etc/network/iptables-save
else
log_warning_msg "No iptables rules saved please use test and save script options"
fi
}
test_rules()
{
log_action_msg "Testing new rules"
log_action_msg "You have 30 seconds to test your new rules"
start || exit 1
log_end_msg 0
log_action_msg "... Please test your rules"
sleep 30
log_action_msg "---- The test is finished ----"
if [ -f /etc/network/iptables-save ]; then
iptables-restore < /etc/network/iptables-save
log_action_msg "Old rules restored"
else
clean
log_action_msg "Rules cleaned"
fi
log_action_msg "If you are happy with this new rules please use save option"
}
case "$1" in
load|restore)
load || exit 1
;;
test)
test_rules || exit 1
;;
start)
log_daemon_msg "WARNING: you are loading new rules you have 5 seconds to cancel (CRTL+C)"
sleep 5
start || exit 1
;;
save)
log_daemon_msg "You need to make a start before if you want to save new rules"
log_daemon_msg "Saving current rules to /etc/network/iptables-save"
iptables-save > /etc/network/iptables-save
;;
flush)
flush || exit 1
;;
clean)
clean || exit 1
;;
*)
N=/usr/bin/$NAME
echo "Usage: $N {restore|load|save|test|clean|flush}"
exit 2
;;
esac
exit 0