Программирование, радиоэлектроника,
саморазвитие и частичка из моей жизни здесь...

Простой Firewall для сервера на основе Linux IPTABLES + скрипт автостарта

Описана реализация простого и в то же время надежного скрипта-файрвола (firewall) для защиты сервера от подключений к критичным приложениям снаружи. Предложенный скрипт подойдет для базовой защиты сервера на Linux, а также может быть использован как основа для построения более сложного файрвола.

Содержание:

  1. Зачем это нужно
  2. Скрипт файрвола
  3. Принцип работы скрипта
  4. Запуск и работа
  5. Заключение

Зачем это нужно

Ничего сверхнового не изобретал, суть задачи проста:

  1. закрыть определенные порты от подключений для наружного(internet) интерфейса;
  2. добавить дополнительные блокированные порты для мониторинга подключений;
  3. автозапуск файрвола при старте сервера на Linux.

Допустим что у нас на сервере запущены такие сервисы (в скобках используемые порты):

  • http, https (80, 443)
  • sshd (22)
  • ftp (21)
  • pop3 (110)
  • imap, imap+ssl (143, 993)
  • smtp (25)
  • mysql (3306)
  • firebird (3050)
  • postgresql (5432)
  • samba (139, 137, 138, 445)

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

Для просмотра списка портов которые прослушиваются на сетевых интерфейсах в Linux можно воспользоваться командой:

netstat -na | grep LISTEN

В качестве примера вывода команды разберем тот что на рисунке ниже:

netstat linux список открытых портов

Рис. 1. Список открытых портов, отображаемый при помощи команды netstat с фильтром.

Здесь мы видим что:

  • порты 3306, 25, 587, 953 открыты только на локальном интерфейсе (127.0.0.1);
  • порты 139 и 445 открыты на всех интерфейсах (0.0.0.0);
  • порт 53 кроме локального (127.0.0.1) интерфейса также открыт на наружном интерфейсе (4.44.444.44);
  • порт 22 прослушивается на всех интерфейсах в протоколе IPv4(0.0.0.0) и IPv6(:::);
  • порт 80 прослушивается на всех интерфейсах в протоколе IPv6 (:::).

Примечание: IP-адрес в примере в таком пространстве IPv4 как 4.44.444.44 не существует, поскольку сегмент 444 в IP адресе не допустим (255 max).

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

Многие приложения (например сервер баз данных PostgreSQL) позволяют в своих настройках указать список интерфейсов на которых они смогут открыть свой порт для прослушивания, а по умолчанию прослушиваются все интерфейсы или только локалхост (127.0.0.1). Поэтому, оставив приложение с настройками по умолчанию и не настроив Firewall вы подвергаете свой сервер опасности взлома и потери данных в следствии действий злоумышленников и вредоносных программ.

Допустим что на сервере должны быть доступны через интернет такие службы как: ssh(22), httpd(80, 443). Все остальные службы работают и связываются через локальный интерфейс (localhost, 127.0.0.1) и также доступны с настройками по умолчанию для других интерфейсов(например при подключении к серверу через свой VPN). Таким образом мы разрешаем то что явно нужно и запрещаем все ненужное для посторонних глаз снаружи из сети Интернет.

Скрипт файрвола

Перед тем как привести полный листинг скрипта хочу рассказать о том как сделать автозапуск правил при старте Linux, а также возможность управления файрволом - Start, Stop.

В Linux есть такая папка как /etc/init.d/ - здесь лежат специально созданные и настроенные скрипты, которые выполняются при старте системы. Для скриптов может быть определен порядок старта, ожидание других служб перед запуском и т.п. Это делает данную папку идеальным местом для запуска нашего скрипта-файрвола.

Итак, откроем пустой файл для редактирования командой:

nano /etc/init.d/iptables

Теперь скопируем в файл листинг скрипта, что предоставлен ниже:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          iptables
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Interactive:     true
# Short-Description: Apply/clear iptables rules
### END INIT INFO

IPTABLES=/sbin/iptables
iface=eth0

case "" in
  start)
    echo "Starting iptables..."

    # Flushing rules
    $IPTABLES -F
    $IPTABLES -X

    # Setting up default policies
    $IPTABLES -P INPUT ACCEPT
    $IPTABLES -P OUTPUT ACCEPT
    $IPTABLES -P FORWARD ACCEPT

    # Closing all, except 80, 443, 22 ports

    # Deny FTP (21)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 21 -j DROP

    # Deny POP3 (110)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 110 -j DROP

    # Deny IMAP (143)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 143 -j DROP

    # Deny IMAP+SSL (993)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 993 -j DROP

    # Deny MYSQL (3306)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 3306 -j DROP

    # Deny FIREBIRD (3050)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 3050 -j DROP

    # Deny POSTGRESQL (5432)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 5432 -j DROP

    # Deny SAMBA (139)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 139 -j DROP

    # Deny SAMBA (138)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 138 -j DROP

    # Deny SAMBA (137)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 137 -j DROP

    # Deny SAMBA (445)
    $IPTABLES -A INPUT -p tcp -i $iface --dport 445 -j DROP

   
    ;;
  stop)
    echo "Stopping iptables..."
    # Clearing rules
    $IPTABLES -F
    $IPTABLES -X

    # Setting default politics to Accept
    $IPTABLES -P INPUT ACCEPT
    $IPTABLES -P OUTPUT ACCEPT
    $IPTABLES -P FORWARD ACCEPT
    ;;
  *)
    echo "Usage: /etc/init.d/iptables {start|stop}"
    exit 1
    ;;
esac

exit 0

Перед сохранением нужно исправить в скрипте значение переменной iface=eth0, в которой указано имя интерфейса который подключен к миру (интернет).

Примечание: для сохранения и выхода из редактора NANO нужно нажать CTRL+X, а потом на запрос о сохранении - Y и Ентер.

Список всех сетевых интерфейсов на Linux-сервере можно посмотреть в новой консоли используя команду:

ifconfig -a

После сохранения изменений в нашем скрипте сделаем его запускаемым и добавим в очередь автозапуска следующими командами:

chmod 755 /etc/init.d/iptables
update-rc.d iptables defaults

Все готово!

Принцип работы скрипта

Прежде чем перейти к запуску и тестированию скрипта распишу немного структуру скрипта.

В шапке есть блок что начинается строкой "### BEGIN INIT INFO" и заканчивается строчкой "### END INIT INFO". В этом блоке указаны настройки инициализации с которыми данный скрипт будет запускаться, а также краткое описание скрипта.

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

После идет основная часть скрипта - условная конструкция на два условия: start и  stop.

В первой секции мы подготавливаем и запускаем файрвол. Очищаем правила и устанавливаем политики по умолчанию для разрешения трафика во всех направлениях.

Остальные строчки в секции состоят из правил запрета, где параметры имеют вот такие значения:

  • -A INPUT   - применять для цепочки входящего трафика;
  • -p tcp        - применять для протокола TCP. Если для сервиса используется протокол UDP то нужно использовать  -p udp;
  • -i $iface    - применять для имени интерфейса что помещено в переменную $iface;
  • --dport 22  - применять если использован указанный порт назначения (destination port), в данном случае 22 (ssh);
  • -j DROP     - операция, которую нужно произвести с с пакетом, в данном случае отвергаем его (дропаем).

Во второй секции мы очищаем все правила файрвола и возвращаем политики по умолчанию (разрешить все).

В конце exit 0 завершает выполнение скрипта с позитивным результатом (без ошибок).

Запуск и работа

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

service iptables start

Соответственно для останова скрипта-файрвола нужно выполнить команду:

service iptables stop

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

iptables -nvL

Пример вывода команды рассмотрим ниже:

iptables список правил

Здесь мы можем видеть что на порт 3306 (сервер баз данных MySQL) из интернета кто-то пробовал подключиться примерно 719 раз (отправлено 719 пакетов общим размером 29116 байт). Всего из интернета (цепочка INPUT) на сервер пришло 96 млн пакетов, а размер принятых данных - 21 ГигаБайт. Также из сервера было отправлено 117 млн пакетов, а размер отправленных данных составляет 117 ГигаБайт.

Вот такие вот полезные данные, могут пригодиться как для мониторинга обьемов трафика, так и за тем на какие порты (службы) охотятся снаружи на вашем сервере.

При отладке файрвола может быть удобно и полезно выводить данную команду многократно с небольшой задержкой. Благодаря огромному количеству утилит и программ в Linux это осуществить очень легко:

watch -n 1 iptables -nvL

Здесь используется утилитка под названием "watch" которая в качестве параметра -n принимает значение задержки в секундах( в данном примере 1 секунда), а последний аргумент команды это название программы которую нужно выводить на экран с установленной периодичностью.

Для тестирования файрвола и вывода этой команды можно с другого сервера или компьютера сделать попытку подключения к запрещенному в нашем скрипте порту. К примеру подключимся к серверу на порт 3306:

telnet your_server_ip_or_hostname 3306

Для любителей Windows в этих целях также можно использовать утилиту TELNET.

Примечание: в Windows7+ утилита telnet по умолчанию не установлена, устанавливаем ее вот так: Панель управления - Программы и компоненты - Включение или отключение компонентов Windows - TELNET.

Заключение

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

Полезные ресурсы по iptables:

  • Викиучебник - структура, примеры, полезные ссылки и т.п;
  • IPTABLES - MAN страничка на английском языке;
  • man iptables - команда в консоли, документация которая всегда под рукой.
Если статья оказалась полезной - помочь проекту можно тут: 👍 ПОМОЩЬ, 🎁 DONATE
0 3887 Linux
Комментарии к публикации (2):
sergey #1sergey
27 Июль 2017 10:21

Я попробовал установить на raspberry pi3 не заработало. Выдало ошибку Job for iptables.service failed. See 'systemctl status iptables.service' and 'journalctl -xn' for details.

0
ph0en1x #2ph0en1x
27 Июль 2017 15:27

sergey, для построения файрвола с автозапуском в Raspbian Jessie, Raspbian Stretch или более новой версии GNU/Debian Linux для Raspberry Pi 2 и 3, лучше воспользоваться таким инструментом как systemd.
Вот статья с более современным подходом, где предоставлен скрипт универсального файрвола для IPv4 и IPv6.

0