About | Blog | xapy

Настройка iptables на домашнем роутере-сервере

Компьютеры, со временем нахождения дома, имеют отвратительное свойство размножаться. Не успел оглянуться, как в квартире стало 2 десктопа + ноут, что неизбежно потянуло за собой организацию доманей сети. Сеть со временем эволюционировала и сегодня основным звеном является заделанная гейтвеем-файрволом машинка с gentoo linux на борту. Дабы не пропадало наличие внешнего ip-адреса, этот же комп, с другой стороны — небольшой домашний сервак. Перечислить все функции, выполняемые этим сервером довольно не просто, но основные — это веб-сервер, почтовик, ssh, хранилище личных репозиториев, сетевой гейтвей-файрвол, безпроводная точка доступа и ещё пару :) При настройке сервера, далеко не последним критерием был уровень безопасности, т.к. опыт показывает, что не смотря на хвалённую защищённость unix-подобных систем, небрежный пользователь может продать всю систему сам того не зная. Один из ключевых барьеров в системе безопасности — файрвол, о настройке которого дальше идёт речь.

Дальше будут подробности настройки iptables, которые в результате позволят нам:

  1. Раздать интернет в локальной сети всем по маске подсети и по вайфай — по mac-адресам.
  2. Защитить ssh сервер от брут-форс атак
  3. Прокинуть порты снаружи внутрь сети
  4. Открыть соответствующий доступ к сервисам, предназначеным для внутреннего и внешнего пользования.
  5. Ограничить исходящий доступ лишь используемыми портами
  6. Обрабатывать некорректные пакеты/бродкасты
  7. Вести лог подозрительных операций
  8. Всё, что не попало под разрешённые категории — блокировать и п. 7

Сразу скажу, что скрипт не весь писал сам, а многие куски поворовал из интернета, но если кого-то обижу — смело пишите, вставлю линк. В качестве базового использовался скрипт, написанный по мотивам Gentoo-linux wiki: HOWTO Использование iptables Финальный результат — в завершении статьи

Начинаем с определения переменных, которые будут использоваться далее:

#!/bin/bash

IPT='/sbin/iptables'
IFC='/sbin/ifconfig'
G="/bin/grep"
SED="/bin/sed"
AWK="/usr/bin/awk"
ECHO="/bin/echo"

# Далее определяем сетевые интерфейсы — два внутренних, внешний и безпроводной
EXTIF='eth2'
INT1IF='eth0'
INT2IF='eth1'
WIFIIF='ath0'

# тут определим маки, которым хотим отдать интернет в полное пользование по wi-fi
LAPTOP_MAC="00:1c:bf:2d:f8:cf"
PPC_MAC="00:02:8a:a0:0a:76"
ANNA_MAC="00:1b:11:b1:9f:92"
WIFIALLOWEDMACS="$LAPTOP_MAC $PPC_MAC $ANNA_MAC"

это всё будет использовано позже. В этом куске реализуем обещанный анти-брутфорс, средствами iptables, модуля recent:

# SSH anti-bruteforce
$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH --rsource
$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --rttl --name SSH --rsource -j LOG --log-prefix "SSH_brute_force "
$IPT -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --rttl --name SSH --rsource -j DROP

В результате, в течении трёх минут, разрешаем не более трёх попыток соединения, остальные — дропаем с записью в лог. В случае срабатывания, в системном логе получаем чледующее:

Mar  1 10:30:45 xa4a kernel: SSH_brute_force IN=eth2 OUT= MAC=00:e0:6f:d9:b4:3d:00:d0:88:04:cf:d4:08:00 SRC=202.144.155.53 DST=82.144.198.94 LEN=60 TOS=0x00 PREC=0x00 TTL=49 ID=18235 DF PROTO=TCP SPT=55457 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
Mar  1 10:30:48 xa4a kernel: SSH_brute_force IN=eth2 OUT= MAC=00:e0:6f:d9:b4:3d:00:d0:88:04:cf:d4:08:00 SRC=202.144.155.53 DST=82.144.198.94 LEN=60 TOS=0x00 PREC=0x00 TTL=49 ID=18236 DF PROTO=TCP SPT=55457 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0
Mar  1 10:30:54 xa4a kernel: SSH_brute_force IN=eth2 OUT= MAC=00:e0:6f:d9:b4:3d:00:d0:88:04:cf:d4:08:00 SRC=202.144.155.53 DST=82.144.198.94 LEN=60 TOS=0x00 PREC=0x00 TTL=49 ID=18237 DF PROTO=TCP SPT=55457 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0

По строке “SSH_brute_force” запросто выбираем эти записи из лога и анализируем.

Сразу же добавляем

$IPT -A INPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT

то есть разрешаем доступ к ssh, дабы не быть отрезанными от роутера последующими правилами.

Абсолютно аналогично разрешаем доступ к сервисам, к которым не планируем ограничивать доступ (средствами файрвола), вроде web-сервера, почтовика и иже, заменяя 22 на соответствующий порт.

Следующим этапом — проброс отдельных портов внутрь сети. Для каждого порта дописываем несколько строк, например:

VNC_TO="10.0.0.2"
$IPT -t nat -A PREROUTING -d $EXTIP -p tcp  --dport 5900 -j DNAT --to-destination $VNC_TO:5900
$IPT -A FORWARD -d $INT2NET -i $EXTIF -p tcp --dport 5900 -j ACCEPT

Тут из существенного — в первой строке вписываем внутренний адрес машины назначения, в последней — вместо $INT2NET — соответствующий интерфейс.

Тут банальный NAT:

$IPT -t nat -A PREROUTING -j ACCEPT
$IPT -t nat -A POSTROUTING                       -j ACCEPT
$IPT -t nat -A OUTPUT                            -j ACCEPT

$IPT -t nat -A POSTROUTING -o $EXTIF -s $INT1NET -j MASQUERADE
$IPT -t nat -A POSTROUTING -o $EXTIF -s $INT2NET -j MASQUERADE
$IPT -t nat -A POSTROUTING -o $EXTIF -s $WIFINET -j MASQUERADE

Далее будем управлять пакетами, служащими для открытия соединения, потому пакеты, относящиеся к открытым (читай разрешённым) соединениям - пропускаем

$IPT -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

Блокируем бродкасты

# Blocking Broadcasts
$IPT -A INPUT   -i $EXTIF  -d  $EXTBC   -j DROPl
$IPT -A INPUT   -i $INT1IF -d  $INT1BC  -j DROPl
$IPT -A INPUT   -i $INT2IF -d  $INT2BC  -j DROPl
$IPT -A INPUT   -i $WIFIIF -d  $WIFIBC  -j DROPl
# (повторить ещё два раза, заменив INPUT на OUTPUT, FORWARD)

Далее блокируем пакеты с адресами, не соответствующими интерфейсам:

# Interface one/internal net one
$IPT -A INPUT   -i $INT1IF -s ! $INT1NET -j DROPl
$IPT -A OUTPUT  -o $INT1IF -d ! $INT1NET -j DROPl
$IPT -A FORWARD -i $INT1IF -s ! $INT1NET -j DROPl
$IPT -A FORWARD -o $INT1IF -d ! $INT1NET -j DROPl
# (То же для каждого из внутренних интерфейсов)

# Теперь проведём добавочную проверку (Egress) пакетов и заблокируем все
# icmp запросы, за исключением пингов:
# дополнительная проверка на Egress
$IPT -A INPUT   -i $EXTIF -d ! $EXTIP  -j DROPl
$IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROPl
## Блокировка исходящих ICMP (исключение: PING)
$IPT -A OUTPUT  -o $EXTIF -p icmp --icmp-type ! 8 -j DROPl
$IPT -A FORWARD -o $EXTIF -p icmp --icmp-type ! 8 -j DROPl

Доступ из локальной сети к локальным же сервисам:

# django
$IPT -A INPUT -i $INT2IF -p tcp --dport 8000 -j ACCEPT
# mysql
$IPT -A INPUT -i $INT2IF -p tcp --dport 3306 -j ACCEPT

Рядом — исходящий доступ для роутера:

# CVS client
$IPT -A OUTPUT -o $EXTIF -p tcp --dport 2401 -j ACCEPT

# DNS client
$IPT -A OUTPUT -o $EXTIF -p udp --dport 53 -j ACCEPT

Дальше начинаем блокировать: описываем общие (tcp и udp) блокируемые порты и отдельно для каждого из протоколов:

COMBLOCK="0:1 13 98 161:162 1214 1999 3049 4329 6346 3128 8000 8008 8080 12345 65535"
TCPBLOCK="$COMBLOCK 98 512:515 1080 6000:6009"
UDPBLOCK="$COMBLOCK 123 161:162 520 517:518 1427 9000 9 6346 3128 8000 8008 8080 12345 65535"

После этого простыми циклами делаем:

   $IPT -A INPUT   -p tcp --dport $i  -j DROPl
   $IPT -A OUTPUT  -p tcp --dport $i  -j DROPl
   $IPT -A FORWARD -p tcp --dport $i  -j DROPl

Самая часторедактируемая часть моего скрипта — настройка исходящего доступа для потребителей розданного интернета. Описываем словами открываемые порты, чтобы по возвращению через n лет было меньше неразберихи:

IRC='6667 6669'
ICQ=5190
JABBER='5222 5223'
STARCRAFT='6112 6113 6114 6115 6116 6117 6118 6119 4000 6200'
MSN=1863
PORTAGE='rsync'
OpenPGP_HTTP_Keyserver=11371
DC="411"
TEAMSPEAK="8767"
SOLDAT="23073"
VNC="5900"
CS="27015 27016 27017 27018"
CVS_CLIENT="2401"
TORRENT_TRACKER="6969"
RUNESCAPE="43594 43595 8010"
TCPSERV="domain ssh smtp http https 8443 8444 ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE $IRC $MSN $ICQ $OpenPGP_HTTP_Keyserver $JABBER $STARCRAFT $DC $RUNESCAPE $SOLDAT $CVS_CLIENT $TORRENT_TRACKER $VNC"
UDPSERV="domain time $STARCRAFT $TEAMSPEAK $CS"

После этого, как и выше — циклом открываем доступ (тут не забываем про беспроводных пользователей):

 $IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP --dport $i --syn -m state --state NEW -j ACCEPT
 $IPT -A FORWARD -i $INT1IF -p tcp -s $INT1NET --dport $i --syn -m state --state NEW -j ACCEPT
 $IPT -A FORWARD -i $INT2IF -p tcp -s $INT2NET --dport $i --syn -m state --state NEW -j ACCEPT
for mac in $WIFIALLOWEDMACS; do
  $IPT -A FORWARD -i $WIFIIF -p tcp -m mac --mac-source $mac --dport $i --syn -m state --state NEW -j ACCEPT
done

Это для tcp. Для udp — всё с точностью до изменения нескольких слов.

В завершение разрешаем пинги: из сети в интернет и из роутера в сеть

$IPT -A OUTPUT  -o $EXTIF -p icmp -s $EXTIP --icmp-type 8 -m state --state NEW -j ACCEPT
$IPT -A FORWARD -i $INT1IF -p icmp -s $INT1NET --icmp-type 8 -m state --state NEW -j ACCEPT
$IPT -A FORWARD -i $INT2IF -p icmp -s $INT2NET --icmp-type 8 -m state --state NEW -j ACCEPT
for mac in $WIFIALLOWEDMACS; do
  $IPT -A FORWARD -i $WIFIIF -p icmp -s $WIFINET -m mac --mac-source $mac --icmp-type 8 -m state --state NEW -j ACCEPT
done

$IPT -A OUTPUT  -o $INT1IF -p icmp -s $INT1NET --icmp-type 8 -m state --state NEW -j ACCEPT
$IPT -A OUTPUT  -o $INT2IF -p icmp -s $INT2NET --icmp-type 8 -m state --state NEW -j ACCEPT
$IPT -A OUTPUT  -o $WIFIIF -p icmp -s $WIFINET --icmp-type 8 -m state --state NEW -j ACCEPT

Завершаем настройку блокировкой всего, что не разрешили:

# Log & block whatever is left
$IPT -A INPUT             -j DROPl
$IPT -A OUTPUT            -j REJECTl
$IPT -A FORWARD           -j DROPl

В описании намеренно опустил некоторые детали, т.к. и так много букв вышло. Далее лежит полная версия скрипта:

#!/bin/bash

IPT='/sbin/iptables'
IFC='/sbin/ifconfig'
G="/bin/grep"
SED="/bin/sed"
AWK="/usr/bin/awk"
ECHO="/bin/echo"

# Flush all existing chains and erase personal chains
CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`
for i in $CHAINS;
  do
  $IPT -t $i -F
  done
  for i in $CHAINS;
do
$IPT -t $i -X
done

EXTIF='eth2'
INT1IF='eth0'
INT2IF='eth1'
WIFIIF='ath0'

LAPTOP_MAC="00:1c:bf:2d:f8:cf"
PPC_MAC="00:02:8a:a0:0a:76"
ANNA_MAC="00:1b:11:b1:9f:92"
WIFIALLOWEDMACS="$LAPTOP_MAC $PPC_MAC $ANNA_MAC"

NFS_ALLOWED_EXT_HOSTS="91.90.16.194"

LPDIF="lo"
LPDIP="127.0.0.1"
LPDMSK="255.0.0.0"
LPDNET="$LPDIP/$LPDMSK"

# SSH anti-bruteforce
$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH --rsource
$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --rttl --name SSH --rsource -j LOG --log-prefix "SSH_brute_force "
$IPT -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --rttl --name SSH --rsource -j DROP

$IPT -A INPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --dport 25 --syn -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --dport 80 --syn -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --dport 81 --syn -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --dport 443 --syn -m state --state NEW -j ACCEPT
$IPT -A INPUT -p tcp --dport 995 --syn -m state --state NEW -j ACCEPT
#$IPT -A INPUT -p tcp -m multiport --dport 49300:49600 --syn -m state --state NEW -j ACCEPT

EXTIP="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
EXTBC="255.255.255.255"
EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`"
EXTMSK="`$IFC $EXTIF|$AWK /$EXTIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"
EXTNET="$EXTIP/$EXTMSK"
$ECHO "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"

INT1IP="`$IFC $INT1IF|$AWK /$INT1IF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
INT1BC="`$IFC $INT1IF|$AWK /$INT1IF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`"
INT1MSK="`$IFC $INT1IF|$AWK /$INT1IF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"
INT1NET="$INT1IP/$INT1MSK"
$ECHO "INT1IP=$INT1IP INT1BC=$INT1BC INT1MSK=$INT1MSK INT1NET=$INT1NET"

INT2IP="`$IFC $INT2IF|$AWK /$INT2IF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
INT2BC="`$IFC $INT2IF|$AWK /$INT2IF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`"
INT2MSK="`$IFC $INT2IF|$AWK /$INT2IF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"
INT2NET="$INT2IP/$INT2MSK"
$ECHO "INT2IP=$INT2IP INT2BC=$INT2BC INT2MSK=$INT2MSK INT2NET=$INT2NET"

WIFIIP="`$IFC $WIFIIF|$AWK /$WIFIIF/'{next}//{split($0,a,":");split(a[2],a," ");print a[1];exit}'`"
WIFIBC="`$IFC $WIFIIF|$AWK /$WIFIIF/'{next}//{split($0,a,":");split(a[3],a," ");print a[1];exit}'`"
WIFIMSK="`$IFC $WIFIIF|$AWK /$WIFIIF/'{next}//{split($0,a,":");split(a[4],a," ");print a[1];exit}'`"
WIFINET="$WIFIIP/$WIFIMSK"
$ECHO "WIFIIP=$WIFIIP WIFIBC=$WIFIBC WIFIMSK=$WIFIMSK WIFINET=$WIFINET"

# Samba printing

$IPT -A FORWARD -p tcp -i $INT2IF -d 192.168.0.2 --dport 445 -j ACCEPT
$IPT -A FORWARD -p tcp -i $INT2IF -d 192.168.0.2 --dport 139 -j ACCEPT
for mac in $WIFIALLOWEDMACS; do
  $IPT -A FORWARD -p tcp -i $WIFIIF -m mac --mac-source $mac -d 192.168.0.2 --dport 139 -j ACCEPT
done
$IPT -A OUTPUT -p tcp -d 192.168.0.2 --dport 445 -j ACCEPT
$IPT -A OUTPUT -p tcp -d 192.168.0.2 --dport 139 -j ACCEPT

# DHCP

$IPT -A INPUT -s 82.144.192.41 -p udp --dport 67 --sport 68 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 68 --sport 67 -j ACCEPT

# Port forwards
# Torrent
TORRENT_TO="10.0.0.2"
$IPT -t nat -A PREROUTING -d $EXTIP -p tcp  --dport 60757 -j DNAT --to-destination $TORRENT_TO:60757
#$IPT -t nat -A PREROUTING -d $EXTIP -p udp  --dport 60757 -j DNAT --to-destination $TORRENT_TO:60757
$IPT -A FORWARD -d $INT2NET -i $EXTIF -p tcp --dport 60757 -j ACCEPT
#$IPT -A FORWARD -d $INT2NET -i $EXTIF -p udp --dport 60757 -j ACCEPT

# VNC
VNC_TO="10.0.0.2"
#VNC_TO="192.168.1.4"
$IPT -t nat -A PREROUTING -d $EXTIP -p tcp  --dport 5900 -j DNAT --to-destination $VNC_TO:5900
$IPT -A FORWARD -d $INT2NET -i $EXTIF -p tcp --dport 5900 -j ACCEPT

# Starcraft
STAR_TO="10.0.0.2"
$IPT -t nat -A PREROUTING -d $EXTIP -p tcp -m multiport --dports 6112:6119 -j DNAT --to-destination $STAR_TO
$IPT -A FORWARD -d $INT2NET -i $EXTIF -p tcp -m multiport --dports 6112:6119 -j ACCEPT
$IPT -t nat -A PREROUTING -d $EXTIP -p udp -m multiport  --dports 6112:6119 -j DNAT --to-destination $STAR_TO
$IPT -A FORWARD -d $INT2NET -i $EXTIF -p udp -m multiport --dports 6112:6119 -j ACCEPT

# QIP
QIP_TO="10.0.0.2"
$IPT -t nat -A PREROUTING -d $EXTIP -p tcp  --dport 11938 -j DNAT --to-destination $QIP_TO:11938
$IPT -A FORWARD -d $INT2NET -i $EXTIF -p tcp --dport 11938 -j ACCEPT
$IPT -t nat -A PREROUTING -d $EXTIP -p tcp  --dport 26708 -j DNAT --to-destination $QIP_TO:26708
$IPT -A FORWARD -d $INT2NET -i $EXTIF -p tcp --dport 26708 -j ACCEPT
$IPT -t nat -A PREROUTING -d $EXTIP -p tcp  --dport 20416 -j DNAT --to-destination $QIP_TO:20416
$IPT -A FORWARD -d $INT2NET -i $EXTIF -p tcp --dport 20416 -j ACCEPT

# Synergy
SYNERGY_TO="10.0.0.1"
$IPT -t nat -A PREROUTING -d $WIFIIP -p tcp  --dport 24800 -j DNAT --to-destination $SYNERGY_TO:24800
$IPT -A FORWARD -d $INT2NET -i $WIFIIF -p tcp --dport 24800 -j ACCEPT
# Mpc
MPC_TO="10.0.0.1"
$IPT -t nat -A PREROUTING -d $WIFIIP -p tcp  --dport 6600 -j DNAT --to-destination $SYNERGY_TO:6600
$IPT -A FORWARD -d $INT2NET -i $WIFIIF -p tcp --dport 6600 -j ACCEPT


# Allow to go outside

$IPT -A OUTPUT -o $INT2IF -p tcp -s $INT2IP -m state --state NEW -j ACCEPT
$IPT -A OUTPUT -o $INT1IF -p tcp -s $INT1IP -m state --state NEW -j ACCEPT
$IPT -A OUTPUT -o $WIFIIF -p tcp -s $WIFIIP -m state --state NEW -j ACCEPT


$IPT -t nat -A PREROUTING -j ACCEPT

# $IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET -j SNAT --to $EXTIP
# Раскомментируйте следующую строку (там где "MASQUERADE"), чтобы не
# использовать NAT для внутренней сети
$IPT -t nat -A POSTROUTING -o $EXTIF -s $INT1NET -j MASQUERADE
$IPT -t nat -A POSTROUTING -o $EXTIF -s $INT2NET -j MASQUERADE
$IPT -t nat -A POSTROUTING -o $EXTIF -s $WIFINET -j MASQUERADE

$IPT -t nat -A POSTROUTING                       -j ACCEPT
$IPT -t nat -A OUTPUT                            -j ACCEPT
#$IPT -A INPUT   -p tcp --dport auth --syn -m state --state NEW -j ACCEPT
$IPT -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Подавить сообщения о существовании цепочки, чтобы сделать вывод на консоль при рестарте "чистым"
$IPT -N DROPl   2> /dev/null
$IPT -A DROPl -m limit --limit 3/minute --limit-burst 10 -j LOG --log-prefix 'FIREWALL DROP BLOCKED:'
$IPT -A DROPl   -j DROP
$IPT -N REJECTl 2> /dev/null
$IPT -A REJECTl -m limit --limit 3/minute --limit-burst 10 -j LOG --log-prefix 'FIREWALL REJECT BLOCKED:'
$IPT -A REJECTl -j REJECT
$IPT -N DROP2   2> /dev/null
$IPT -A DROP2 -m limit --limit 3/second --limit-burst 10 -j LOG --log-prefix 'FIREWALL DROP UNKNOWN:'
$IPT -A DROP2   -j DROP
$IPT -N REJECT2 2> /dev/null
$IPT -A REJECT2 -m limit --limit 3/second --limit-burst 10 -j LOG --log-prefix 'FIREWALL REJECT UNKNOWN:'
$IPT -A REJECT2 -j REJECT
# А теперь, для теста, журналируемый ACCEPT
$IPT -N ACCEPTl   2> /dev/null
$IPT -A ACCEPTl -m limit --limit 10/second --limit-burst 50 -j LOG --log-prefix 'FIREWALL ACCEPT:'
$IPT -A ACCEPTl   -j ACCEPT

$IPT -A INPUT   -i $LPDIF -s   $LPDIP   -j ACCEPT
$IPT -A INPUT   -i $LPDIF -s   $EXTIP   -j ACCEPT
$IPT -A INPUT   -i $LPDIF -s   $INT1IP  -j ACCEPT
$IPT -A INPUT   -i $LPDIF -s   $INT2IP  -j ACCEPT
$IPT -A INPUT   -i $LPDIF -s   $WIFIIP  -j ACCEPT
$IPT -A OUTPUT  -o $LPDIF -j ACCEPT

# Blocking Broadcasts
$IPT -A INPUT   -i $EXTIF  -d  $EXTBC   -j DROPl
$IPT -A INPUT   -i $INT1IF -d  $INT1BC  -j DROPl
$IPT -A INPUT   -i $INT2IF -d  $INT2BC  -j DROPl
$IPT -A INPUT   -i $WIFIIF -d  $WIFIBC  -j DROPl
$IPT -A OUTPUT  -o $EXTIF  -d  $EXTBC   -j DROPl
$IPT -A OUTPUT  -o $INT1IF -d  $INT1BC  -j DROPl
$IPT -A OUTPUT  -o $INT2IF -d  $INT2BC  -j DROPl
$IPT -A OUTPUT  -o $WIFIIF -d  $WIFIBC  -j DROPl
$IPT -A FORWARD -o $EXTIF  -d  $EXTBC   -j DROPl
$IPT -A FORWARD -o $INT1IF -d  $INT1BC  -j DROPl
$IPT -A FORWARD -o $INT2IF -d  $INT2BC  -j DROPl
$IPT -A FORWARD -o $WIFIIF -d  $WIFIBC  -j DROPl

# Interface one/internal net one
$IPT -A INPUT   -i $INT1IF -s ! $INT1NET -j DROPl
$IPT -A OUTPUT  -o $INT1IF -d ! $INT1NET -j DROPl
$IPT -A FORWARD -i $INT1IF -s ! $INT1NET -j DROPl
$IPT -A FORWARD -o $INT1IF -d ! $INT1NET -j DROPl
# Interface two/internal net two
$IPT -A INPUT   -i $INT2IF -s ! $INT2NET -j DROPl
$IPT -A OUTPUT  -o $INT2IF -d ! $INT2NET -j DROPl
$IPT -A FORWARD -i $INT2IF -s ! $INT2NET -j DROPl
$IPT -A FORWARD -o $INT2IF -d ! $INT2NET -j DROPl
# Interface wifi net three
$IPT -A INPUT   -i $WIFIIF -s ! $WIFINET -j DROPl
$IPT -A OUTPUT  -o $WIFIIF -d ! $WIFINET -j DROPl
$IPT -A FORWARD -i $WIFIIF -s ! $WIFINET -j DROPl
$IPT -A FORWARD -o $WIFIIF -d ! $WIFINET -j DROPl

# Теперь проведём добавочную проверку (Egress) пакетов и заблокируем все
# icmp запросы, за исключением пингов:
# дополнительная проверка на Egress
$IPT -A INPUT   -i $EXTIF -d ! $EXTIP  -j DROPl
$IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROPl
## Блокировка исходящих ICMP (исключение: PING)
$IPT -A OUTPUT  -o $EXTIF -p icmp --icmp-type ! 8 -j DROPl
$IPT -A FORWARD -o $EXTIF -p icmp --icmp-type ! 8 -j DROPl

# Local services
$IPT -A INPUT -i $INT2IF -p tcp --dport 3632 -j ACCEPT
$IPT -A INPUT -i $INT1IF -p tcp --dport 3632 -j ACCEPT
$IPT -A INPUT -i $WIFIIF -p tcp --dport 3632 -j ACCEPT

# django
$IPT -A INPUT -i $INT2IF -p tcp --dport 8000 -j ACCEPT
# mysql
$IPT -A INPUT -i $INT2IF -p tcp --dport 3306 -j ACCEPT

# NFS
$IPT -A INPUT -i $INT2IF -p tcp --dport 2049 -j ACCEPT
$IPT -A INPUT -i $INT2IF -p udp --dport 2049 -j ACCEPT
$IPT -A INPUT -i $INT1IF -p tcp --dport 2049 -j ACCEPT
$IPT -A INPUT -i $INT1IF -p udp --dport 2049 -j ACCEPT
$IPT -A INPUT -i $WIFIIF -p tcp --dport 2049 -j ACCEPT
$IPT -A INPUT -i $WIFIIF -p udp --dport 2049 -j ACCEPT

$IPT -A INPUT -i $INT2IF -p tcp --dport 111 -j ACCEPT
$IPT -A INPUT -i $INT2IF -p udp --dport 111 -j ACCEPT
$IPT -A INPUT -i $INT1IF -p tcp --dport 111 -j ACCEPT
$IPT -A INPUT -i $INT1IF -p udp --dport 111 -j ACCEPT
$IPT -A INPUT -i $WIFIIF -p tcp --dport 111 -j ACCEPT
$IPT -A INPUT -i $WIFIIF -p udp --dport 111 -j ACCEPT

for host in $NFS_ALLOWED_EXT_HOSTS
do
  $IPT -A INPUT -i $EXTIF -s $host -p tcp --dport 2049 -j ACCEPT
  $IPT -A INPUT -i $EXTIF -s $host -p udp --dport 2049 -j ACCEPT
  $IPT -A INPUT -i $EXTIF -s $host -p udp --dport 32767 -j ACCEPT
  $IPT -A INPUT -i $EXTIF -s $host -p tcp --dport 32767 -j ACCEPT
  $IPT -A INPUT -i $EXTIF -s $host -p tcp --dport 111 -j ACCEPT
  $IPT -A INPUT -i $EXTIF -s $host -p udp --dport 111 -j ACCEPT
done


$IPT -A INPUT -i $INT2IF -p udp --dport 32767 -j ACCEPT
$IPT -A INPUT -i $INT2IF -p tcp --dport 32767 -j ACCEPT
$IPT -A INPUT -i $INT1IF -p udp --dport 32767 -j ACCEPT
$IPT -A INPUT -i $INT1IF -p tcp --dport 32767 -j ACCEPT
$IPT -A INPUT -i $WIFIIF -p udp --dport 32767 -j ACCEPT
$IPT -A INPUT -i $WIFIIF -p tcp --dport 32767 -j ACCEPT

# NTP client and server
$IPT -A INPUT -p udp --dport 123 -j ACCEPT
$IPT -A OUTPUT -o $EXTIF -p udp --dport 123 -j ACCEPT

# CVS client
$IPT -A OUTPUT -o $EXTIF -p tcp --dport 2401 -j ACCEPT

# NFS mount
$IPT -A OUTPUT -o $INT2IF -p tcp --dport 111 -j ACCEPT
$IPT -A OUTPUT -o $INT2IF -p udp --dport 111 -j ACCEPT

$IPT -A OUTPUT -o $INT2IF -p tcp --dport 2049 -j ACCEPT
$IPT -A OUTPUT -o $INT2IF -p udp --dport 2049 -j ACCEPT

$IPT -A OUTPUT -o $INT2IF -p tcp --dport 32767 -j ACCEPT
$IPT -A OUTPUT -o $INT2IF -p udp --dport 32767 -j ACCEPT

# DNS client
$IPT -A OUTPUT -o $EXTIF -p udp --dport 53 -j ACCEPT
# Некоторые распространённые:
# 0 это tcpmux; SGI обладала уязвимостью, порт 1 также используется (нужно уточнение Fank)
# 13 это daytime
# 98 обслуживает Linuxconf
# 137:139, 445 это протоколы NetBIOS от Microsoft
# SNMP: 161,2
# Squid flotilla: 3128, 8000, 8008, 8080
# 1214 это Morpheus или KaZaA
# 3049 это очень опасный Linux Trojan, mistakable for NFS
# Common attacks: 1999, 4329, 6346
# Common Trojans 12345 65535
COMBLOCK="0:1 13 98 161:162 1214 1999 3049 4329 6346 3128 8000 8008 8080 12345 65535"
# TCP ports:
# 98 is Linuxconf
# 512-515 is rexec, rlogin, rsh, printer(lpd)
#   [very serious vulnerabilities; attacks continue daily]
# 1080 is Socks proxy server
# 6000 is X (NOTE X over SSH is secure and runs on TCP 22)
# Block 6112 (Sun's/HP's CDE)
TCPBLOCK="$COMBLOCK 98 512:515 1080 6000:6009"

# UDP ports:
# 161:162 is SNMP
# 520=RIP, 9000 is Sangoma
# 517:518 are talk and ntalk (more annoying than anything)
UDPBLOCK="$COMBLOCK 123 161:162 520 517:518 1427 9000 9 6346 3128 8000 8008 8080 12345 65535"

echo -n "FW: Blocking attacks to TCP port"
for i in $TCPBLOCK;
do
 echo -n "$i "
   $IPT -A INPUT   -p tcp --dport $i  -j DROPl
   $IPT -A OUTPUT  -p tcp --dport $i  -j DROPl
   $IPT -A FORWARD -p tcp --dport $i  -j DROPl
done
echo ""

echo -n "FW: Blocking attacks to UDP port "
for i in $UDPBLOCK;
do
 echo -n "$i "
  $IPT -A INPUT   -p udp --dport $i  -j DROPl
  $IPT -A OUTPUT  -p udp --dport $i  -j DROPl
  $IPT -A FORWARD -p udp --dport $i  -j DROPl
done
echo ""

# Source Address Verification
for f in /proc/sys/net/ipv4/conf/*/rp_filter;
do
 echo 1 > $f
done
# Disable IP source routing and ICMP redirects
for f in /proc/sys/net/ipv4/conf/*/accept_source_route;
do
 echo 0 > $f
done
for f in /proc/sys/net/ipv4/conf/*/accept_redirects;
do
 echo 0 > $f
done
echo 1 > /proc/sys/net/ipv4/ip_forward

IRC='6667 6669'
ICQ=5190
JABBER='5222 5223'
STARCRAFT='6112 6113 6114 6115 6116 6117 6118 6119 4000 6200'
MSN=1863
PORTAGE='rsync'
OpenPGP_HTTP_Keyserver=11371
DC="411"
TEAMSPEAK="8767"
SOLDAT="23073"
VNC="5900"
CS="27015 27016 27017 27018"
CVS_CLIENT="2401"
TORRENT_TRACKER="6969"
RUNESCAPE="43594 43595 8010"
TCPSERV="domain ssh smtp http https 8443 8444 ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time $PORTAGE $IRC $MSN $ICQ $OpenPGP_HTTP_Keyserveri $JABBER $STARCRAFT $DC $RUNESCAPE $SOLDAT $CVS_CLIENT $TORRENT_TRACKER $VNC"
UDPSERV="domain time $STARCRAFT $TEAMSPEAK $CS"
echo -n "FW: Allowing inside systems to use service(tcp):"
for i in $TCPSERV;
do
 echo -n "$i "
 $IPT -A OUTPUT  -o $EXTIF -p tcp -s $EXTIP --dport $i --syn -m state --state NEW -j ACCEPT
 $IPT -A FORWARD -i $INT1IF -p tcp -s $INT1NET --dport $i --syn -m state --state NEW -j ACCEPT
 $IPT -A FORWARD -i $INT2IF -p tcp -s $INT2NET --dport $i --syn -m state --state NEW -j ACCEPT
for mac in $WIFIALLOWEDMACS; do
  $IPT -A FORWARD -i $WIFIIF -p tcp -m mac --mac-source $mac --dport $i --syn -m state --state NEW -j ACCEPT
done
done
echo ""

echo -n "FW: Allowing inside systems to use service(udp):"
for i in $UDPSERV;
do
 echo -n "$i "
 $IPT -A OUTPUT  -o $EXTIF -p udp -s $EXTIP --dport $i -m state --state NEW -j ACCEPT
 $IPT -A FORWARD -i $INT1IF -p udp -s $INT1NET --dport $i -m state --state NEW -j ACCEPT
 $IPT -A FORWARD -i $INT2IF -p udp -s $INT2NET --dport $i -m state --state NEW -j ACCEPT
 for mac in $WIFIALLOWEDMACS; do
   $IPT -A FORWARD -i $WIFIIF -p udp -m mac --mac-source $mac --dport $i -m state --state NEW -j ACCEPT
 done
done
echo ""

# Allow to ping out
$IPT -A OUTPUT  -o $EXTIF -p icmp -s $EXTIP --icmp-type 8 -m state --state NEW -j ACCEPT
$IPT -A FORWARD -i $INT1IF -p icmp -s $INT1NET --icmp-type 8 -m state --state NEW -j ACCEPT
$IPT -A FORWARD -i $INT2IF -p icmp -s $INT2NET --icmp-type 8 -m state --state NEW -j ACCEPT
for mac in $WIFIALLOWEDMACS; do
  $IPT -A FORWARD -i $WIFIIF -p icmp -s $WIFINET -m mac --mac-source $mac --icmp-type 8 -m state --state NEW -j ACCEPT
done

# Allow firewall to ping internal systems
$IPT -A OUTPUT  -o $INT1IF -p icmp -s $INT1NET --icmp-type 8 -m state --state NEW -j ACCEPT
$IPT -A OUTPUT  -o $INT2IF -p icmp -s $INT2NET --icmp-type 8 -m state --state NEW -j ACCEPT
$IPT -A OUTPUT  -o $WIFIIF -p icmp -s $WIFINET --icmp-type 8 -m state --state NEW -j ACCEPT


# Log & block whatever is left
$IPT -A INPUT             -j DROPl
$IPT -A OUTPUT            -j REJECTl
$IPT -A FORWARD           -j DROPl
Add post to: Delicious Reddit Slashdot Digg Technorati Google
Comment

Comments

No comments for this post

Comment form for «my-iptables»

Required. 30 chars of fewer.

Required.

captcha image Please, enter symbols, which you see on the image