Linux обладает отличными средствами фильтрации сетевого трафика, но обычно в нём строят статический firewall. В данной статье я опишу идею и реализацию интерактивного firewall, который в случае подозрительной активности выводит пользователю окно с предложением блокирования трафика или игнорирования предупреждения.Рассмотрим следующую заготовку firewall, которую в дальнейшем можно обучать интерактивно:
cat slackwall.initstate
# Generated by iptables-save v1.4.10 on Sat Dec 3 21:42:46 2011
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:FIREWALL-INPUT - [0:0]
:FIREWALL-FORWARD - [0:0]
:FIREWALL-OUTPUT - [0:0]
-A INPUT -m state --state INVALID -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -j FIREWALL-INPUTFIREWALL-INPUT
-A INPUT -j LOG --log-prefix "FIREWALL-INPUT "
-A INPUT -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -m state --state INVALID -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -p icmp -j ACCEPT
-A FORWARD -p udp -m udp --dport 53 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j FIREWALL-FORWARD
-A FORWARD -j LOG --log-prefix "FIREWALL-FORWARD "
-A FORWARD -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -m state --state INVALID -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -p icmp -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -j FIREWALL-OUTPUT
-A OUTPUT -j LOG --log-prefix "FIREWALL-OUTPUT "
-A OUTPUT -j REJECT --reject-with icmp-port-unreachable
COMMIT
# Completed on Sat Dec 3 21:42:46 2011
В трёх основных цепочках мы сначала запрещаем обрывки соединений, потом разрешаем уже установленные соединения, DNS и ICMP трафик.
Далее пакеты перенаправляются в одну из трёх обучаемых цепочек:
FIREWALL-INPUT
FIREWALL-OUTPUT
FIREWALL-FORWARD
откуда пакеты, для которых не нашлось правила возвращаются в одну из основных цепочек и ЛОГИРУЮТСЯ а затем отклоняются ПО УМОЛЧАНИЮ.
В цепочке FIREWALL-OUTPUT для персонального firewall лучше держать только одно разрешающее правило для всего трафика, иначе обучение становится трудоёмким.
Таким образом пакет в обучаемой цепочке шлибо обрабатывается с соответствующим решением, либо попадает в LOG firewall`а и отклоняется.
То есть строки о "необученных пакетах" можно регулярно считывать, парсить, предлагать решение пользователю и вносить новые правила в обучаемые цепочки.
Например если есть некий shell сценарий обработки SYSLOG, можно выполнить от рута:
tail -n 1 -f /var/log/syslog | ./slackwall
В данном примере обработчик - скрипт slackwall. Вот его текст:
#!/bin/sh
while read string
do
echo $string | grep FIREWALL > /dev/null || continue
for token in $string
do
echo $token | grep "=" > /dev/null && export $token
echo $token | grep "FIREWALL" > /dev/null && export CHAIN=$token
done
[ -z "$IN" ] && unset SRC
[ -z "$OUT" ] && unset DST
HSRC=`host $SRC 2>/dev/null | grep "domain name pointer" | awk '{ print $5 }'`
HDST=`host $DST 2>/dev/null | grep "domain name pointer" | awk '{ print $5 }'`
echo $PROTO | grep "^[[:digit:]]*$" > /dev/null && unset DPT
PROTO=`cat /etc/protocols | grep "[[:space:]]$PROTO[[:space:]]" | awk '{ print $1 }'`
HPROTO=`cat /etc/services | grep -i "[[:space:]]$DPT/$PROTO"`
HSRC=${HSRC:-$SRC}
HDST=${HDST:-$DST}
HPROTO=${HPROTO:-"$DPT/$PROTO"}
unset IHSRC IHDST ISRC IDST IDPT IPROTO
[ -z "$HSRC" ] || IHSRC="-s $HSRC"
[ -z "$HDST" ] || IHDST="-d $HDST"
[ -z "$SRC" ] || ISRC="-s $SRC"
[ -z "$DST" ] || IDST="-d $DST"
[ -z "$DPT" ] || IDPT="--dport $DPT"
IPROTO="-p $PROTO"
cat slackwall.userules | grep "iptables -A $CHAIN $IPROTO $IHSRC $IHDST $IDPT -j" \
&& echo Alredy && continue
cat slackwall.userules | grep "iptables -A $CHAIN $IPROTO $ISRC $IHDST $IDPT -j" \
&& echo Alredy && continue
cat slackwall.userules | grep "iptables -A $CHAIN $IPROTO $IDPT -j" \
&& echo Alredy && continue
unset COMMAND
ACTION=6
LANG=C xmessage -buttons BlockFQDN:1,BlockIP:2,AcceptFQDN:3,AcceptIP:4,BlockPortOnAllIP:5,Skip:6 \
-default Skip -timeout 15 "$HSRC => $HDST ($HPROTO)"
ACTION=$?
[ $ACTION == 0 ] && continue
[ $ACTION == 1 ] && COMMAND="iptables -A $CHAIN $IPROTO $IHSRC $IHDST $IDPT -j REJECT"
[ $ACTION == 2 ] && COMMAND="iptables -A $CHAIN $IPROTO $ISRC $IDST $IDPT -j REJECT"
[ $ACTION == 3 ] && COMMAND="iptables -A $CHAIN $IPROTO $IHSRC $IHDST $IDPT -j ACCEPT"
[ $ACTION == 4 ] && COMMAND="iptables -A $CHAIN $IPROTO $ISRC $IDST $IDPT -j ACCEPT"
[ $ACTION == 5 ] && COMMAND="iptables -A $CHAIN $IPROTO $IDPT -j REJECT"
[ $ACTION == 6 ] && continue
$COMMAND
[ "$?" == 0 ] && echo "$COMMAND" >> slackwall.userules
done
Он парсит строки SYSLOG и рисует на экране пользователя вопрос с помощью xmessage и затем добавляет правило в ядро и дублирует его в сценарий slackwall.userules, предназначенный для начальной инициализации firewall.
Вот его начальное состояние:
#!/bin/bash
modprobe nf_conntrack
modprobe nf_conntrack_amanda
modprobe nf_conntrack_ftp
modprobe nf_conntrack_h323
modprobe nf_conntrack_irc
modprobe nf_conntrack_netbios_ns
modprobe nf_conntrack_netlink
modprobe nf_conntrack_pptp
modprobe nf_conntrack_proto_dccp
modprobe nf_conntrack_proto_gre
modprobe nf_conntrack_proto_sctp
modprobe nf_conntrack_proto_udplite
modprobe nf_conntrack_sane
modprobe nf_conntrack_sip
modprobe nf_conntrack_tftp
modprobe xt_conntrack
iptables -F FIREWALL-INPUT
iptables -F FIREWALL-FORWARD
iptables -F FIREWALL-OUTPUT
iptables -A FIREWALL-OUTPUT -j ACCEPT
Для начального запуска firewall нужно выполнить:
1. Разрешаем руту рисовать на X сервере (выполняется от пользователя, остальное всё от рута)
$xhost +localhost
2. Загружаем неизменяемую часть firewall
#cat slackwall.initstate | iptables-restore
3. Загружаем пользовательские правила, в дальнейшем их можно отредактировать и перезапустить эту комманду
#./slackwall.userules
4. Запускаем скрипт обучения:
#tail -n 1 -f /var/log/syslog | ./slackwall
У меня это работает в таком виде на Slackware 13.37, Linux psc 2.6.37.6-tinyslack Atom(TM) CPU D510 @ 1.66GHz GenuineIntel GNU/Linux.
Ссылка на готовый пакет: https://sourceforge.net/projects/slackwall/
URL:
Обсуждается: http://www.opennet.dev/tips/info/2658.shtml