Разговоры о iptables. video2. Bash script для быстрой модификации iptables.

В этом видео я продолжу рассказ о утилите iptables.
Сегодня речь пойдёт о том как:
– написать базовый, простой список правил для защиты вашего сервера (веб сервера и тп);
– доступ к основным портам вашего сервера;
– как найти используемые вашим сервером порты?;
– подготовить, написать простой скрипт для создания и простого модифицирования ваших правил;
– ответы на вопросы.

Когда у вас появляется первый сервер находящийся в Интернете, вы могли просто арендовать виртуалку у какого-либо хостера, его,
как в прочем и любой следующий сервер, необходимо защитить от возможных внешних атак и вероятного подбора паролей.
Защита порта ssh очень важна и её не может быть мало.
По этому, как я уже рассказывал в своих предыдущих видео, необходимо по возможности ограничить доступ к вашему серверу по ssh(впрочем и по другим протоколам тоже). Вы можете узнать какие ip адреса принадлежат вашему провайдеру и компании в которой вы работаете и открыть доступ только для этих подсетей – в случае чего вы сможете зайти в личный кабинет на сайте вашего хостера и добавить новые адреса.
Закром свой ssh порт. Допустим вы сидите в у себя дома в подсети 1.1.1.0/24 своего домашнего интернет провайдера.
Тогда правило разрешающее доступ с этой подсети будет следующее:
sudo iptables -A INPUT -s 1.1.1.0/24 -d 0.0.0.0/0 -p tcp --dport 22 -j ACCEPT
Плюс, вы знаете, что компания в которой вы работаете имеет следующие публичные адреса – 2.2.2.0/24. Добавляем и их:
sudo iptables -A INPUT -s 2.2.2.0/24 -d 0.0.0.0/0 -p tcp --dport 22 -j ACCEPT
Далее следует проверить какой ip вы сейчас используете для подключения к серверу – на всякий случай!
~$ who
alex pts/0 2015-08-12 11:47 (192.168.56.1)
alex pts/1 2015-08-12 12:11 (192.168.56.1)

Если данный адрес не подпадает под список адресов уже добавленных в iptables, следует добавить и это адрес, а лучше всю подсетку, проверив информацию в RIPE.
Далее необходимо добавить следующие правила:
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Их даже лучше поставить как можно выше – чем ниже номер правила в списке, тем быстрее оно будет обрабатываться и если какой-либо пакет подпадает под правило, то с ним выполняется определённое действие. Если действие, например, ACCEPT или DROP, то все последующие правила не проверяются – скорость обработки пакетов возрастает.
Правило: sudo iptables -A INPUT -i lo -j ACCEPT
Это правило необходимо для корректной работы множества внутренних служб, например, для работы БД.
Далее желательно разрешить доступ для всех пакетов относящихся к уже установленным сессиям- дабы увеличить скорость обработки трафика. Плюс, я доверяю своему серверу – если он установил соединение сам, то наверное это было для чего-то нужно.
Например, соединение с DNS серверами, NTP серверами, почтовыми серверами и тп.
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Следующим шагом будет проверка служб запущенных у вас на сервере:
netstat -natup
netstat -atup

Я проверяю запущенные у меня службы – что это значит?
Например, если вы сидите за своим домашним компьютером, который подключён к домашнему роутеру, то на этом самом роутере по умолчанию не настроен проброс портов, потому что он не нужен. Все подключения устанавливаются, инициалицируются вами, вашим компьютером – вы открываете браузер – устанавливаете соединение с каким-то веб сервером. Запускаете почтовый клиент – коннектитесь к почтовому серверу, спрашиваете у него о том если ли для вас письма, отправляете кому-то письма сами. Даже когда к вам поступает входящий звонок, например, по Skype соединение уже было установлено – вы подключены к серверу, котовый управляет вашими звонками, рассказывает как одному клиету подключиться к другому.
На вашем сервере, в отличии от домашнего компьютера может быть запущен, например, веб сервер которвый ждёт когда кто-то отправит к нему запрос о какой-либо веб странице.
Ну конечно, запущен ssh сервер и возможно что-то ещё? VPN? FTP? SNMP? Что-то ещё?
Это и нужно проверить командо netstat.

Таким образом, проверив запущенные службы на вашем сервере можно понять, какие порты нужно открыть. Возможно в данном списке есть ряд служб запущенный по умолчанию, но вы не хотите что бы они были доступны из вне. Вы можете не открывать доступ к этим службам и портам. Я буду сегодня показывать что можно настроить на примере моего сервера.
Доступ на порт tcp 22 для работы по ssh я открыл.
Следующее, открыть доступ к веб серверу:
sudo iptables -A INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -p tcp --dport 80 -j ACCEPT
Ограничений по ip адресам делать не будуту – веб сервер должен быть доступ всем.
Если у вы поддерживаете https, то необходимо дополнительно открыть порт tcp 443 – https стандартно работает на этом порту. Если вы не уверены есть ли у вас https, то можно проверить слушается у вас этот порт через netstat -nat или просто закрыть, если вы не уверены – значит вы ничего не настраивали:
sudo iptables -A INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -p tcp --dport 443 -j ACCEPT
Возможно, вы используете какую-либо систему мониторинга – например, я использую cacti. Систему мониторинга лучше держать как и систему с бекапами на отдельном сервере. Чтобы если что произошло, то можно было легко восстановить хронологию событий и быстрее понять причины случившегося.
Моя система мониторинга использует протокол SNMP для мониторинга. Простокол SNMP для сбора данных использует протокол udp, порт 161.
sudo iptables -A INPUT -s 5.101.102.99/32 -p udp --dport 161 -j ACCEPT
Лучше ограничить доступ к вашему серверу на данный порт не только по паролю в настройках snmp демона, но и по ip – серверов мониторинга наверное у вас не сотни. А если сотни, то наверное они сидят в каких-то подсетках.
Суть в том, что данным протоколом можно стянуть не только информацию о объёме вашего жёсткого диска и загрузке процессора, но в худшем случае инфомацию о логин-паролях и даже можно что-то перенастроить на серевере.
Правда для этого нужно специально включать такую возможность… Лучше всё закрыть по ip.

PING
Кто-то закрывает доступ, кто-то нет. Я лично оставляю открытым доступ по протоколу icmp. Проблем мне это пока не доставляет.
sudo iptables -A INPUT -p icmp -j ACCEPT

FTP
Если вы пользуетесь каким-либо FTP сервером, то нужно дать доступ к нему:
Лучше конечно с конкретных подсетей, либо в настройках FTP завести отдельного пользователя, без прав на sudo
sudo iptables -A INPUT -s 1.1.1.0/24 -p tcp -m tcp --dport 21 -j ACCEPT
Можно указать конкретный диапазон портов, аналогичный диапазону указанному в настройках FTP для работы сервера в пассивном режиме.
sudo iptables -A INPUT -s 1.1.1.0/24 -p tcp -m tcp --dport 1030:1040 -j ACCEPT

NTP
Если ваш сервер раздаёт время для клиентов в локальной сети, например, то для определённых подсетей, можно открыть доступ. Если у вас нет локальных усройств – не открывайте.
sudo iptables -A INPUT -s 10.20.30.0/23 -p udp --dport 123 -j ACCEPT

DENY ALL
Ну и конечно в конце нужно закрыть доступ ко всему, что не было открыто.
sudo iptables -A INPUT -j DROP

Простой скрипт для быстрой модификации iptalbes.
Теперь я составлю простой скрипт, который можно будет легко редактировать и изменять настройки ip-tables:
:~$ nano iptables-v4-rules.sh
———————-
#!/bin/bash

MyWebServerIP="192.168.56.4/32"
MyMonitoringServerIP="5.101.102.99/32"
MyHomeNetwork="1.1.1.0/24"
MyHomeNetwork2="1.0.0.0/24"
MyWorkNetwork="2.2.2.0/24"
MyLANips="10.10.1.0/23"

#remove all previous made rules:
sudo iptables --flush

#Allow access to Loopback interfaces
sudo iptables -A INPUT -i lo -j ACCEPT

#Allow any already established connections.
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#Allow access to web server:
sudo iptables -A INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -p tcp --dport 443 -j ACCEPT

#Allow access from Home and Office:
sudo iptables -A INPUT -s $MyHomeNetwork -d $MyWebServerIP -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -s $MyHomeNetwork2 -d $MyWebServerIP -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -s $MyWorkNetwork -d $MyWebServerIP -p tcp --dport 22 -j ACCEPT

#Allow access from the Monitoring server via SNMP:
sudo iptables -A INPUT -s $MyMonitoringServerIP -d $MyWebServerIP -p udp --dport 161 -j ACCEPT

#Allow access with ICMP:
sudo iptables -A INPUT -p icmp -j ACCEPT

#Allow access to FTP server:
sudo iptables -A INPUT -s $MyHomeNetwork -d $MyWebServerIP -p tcp -m tcp --dport 21 -j ACCEPT
sudo iptables -A INPUT -s $MyHomeNetwork2 -d $MyWebServerIP -p tcp -m tcp --dport 21 -j ACCEPT
sudo iptables -A INPUT -s $MyWorkNetwork -d $MyWebServerIP -p tcp -m tcp --dport 21 -j ACCEPT

sudo iptables -A INPUT -s $MyHomeNetwork -d $MyWebServerIP -p tcp -m tcp --dport 1030:1040 -j ACCEPT
sudo iptables -A INPUT -s $MyHomeNetwork2 -d $MyWebServerIP -p tcp -m tcp --dport 1030:1040 -j ACCEPT
sudo iptables -A INPUT -s $MyWorkNetwork -d $MyWebServerIP -p tcp -m tcp --dport 1030:1040 -j ACCEPT

#Allow access from LAN to NTP:
sudo iptables -A INPUT -s $MyLANips -d $MyWebServerIP -p udp --dport 123 -j ACCEPT

#Drop all other connectoins:
sudo iptables -A INPUT -j DROP

Данный скрипт позволяет легко редактировать ваши правила – переменные можно легко менять, например, у вас сменился адрес домашней сети – меняете в одном месте и все правила будут легко изменены.
Также сохраняются все комментарии – просто смотря на список правил можно через какое-то время забыть что они значат и зачет настраивались – в скрипте можно оставить себе комментарии или ссылки.

Ответы на вопросы.
попрос был про фильтрацию трафика на основе TCP флагов.
Вдавать в подробности я не буду – покажу рабочий пример в одном из следующих видео:
В общем случае моё правило выглядело так:
sudo iptables -A INPUT -p tcp -m tcp –dport 22 –tcp-flags FIN,SYN,RST,ACK SYN -j DROP

На этом всё.
Удачи!