Firewall iptables
Итак в один прекрасный момент возникла необходимость установить фаервол на сервере под линуксом, который будет интернет-шлюзом и не только. Основные задачи:
- закрыть доступ сотрудникам на определенные сайты - соц. сети и прочие, при этом не закрывая их для начальства.
- закрыть аську (есть чат для сотрудников), также оставив доступ к ней начальству.
- запретить выход в сеть другим нежелательным приложениям.
- сделать проброс портов для возможности it-отделу подключаться к своим рабочим компьютерам из внешней сети.
- открыть доступ из вне к серверу для администрирования через ssh.
- открыть из вне 80ый порт для доступа к будущему сайту.
- открыть из вне порты 25 и 110 для почтового сервера.
- Для IT-отдела отдельно открывать все, что понадобится)
В итоге сотрудникам в внешнюю сеть открыты только порты 80 (http) 443 (https) 53 (dns), и закрыты вконтактики и проч.. Аськи работать не будут так как используют др. порты (основной 5190).
Реализовывать эти задачи будем с помощью iptables — утилиты командной строки, является стандартным интерфейсом управления работой межсетевого экрана (брандмауэра) netfilter для ядер Linux версий 2.4 и 2.6. После дня изучения был создан достаточно простой скрипт настройки, наверно не лишенный недостатков но вполне рабочий. Теорию копипастить не буду, в сети ее море, да и из комментариев ниже многое понятно. Приступим. Если iptables не установлен - ставим:
sudo suapt-get install iptables Создаем скрипт настройки и даем права на его выполнение:
touch fw.shchmod +x fw.sh Создаем два текстовых файла. в одном будет храниться список vip ip-адресов, с которых будут доступны все сайты, во втором - список запрещенных сайтов:
touch sbd.txttouch ipbd.txt и заполняем их:
nano sbd.txt vkontakte.rudurov.ruvk.comodnoklassniki.ruи прочие....
nano ipbd.txt 10.10.10.1010.10.10.11и.т.д.
Далее переходим к написанию скрипта настройки. Имеем следующее: локальная сеть 10.10.10.0/24 на сетевом адаптере eth1, внешняя сеть на адаптере eth0 c ip к примеру 88.45.65.2.
nano fw.sh #!/bin/bash#################################################### Переменные################################################### #указываем внешний ip сервера и внешн. сетевой интерфейсINET_IP1=88.45.65.2INET_IFACE1=eth0 # указываем внутренний ip сервера и внутр. сетевой интерфейсLAN_IP=10.10.10.4LAN_IFACE=eth1 # внутренняя сетьLAN_RANGE=10.10.10.0/24 # сетевой интерфейс петли и ipLO_IFACE=loLO_IP=127.0.0.1 # IP адреса в локалке, на которые делаем проброс портовIP_FORW[1]=10.10.10.57# внешний портPORT_V[1]=3389# внутренний портPORT_I[1]=3389PRTCL[1]=tcp IP_FORW[2]=10.10.10.50# внешний портPORT_V[1]=3489# внутренний портPORT_I[1]=3389PRTCL[2]=tcp ip=iptables # указываем путь к текстовому файлу, содержащему список запрещенных сайтовbadsite=( $(cat "/home/virtdiver/sbd.txt") ) # указываем путь к текстовому файлу, содержащему список ip,# для которых все сайты открытыgoodip=( $(cat "/home/virtdiver/ipbd.txt") ) #################################################### Сброс настроек iptables (Очистка таблиц)################################################### $ip -F -t filter$ip -F -t nat$ip -F -t mangle$ip -F #################################################### Политики по умолчанию: все блокировать что явно# не разрешено ниже =)################################################### $ip -P INPUT DROP$ip -P OUTPUT DROP$ip -P FORWARD DROP #################################################### Разрешаем форвардинг#################################################### только разрешаем# настройка самого форвардинга ниже# ставим в файл "1". (по умолчанию "0" - выключен)echo 1 > /proc/sys/net/ipv4/ip_forward #################################################### Включаем NAT (сетевую трансляцию адресов) для# возможности выхода в интернет из локалки################################################### # "!" = адреса назначения все, кроме $LAN_RANGE$ip -t nat -A POSTROUTING -o $INET_IFACE1 -s $LAN_RANGE ! -d $LAN_RANGE -j SNAT --to-source $INET_IP1 #################################################### Делаем проброс портов, для доступа например# через удаленный рабочий стол (RDP) из внешней# сети к компьютеру в локалке.################################################### # Подставляем в цикле значения ip, портов, и протоколов# из массива, обьявленного в разделе "переменные"
for ((i=1; i<=${#IP_FORW[*]}; i++)); do
# Прокидываем порт$ip -t nat -A PREROUTING --dst $INET_IP1 -p ${PRTCL[$i]} --dport ${PORT_V[$i]} -j DNAT --to-destination ${IP_FORW[$i]}:${PORT_I[$i]}$ip -t nat -A POSTROUTING -p ${PRTCL[$i]} --dst ${IP_FORW[$i]} --dport ${PORT_I[$i]} -j SNAT --to-source $LAN_IP# Разрешаем трафик между внешней сеткой и компьютером в сети, идущий с\на определенный порт$ip -A FORWARD -i $INET_IFACE1 -o $LAN_IFACE -d ${IP_FORW[$i]} -p ${PRTCL[$i]} --dport ${PORT_I[$i]} -j ACCEPT$ip -A FORWARD -i $LAN_IFACE -o $INET_IFACE1 -s ${IP_FORW[$i]} -p ${PRTCL[$i]} --sport ${PORT_I[$i]} -j ACCEPT
done #################################################### Отбрасываем все пакеты, которые не могут быть# идентифицированы и поэтому не могут иметь# определенного статуса.################################################### $ip -A INPUT -m state --state INVALID -j DROP$ip -A FORWARD -m state --state INVALID -j DROP #################################################### Разрешаем трафик через петлю################################################### # Разрешаем входящий трафик на интерфейс петли$ip -A INPUT -p all -i $LO_IFACE -j ACCEPT # Разрешаем исходящий трафик с интерфейса петли$ip -A OUTPUT -p all -o $LO_IFACE -j ACCEPT #################################################### Разрешаем трафик через внутренний сет. адаптер################################################### # между сервером и локалкой пока разрешаем все, так как в функции сервера# будет входить много др. задач....# Разрешаем входящие новые и установившиеся соединения# в сет. адаптер лок.сети из лок.сети$ip -A INPUT -p all -i $LAN_IFACE -s $LAN_RANGE --match state --state NEW,ESTABLISHED -j ACCEPT # Разрешаем исходящие новые и установившиеся соединения# в внутреннюю сеть c сет. адаптера лок. сети$ip -A OUTPUT -p all -o $LAN_IFACE -d $LAN_RANGE --match state --state NEW,ESTABLISHED -j ACCEPT #################################################### Разрешаем входящие новые и установившиеся# tcp-соединения с внешней сети к серверу и# установившиеся и инициированные ими соединения# с сервера в внешнюю сеть на порты 80(http) и# 22(ssh)################################################### # т.е. к примеру из внешней сети можно будет подключиться к серверу по ssh,# а с сервера к другому в интернете нельзя, так как в эту сторону# новые подключения блокируются$ip -A INPUT -p tcp -i $INET_IFACE1 -m multiport --dports 80,22,25,110 --match state --state NEW,ESTABLISHED -j ACCEPT$ip -A OUTPUT -p tcp -o $INET_IFACE1 -m multiport --sports 80,22,25,110 --match state --state ESTABLISHED,RELATED -j ACCEPT #################################################### Разрешаем при необходимости непосредственно с# сервера выход в внешнюю сеть на определенные# порты, например dns,http,https################################################### $ip -A INPUT -i $INET_IFACE1 -p tcp -m multiport --sports 80,53,443 -j ACCEPT$ip -A OUTPUT -o $INET_IFACE1 -p tcp -m multiport --dports 80,53,443 -j ACCEPT$ip -A INPUT -i $INET_IFACE1 -p udp -m multiport --sports 53 -j ACCEPT$ip -A OUTPUT -o $INET_IFACE1 -p udp -m multiport --dports 53 -j ACCEPT #################################################### открываем IT-отделу, то бишь себе) ,# все что понадобится################################################### # tcp$ip -A FORWARD -p tcp -s 10.10.10.9 ! -d $LAN_RANGE -m multiport --dports 80,53,443,22,25,110,5190 -j ACCEPT$ip -A FORWARD -p tcp -d 10.10.10.9 ! -s $LAN_RANGE -m multiport --sports 80,53,443,22,25,110,5190 -j ACCEPT# udp$ip -A FORWARD -p udp -s 10.10.10.9 ! -d $LAN_RANGE -m multiport --dports 53 -j ACCEPT$ip -A FORWARD -p udp -d 10.10.10.9 ! -s $LAN_RANGE -m multiport --sports 53 -j ACCEPT # tcp$ip -A FORWARD -p tcp -s 10.10.10.20 ! -d $LAN_RANGE -m multiport --dports 80,53,443,22,25,110,5190 -j ACCEPT$ip -A FORWARD -p tcp -d 10.10.10.20 ! -s $LAN_RANGE -m multiport --sports 80,53,443,22,25,110,5190 -j ACCEPT# udp$ip -A FORWARD -p udp -s 10.10.10.20 ! -d $LAN_RANGE -m multiport --dports 53 -j ACCEPT$ip -A FORWARD -p udp -d 10.10.10.20 ! -s $LAN_RANGE -m multiport --sports 53 -j ACCEPT # tcp$ip -A FORWARD -p tcp -s 10.10.10.21 ! -d $LAN_RANGE -m multiport --dports 80,53,443,22,25,110,5190 -j ACCEPT$ip -A FORWARD -p tcp -d 10.10.10.21 ! -s $LAN_RANGE -m multiport --sports 80,53,443,22,25,110,5190 -j ACCEPT# udp$ip -A FORWARD -p udp -s 10.10.10.21 ! -d $LAN_RANGE -m multiport --dports 53 -j ACCEPT$ip -A FORWARD -p udp -d 10.10.10.21 ! -s $LAN_RANGE -m multiport --sports 53 -j ACCEPT #################################################### Разрешаем аську избранным################################################### i=0for i in "${goodip[@]}"do$ip -A FORWARD -p tcp -d $i --sport 5190 -j ACCEPT$ip -A FORWARD -p tcp -s $i --dport 5190 -j ACCEPTdone #################################################### Закрываем доступ к запрещеным сайтам всем кроме# VIP ip-адресов. Файлы со списками обьявлены в# разделе "переменные"################################################### # !!! то правило, что выше - то главнее!!!# поэтому этим правилом разрешаем избраннымj=0for j in "${badsite[@]}"doi=0for i in "${goodip[@]}"do$ip -A FORWARD -d $i -s $j -j ACCEPTdonedone # а этим правилом запрещаем всем. Так как первое правило выше,# значит главнее, оно не убьется вторымi=0for i in "${badsite[@]}"do$ip -A FORWARD -s $i -j DROPdone ################################################### #################################################### Разрешаем пакеты с внутренней сети во# внешнюю и обратно, идущие через порты# http\dns\https\ и др. по необходимости#################################################### tcp$ip -A FORWARD -p tcp -s $LAN_RANGE ! -d $LAN_RANGE -m multiport --dports 80,53,443 -j ACCEPT$ip -A FORWARD -p tcp -d $LAN_RANGE ! -s $LAN_RANGE -m multiport --sports 80,53,443 -j ACCEPT# udp$ip -A FORWARD -p udp -s $LAN_RANGE ! -d $LAN_RANGE -m multiport --dports 53 -j ACCEPT$ip -A FORWARD -p udp -d $LAN_RANGE ! -s $LAN_RANGE -m multiport --sports 53 -j ACCEPT #################################################### Разрешаем c сервера ping наружу, а сервер с# внешней сети пинговать запрещаем################################################### $ip -A INPUT -p icmp -m icmp -i $INET_IFACE1 --icmp-type echo-reply -j ACCEPT$ip -A OUTPUT -p icmp -m icmp -o $INET_IFACE1 --icmp-type echo-request -j ACCEPT Запускаем файл:
fw.sh Проверяем внесение правил командами:
iptables -L # таблицы input, output, forward
и
iptables -L -t nat # таблица nat
При перезагрузке правила не сохранятся, поэтому стоит добавить скрипт в автозагрузку (в /etc/rc.local) или воспользоваться встроенной утилитой iptables-save.
Выходим из рута:
exit И на этом настройка закончена.
Oct. 10, 2010