Настройка простого Firewall для VPS (Virtual Private Server) на базе Ubuntu Server

HELP-ME-24.COM (Freelance Team), Черноусов Антон

В каждый Linux-дистрибутив входит свой отдельный набор команд и скриптов для управления Firewall. В CentOS и RedHat это FirewallD (в современных версиях), в OpenSuse это SuseFirewall2, в Ubuntu соответственно пакет называется UFW, ну и в прочих дистрибутивах вы можете найти еще с десяток Firewall на любой вкус и цвет.

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

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

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

Типовая настройка Firewall для VPS-сервера в Linux

Сегодня мы будем рассматривать пример такого shell-скрипта который я обычно использую на клиентских VPS-серверах (если клиент не настаивает на использовании какого-то определенного решения).

Запуск скрипта Firewall при настройке сетевого интерфейса

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

Простого применения набора правил iptables при старте сервера обычно недостаточно, так как на момент запуска не все интерфейсы могут быть активны и например VPN-интерфейсу требуется некоторое время чтобы стать активным.

В Ubuntu Linux для реализации вышеописанного функционала в файл /etc/network/interfaces необходимо добавить опцию:

post-up /etc/firewall.sh

Данная опция, устанавливается в раздел каждого интерфейса для которого мы назначаем специфические правила Firewall и просто запускает скрипт когда интерфейс становится активным.

Простейший Firewall для VPS-сервера

В простейшем случае этот скрипт имеет вид:

#!/bin/sh
#########################
# Настройки интерфейсов #
########################
MAIN_EXT_INTERFACE="eth0"
MAIN_VPN_INTERFACE="vpn-bridge"
IPT="/sbin/iptables"

####################
# Правила iptables #
####################

# Удаляем все старые правила
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X

# Настраиваем политики по умолчанию
$IPT -P OUTPUT ACCEPT
$IPT -P INPUT DROP
$IPT -P FORWARD DROP

# Разрешаем все операции с loopback интерфейса
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A FORWARD -o lo -j ACCEPT

# Поддерживаем уже установленные соединения
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Разрешаем доступ по SSH (все интерфейсы)
$IPT -A INPUT -p tcp --dport 22 -j ACCEPT

# VPN Server
$IPT -A INPUT -p udp --dport 1919 -j ACCEPT
$IPT -A INPUT -i $MAIN_VPN_INTERFACE  -j ACCEPT

# Web-server
$IPT -A INPUT -i $MAIN_EXT_INTERFACE -p tcp --dport 80  -j ACCEPT
$IPT -A INPUT -i $MAIN_EXT_INTERFACE -p tcp --dport 443  -j ACCEPT

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

Первым делом, мы описываем сетевые интерфейсы и путь к исполняемому файлу iptables.

MAIN_EXT_INTERFACE="eth0"
MAIN_VPN_INTERFACE="vpn-bridge"
IPT="/sbin/iptables"

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

В дальнейшем мы будем просто писать  $IPT вместо /sbin/iptables и это даст более короткую запись, а вот $MAIN_EXT_INTERFACE вместо eth0 даст более осмысленную запись и вы сможете при переносе скрипта просто изменить значение переменной на имя внешнего интерфейса на вашем новом сервере и не проводить замену всех имен интерфейсов в скрипте.

Следующим этапом, очищаем существующие правила (инициализируем состояние Firewall):

$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X

Теоретически у вас может быть и больше цепочек iptables и я перечислил только основные. После очистки назначаем политики по умолчанию на основные "цепочки" iptables:

$IPT -P OUTPUT ACCEPT
$IPT -P INPUT DROP
$IPT -P FORWARD DROP

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

  • OUTPUT ACCEPT - Разрешаем весь исходящий трафик с сервера (запрещать его имеет смысл только в случае жесткой паранойи владельца сервера, но тогда нам придется описать перечень сетевых ресурсов с которыми сможет взаимодействовать сервер).
  • INPUT DROP - Запрещаем весь входящий трафик (мы его будем разрешать отдельно и это то из за чего собственно весь Firewall и затевался)
  • FORWARD DROP - Весь маршрутизируемый сервером трафик мы запрещаем (наш VPS выступает лишь в качестве сервера приложений)

В продолжение базовых правил к этапу инициализации относятся еще и следующие конструкции:

$IPT -A INPUT -i lo -j ACCEPT
$IPT -A FORWARD -o lo -j ACCEPT
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Первые две команды, разрешают входящие подключения на локальный интерфейс и без них невозможно будет взаимодействие локальных сервисов. Например web-сервер не сможет подключиться к локальной базе данных по адресу 127.0.0.1.

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

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

  • $IPT -A INPUT -p tcp --dport 22 -j ACCEPT - принимаем ssh-подключения на всех интерфейсах. Я предпочитаю описывать именно так на случай ошибки в имени внешнего VPN-интерфейса. Если, вы ошибетесь в имени интерфейса при его инициализации, то ssh-соединение не будет прервано и вы сможете оперативно исправить ошибку.
  • $IPT -A INPUT -i $MAIN_VPN_INTERFACE -j ACCEPT - разрешаем любые взаимодействия между VPS-сервером и рабочими станциями разработчиков по VPN-туннелю.
  • $IPT -A INPUT -i $MAIN_EXT_INTERFACE -p tcp --dport 80 -j ACCEPT - а наборы вот таких инструкций разрешают доступы к публичным сервисам предоставляемым VPS-сервером (в моем случае это web-сервер с доступом по 80-ому и 443-ему порту).

Как вы видите, ничего сложного в настройке iptables нет и скрипты получаются простые, читаемые и легкие в сопровождении. Кстати, если вам интересно будет почитать о более сложных конструкциях, то я с удовольствием могу продолжить цикл статей по настройке iptables.

Оставьте комментарий

Вы должны быть вошедший в чтобы отправить комментарий