Поиск по сайту:

Как настроить брандмауэр с помощью Iptables в Ubuntu 14.04


Введение

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

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

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

Примечание. В этом руководстве рассматривается безопасность IPv4. В Linux безопасность IPv6 поддерживается отдельно от IPv4. Например, \iptables поддерживает только правила брандмауэра для адресов IPv4, но у него есть аналог IPv6, называемый ip6tables, который можно использовать для поддержки правил брандмауэра для сетевых адресов IPv6.

Если ваш VPS настроен для IPv6, не забудьте защитить сетевые интерфейсы IPv4 и IPv6 с помощью соответствующих инструментов. Дополнительные сведения об инструментах IPv6 см. в этом руководстве: Как настроить инструменты для использования IPv6 на Linux VPS.

Предпосылки

Прежде чем приступить к работе с этим учебным пособием, у вас должна быть отдельная учетная запись суперпользователя без полномочий root — пользователь с привилегиями sudo — настроенный на вашем сервере. Если вам нужно настроить это, следуйте этому руководству: Initial Server Setup with Ubuntu 14.04.

Основные команды iptables

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

Во-первых, вы должны знать, что команды iptables должны выполняться с привилегиями root. Это означает, что вам нужно войти в систему как root, использовать su или sudo -i, чтобы получить корневую оболочку, или предварять все команды sudo. В этом руководстве мы будем использовать sudo, так как это предпочтительный метод в системе Ubuntu.

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

  1. sudo iptables -L
Output:
Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination

Как видите, у нас есть три цепочки по умолчанию (INPUT, OUTPUT и FORWARD). Мы также можем видеть политику по умолчанию каждой цепочки (каждая цепочка имеет ACCEPT в качестве политики по умолчанию). Мы также видим некоторые заголовки столбцов, но не видим никаких реальных правил. Это связано с тем, что Ubuntu не поставляется с набором правил по умолчанию.

Мы можем увидеть вывод в формате, отражающем команды, необходимые для включения каждого правила и политики, используя вместо этого флаг -S:

  1. sudo iptables -S
Output:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT

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

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

  1. sudo iptables -F

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

  1. sudo iptables -P INPUT ACCEPT
  2. sudo iptables -P OUTPUT ACCEPT
  3. sudo iptables -F

Затем вы можете изменить политику сброса по умолчанию обратно на DROP после того, как вы установили правила, которые явно разрешают ваше соединение. Мы рассмотрим, как это сделать через мгновение.

Сделайте свое первое правило

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

Полное правило, которое нам нужно, таково:

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

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

  • -A INPUT: флаг -A добавляет правило в конец цепочки. Это часть команды, которая сообщает iptables, что мы хотим добавить новое правило, что мы хотим, чтобы это правило было добавлено в конец цепочки, и что цепочка, с которой мы хотим работать, является цепочкой INPUT.
  • -m conntrack: iptables имеет набор основных функций, а также набор расширений или модулей, предоставляющих дополнительные возможности. В этой части команды мы заявляем, что хотим иметь доступ к функциям, предоставляемым модулем conntrack. Этот модуль предоставляет доступ к командам, которые можно использовать для принятия решений на основе отношения пакета к предыдущим соединениям.
  • –ctstate: это одна из команд, доступных при вызове модуля conntrack. Эта команда позволяет нам сопоставлять пакеты на основе того, как они связаны с пакетами, которые мы видели ранее. Мы передаем ему значение ESTABLISHED, чтобы разрешить пакеты, являющиеся частью существующего соединения. Мы передаем ему значение RELATED, чтобы разрешить пакеты, связанные с установленным соединением. Это часть правила, которая соответствует нашему текущему сеансу SSH.
  • -j ПРИНЯТЬ: указывает цель совпадающих пакетов. Здесь мы сообщаем iptables, что пакеты, соответствующие предыдущим критериям, должны быть приняты и пропущены.

Мы помещаем это правило в начало, потому что хотим убедиться, что соединения, которые мы уже используем, сопоставляются, принимаются и извлекаются из цепочки до достижения каких-либо правил DROP.

Мы можем увидеть изменения, если перечислим правила:

  1. sudo iptables -L
Output:
Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination

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

Принять другие необходимые подключения

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

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

Две строки, которые мы собираемся использовать для добавления этих правил:

  1. sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
  2. sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Как видите, они очень похожи на наше первое правило, но, возможно, более простые. Новые опции:

  • -p tcp: Этот параметр сопоставляет пакеты, если используется протокол TCP. Это протокол на основе соединения, который будет использоваться большинством приложений, поскольку он обеспечивает надежную связь.
  • –dport: этот параметр доступен, если задан флаг -p tcp. Это дает дополнительное требование соответствия порта назначения для соответствующего пакета. Первое правило соответствует TCP-пакетам, предназначенным для порта 22, а второе правило соответствует TCP-трафику, направленному на порт 80.

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

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

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

  1. sudo iptables -I INPUT 1 -i lo -j ACCEPT

Это выглядит немного иначе, чем другие наши команды. Давайте рассмотрим, что он делает:

  • -I INPUT 1: флаг -I указывает iptables вставить правило. Это отличается от флага -A, который добавляет правило в конец. Флаг -I принимает цепочку и позицию правила, в которую вы хотите вставить новое правило. В данном случае мы добавляем это правило в качестве самого первого правила цепочки INPUT. Это снизит остальные правила. Мы хотим, чтобы это было наверху, потому что оно является фундаментальным и не должно зависеть от последующих правил.
  • -i lo: Этот компонент правила соответствует, если интерфейс, который использует пакет, является интерфейсом \lo. Интерфейс \lo — это другое имя устройства обратной связи. Это означает, что любой пакет, использующий этот интерфейс для связи (пакеты, сгенерированные на нашем сервере, для нашего сервера), должен быть принят.

Чтобы увидеть наши текущие правила, мы должны использовать флаг -S. Это связано с тем, что флаг -L не содержит некоторой информации, такой как интерфейс, к которому привязано правило, что является важной частью только что добавленного правила:

  1. sudo iptables -S
Output:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

Реализация правила удаления

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

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

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

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

  1. sudo iptables -P INPUT DROP

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

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

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

Альтернативный подход состоит в том, чтобы сохранить политику по умолчанию для цепочки как accept и добавить правило, которое отбрасывает все оставшиеся пакеты в конец самой цепочки.

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

  1. sudo iptables -P INPUT ACCEPT

Теперь вы можете добавить правило в конец цепочки, которое будет отбрасывать все оставшиеся пакеты:

  1. sudo iptables -A INPUT -j DROP

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

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

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

  1. sudo iptables -D INPUT -j DROP
  2. sudo iptables -A INPUT new_rule_here
  3. sudo iptables -A INPUT -j DROP

Либо вы можете вставить нужные вам правила в конец цепочки (но до перетаскивания), указав номер строки. Чтобы вставить правило в строку номер 4, вы можете ввести:

  1. sudo iptables -I INPUT 4 new_rule_here

Если у вас возникли проблемы с определением номера строки каждого правила, вы можете указать iptables нумеровать правила, набрав:

  1. sudo iptables -L --line-numbers
Output:
Chain INPUT (policy DROP) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere 2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED 3 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh 4 ACCEPT tcp -- anywhere anywhere tcp dpt:http Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination

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

Список и удаление правил Iptables

Если вы хотите узнать подробности о перечислении и удалении правил iptables, ознакомьтесь с этим руководством: Как составить список и удалить правила брандмауэра Iptables.

Сохранение конфигурации Iptables

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

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

Есть несколько способов сделать это, но проще всего использовать пакет iptables-persistent. Вы можете загрузить это из стандартных репозиториев Ubuntu:

  1. sudo apt-get update
  2. sudo apt-get install iptables-persistent

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

Он также спросит вас, хотите ли вы сохранить настроенные вами правила IPv6. Они настраиваются с помощью отдельной утилиты под названием ip6tables, которая управляет потоком пакетов IPv6 почти таким же образом.

После завершения установки у вас будет новая служба с именем iptables-persistent, настроенная для запуска при загрузке. Этот сервис загрузит ваши правила и применит их при запуске сервера.

Сохранение обновлений

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

Сохраните правила брандмауэра с помощью этой команды:

  1. sudo invoke-rc.d iptables-persistent save

Заключение

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

Чтобы узнать больше о защите вашей сети с помощью iptables, ознакомьтесь с этими руководствами:

  • Как реализовать базовый шаблон брандмауэра с Iptables в Ubuntu 14.04
  • Iptables Essentials: общие правила и команды брандмауэра
  • Как настроить брандмауэр Iptables для защиты трафика между вашими серверами
  • Глубокое погружение в архитектуру Iptables и Netfilter
  • Как протестировать конфигурацию брандмауэра с помощью Nmap и Tcpdump