Как реализовать базовый шаблон брандмауэра с Iptables в Ubuntu 14.04

Вступление

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

В этом руководстве мы создадим брандмауэр, который может стать основой для более сложных наборов правил. Этот брандмауэр будет в первую очередь ориентирован на предоставление разумных значений по умолчанию и создание структуры, которая поощряет простоту расширения. Мы будем демонстрировать это на сервере Ubuntu 14.04.

Предпосылки

Прежде чем начать, вы должны иметь общее представление о политиках брандмауэра, которые вы хотите реализовать. Вы можете следить заthis guide, чтобы получить лучшее представление о некоторых вещах, о которых вам следует подумать.

Чтобы следовать, вам нужно будет иметь доступ к серверу Ubuntu 14.04. В этом руководстве мы будем использовать пользователя без полномочий root с правамиsudo. Вы можете узнать, как настроить этот тип пользователя в нашихUbuntu 14.04 initial server setup guide.

Когда вы закончите, продолжайте ниже.

Установка службы постоянного брандмауэра

Для начала вам необходимо установить пакетiptables-persistent, если вы еще этого не сделали. Это позволит нам сохранить наши наборы правил и автоматически применять их при загрузке:

sudo apt-get update
sudo apt-get install iptables-persistent

Во время установки вас спросят, хотите ли вы сохранить текущие правила. Скажи «да» здесь. Мы будем редактировать сгенерированные файлы правил на мгновение.

Примечание об IPv6 в этом руководстве

Прежде чем мы начнем, мы должны кратко поговорить об IPv4 против IPv6. Командаiptables обрабатывает только трафик IPv4. Для трафика IPv6 используется отдельный вспомогательный инструмент под названиемip6tables. Правила хранятся в отдельных таблицах и цепочках. Дляiptables-persistent правила IPv4 записываются и считываются из/etc/iptables/rules.v4, а правила IPv6 хранятся в/etc/iptables/rules.v6.

В этом руководстве предполагается, что выnot активно используете IPv6 на своем сервере. Если ваши сервисы не используют IPv6, безопаснее полностью заблокировать доступ, как мы будем делать в этой статье.

Реализация базовой политики брандмауэра (быстрый способ)

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

Чтобы реализовать нашу политику и структуру брандмауэра, мы будем редактировать файлы/etc/iptables/rules.v4 и/etc/iptables/rules.v6. Откройте файлrules.v4 в текстовом редакторе с правамиsudo:

sudo nano /etc/iptables/rules.v4

Внутри вы увидите файл, который выглядит примерно так:

/etc/iptables/rules.v4

# Generated by iptables-save v1.4.21 on Tue Jul 28 13:29:56 2015
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Tue Jul 28 13:29:56 2015

Заменить содержимое на:

/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]
:POSTROUTING ACCEPT [0:0]
COMMIT

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

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

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

Затем откройте файл/etc/iptables/rules.v6, чтобы изменить правила IPv6:

sudo nano /etc/iptables/rules.v6

Мы можем заблокировать весь трафик IPv6, заменив содержимое файла следующей конфигурацией:

/etc/iptables/rules.v6

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT

*raw
:PREROUTING DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT

*nat
:PREROUTING DROP [0:0]
:INPUT DROP [0:0]
:OUTPUT DROP [0:0]
:POSTROUTING DROP [0:0]
COMMIT

*security
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT

*mangle
:PREROUTING DROP [0:0]
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:POSTROUTING DROP [0:0]
COMMIT

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

Чтобы проверить этот файл на наличие синтаксических ошибок, мы можем использовать командуip6tables-restore с опцией-t:

sudo ip6tables-restore -t /etc/iptables/rules.v6

Когда оба файла правил не сообщают о синтаксических ошибках, вы можете применить правила внутри, набрав:

sudo service iptables-persistent reload

Это немедленно осуществит политику, изложенную в ваших файлах. Вы можете проверить это, перечислив правилаiptables, которые используются в настоящее время:

sudo iptables -S
sudo ip6tables -S

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

Объяснение нашей общей стратегии брандмауэра

В базовом брандмауэре, который мы создали с помощью вышеуказанных правил, мы создали расширяемую среду, которую можно легко настроить для добавления или удаления правил. Для трафика IPv4 нас в основном интересует цепочкаINPUT в таблицеfilter. Эта цепочка будет обрабатывать все пакеты, предназначенные для нашего сервера. Мы также разрешили весь исходящий трафик и запретили пересылку всех пакетов, что было бы целесообразно, только если этот сервер работал в качестве маршрутизатора для других хостов. Мы принимаем пакеты во всех других таблицах, поскольку в этом руководстве мы ищем только фильтрацию пакетов.

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

В основную цепочкуINPUT мы добавили несколько общих правил для трафика, которые, как мы уверены, всегда будут обрабатываться одинаково. Например, мы всегда хотим запретить пакеты, которые считаются «недействительными», и мы всегда хотим разрешить трафик на локальном интерфейсе обратной связи и данные, связанные с установленным соединением.

После этого мы сопоставляем трафик на основе используемого протокола и перетасовываем его в цепочку, специфичную для протокола. Эти специфичные для протокола цепочки предназначены для хранения правил, которые соответствуют и разрешают трафик для определенных сервисов. В этом примере мы разрешаем только SSH в нашей цепочкеTCP. Если бы мы предлагали другую услугу, такую ​​как HTTP (S) -сервер, мы могли бы добавить исключения, которые и здесь. Эти цепочки будут в центре большинства ваших настроек.

Любой трафик, который не соответствует общим правилам или правилам обслуживания в конкретном протоколе, обрабатывается последними несколькими правилами в цепочкеINPUT. Мы установили политику по умолчанию наDROP для нашего брандмауэра, которая будет отклонять пакеты, которые не проходят через наши правила. Однако правила в конце цепочкиINPUT отклоняют пакеты и отправляют клиенту сообщение, имитирующее реакцию сервера, если бы на этом порту не было запущено никаких служб.

Для трафика IPv6 мы просто отбрасываем весь трафик. Наш сервер не использует этот протокол, поэтому безопаснее вообще не взаимодействовать с трафиком.

(Необязательно) Обновление серверов имен

Блокировка всего трафика IPv6 может помешать тому, как ваш сервер решает проблемы в Интернете. Например, это может повлиять на то, как вы используете APT.

Если вы получаете подобные ошибки при попытке запуститьapt-get update:

ошибка

Err http://security.ubuntu.com trusty-security InRelease

Err http://security.ubuntu.com trusty-security Release.gpg
  Could not resolve 'security.ubuntu.com'

. . .

Вы должны следовать этому разделу, чтобы снова запустить APT.

Во-первых, установите ваши серверы имен на внешние серверы имен. В этом примере используются серверы имен Google. Откройте/etc/network/interfaces для редактирования:

sudo nano /etc/network/interfaces

Обновите строкуdns-nameservers, как показано:

/etc/network/interfaces

. . .
iface eth0 inet6 static
        address 2604:A880:0800:0010:0000:0000:00B2:0001
        netmask 64
        gateway 2604:A880:0800:0010:0000:0000:0000:0001
        autoconf 0
        dns-nameservers 8.8.8.8 8.8.4.4

Обновите настройки вашей сети:

sudo ifdown eth0 && sudo ifup eth0

Ожидаемый результат:

Выход

RTNETLINK answers: No such process
Waiting for DAD... Done

Затем создайте новое правило брандмауэра, чтобы принудительно устанавливать IPv4, когда он доступен. Создайте этот новый файл:

sudo nano /etc/apt/apt.conf.d/99force-ipv4

Добавьте эту единственную строку в файл:

/etc/apt/apt.conf.d/99force-ipv4

Acquire::ForceIPv4 "true";

Сохраните и закройте файл. Теперь вы должны быть в состоянии использовать APT.

Реализация наших брандмауэров с помощью команды IPTables

Теперь, когда вы понимаете общую идею созданной нами политики, мы рассмотрим, как вы могли бы создать эти правила с помощью командiptables. Мы получим те же правила, которые мы указали выше, но мы создадим наши политики, добавляя правила итеративно. Посколькуiptables применяет каждое из правил немедленно, порядок правил очень важен (мы оставляем правила, запрещающие пакеты, до конца).

Сбросить ваш брандмауэр

Начнем со сброса правил брандмауэра, чтобы мы могли видеть, как политики можно создавать из командной строки. Вы можете сбросить все свои правила, набрав:

sudo service iptables-persistent flush

Вы можете проверить, что ваши правила сбрасываются, набрав:

sudo iptables -S

Вы должны увидеть, что правила в таблицеfilter пропали, а политика по умолчанию установлена ​​наACCEPT для всех цепочек:

output-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

Создать протокол-специфичные цепочки

Мы начнем с создания всех наших цепочек протоколов. Они будут использоваться для хранения правил, которые создают исключения из нашей политики запрета для служб, которые мы хотим предоставить. Мы создадим один для трафикаUDP, один дляTCP и один дляICMP:

sudo iptables -N UDP
sudo iptables -N TCP
sudo iptables -N ICMP

Мы можем пойти дальше и добавить исключение для трафика SSH. SSH использует TCP, поэтому мы добавим правило для приема трафика TCP, предназначенного для порта 22, в цепочку TCP:

sudo iptables -A TCP -p tcp --dport 22 -j ACCEPT

Если бы мы хотели добавить дополнительные службы TCP, мы могли бы сделать это сейчас, повторив команду с замененным номером порта.

Создать общие правила принятия и отклонения правил

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

Сначала мы создадим исключение для приема всего трафика, который является частью установленного соединения или связан с установленным соединением:

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Это правило использует расширениеconntrack, которое обеспечивает внутреннее отслеживание, так чтоiptables имеет контекст, необходимый для оценки пакетов как части более крупных соединений, а не как поток дискретных, несвязанных пакетов. TCP - это протокол, основанный на соединении, поэтому установленное соединение довольно четко определено. Для UDP и других протоколов без установления соединения установленные соединения относятся к трафику, который видел ответ (источником исходного пакета будет пункт назначения ответного пакета, и наоборот). Связанное соединение относится к новому соединению, которое было инициировано в связи с существующим соединением. Классическим примером здесь является соединение для передачи данных FTP, которое будет связано с уже установленным управляющим соединением FTP.

Мы также хотим разрешить весь трафик, исходящий из локального интерфейса обратной связи. Это трафик, генерируемый сервером и предназначенный для сервера. Он используется службами на хосте для связи друг с другом:

sudo iptables -A INPUT -i lo -j ACCEPT

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

sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

Создание правил перехода в цепочки протокола

До сих пор мы создали некоторые общие правила в цепочкеINPUT и некоторые правила для конкретных приемлемых сервисов в наших цепочках для конкретных протоколов. Однако прямо сейчас трафик входит в цепочкуINPUT и не имеет возможности достичь наших цепочек, зависящих от протокола.

Нам нужно направить трафик в цепочкеINPUT в соответствующие цепочки, зависящие от протокола. Мы можем сопоставить тип протокола, чтобы отправить его в нужную цепочку. Мы также обеспечим, чтобы пакет представлял новое соединение (любые установленные или связанные соединения должны быть обработаны ранее). Для пакетов TCP мы добавим дополнительное требование, чтобы пакет был пакетом SYN, который является единственным допустимым типом для запуска соединения TCP:

sudo iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
sudo iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
sudo iptables -A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

Отклонить весь оставшийся трафик

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

Мы будем запрещать трафик, используя цельREJECT, которая отправляет ответное сообщение клиенту. Это позволяет нам указать исходящий обмен сообщениями, чтобы мы могли имитировать ответ, который был бы получен, если бы клиент попытался отправить пакеты на обычный закрытый порт. Ответ зависит от протокола, используемого клиентом.

Попытка достичь закрытого порта UDP приведет к сообщению ICMP «Порт недоступен». Мы можем имитировать это, набрав:

sudo iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable

Попытка установить TCP-соединение на закрытом порту приводит к ответу TCP RST:

sudo iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset

Для всех других пакетов мы можем отправить ICMP-сообщение «недоступен протокол», чтобы указать, что сервер не отвечает на пакеты этого типа:

sudo iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable

Настройка политик по умолчанию

Последние три добавленных правила должны обрабатывать весь оставшийся трафик в цепочкеINPUT. Однако в качестве меры предосторожности мы должны установить политику по умолчанию наDROP. Мы также должны установить эту политику в цепочкеFORWARD, если этот сервер не настроен как маршрутизатор для других машин:

sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP

Предупреждение

[.warning] # Если ваша политика установлена ​​наDROP, если вы очиститеiptables с помощьюsudo iptables -F, ваше текущее SSH-соединение будет разорвано! Очистка с помощьюsudo iptables-persistent flush - лучший способ очистить правила, поскольку она также сбрасывает политику по умолчанию.
#

Чтобы соответствовать нашей политике IPv6 отбрасывания всего трафика, мы можем использовать следующие командыip6tables:

sudo ip6tables -P INPUT DROP
sudo ip6tables -P FORWARD DROP
sudo ip6tables -P OUTPUT DROP

Это должно копировать наши правила, установленные довольно близко.

Сохранение правил IPTables

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

Сохраните текущие правила (как IPv4, так и IPv6), набрав:

sudo service iptables-persistent save

Это перезапишет ваши файлы/etc/iptables/rules.v4 и/etc/iptables/rules.v6 с политиками, которые вы создали в командной строке.

Заключение

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

Структура, установленная в этом руководстве, должна позволить вам легко вносить изменения и может помочь в разъяснении существующих политик. Ознакомьтесь с некоторыми другими нашими руководствами, чтобы узнать, как создать политику межсетевого экрана с помощью некоторых популярных служб:

Related