Если вы когда-нибудь анализировали содержимое журналов нового облачного сервера, то наверняка замечали подозрительную активность с первых же секунд его сетевой жизни. Кто эти незнакомцы, сканирующие порты? Чем грозит такой интерес?
Привет! Меня зовут Марк, я методолог по информационной безопасности в Selectel. В этой статье расскажу, как использовать механизм cloud-init для базовой настройки параметров безопасности облачных Linux-серверов в небольших проектах. Рассмотрим, каким образом такая практика помогает реализовать меры по обеспечению безопасности персональных данных в соответствии с Приказом ФСТЭК № 21.
О каких рисках стоит задуматься
Использование облачной платформы зачастую начинается с заказа одного или нескольких серверов. Цели могут быть самые разные: размещение личного pet-проекта, создание рабочего Telegram-бота, небольшого интернет-магазина, публикация сайта-визитки.
Если сервер один или их немного, настройки параметров безопасности, как правило, выполняются администратором вручную и требуют времени. Именно этот период — от момента первого запуска системы до окончания ее базовой настройки — является подарком для тысяч ботов. Кроме того, при работе с конфигурацией вручную есть риск допустить ошибки, которые будут замечены не сразу.
После первой загрузки, машина с публичным IP-адресом становится доступна для атак, часто направленных на подбор пароля для подключения по SSH. Проблема в том, что по умолчанию SSH-сервер дает root-доступ к управлению системой и может аутентифицировать пользователя не только по заранее заданному ключу, но и по паролю.
Другой распространенный сценарий атак также предполагает активность ботов, которые пытаются эксплуатировать известные уязвимости веб-серверов для получения доступа к управлению содержимым веб-сайта или даже ко всей системе.
Последствия описанных атак в случае успеха могут оказаться довольно неприятными, а для небольшого бизнеса — катастрофическими. Получив административный доступ к облачному серверу, злоумышленник может организовать скрытый канал управления или установить шпионскую программу. В будущем это позволит ему продать удаленный доступ, похитить уже наполненную базу персональных данных, организовывать DDoS-атаки на другие ресурсы.
Чтобы быть уверенным в безопасности сервера, нужно исключить период ручной первоначальной настройки, когда защитные механизмы еще не активны и система находится в уязвимом состоянии. Что предпринять, чтобы при развертывании сервиса не потерять деловую репутацию? И как не стать невольным соучастником противоправных действий при запуске pet-проекта?
Облачные серверы для любых задач
Настройка безопасной конфигурации
Ботов очень много, и они невероятно быстры. В этой игре на время выигрышной является стратегия создания виртуальных серверов сразу в базовой безопасной конфигурации. Другими словами, необходимо настроить систему до ее первого запуска. Для этого мы зададим пользовательские параметры user data, которые будут автоматически применены при первой загрузке с использованием механизма cloud-init.
user data — данные конфигурации, которые передает пользователь облачной платформы экземпляру cloud-init при запуске. Форматов для хранения user data несколько — мы использовали YAML как наиболее удобный. Подробнее можно прочитать в нашей статье и документации разработчиков.
Рассмотрим несколько основных параметров, а также простых и проверенных временем инструментов. Для описания user data будем использовать YAML-файл, который мы шаг за шагом заполним при составлении конфигурации.
Управление административным доступом
Начнем с защиты подключения по SSH. Как было отмечено ранее, по умолчанию SSH-сервер дает полный доступ к управлению системой единственному пользователю root и может аутентифицировать его не только по ключу, но и по паролю.
Создадим новую группу admins
и входящего в нее пользователя admin
. Далее включим его в группу sudo
, дадим разрешение на выполнение команд с повышенными привилегиями без ввода пароля, зададим Bash командной оболочкой по умолчанию и добавим публичный SSH-ключ администратора в список авторизованных ключей ~/.ssh/authorized_keys
.
Здесь и далее отдельные настройки будут сопровождаться ссылкой на принятое ФСТЭК обозначение соответствующей меры защиты персональных данных.
В контексте приказа ФСТЭК России № 21 такой подход соответствуют реализации мер ИАФ.3, ИАФ.5 и УПД.1. Причем мера ИАФ.5 (защита обратной связи при вводе аутентификационной информации) реализуется за счет того, что интерактивный ввод пароля не используется, а значит, его невозможно и подсмотреть.
Для cloud-init выполненные настройки описываются в следующем формате:
groups:
- admins
users:
- name: admin
primary_group: admin
groups:
- sudo
- admins
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- <ssh_public_key>
Теперь скорректируем настройки SSH-сервера путем перезаписи отдельных строк конфигурационного файла /etc/ssh/sshd_config
с использованием утилиты sed:
runcmd:
- sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
- sed -i -e '/^PasswordAuthentication/s/^.*$/PasswordAuthentication no/' /etc/ssh/sshd_config
- sed -i -e '/^#ClientAliveInterval/s/^.*$/ClientAliveInterval 5m/' /etc/ssh/sshd_config
- sed -i -e '/^#ClientAliveCountMax/s/^.*$/ClientAliveCountMax 3/' /etc/ssh/sshd_config
- sed -i -e '$aAllowGroups admins' /etc/ssh/sshd_config
Указанные параметры запрещают аутентификацию по паролю при использовании SSH, а также вход пользователя root
и любых других пользователей, не принадлежащих ранее созданной группе admins
(меры ИАФ.1 и УПД.2). Кроме того, реализуется автоматическое завершение открытой SSH-сессии на стороне сервера при отсутствии сетевой активности SSH-клиента в течение 15 минут — например, при переходе компьютера администратора в спящий режим или при потере интернет-соединения.
Если по какой-то причине администратор оставил компьютер с открытой SSH-сессией незаблокированным, в теории есть риск неконтролируемого доступа к управлению сервером. Чтобы избежать этого, задаем значение переменной окружения TMOUT
равным 900:
runcmd:
- printf "%s\n""readonly TMOUT=900" "export TMOUT" >> /etc/profile
Если пользователь не совершал никаких действий на сервере в течение заданных 900 секунд (15 минут), происходит автоматический выход из учетной записи и завершение SSH-сессии с отправкой стандартного сообщения «timed out waiting for input: auto-logout» (мера УПД.10).
Противодействие подбору учетных данных
В качестве дополнительной меры защиты можно реализовать автоматическую блокировку IP-адресов, с которых пытаются подобрать учетные данные (логин и пароль) для подключения по SSH (мера УПД.6). Для этого используем пакет fail2ban:
package_update: true
packages:
- fail2ban
write_files:
- path: /etc/fail2ban/jail.local
permissions: 0640
owner: root:root
content: |
[sshd]
enabled = true
findtime = 1m
nmaxretry = 5
bantime = 15m
runcmd:
- systemctl enable fail2ban
Параметры fail2ban задаются в конфигурационном файле /etc/fail2ban/jail.local
и предполагают 15-минутную блокировку IP-адреса, если в течение минуты было предпринято пять неудачных попыток входа по SSH.
Фильтрация трафика
Следующим шагом настроим базовые правила фильтрации входящего трафика с использованием встроенного межсетевого экрана iptables:
package_update: true
packages:
- iptables-persistent
write_files:
- path: /etc/iptables/rules.v4
permissions: 0640
owner: root:root
content: |
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp --icmp-type 3 -j ACCEPT
-A INPUT -p icmp --icmp-type 11 -j ACCEPT
COMMIT
Базовые правила фильтрации для IPv4-трафика, разрешающие по умолчанию только входящие подключения по SSH и сетевое взаимодействие в рамках инициированных сервером соединений (мера УПД.3), описаны в правилах /etc/iptables/rules.v4
. Для автоматической загрузки правил из файла устанавливается пакет iptables-persistent
. Также в целях безопасности рекомендуется отключить обработку IPv6-трафика:
runcmd:
- printf "%s\n" "net.ipv6.conf.all.disab
le_ipv6 = 1" "net.ipv6.conf.default.disable_ipv6 = 1" "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf && sysctl -p
Журнал событий безопасности
Завершающим этапом является настройка логирования событий безопасности (меры РСБ.1 и РСБ.3). Все действия, связанные с попытками аутентификации пользователей, удаленного подключения к серверу, а также с созданием, изменением, удалением учетных записей, фиксируются по умолчанию компонентами операционной системы (PAM). Однако для своевременного выявления подозрительных действий рекомендуется настроить мониторинг изменения основных лог-файлов, повышения привилегий, изменения прав доступа. Для этого используем возможности подсистемы Linux Audit (auditd):
package_update: true
packages:
- auditd
write_files:
- path: /etc/audit/rules.d/audit.rules
permissions: 0640
owner: root:root
content: |
-D
-e 1
-f 1
-a always,exclude -F msgtype=CWD
-a always,exclude -F msgtype=PATH
-a always,exclude -F msgtype=PROCTITLE
-a always,exit -F dir=/var/log/audit/ -F perm=wa -F auid!=unset -F key=audit-trail-modification
-a always,exit -F path=/var/log/syslog -F perm=wa -F auid!=unset -F key=audit-trail-modification
-a always,exit -F path=/var/log/auth.log -F perm=wa -F auid!=unset -F key=audit-trail-modification
-a always,exit -F arch=x86_64 -S setuid -F auid!=unset -F a0=0 -F exe=/usr/bin/su -F key=elevated-privileges-session
-a always,exit -F arch=x86_64 -S setresuid -F auid!=unset -F a0=0 -F exe=/usr/bin/sudo -F key=elevated-privileges-session
-a always,exit -F arch=x86_64 -S execve -F auid!=unset -C uid!=euid -F euid=0 -F key=elevated-privileges-session
-a always,exit -F arch=x86_64 -S chmod -S fchmod -S chown -S fchown -S lchown -F auid!=unset -F key=access-rights-modification
Описанные типы событий безопасности будут записываться в журнал /var/log/audit/audit.log
и могут быть просмотрены непосредственно в файле или с использованием утилит ausearch
и aureport
. При необходимости список событий может быть дополнен в правилах /etc/audit/rules.d/audit.rules
.
Применение настроек
Для применения всех выполненных настроек необходимо перезагрузить сервер.
Содержимое user data с учетом всего вышесказанного:
#cloud-config
package_update: true
packages:
- iptables-persistent
- fail2ban
- auditd
groups:
- admins
users:
- name: admin
primary_group: admin
groups:
- sudo
- admins
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- <ssh_public_key>
write_files:
- path: /etc/iptables/rules.v4
permissions: 0640
owner: root:root
content: |
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp --icmp-type 3 -j ACCEPT
-A INPUT -p icmp --icmp-type 11 -j ACCEPT
COMMIT
- path: /etc/fail2ban/jail.local
permissions: 0640
owner: root:root
content: |
[sshd]
enabled = true
findtime = 1m
nmaxretry = 5
bantime = 15m
- path: /etc/audit/rules.d/audit.rules
permissions: 0640
owner: root:root
content: |
-D
-e 1
-f 1
-a always,exclude -F msgtype=CWD
-a always,exclude -F msgtype=PATH
-a always,exclude -F msgtype=PROCTITLE
-a always,exit -F dir=/var/log/audit/ -F perm=wa -F auid!=unset -F key=audit-trail-modification
-a always,exit -F path=/var/log/syslog -F perm=wa -F auid!=unset -F key=audit-trail-modification
-a always,exit -F path=/var/log/auth.log -F perm=wa -F auid!=unset -F key=audit-trail-modification
-a always,exit -F arch=x86_64 -S setuid -F auid!=unset -F a0=0 -F exe=/usr/bin/su -F key=elevated-privileges-session
-a always,exit -F arch=x86_64 -S setresuid -F auid!=unset -F a0=0 -F exe=/usr/bin/sudo -F key=elevated-privileges-session
-a always,exit -F arch=x86_64 -S execve -F auid!=unset -C uid!=euid -F euid=0 -F key=elevated-privileges-session
-a always,exit -F arch=x86_64 -S chmod -S fchmod -S chown -S fchown -S lchown -F auid!=unset -F key=access-rights-modification
runcmd:
- printf "%s\n""readonly TMOUT=900" "export TMOUT" >> /etc/profile
- printf "%s\n" "net.ipv6.conf.all.disable_ipv6 = 1" "net.ipv6.conf.default.disable_ipv6 = 1" "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf && sysctl -p
- sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
- sed -i -e '/^PasswordAuthentication/s/^.*$/PasswordAuthentication no/' /etc/ssh/sshd_config
- sed -i -e '/^#ClientAliveInterval/s/^.*$/ClientAliveInterval 5m/' /etc/ssh/sshd_config
- sed -i -e '/^#ClientAliveCountMax/s/^.*$/ClientAliveCountMax 3/' /etc/ssh/sshd_config
- sed -i -e '$aAllowGroups admins' /etc/ssh/sshd_config
- systemctl enable fail2ban
- reboot
Для использования описанной конфигурации необходимо внести в нее свои данные — как минимум публичный SSH-ключ <ssh_public_key>
— и сохранить в текстовом файле, например, cloud-config.txt
. При создании нового облачного сервера в панели управления my.selectel.ru в разделе Автоматизация нужно выбрать опцию Файл, указать путь к сохраненному файлу конфигурации или просто перетащить его в выделенное поле.
Остается проверить параметры нового сервера и нажать кнопку Создать. Начнется процесс установки и первоначальной настройки, в ходе которой он будет перезагружен.
После запуска сервера к нему можно подключаться по SSH с использованием заданного в конфигурации имени пользователя (в описанном примере — admin) и соответствующего ключа. Для дополнительной защиты рекомендуется зашифровать используемые SSH-ключи парольной фразой.
Итоги
Описанные в статье действия позволяют:
- предпринять базовые меры безопасности, необходимые для начала работы с облачным сервером;
- успешно противодействовать ботам, атакующим хост сразу после создания;
- реализовать часть обязательных мер защиты персональных данных в соответствии с требованиями ФСТЭК России.
В более сложных проектах, автоматизировать создание и настройку облачных ресурсов следует с помощью систем управления облачной инфраструктурой — например, Terraform — и конфигурациями.