Не дать угнать за 60 секунд: автоматизируем базовую настройку облачного сервера

ty38m-zhjdliuwttlvo-uvklfxu.png


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

Привет! Меня зовут Марк, я методолог по информационной безопасности в Selectel. В этой статье расскажу, как использовать механизм cloud-init для базовой настройки параметров безопасности облачных Linux-серверов в небольших проектах. Рассмотрим, каким образом такая практика помогает реализовать меры по обеспечению безопасности персональных данных в соответствии с Приказом ФСТЭК № 21.
Используйте навигацию, если не хотите читать текст полностью:

→ О каких рисках стоит задуматься
→ Настройка безопасной конфигурации
    → Управление административным доступом
    → Противодействие подбору учетных данных
    → Фильтрация трафика
    → Журнал событий безопасности
    → Применение настроек
→ Итоги

О каких рисках стоит задуматься


Использование облачной платформы зачастую начинается с заказа одного или нескольких серверов. Цели могут быть самые разные: размещение личного pet-проекта, создание рабочего Telegram-бота, небольшого интернет-магазина, публикация сайта-визитки.

Если сервер один или их немного, настройки параметров безопасности, как правило, выполняются администратором вручную и требуют времени. Именно этот период — от момента первого запуска системы до окончания ее базовой настройки — является подарком для тысяч ботов. Кроме того, при работе с конфигурацией вручную есть риск допустить ошибки, которые будут замечены не сразу.

После первой загрузки, машина с публичным IP-адресом становится доступна для атак, часто направленных на подбор пароля для подключения по SSH. Проблема в том, что по умолчанию SSH-сервер дает root-доступ к управлению системой и может аутентифицировать пользователя не только по заранее заданному ключу, но и по паролю.

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

Последствия описанных атак в случае успеха могут оказаться довольно неприятными, а для небольшого бизнеса — катастрофическими. Получив административный доступ к облачному серверу, злоумышленник может организовать скрытый канал управления или установить шпионскую программу. В будущем это позволит ему продать удаленный доступ, похитить уже наполненную базу персональных данных, организовывать DDoS-атаки на другие ресурсы.

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

nblot_ve1t3hcw5bluwc_-did08.png

Настройка безопасной конфигурации


Ботов очень много, и они невероятно быстры. В этой игре на время выигрышной является стратегия создания виртуальных серверов сразу в базовой безопасной конфигурации. Другими словами, необходимо настроить систему до ее первого запуска. Для этого мы зададим пользовательские параметры 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-сервера путем перезаписи отдельных строк конфигурационного файла /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.disable_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:
      - 
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-ключ  — и сохранить в текстовом файле, например, cloud-config.txt. При создании нового облачного сервера в панели управления my.selectel.ru в разделе Автоматизация нужно выбрать опцию Файл, указать путь к сохраненному файлу конфигурации или просто перетащить его в выделенное поле.

e51285e5e2298f58c4fa5c47566da2f3.png


Остается проверить параметры нового сервера и нажать кнопку Создать. Начнется процесс установки и первоначальной настройки, в ходе которой он будет перезагружен.

После запуска сервера к нему можно подключаться по SSH с использованием заданного в конфигурации имени пользователя (в описанном примере — admin) и соответствующего ключа. Для дополнительной защиты рекомендуется зашифровать используемые SSH-ключи парольной фразой.

Итоги


Описанные в статье действия позволяют:

  • предпринять базовые меры безопасности, необходимые для начала работы с облачным сервером;
  • успешно противодействовать ботам, атакующим хост сразу после создания;
  • реализовать часть обязательных мер защиты персональных данных в соответствии с требованиями ФСТЭК России.


В более сложных проектах, автоматизировать создание и настройку облачных ресурсов следует с помощью систем управления облачной инфраструктурой — например, Terraform — и конфигурациями.

Читайте также:

© Habrahabr.ru