Настройка Iptables для защиты трафика между серверами

Развертывание дискретных компонентов в настройках приложения на разных нодах является распространенным способом уменьшения нагрузки и горизонтального масштабирования сервера. Типичный пример такой конфигурации – настройка базы данных на отдельном сервере. У такой настойки большое количество преимуществ, но подключение серверов по сети влечёт за собой ряд проблем безопасности.

В этом руководстве показано, как создать простой брандмауэр на каждом из серверов распределенной установки. Это позволяет настроить политику для разрешения трафика между компонентами установки и  запрещения другого трафика.

Для демонстрации примеров используется два сервера Ubuntu 14.04; на одном из них установлены WordPress и Nginx, а на другом СУБД MySQL. Используйте эти примеры, чтобы настроить свои серверы, учитывая их индивидуальные  потребности.

Требования

Для начала нужно выполнить предварительную настройку двух свежих серверов Ubuntu 14.04. Создайте аккаунт пользователя с правами sudo на каждом сервере. Подробные инструкции можно получить в этой статье.

Базовая настройка фаервола

Сначала нужно определить базовые конфигурации брандмауэра для каждого сервера. Для этого рекомендуется заблокировать весь трафик, кроме SSH-трафика, а затем открыть нужные порты в брандмауэре.

Установите пакет iptables-persistent:

sudo apt-get update
sudo apt-get install iptables-persistent
sudo nano /etc/iptables/rules.v4

Вставьте базовые правила в файл /etc/iptables/rules.v4:

*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] # Custom per-protocol chains
:UDP - [0:0] :TCP - [0:0] :ICMP - [0:0] # Acceptable UDP traffic
# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
# Acceptable ICMP traffic
# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT
# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP
# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
# Commit the changes
COMMIT
*raw
:PREROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT
*nat
:PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT
*security
:INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT
*mangle
:PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTRUTING ACCEPT [0:0] COMMIT

Внимание! При использовании этого кода в реальной среде разработки пока что не нужно перезагружать правила брандмауэра. Активация этого базового набора правил сразу прервёт соединение между сервером приложения и сервером базы данных. Сначала нужно отладить правила.

Открытие портов сервисов

Чтобы добавить исключения в правила фаервола и обеспечить взаимодействие между серверами, нужно узнать, какие сетевые порты используются для этого.

Номера сетевых портов можно узнать в конфигурационных файлах; но есть и метод, независимый от приложения: нужно просто проверить, какие сервисы прослушивают подключения на каждом сервере.

Для этого можно использовать инструмент netstat. Поскольку приложение работает только по IPv4, используйте аргумент -4.

Примечание: Если приложение работает по IPv6, не используйте этот аргумент.

Также для поиска сервисов понадобится аргумент –plunt.

На веб-сервере можно увидеть следующее:

sudo netstat -4plunt
Output
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1058/sshd
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4187/nginx

Первый выделенный столбец показывает IP-адрес и порт, которые используются приложением, выделенным в конце строки. Адрес 0.0.0.0. значит, что запрашиваемый сервис прослушивает все доступные адреса.

На сервере БД появится:

sudo netstat -4plunt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1097/sshd
tcp        0      0 192.0.2.30:3306         0.0.0.0:*               LISTEN      3112/mysqld

Этот вывод читается так же.

В приведённом выше примере 192.0.2.30 – это внутренний IP-адрес сервера БД. В настройках приложения система MySQL заблокирована до частного интерфейса по соображениям безопасности.

Запишите полученные значения. Это сведения о настройках сети, которые необходимы для отладки правил брандмауэра.

В данном сценарии на веб-сервере нужно открыть следующие порты:

  • Порт 80 для всех адресов;
  • Порт 22 для всех адресов (уже учтено правилами фаервола).

На сервере БД нужно открыть:

  • Порт 3306 для адреса 192.0.2.30 (или связанного с ним интерфейса);
  • Порт 22 для всех адресов (уже учтено правилами фаервола).

Отладка правил фаервола

Итак, теперь вы знаете, какие порты должны быть открыты. Приступайте к редактированию правил фаервола. Откройте файл, хранящий правила, в редакторе с правами sudo:

sudo nano /etc/iptables/rules.v4

На веб-сервере нужно добавить порт 80 в список допустимого трафика. Поскольку сервер слушает все доступные адреса, не нужно ограничивать его интерфейсом или каким-либо целевым адресом.

Для подключения посетители будут использовать протокол TCP. Базовый фреймворк уже имеет цепочку правил по имени TCP, которая предназначена для исключений протокола TCP. Добавьте порт 80 в эту цепочку (сразу после исключения для SSH):

*filter
. . .
# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 80 -j ACCEPT
. . .

Веб-сервер инициирует соединение с сервером базы данных. Теперь брандмауэр не ограничивает исходящий трафик и входящий трафик, связанный с взаимодействующими серверами; таким образом, теперь не нужно открывать дополнительные порты на этом сервере, чтобы разрешить это соединение.

Сохраните и закройте файл. Теперь веб-сервер защищён политикой фаервола, которая блокирует любой трафик, неразрешённый правилами.

Проверьте синтаксис на наличие ошибок:

sudo iptables-restore -t < /etc/iptables/rules.v4

Если ошибок не обнаружено, перезапустите фаервол, чтобы активировать новый набор правил.

sudo service iptables-persistent reload

Редактирование правил на сервере БД

На сервере БД нужно открыть порт 3306 для внутреннего IP-адреса сервера. В данном случае это 192.0.2.30. Можно ограничить трафик, предназначенный для этого адреса, индивидуально или через интерфейс, которому присвоен этот адрес.

Чтобы найти сетевой интерфейс, связанный с этим адресом, введите:

ip -4 addr show scope global
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 203.0.113.5/24 brd 104.236.113.255 scope global eth0
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.0.2.30/24 brd 192.0.2.255 scope global eth1
valid_lft forever preferred_lft forever

Выделенные строки показывают, что с этим адресом связан интерфейс eth1.

Теперь нужно отредактировать правила фаервола на сервере БД. Откройте файл правил с правами sudo:

sudo nano /etc/iptables/rules.v4

Добавьте правило в цепочку TCP, чтобы создать исключение для соединения между сервером БД и веб-сервером.

Чтобы ограничить доступ при помощи самого адреса, введите:

*filter
. . .
# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -d 192.0.2.30 -j ACCEPT
. . .

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

*filter
. . .
# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -i eth1 -j ACCEPT
. . .

Сохраните и закройте файл.

Проверьте синтаксис на ошибки:

sudo iptables-restore -t < /etc/iptables/rules.v4

Если ошибок в синтаксисе нет, перезапустите правила фаервола:

sudo service iptables-persistent reload

Теперь оба сервера защищены от вредоносного трафика, но при этом могут обмениваться важными данными и взаимодействовать.

Заключение

Надёжный брандмауэр – неотъемлемая часть развертывания приложения. В данном руководстве конфигурация включает в себя два сервера, – для Nginx и для MySQL, –  при помощи которых работает приложение WordPress; однако этот метод работает вне зависимости от выбора программного обеспечения.

Tags: , , , ,

Добавить комментарий