PDF Печать E-mail

Настройка firewall iptables на сервере, являющимся интернет-шлюзом

(Это не совсем доработанная статья, конфиг в процессе тестирования)

Итак в один прекрасный момент возникла необходимость установить фаервол на сервере под линуксом, который будет интернет-шлюзом и не только. Основные задачи:

- закрыть доступ сотрудникам на определенные сайты - соц. сети и прочие, при этом не закрывая их для начальства.

- закрыть аську (есть чат для сотрудников), также оставив доступ к ней начальству.

- запретить выход в сеть другим нежелательным приложениям.

- сделать проброс портов для возможности it-отделу подключаться к своим рабочим компьютерам из внешней сети.

- открыть доступ из вне к серверу для администрирования через ssh.

- открыть из вне 80ый порт для доступа к будущему сайту.

- открыть из вне порты 25 и 110 для почтового сервера.

- Для IT-отдела отдельно открывать все, что понадобится)

 

 

В итоге сотрудникам в внешнюю сеть открыты только порты 80 (http) 443 (https) 53 (dns), и закрыты вконтактики и проч.. Аськи работать не будут так как используют др. порты (основной 5190).

 

Реализовывать эти задачи будем с помощью iptables — утилиты командной строки, является стандартным интерфейсом управления работой межсетевого экрана (брандмауэра) netfilter для ядер Linux версий 2.4 и 2.6. После дня изучения был создан достаточно простой скрипт настройки, наверно не лишенный недостатков но вполне рабочий. Теорию копипастить не буду, в сети ее море, да и из комментариев  ниже многое понятно. Приступим. Если iptables не установлен - ставим:

 

sudo su


apt-get install iptables

 

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

 

touch fw.sh

 

chmod +x fw.sh

 

Создаем два текстовых файла. в одном будет храниться список vip ip-адресов, с которых будут доступны все сайты, во втором - список запрещенных сайтов:

 

touch sbd.txt


touch ipbd.txt

 

и заполняем их:

 

nano sbd.txt

 

vkontakte.ru

durov.ru

vk.com

odnoklassniki.ru

и прочие....

 

nano ipbd.txt

 

10.10.10.10

10.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.2

INET_IFACE1=eth0


# указываем внутренний ip сервера и внутр. сетевой интерфейс

LAN_IP=10.10.10.4

LAN_IFACE=eth1


# внутренняя сеть

LAN_RANGE=10.10.10.0/24


# сетевой интерфейс петли и ip

LO_IFACE=lo

LO_IP=127.0.0.1


# IP адреса в локалке, на которые делаем проброс портов

IP_FORW[1]=10.10.10.57

# внешний порт

PORT_V[1]=3389

# внутренний порт

PORT_I[1]=3389

PRTCL[1]=tcp


IP_FORW[2]=10.10.10.50

# внешний порт

PORT_V[1]=3489

# внутренний порт

PORT_I[1]=3389

PRTCL[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=0

for 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 ACCEPT

done


###################################################

# Закрываем доступ к запрещеным сайтам всем кроме

# VIP ip-адресов. Файлы со списками обьявлены в

# разделе "переменные"

###################################################


# !!! то правило, что выше - то главнее!!!

# поэтому этим правилом разрешаем избранным

j=0

for j in "${badsite[@]}"

do

i=0

for i in "${goodip[@]}"

do

$ip -A FORWARD -d $i -s $j -j ACCEPT

done

done


# а этим правилом запрещаем всем. Так как первое правило выше,

# значит главнее, оно не убьется вторым

i=0

for i in "${badsite[@]}"

do

$ip -A FORWARD -s $i -j DROP

done


###################################################


###################################################

# Разрешаем пакеты с внутренней сети во

# внешнюю и обратно, идущие через порты

# 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

 

И на этом настройка закончена.