Защита Joomla с помощью iptables Печать
Добавил(а) microsin   

Если у Вас на HTTP-сервере установлена устаревшая версия PHP 5.2, или старая система Linux, или есть какая-то другая причина, которая не позволяет сменить систему, то велика вероятность взлома сервера через какую-нибудь уязвимость. Уменьшить эту вероятность, или хотя бы запретить генерировать вредоносный трафик с сервера Вы можете, если установите на него файервол. В системе Debian (и в других *nix системах) очень популярен файервол iptables. Настройка его довольно проста, здесь я рассмотрю базовую установку iptables для защиты сервера с CMS Joomla (хотя таким способом может быть защищена и любая другая система управления сайтом).

[Установка iptables]

apt-get install iptables

[Настройка и запуск]

iptables -L

Если у Вас iptables только что установлен и пока не настроен, то в результате получится следующее:

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

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

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

# iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

Что интересно, процесс запущенного сервиса iptables (командой ps -ef) просмотреть нельзя, потому что он встроен в ядро.

Конфигурируется iptables командами наподобие следующих (не нужно в команду вводить текст после слешей //, это просто комментарий к команде):

iptables -F // сброс (flush) всех ранее настроенных правил
iptables -A INPUT -p tcp --dport 80 -j ACCEPT // Apache
iptables -A INPUT -p icmp -j ACCEPT // разрешить пакеты ICMP (ping)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT // sshd, доступ к SSH
iptables -A INPUT -p tcp --dport 25 -j ACCEPT // входящая почта (SMTP)
iptables -A INPUT -p tcp --dport 110 -j ACCEPT // исходящая почта (POP3)
iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state RELATED -j ACCEPT
iptables -A INPUT -j REJECT // все остальные пакеты отбрасываются

Здесь приведен пример простейшей настройки правил для HTTP-сервера, который фильтрует только входящий трафик. Если Вы введете эти команды построчно, одну за другой, то iptables начнет пропускать только этот указанный входящий трафик, весь посторонний входящий трафик будет отбрасываться. Все настроенные правила будут сохранены в оперативной памяти сервера до его последующей перезагрузки, т. е. после перезагрузки эти правила сбросятся, и iptables снова перестанет фильтровать трафик; как сделать правила постоянными (persistent) мы рассмотрим далее.

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

ОК, iptables мы настраивать научились, но как сделать так, чтобы наши правила автоматом применялись применялись при каждой перезагрузке сервера?

Конечно, разумной идеей будет тупо подготовить shell-скрипт, записать туда все нужные команды iptables, а потом добавить этот скрипт в автозагрузку (для Debian это к примеру каталоги в папке /etc/network, такие как if-up.d и run). Вот пример такого скрипта:

#!/bin/sh
 
iptables -F
iptables -X
 
iptables --new-chain out_apache
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner www-data -j out_apache
iptables -A out_apache -p tcp --syn -d 127.0.0.1 --dport 25 -j RETURN
 
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT --match state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --sport 20 --match state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j REJECT
iptables -A out_apache -j REJECT

Но можно поступить лучше, как советует руководство по iptables [1]:

1. Настройте iptables и проверьте его работу.

2. Сохраните текущую конфигурацию iptables в файл с помощью команды iptables-save:

iptables-save > /var/lib/iptables/rules

После этой команды создастся файл конфигурации /var/lib/iptables/rules, в который будут записаны все текущие (активные на данный момент) правила iptables. Это может быть и любой другой файл.

3. Для того, чтобы применить правила, записанные в файл, существует команда iptables-restore. Вот пример такой команды, которая применит сохраненные нами правила:

iptables-restore < /var/lib/iptables/rules

Обычно эта команда добавляется в любой скрипт автозагрузки, который запускается после инициализации сети. В системе Debian это может быть любой скрипт, помещенный в папку /etc/network/if-up.d. Вот пример такого скрипта (он выполнится автоматом после запуска сетевого интерфейса):

#!/bin/sh
/sbin/iptables-restore < /var/lib/iptables/rules

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

Добавьте перед всезапрещающим правилом следующие правила:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT

После этого сохраните текущую конфигурацию (см. предыдущий раздел).

Причины для этой ошибки могут быть самые разные. Смысл в том, что в правиле, которое Вы ввели, имеется недопустимое имя цепочки (chain), цели (target) или совпадения (match). Цепочки по умолчанию заданы в зарезервированные имена INPUT, FORWARD и OUTPUT. Могут быть также добавлены пользовательские цепочки, которые привязаны к определенному набору правил.

Я столкнулся с ошибкой "No chain/target/match by that name", когда пытался использовать правила с привязкой на совпадение с состоянием соединения (-m state, я выделил жирным шрифтом):

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT

Проблема была решена переконфигурированием ядра - была активирована возможность использовать соответствующие модули ядра (stateful-фильтрация).

Это специфические термины iptables, обозначающие цепочки (chain, нужны для создания таблицы правил), цели (target, определяет как именно действует заданное правило) и совпадения (match, специальное условие, при котором правило срабатывает).

CHAIN. Цепочки по умолчанию заданы в зарезервированные имена INPUT, FORWARD и OUTPUT. Можно также добавлять и свои цепочки командой iptables --new-chain имя_цепочки. Цепочки - это по сути таблицы правил, специально предназначенные для трафика определенного вида. Как я уже упоминал, 3 цепочки существуют изначально, это INPUT, FORWARD и OUTPUT. Самые важные для WWW-сервера это только цепочки INPUT (регулируют входящий трафик) и OUTPUT (регулируют исходящий трафик).

TARGET. Цели можно посмотреть в файле ip_tables_targets:

# cat /proc/net/ip_tables_targets
MASQUERADE
TCPMSS
REJECT
REDIRECT
LOG
DNAT
SNAT
ERROR

Цели определяют, что нужно делать с указанным трафиком, т. е. куда надо перескочить при обработке указанного трафика в правиле (обычно это цели ACCEPT или REJECT).

MATCH. Допустимые совпадения можно посмотреть в файле ip_tables_matches:

# cat /proc/net/ip_tables_matches
limit
connlimit
owner
length
ttl
tcpmss
multiport
tos
dscp
recent
owner
state
icmp
udplite
udp
tcp

Смысл совпадений можно понять из имен. По совпадениям определяется, на какой трафик или по каким признакам сработает правило.

[Ссылки]

1. Debian iptables site:wiki.debian.org.
2. Iptables Firewall site:wiki.kartbuilding.net.
3. Apache Hardening site:wiki.debian.org.
4. Installing apache on Debian site:articles.slicehost.com.
5Автоматическая загрузка правил для iptables.
6. Добавление правил iptables для отражения атак на сервер.