Автоматизируем настройку облачного сервера по ФСТЭК

Автоматизируем базовую настройку облачного сервера по правилам ИБ

Марк Песков
Марк Песков Методолог по информационной безопасности
19 августа 2024

Подробная инструкция о том, как не дать угнать сервер в первые же секунды его создания и как удовлетворить все требования приказа ФСТЭК 21 о безопасности персональных данных.

Изображение записи

Если вы когда-нибудь анализировали содержимое журналов нового облачного сервера, то наверняка замечали подозрительную активность с первых же секунд его сетевой жизни. Кто эти незнакомцы, сканирующие порты? Чем грозит такой интерес?

Привет! Меня зовут Марк, я методолог по информационной безопасности в 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 — и конфигурациями.