-
Настройка FIREWALL
Итак, наш веб-сервер управляется ОС Debian, и нам необходимо обезопасить его, настроить всё так, чтобы свести все риски к минимуму. Для начала, выполняем базовую настройку Firewall. Наш выбор - IPTables.
Изначально фаервол открыт, весь трафик проходит через него беспрепятственно. Список правил iptables мы проверяем следующей командой:
# iptables -L -v -n Chain INPUT (policy ACCEPT 5851 packets, 7522K bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 320M packets, 19G bytes) pkts bytes target prot opt in out source destination
Всё ясно. Удаление всех правил из IPTables осуществляется следующей командой:
iptables -F
Правила по умолчанию IPTables
Правила по умолчанию -- удобная и полезная вещь. В IPTables они задаются с помощью политик (-P). Обычная практика -- отбрасывание всех пакетов и ряд разрешающих правил конкретных случаев.
Отбрасывать (блокировать) все пакеты позволяет следующее правило:
iptables -P INPUT DROP
Дополнительное усиление защиты -- запрет пересылаемых пакетов, то есть пакетов, маршрутизируемых брандмауэром к точке назначения. Этот уровень защиты включается следующим правилом:
iptables -P FORWARD DROP
Для loopback мы разрешаем локальный трафик:
iptables -A INPUT -i lo -j ACCEPT
В следующем правиле используется модуль (-m) state. Он позволяет проверить состояние устанавливаемого соединения, которое может быть RELATED или ESTABLISHED. Соединение устанавливается только тогда, когда оно удовлетворяет настройкам правила. Состояние ESTABLISHED указывает на то, что в рамках соединения уже пересылались пакеты, состояние RELATED -- на то, что пересылкой пакета устанавливается новое соединение, но оно связано с уже существующим соединением.
Следующее правило разрешает работу всех уже инициированных соединений (ESTABLISHED) и дочерних по отношению к ним:
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
А это правило допускает и новые соединения:
iptables -A OUTPUT -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
Данное правило разрешает форвардинг новых, существующих (инициированных) и их дочерних соединений:
iptables -A FORWARD -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
Пара правил ниже говорит, что следует отбрасывать все пакеты, которые невозможно идентифицировать, то есть определенный статус они иметь не могут.
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP iptables -A FORWARD -m conntrack --ctstate INVALID -j DROP
Разрешающие правила
Следующий шаг: определяем разрешающие правила, обеспечивающие корректную работу нашего веб-сервера. Их мы оформляем отдельной цепочкой.
Создаём пользовательские цепочки:
iptables -N my_packets
Переход в пользовательскую цепочку осуществляется следующей командой:
iptables -A INPUT -p tcp -j my_packets
Есть ряд ограничений, накладываемых на движение по цепочкам
-
цепочка должна быть создана до того, как на неё выполняется переход;
-
цепочка должна находиться в той же таблице, что и цепочка, с которой происходит переход.
Далее мы открываем порт для ssh. Важно: обязательно укажите свой порт, если ранее он был изменён!
iptables -A my_packets -p tcp -m tcp --dport 22 -j ACCEPT
Если подключение по ssh позволено только некоторым лицам, имеющим статические ip адреса, есть смысл настроить ограничение по ip адресам. Чтобы сделать это, мы вместо предыдущей команды используем такую:
iptables -A my_packets -s х.х.х.х -p tcp -m tcp --dport 22 -j ACCEPT
где х.х.х.х - ip адрес, с которого выполняется подключение.
Так как у нас работает веб-сервер, мы должны открывать порты 80 и 443. Для этого используем следующие команды:
iptables -A my_packets -p tcp -m tcp --dport 80 -j ACCEPT iptables -A my_packets -p tcp -m tcp --dport 443 -j ACCEPT
В дополнение ко всем этим правилам, можно настроить ряд правил для следующих случаев:
- Удалённое подключение к серверу MySQL Если такое возможно, лучше ограничивать подключение по ip адресам:
iptables -A my_packets -s х.х.х.х -p tcp -m tcp --dport 3306 -j ACCEPT
- Сервер настроен на прием почты Для такого случая хорошо иметь следующий набор правил:
iptables -A my_packets -p tcp -m tcp --dport 110 -j ACCEPT iptables -A my_packets -p tcp -m tcp --dport 143 -j ACCEPT iptables -A my_packets -p tcp -m tcp --dport 993 -j ACCEPT iptables -A my_packets -p tcp -m tcp --dport 995 -j ACCEPT
Всё. Этих правил достаточно, чтобы наш веб-сервер корректно работал. Для остальных портов и протоколов настраиваем REJECT, то есть не принимаем ничего:
iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
От DROP эта директива отличается тем, что отправитель получает IСМР-сообщение "Port unreachable" («Порт недоступен»). Опция --reject-with позволяет изменить тип ICMP-сообщения и имеет следующие аргументы:
- icmp-net-unreachable — сеть недоступна;
- icmp-host-unreachable — узел недоступен;
- icmp-port-unreachable — порт недоступен;
- icmp-proto-unreachable — неподдерживаемый протокол;
- icmp-net-prohibited — сеть запрещена;
- icmp-host-prohibited — узел запрещен.
По умолчанию передаётся сообщение с аргументом port-unreachable.
TCP-пакеты можно отклонить с помощью аргумента tcp-reset, он подразумевает отправку RST-сообщения. С точки зрения безопасности, это наилучший способ. TCP RST пакеты используются для закрытия TCP соединений.
2. Настройка fail2ban
Fail2ban — простой локальный сервис, отслеживающий log–файлы запущенных программ. Руководствуясь условиями, сервис блокирует по IP обнаруженных нарушителей.
Fail2ban успешно справляется с различными атаками на все популярные *NIX–сервисы (Apache, Nginx, ProFTPD, vsftpd, Exim, Postfix, named и т.д.) Так же Fail2ban защитает SSH–сервер от bruteforce-атак прямо “из коробки”.
Установка fail2ban
Fail2ban есть в репозитории, так что установить его очень просто:
apt-get install fail2ban
Настройка Fail2ban
В первую очередь, необходимо настроить защиту сервера по протоколу SSH. Для начала, найдите в файле jail.conf секцию [ssh] и убедитесь в том, что в значении параметра enabled фигурирует true.
Затем следует указать значения параметров fail2ban:
- filter — используемый фильтр. По умолчанию это /etc/fail2ban/filter.d/sshd.conf;
- action — действия, выполняемые fail2ban, когда обнаружен атакующий ip-адрес; описания правил реагирования атаки есть в файле /etc/fail2ban/action.d., то есть значение параметра не может быть таким, которого нет в этом файле;
- logpath — полный путь к файлу, в который записывается записываются данные о попытках получения доступа к VPS;
- findtime — время (в секундах), в течение которого фиксируется подозрительная активность;
- maxretry — максимальное разрешенное количество попыток подключения к серверу;
- bantime — время блокировки попавшего в черный список ip.
Важно: прописывать все параметры необязательно, если вы не сделаете этого, будут действовать настройки, указанные в главном разделе [DEFAULT]. Главное -- указать для переменной enabled значение true.
Защита протокола SSH
Рассмотрим применение параметров реагирования в деталях. Ниже -- пример конфигурации fail2ban на порту SSH:
[ssh] enabled = true port = ssh filter = sshd action = iptables[name=sshd, port=ssh, protocol=tcp] sendmail-whois[name=ssh, dest=****@yandex.ru, sender=fail2ban@***.ru] logpath = /var/log/auth.log maxretry = 3 bantime = 600
Расшифровка: если выполнено более 3 неудачных попыток подключения к серверу через порт SSH, то ip-адрес, с которого выполнялась авторизация, блокируется на 10 минут. Правило запрета добавляется в IPTables, а владелец сервера получает уведомление на адрес, указанный в переменной dest. В уведомлении -- заблокированный ip, WHOIS-данные об этом ip и причина блокировки.
Дополнительно, для защиты SSH можно активировать следующую секцию:
[ssh-ddos] enabled = true port = ssh filter = sshd-ddos logpath = /var/log/auth.log maxretry = 2
3. Настройка прав доступа к файлам сайта
Сервер нельзя считать безопасным, если не выполнена настройка прав доступа к файлам Drupal сайта. Приведённый ниже пример -- один из способов изменения владельца и прав на файлы/каталоги Drupal-сайта. Вводные:
- webmaster принадлежит группе webmaster и является владельцем сайта;
- сам сайт находится на сервере, где веб-сервер работает под пользователем www-data.
Настраиваем права:
#cd /path_to_drupal_installation #chown -R webmaster:www-data . #find . -type d -exec chmod u=rwx,g=rx,o= '{}' \; #find . -type f -exec chmod u=rw,g=r,o= '{}' \;
Пользователь www-data должен иметь права на запись в директорию, поэтому у директории «files» в каталоге sites/default (и у любых других каталогов сайтов, если установка многосайтовая) разрешения различные. Бит s группы владельца используется и для каталога, так как нам надо, чтобы все файлы, созданные в нем веб-сервером, принимали идентификатор группы каталога webmaster, а не группы владельца, создавшего файл в этом каталоге.
#cd /path_to_drupal_installation/sites #find . -type d -name files -exec chown -R www-data:webmaster '{}' \; #find . -type d -name files -exec chmod ug=rwx,o=,g+s '{}' \; #for d in ./*/files do find $d -type d -exec chmod ug=rwx,o=,g+s '{}' \; find $d -type f -exec chmod ug=rw,o= '{}' \; done
Для временного каталога у нас тоже другие права, ведь веб-сервер должен иметь права на запись в этот каталог.
#cd /path_to_drupal_installation #chown -R www-data:webmaster tmp #chmod ug=rwx,o=,g+s tmp
settings.php и .htaccess: особые права
Файл settings.php содержит пароль базы данных и имя пользователя, причём указаны они там простым текстом. Так что после его создания, надо установить такие права, которые позволяют чтение только определённым пользователям. Обычно, необходимо просто лишить прав пользователя «other»:
#chmod 440 './sites/*/settings.php' #chmod 440 './sites/*/default.settings.php'
.htaccess - конфигурационный файл Apache, дающий власть над работой веб-сервера и настройками сайта. Соответственно, права должны допускать чтение только определёнными пользователями:
#chmod 440 './.htaccess' #chmod 440 './tmp/.htaccess' #chmod 440 './sites/*/files/.htaccess'
4. Безопасная настройка ssh
Чтобы сделать систему более защищённой, рекомендую внести некоторые изменения в настройки сервера SSH. Лучше запускать его на нестандартном порту, иначе к нему постоянно будут обращаться боты, в том числе подбирающие пароли. В Debian, как и в других дистрибутивах Linux, SSH по умолчанию работает на порту 22. Можно изменить его на, скажем, 2223. Кроме того, стоит изменить конфигурацию так, чтобы root подключался только с использованием ssh ключа. По умолчанию, в Debian пользователь root по SSH не может пройти авторизацию паролем.
Лучше изменять порт SSH до настройки firewall. Если же вы не сделали это, надо выполнить следующие действия:
-
Перед сменой порта SSH добавьте в IPTables правило, разрешающие подключение по новому порту
iptables -A my_packets -p tcp -m tcp --dport 2223 -j ACCEPT
-
Измените порт сервера SSH в /etc/ssh/sshd_config. Там нужно изменить соответствующие строки, чтобы они выглядели так:
Port 2223 PermitRootLogin prohibit-password PubkeyAuthentication yes ChallengeResponseAuthentication no
Не забудьте сохранить изменения! Затем перезапустите SSH-сервер:
# service sshd restart
Тут можно и нужно проверить изменения:
# netstat -tulnp | grep ssh tcp 0 0 0.0.0.0:2223 0.0.0.0:* LISTEN 640/sshd tcp6 0 0 :::2223 :::* LISTEN 640/sshd
Всё в порядке. SSH-сервер слушает порт 2223, теперь новое подключение будет осуществляться только через этот порт, а после перезапуска SSH старое подключение не будет разорвано.
Внимание! Перед отключением авторизации по паролю для пользователя root проверьте, есть ли в файле /root/.ssh/authorized_keys ваш открытый ключ.