A seguir, vamos configurar o firewall, onde para isto utilizaremos o script abaixo, que bloqueia tudo que não seja necessariamente importante, como por exemplo, Instant Messaging, P2P, BitTorrent, etc:
#!/bin/bash
FW=/sbin/iptables
if [ -z $FW ]; then
echo "iptables: Command not found"
exit 1
fi
SYSCTL=/sbin/sysctl
if [ -z $SYSCTL ]; then
echo "sysctl: Command not found"
exit 1
fi
PROBE=/sbin/modprobe
if [ -z $PROBE ]; then
echo "modprobe: Command not found"
exit 1
fi
ETH0="192.168.0.0/24"
NET="0/0"
LO="127.0.0.1"
PA="1024:65535"
CONFIG_DIR="/etc/firewall"
set_policy() {
# POLICY is DROP or ACCEPT
local POLICY=$1
$FW -P INPUT $POLICY
$FW -P OUTPUT $POLICY
$FW -P FORWARD $POLICY
}
flush() {
$FW -F
$FW -F -t nat
$FW -X
$FW -X -t nat
}
allow_loopback() {
$FW -A INPUT -j ACCEPT -i lo -d $LO
$FW -A OUTPUT -j ACCEPT -o lo -s $LO
}
allow_icmp() {
local FILE=$(cat $CONFIG_DIR/icmp_types.conf | grep -v ^#)
$FW -N ALLOW_ICMP
for TYPE in $FILE
do
$FW -A ALLOW_ICMP -j ACCEPT -p icmp --icmp-type $TYPE -d $ETH0
done
$FW -A ALLOW_ICMP -j ACCEPT -m limit --limit 1/s
$FW -A ALLOW_ICMP -j DROP
$FW -A INPUT -j ALLOW_ICMP -p icmp
$FW -A OUTPUT -j ALLOW_ICMP -p icmp
$FW -A FORWARD -j ALLOW_ICMP -p icmp
}
service_ports() {
local FILE=$(cat $CONFIG_DIR/service_ports.conf | grep -v ^#)
for PORT in $FILE
do
# Allow LAN to acess the firewall and the internet
$FW -A INPUT -j ALLOW_TCP -p tcp -s $ETH0 --sport $PA -d $NET --dport $PORT
$FW -A OUTPUT -j ALLOW_TCP -p tcp -s $NET --sport $PORT -d $ETH0 --dport $PA
$FW -A FORWARD -j ALLOW_TCP -p tcp -s $ETH0 --sport $PA -d $NET --dport $PORT
$FW -A FORWARD -j ALLOW_TCP -p tcp -s $NET --sport $PORT -d $ETH0 --dport $PA
# Allow the firewall to access the internet
$FW -A INPUT -j ALLOW_TCP -p tcp -i ppp0 --sport $PORT --dport $PA
$FW -A OUTPUT -j ALLOW_TCP -p tcp -o ppp0 --sport $PA --dport $PORT
done
}
adm_ports() {
local FILE=$(cat $CONFIG_DIR/admin_ports.conf | grep -v ^#)
for PORT in $FILE
do
$FW -A INPUT -j ALLOW_TCP -p tcp -s $ETH0 --sport $PA -d $NET --dport $PORT
$FW -A OUTPUT -j ALLOW_TCP -p tcp -s $NET --sport $PORT -d $ETH0 --dport $PA
done
}
allow_tcp() {
$FW -N ALLOW_TCP
$FW -A ALLOW_TCP -j ACCEPT -p tcp --syn
$FW -A ALLOW_TCP -j ACCEPT -p tcp -m state --state ESTABLISHED,RELATED
# Drop undesirable packages TCP
$FW -A ALLOW_TCP -j LOG --log-prefix "FIREWALL: NEW without syn: " -p tcp ! --syn -m state --state NEW
$FW -A ALLOW_TCP -j DROP -p tcp ! --syn -m state --state NEW
# Drop packages TCP badly formed
#$FW -A ALLOW_TCP -j LOG --log-prefix "FIREWALL: Badly formed: " -m unclean
#$FW -A ALLOW_TCP -j DROP -m unclean
# Port Scanner
local FILE=$(cat $CONFIG_DIR/tcp_flags.conf | grep -v ^#)
for FLAGS in $FILE
do
$FW -A ALLOW_TCP -j LOG --log-prefix "FIREWALL: ($FLAGS): " -p tcp --tcp-flags ALL $FLAGS
$FW -A ALLOW_TCP -j DROP -p tcp --tcp-flags ALL $FLAGS
done
$FW -A ALLOW_TCP -j DROP
adm_ports
service_ports
}
accept_dns_conn() {
# To resolv internal network
$FW -A INPUT -j ACCEPT -p udp -s $ETH0 --sport $PA -d $NET --dport 53
$FW -A OUTPUT -j ACCEPT -p udp -s $NET --sport 53 -d $ETH0 --dport $PA
$FW -A FORWARD -j ACCEPT -p udp -s $ETH0 --sport $PA -d $NET --dport 53
$FW -A FORWARD -j ACCEPT -p udp -s $NET --sport 53 -d $ETH0 --dport $PA
}
accept_proxy() {
$FW -t nat -A PREROUTING -j REDIRECT -p tcp -s $ETH0 --dport 80 -i eth0 --to-port 3128
}
accept_internet() {
$FW -t nat -A POSTROUTING -j MASQUERADE -s $ETH0 -o ppp0
}
setup_kernel() {
# Load Modules
$PROBE ip_nat_ftp
$PROBE ip_conntrack_ftp
# Disable IP Spoofing attack
$SYSCTL -w net.ipv4.conf.all.rp_filter=2 > /dev/null 2>&1
# Enable IP Forward
$SYSCTL -w net.ipv4.ip_forward=1 > /dev/null 2>&1
# Kill Timestamps
$SYSCTL -w net.ipv4.tcp_timestamps=0 > /dev/null 2>&1
# Enable protection Cookie TCP syn
$SYSCTL -w net.ipv4.tcp_syncookies=1 > /dev/null 2>&1
# Disable ICMP broadcast
$SYSCTL -w net.ipv4.icmp_echo_ignore_broadcasts=1 > /dev/null 2>&1
# Enable protection to bad error message
$SYSCTL -w net.ipv4.icmp_ignore_bogus_error_responses=1 > /dev/null 2>&1
# It certifys that packages routed in the origin had been discarded
$SYSCTL -w net.ipv4.conf.all.accept_source_route=0 > /dev/null 2>&1
# Change TTL value
$SYSCTL -w net.ipv4.ip_default_ttl=255 > /dev/null 2>&1
# Ratemask to ICMPs: 0 3 4 5 8 11 12
$SYSCTL -w net.ipv4.icmp_ratemask=6457 > /dev/null 2>&1
# Recommended values of datagram TCP thinking about DOS and DRDOS attack
$SYSCTL -w net.ipv4.tcp_fin_timeout=30 > /dev/null 2>&1
$SYSCTL -w net.ipv4.tcp_keepalive_time=1800 > /dev/null 2>&1
$SYSCTL -w net.ipv4.tcp_window_scaling=0 > /dev/null 2>&1
$SYSCTL -w net.ipv4.tcp_sack=0 > /dev/null 2>&1
}
start() {
echo "Starting Firewall: "
set_policy DROP
allow_loopback
allow_icmp
allow_tcp
accept_dns_conn
accept_proxy
accept_internet
setup_kernel
}
stop() {
echo "Stopping Firewall: "
set_policy ACCEPT
flush
}
status() {
echo ">> Showing table default: "
$FW -L
echo ""
echo ">> Showing table nat: "
$FW -L -t nat
}
restart() {
stop
start
}
# Start of the firewall script
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
internet)
accept_internet
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
Para finalizar ainda temos os seguintes arquivos de configurações, que devem ficar no diretório /etc/firewall, utilizados pelo script acima:
Arquivo icmp_types.conf:
0
3/0
3/1
3/2
3/3
3/4
4
5
8
11
12
Arquivo service_ports.conf:
20
21
22
25
80
110
143
443
3128
Arquivo admin_ports.conf:
# Only administration ports, but only for INPUT and OUTPUT
22
Arquivo tcp_flags.conf:
# Flags TCP that they cannot happen in a normal
# communication, thus indicating possible sweepings
FIN,SYN
FIN,RST
FIN,URG,PSH
NONE
RST,URG
RST,PSH
SYN,RST
SYN,URG
SYN,PSH
SYN,URG,PSH
Agora, para que o script do firewall seja iniciado juntamente com o servidor, estaremos copiando o mesmo no diretório /etc/init.d, com o nome de firewall, e depois criaremos um link simbólico no diretório /etc/rc3.d apontando para ele, com o nome de S99firewall.