demon.pmi.basnet.by - авторская страница разработчика сайтов.

Настраиваем IpTables для шлюза

Постановка задачи: Есть сервер с двумя интерфесами eth0 и eth1. По интерфейсу eth1 создан тунель для pppoe соединений с провайдером ppp0 и ppp1. Необходимо обезопасить нашу локальную сеть от нехорошего влияния извне, а так же сам Интернет от влияния нашей маленькой сети. Понятно, что за основу был взят скрипт из бескрайной паутины, но был адаптирован для нашей сети для выполнения следующих целей: запретить все; разрешить только то, что можно; дать с помощью маскарадинга интернет в локальную сеть (кому положено); сделать редирект на прозрачный сквид; дать торрент для одной машины из сети.

На самом деле есть библия по IpTables, где изложено все! Абсолютно все про IpTables... www.opennet.ru/docs/RUS/iptables/index.html

Создадим новый скрипт в каталоге /etc/init.d:


server:/# touch /etc/init.d/rc.firewall
server:/# vim /etc/init.d/rc.firewall

Сама статья сырая и будет еще перерабатываться, но пока я приведу описание основных моментов и приведу сам конфиг iptables

#! /bin/sh
### BEGIN INIT INFO
# Provides:          rc.firewall
# Required-Start:    
# Required-Stop:
# Default-Start:     3
# Default-Stop:	     0 6 	
# Short-Description: Run /etc/init.d/rc.firewall if it exist
### END INIT INFO
######################################################################################
# Configured by Demon, 2009
######################################################################################
# Внешний интерфейс (к ADSL модему 1)
 EXTIF="eth1"
# Внешний интерфейс (тунель по EXTIF - канал 1 провайдера)
 PPPIF="ppp+"
# Внутренний интерфейс (Локальная сеть)
 INTIF="eth0"

# Loop-устройство - localhost
 LPDIF=lo
 LPDIP=127.0.0.1
 LPDMSK=255.0.0.0
 LPDNET="$LPDIP/$LPDMSK"

# Переменные текстовых инструментов
 IPT='/sbin/iptables'
 IFC='/sbin/ifconfig'
 G='/bin/grep'
 SED='/bin/sed'

 UNPRIPORTS="1024:65535"
# Перечень ip адресов закрытых для FORWARD 
 FILENAME_DENY="/etc/deny_inet_hosts"
 FILENAME_ALLOW="/etc/allow.txt"
 FILENAME_PERRING="/etc/perring.txt"


start_fw()
{
	echo ""	
	echo "IpTables configured by Demon"
	# Deny вместо accept: предотвращает открытие "дыр"
	# в то время, как мы закрываем порты и все такое. Все запрещено!
	 $IPT 	-P INPUT       DROP
	 $IPT 	-P OUTPUT      DROP
	 $IPT 	-P FORWARD     DROP
	# Сброс всех существующих цепочек и стирание персональных цепочек
	 CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`
	 for i in $CHAINS
	 do
	  $IPT -t $i -F
	  $IPT -t $i -X
	 done
	 echo 1 > /proc/sys/net/ipv4/tcp_syncookies
	 echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
	# Проверка адреса источника
	 for f in /proc/sys/net/ipv4/conf/*/rp_filter;
	 do
	  echo 1 > $f
	 done
	# Запрет маршрутизации IP от источника и редиректов ICMP
	 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

	# Установка переменных среды для внешнего интерфейса ETH1
	 EXTIP="192.168.2.2"
	 EXTBC="192.168.2.255"
	 EXTMSK="255.255.255.0"
	 EXTNET="$EXTIP/$EXTMSK"
 	 echo ""
	 echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET"

	# Устанвка переменных среды для внутреннего интерфейса
	 INTIP="192.168.1.1"
	 INTBC="192.168.1.255"
	 INTMSK="255.255.255.0"
	 INTNET="192.168.1.0/24"
	 echo ""
	 echo "INTIP=$INTIP INTBC=$INTBC INTMSK=$INTMSK INTNET=$INTNET"

	# Отключаем сообщения о том, что цепочки уже существуют (чтобы перезапуск был без мусора)
	 $IPT -N DROP   2> /dev/null
	 $IPT -N REJECT 2> /dev/null
	 
	
	# Весь траффик от устройства loopback принимается
	# если IP совпадает с любым из наших интерфейсов.
	 $IPT -A INPUT    -i $LPDIF -s   $LPDIP  -j ACCEPT
	 $IPT -A INPUT    -i $LPDIF -s   $EXTIP  -j ACCEPT
	 $IPT -A INPUT    -i $LPDIF -s   $INTIP  -j ACCEPT

	# Широковещательные пакеты
	 $IPT -A INPUT   -i $INTIF -d   $INTBC  -j ACCEPT
	 $IPT -A OUTPUT  -o $EXTIF -d   $EXTBC  -j ACCEPT
	 $IPT -A OUTPUT  -o $INTIF -d   $INTBC  -j ACCEPT
	 $IPT -A FORWARD -o $EXTIF -d   $EXTBC  -j ACCEPT
	 $IPT -A FORWARD -o $INTIF -d   $INTBC  -j ACCEPT
	
	# Блокируем доступ к внутренней сети из WAN
	# Это также призвано не дать нечестивым крякерам использовать нашу сетку
	# в качестве отправной точки для атак на других людей
	# Перевод с языка iptables:
	# "если пришедшие на наружный интерфейс пакеты были отправлены не с выданного
	# nefarious адреса, выкинуть их как горячую картошку"
	 $IPT -A INPUT  -i $EXTIF -d ! $EXTIP  -j DROP
	# А сейчас мы блокируем внутренние адреса, кроме двух, присвоенных нашим двум
	# внутренним интерфейсам.....только помните, что если вы воткнете свой лэптоп или
	# какой другой pc в напрямую в одну из этих сетевых карт, то нужно удостовериться,
	# что они имеют именно эти IP-адреса или добавить соответствующий адрес отдельно.
	# Первый интерфейс/внутренняя сеть
	 $IPT -A INPUT   -i $INTIF -s ! $INTNET -j DROP
	 $IPT -A OUTPUT  -o $INTIF -d ! $INTNET -j DROP
	 $IPT -A FORWARD -i $INTIF -s ! $INTNET -j DROP
	 $IPT -A FORWARD -o $INTIF -d ! $INTNET -j DROP
	# Дополнительная Egress-проверка
	 $IPT -A OUTPUT  -o $EXTIF -s ! $EXTNET -j DROP
	# Разрешаем пакеты ICMP (смысла особого их блокировать я не нашел)
	 $IPT -A INPUT -p icmp -j ACCEPT
	 $IPT -A OUTPUT -p icmp -j ACCEPT
	 $IPT -A FORWARD -p icmp -j ACCEPT
	 
	 $IPT -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1300

	
	# печально известные порты:
	# 0 - tcpmux; у SGI есть уязвимость, через которую можно атаковать
	# 13 - daytime
	# 98 - Linuxconf
	# 111 - sunrpc (portmap)
	# SNMP: 161,2
	# Флотилия Squid: 8000, 8008, 8080 
	# 1214 - Morpheus или KaZaA
	# 2049 - NFS
	# 3049 - очень заразный троян для Linux, часто путаемый с NFS
	# Часто атакуемые: 1999, 4329, 6346
	# Частые трояны 12345 65535
	 COMBLOCK="0:1 13 98 111 161:162 1214 1999 2049 3049 4329 6346 8000 8008 12345 65535"
	# Порты TCP:
	# 98 - Linuxconf
	# 512-5!5 - rexec, rlogin, rsh, printer(lpd)
	#   [очень серьезеные уязвимости; продолжаются ежедневные атаки]
	# 1080 - прокси-серверы Socks
	# 6000 - X (ЗАМЕЧАНИЕ. X через SSH - безопасен, и работает на порту TCP 22)
	# Блокировка 6112 (CDE у Sun и HP)
	 TCPBLOCK="$COMBLOCK 98 512:515 1080 6000:6009 6112"
	# Порты UDP:
	# 161:162 - SNMP
	# 520=RIP, 9000 - Sangoma
	# 517:518 - talk и ntalk (самые надоедливые)
	 UDPBLOCK="$COMBLOCK 520 123 517:518 1427 9000"
	echo ""	 
	echo "Blocking attacks to TCP port"
	for i in $TCPBLOCK;
	do
	 echo -n "$i "
	  $IPT -A INPUT   -p tcp --dport $i  -j DROP
	  $IPT -A OUTPUT  -p tcp --dport $i  -j DROP
	  $IPT -A FORWARD -p tcp --dport $i  -j DROP
	done
	echo ""
	echo "Blocking attacks to UDP port "
	for i in $UDPBLOCK;
	do
	 echo -n "$i "
	  $IPT -A INPUT   -p udp --dport $i  -j DROP
	  $IPT -A OUTPUT  -p udp --dport $i  -j DROP
	  $IPT -A FORWARD -p udp --dport $i  -j DROP
	done
	echo ""
	# Открываем отлеживание соединений по ftp
	 MODULES="ip_nat_ftp ip_conntrack_ftp"
	 for i in $MODULES;
	 do
	  echo "Inserting module $i"
	  modprobe $i
	 done

	# Защищаем некоторые распространенные клиенты для чата.
	# Уберите из списка допустимых для пущей безопасности.
	 IRC='ircd'                                 # сервис IRC
	 MSN=1863                                   # сервис MSN
	 WebMoney=2802                              # сервис WebMoney
	 ICQ=5190                                   # сервис ICQ
	 SSH2=122                                   # наш порт SSH2
	 ADD="81 88"                                # "редкие" порты ТСР 
	 Lineage="2106 6666 7777 9923 17453"        # игра Lineage
	 CS="27015 27016 27017 27018"               # игра Half-Life, CS
	 Cardsh="10300 10500 11150 14450"           # порты для кардшаринга 
	 RA="3389 4899 2083 9010 3128 8080"         # удаленное администрирование 
	 NFS='sunrpc'                               # распределенная файловая система
	 PORTAGE='rsync'
	 OpenPGP_HTTP_Keyserver=11371
	# Все порты сервисов читаются из /etc/services
	  TCPSERV="domain http https ftp ftp-data mail pop3 pop3s imap3 imaps imap2 time www \ 
webmin $WebMoney $SSH2 $RA $PORTAGE $MSN $ICQ $IRC $Lineage $Cardsh $ADD $CS $OpenPGP_HTTP_Keyserver" UDPSERV="domain time netbios-ns netbios-dgm netbios-ssn microsoft-ds $CS" echo "" echo -n "Allowing inside systems to use service TCP:" echo "" for i in $TCPSERV; do echo -n "$i " $IPT -A INPUT -i $INTIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT $IPT -A INPUT -i $EXTIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT $IPT -A INPUT -i $PPPIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT $IPT -A OUTPUT -o $INTIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT $IPT -A OUTPUT -o $EXTIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT $IPT -A OUTPUT -o $PPPIF -p tcp --dport $i --syn -m state --state NEW -j ACCEPT # форвардинг по TCP разрешаем только тем кому можно (кто имеет доступ # в интернет из локальной сети for ip in $(cat $FILENAME_ALLOW); do $IPT -A FORWARD -i $INTIF -p tcp -s $ip --dport $i --syn -m state --state NEW -j ACCEPT done done echo "" echo -n "Allowing inside systems to use service UDP (only Internal Lan):" echo "" for i in $UDPSERV; do echo -n "$i " $IPT -A INPUT -i $INTIF -p udp --dport $i -m state --state NEW -j ACCEPT $IPT -A OUTPUT -o $INTIF -p udp --dport $i -m state --state NEW -j ACCEPT $IPT -A OUTPUT -o $EXTIF -p udp --dport $i -m state --state NEW -j ACCEPT # форвардинг по UDP разрешаем только тем кому можно (кто имеет доступ # в интернет из локальной сети for ip in $(cat $FILENAME_ALLOW); do $IPT -A FORWARD -i $INTIF -p udp -s $ip --dport $i -m state --state NEW -j ACCEPT done done # надо открыть наружу UDP порт domain=53 (иначе не работает DNS) $IPT -A OUTPUT -o $PPPIF -p udp --dport domain -m state --state NEW -j ACCEPT $IPT -A INPUT -i $PPPIF -p udp --dport domain -m state --state NEW -j ACCEPT # DNS rndc сервер на Lo разрешаем. (обход ошибки connection refused) $IPT -A OUTPUT -p tcp -m tcp -o $LPDIF --dport 953 --sport $UNPRIPORTS -j ACCEPT echo "" echo "SQUID exceptions and REDIRECT" # у нас есть пиринг! нет смысла заворачивать его на squid3? иначе он начнет резать скорость, # банеры и проч. А пиринг - это хорошо, потому что быстро! Поэтому еще на этапе PREROUTING # мы принимаем пакеты и выпускаем их в локальную сеть минуя squid for ip in $(cat $FILENAME_PERRING); do $IPT -t nat -A PREROUTING -p tcp -d $ip --dport 80 -j ACCEPT done #Заворачиваем весь остальной трафик по 80 порту на наш прозрачный SQUID $IPT -t nat -A PREROUTING -i eth0 -p tcp -s $INTNET -d ! 192.168.1.1 -m multiport \
--dport 80 -j REDIRECT --to-port 3128 echo "" echo "NAT up!" $IPT -t nat -A PREROUTING -j ACCEPT $IPT -t nat -A POSTROUTING -o $PPPIF -s $INTNET -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 -A INPUT -j DROP $IPT -A OUTPUT -j REJECT $IPT -A FORWARD -j DROP } flush_fw() { # Сброс всех цепочек, стандартных, нестандартных. Обнуление нашего iptables $IPT -P INPUT ACCEPT $IPT -P FORWARD ACCEPT $IPT -P OUTPUT ACCEPT $IPT -t nat -P PREROUTING ACCEPT $IPT -t nat -P POSTROUTING ACCEPT $IPT -t nat -P OUTPUT ACCEPT $IPT -t mangle -P PREROUTING ACCEPT $IPT -t mangle -P OUTPUT ACCEPT $IPT -F $IPT -t nat -F $IPT -t mangle -F $IPT -X $IPT -t nat -X $IPT -t mangle -X } case "$1" in start) echo -n "Starting firewall: iptables" start_fw echo "" echo -n "Starting firewall Ok!" echo "" ;; stop) echo -n "Stopping firewall: iptables" flush_fw echo "" echo -n "Stopping firewall Ok!" echo "" ;; save) echo -n "Saving firewall: iptables" iptables-save > /etc/rules-save echo "" echo -n "Status save Ok!." echo "" ;; restart) echo -n "Restarting firewall: iptables" flush_fw start_fw echo "" echo -n "Status restart Ok!" echo "" ;; reload|force-reload) echo -n "Reloading configuration files for firewall: iptables" echo "." ;; *) echo "Usage: /etc/init.d/rc.firewall start|stop|restart|reload|force-reload" exit 1 ;; esac exit 0

Выставим правильные права на сам скрипт:


server:/# chown root:root /etc/init.d/rc.firewall
server:/# chmod +x /etc/init.d/rc.firewall

И добавим скрипт в автозагрузку:


server:/# ln -s /etc/init.d/rc.firewall /etc/rc3.d/S99rc.firewall
Обратите внимание на то, что ссылка создается в каталог /etc/rc3.d Если у Вас в /etc/inittab установлен не 3 режим работы сервера (id:3:initdefault: многопользовательская платформа с поддержкой сети), а второй (id:2:initdefault: однопользовательская платформа с поддержкой сети) то необходимо создать эту сслыку в каталог rc2.d!!!

Написать комментарий

  • Обязательные для заполнения поля помечены знаком *.