Настройка безопасности Drupal веб-сервера

Опубликовано admin - вт, 01/02/2018 - 20:47
  1. Настройка 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

Есть ряд ограничений, накладываемых на движение по цепочкам

  1. цепочка должна быть создана до того, как на неё выполняется переход;

  2. цепочка должна находиться в той же таблице, что и цепочка, с которой происходит переход.

Далее мы открываем порт для 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. Если же вы не сделали это, надо выполнить следующие действия:

  1. Перед сменой порта SSH добавьте в IPTables правило, разрешающие подключение по новому порту

iptables -A my_packets -p tcp -m tcp --dport 2223 -j ACCEPT
  1. Измените порт сервера 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 ваш открытый ключ.

Добавить комментарий

Filtered HTML

  • Допустимые HTML-теги: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd>
  • Строки и абзацы переносятся автоматически.
  • Web page addresses and email addresses turn into links automatically.