OpenSSH Daemon — программа-сервер, обслуживающая запросы программы-клиента ssh (secure shell — безопасная оболочка). Вместе эти программы заменяют rlogin и rsh и обеспечивают защищённую и зашифрованную связь между двумя непроверенными компьютерами через незащищённую сеть.

sshd — служба, принимающая запросы на соединения от клиентов. Обычно она запускается при загрузке системы из /etc/rc. Для каждого нового соединения создаётся (с помощью вызова fork) новый экземпляр службы. Ответвлённый экземпляр обрабатывает обмен ключами, шифрование, аутентификацию, выполнение команд и обмен данными.

Параметры определяются при помощи ключей командной строки или файла настроек /etc/ssh/sshd_config. Ключи командной строки имеют больший приоритет, чем значения, указанные в файле конфигурации. При получении сигнала отбоя SIGHUP перечитывает свой файл конфигурации путём запуска собственной копии с тем же самым именем, с которым был запущен, например /usr/sbin/sshd.

На свежеустановленной системе Linux обычно открыт только 22 порт для ssh подключения и порт 546 для клиента dhcpv6-client (чтобы сервер автоматически мог получить ip-адрес). Т.к. серверы не имеют графического интерфейса, нас интересует только организация безопасного ssh подключения. Если сервер имеет белый ip-адрес в Интернете, за день совершается не мене 15000 попыток брутфорса паролей ботнетом, целенаправленный подбор хакерами и даже DDoS.

Частично настройки через Ansible рассмотрены в security-audit > CIS Benchmark

Права файла конфигурации sshd

Установим правильные права на файл настроек sshd демона /etc/ssh/sshd_config, чтобы никто кроме пользователя root не мог ни посмотреть, ни изменить файл.

chown root. /etc/ssh/sshd_config
chmod og-rwx /etc/ssh/sshd_config

Перед изменениями настроек сохранить бэкап (все операции выполнять от root, либо, что более предпочтительно, с добавлением sudo к команда):

cp /etc/ssh/sshd_config{,.bkp}

Описание всех параметров файла:

man sshd_config

Перед применением настроек проверить правописание параметров в /etc/ssh/sshd_config. Пример опечатки: параметр называется HostKey, а у нас HosKey.

# sshd -t
/etc/ssh/sshd_config: line 23: Bad configuration option: HosKey
/etc/ssh/sshd_config: terminating, 1 bad configuration options

Все настройки из файла вступают в силу после перезаггрузки службы sshd:

systemctl restart sshd

ssh только на конкретном сетевом интерфейсе

При наличии одного сетевого интерфейса настройки неактуальны, но если интерфейсом несколько, особенно если один из них будет открыт из Интернет, мы можем ограничить, на каком именно интерфейсе работает ssh. По умолчанию ssh работает для любого интерфейса: строка с ListenAddress закомментирована.

/etc/ssh/sshd_config
#ListenAddress 0.0.0.0
#ListenAddress ::

Если раскомментировать первую строку ListenAddress 0.0.0.0 — всё равно будет слушать на любом интерфейсе. Вторая строка указывает то же самое, но для ip-адресации IPv6. Для конкретизации необходимо указать ip-адрес сетевого интерфейса. Только в дальнейшем учесть,что если будем менять ip-адрес, надо будет его изменить и в настройках /etc/ssh/sshd_config,чтобы не потерять доступ к серверу.

/etc/ssh/sshd_config
ListenAddress 10.157.38.30

Форматы записей:

ListenAddress хост | адрес-IPv4 | адрес-^6
ListenAddress хост | адрес-IPv4 : порт
ListenAddress [хост | адрес-IPv6 : порт ]

Если порт не указан, sshd будет ожидать соединения на указанном адресе и на всех указанных ранее (но не после) в параметре Port портах. Допустимо указание нескольких параметров.

Порт ssh

В /etc/ssh/sshd_config изменим порт с 22, который является стандартным, на любой другой. Рекомендуется ставить свободный порт больше 1024 и до максимально возможного значения 65535. Если хакеры не знают, какой именно порт используется для ssh, это сразу резко сократит попытки входа. Для всех серверов в компании желательно указать один и тот же порт, чтобы не было неудобств. Можно это сделать только для серверов, которые смотрят в Интернет.

/etc/ssh/sshd_config
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
Port 10090

Сохранить файл. Открыть порт в файрволе. Порт сервиса ssh (по умолчанию 22), который открыт в Linux по умолчанию, можно будет закрыть уже после теста соединения по новому порту.

firewall-cmd --add-port=10090/tcp --permanent
firewall-cmd --reload
 
# проверка
firewall-cmd --list-all

Если SELinux не отключали и он находится в режиме Enforcing, дополнительно надо изменить метку порта. Команда с подсказкой расположены в комментарии /etc/ssh/sshd_config над опцией изменения порта.

# чтобы работала команда semanage:
yum -y install policycoreutils-python
# опцуионально, если надобудет искать проблемы
yum -y install setroubleshooting
# меняем метку порта для SELinux
semanage port -a -t ssh_port_t -p tcp 10090
 
# Проверка. Метка теперь не только на 22 порту, но и на 10090
# semanage port -l | grep ssh
ssh_port_t                     tcp      10090, 22

Теперь для вступления в силу изменения порта в файле /etc/ssh/sshd_config перезагрузить службу sshd.

Проверка подключения. Дополнительно надо указать порт:

ssh nikolay@10.157.38.30 -p 10090

Если есть файл настроек подключения к удаленному серверу, сразу внести порт туда. vim .ssh/config (из своего домашнего каталога)

~/.ssh/config
Host bd-vm-proxydev
  HostName 10.157.38.30
  User nikolay
  Port 10090

И тогда подключаться надо так:

ssh bd-vm-proxydev

Ограничения для ssh сессий

Можно ограничить попытки авторизации с помощью программы fail2ban, которая будет рассмотрена отдельно, но здесь рассмотрим такие настройки в /etc/ssh/sshd_config. По умолчанию они закомментированы:

/etc/ssh/sshd_config
# Authentication:
 
#LoginGraceTime 2m
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
...
#MaxStartups 10:30:100

LoginGraceTime 2m — сервер отключается по истечении этого времени, если пользователю не удалась регистрация в системе. Если стоит значение «0», то время ожидания не ограничено. По умолчанию - 120 секунд (2 минуты).

StrictModes yes — проверять наборы прав доступа и принадлежность конфигурационных файлов и домашнего каталога пользователя перед разрешением регистрации в системе. Это рекомендуется выполнять, потому что новички иногда оставляют свои каталоги или файлы доступными для записи всем. По умолчанию - «yes».

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

MaxSessions 10 — определяет максимальное количество открытых сеансов на одно соединение. Более точный способ подумать об этом параметре: он позволяет контролировать количество сеансов SSH, отправляемых через одно TCP-соединение. По умолчанию - 10. Настройка MaxSessions очень проста. Чем меньше число, тем меньше подключений и наоборот. MaxSessions 1 отключает мультиплексирование сессий, MaxSessions 0запрещает все shell, login и subsystem сессии, при этом переадресация разрешена.

MaxStartups 10:30:100 — ограничение на число одновременных соединений, в которых не был пройден этап аутентификации. Все последующие соединения не будут приниматься, пока на уже существующем соединении не будет произведена аутентификация или не истечет время, указанное в параметре LoginGraceTime. По умолчанию - 10. Как альтернатива, может быть задействован ранний случайный отказ в подключении, путем указания трёх разделённых через двоеточие значений «старт:норма:предел» (например, “10:30:100”). Соединение будет сбрасываться с вероятностью «норма/100» (30%), если имеется «старт» (10) (10) соединений с не пройденным этапом аутентификации. Вероятность возрастает линейно и постоянно попытки будут отвергаться при достижении числа «предел» (100).

Разделение прав пользователей

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

Ограниченный список доступа по SSH

Убедимся, что доступ к SSH ограничен. Для этого в /etc/ssh/sshd_config зададим один или более параметров, которые указаны ниже в порядке обработки:

/etc/ssh/sshd_config
DenyUsers <userlist>
AllowUsers <userlist>
DenyGroups <grouplist>
AllowGroups <grouplist>

DenyUsers — список имён пользователей через пробел. Если параметр определён, регистрация в системе пользователей, чьи имена соответствуют одному из шаблонов, будет запрещена. Допустимы только имена пользователей; числовой идентификатор пользователя не распознаётся. По умолчанию разрешена регистрация в системе для всех пользователей. Если шаблон указывается в форме ПОЛЬЗОВАТЕЛЬ@ХОСТ, его две части проверяются отдельно, таким образом запрещается доступ только пользователям с указанными именами, подключающимся с указанных хостов.

AllowUsers — список имён пользователей через пробел. Если параметр определён, регистрация в системе будет разрешена только пользователям, чьи имена соответствуют одному из шаблонов. Допустимы только имена пользователей; числовой идентификатор пользователя не распознаётся. По умолчанию разрешена регистрация в системе для всех пользователей. Если шаблон указывается в форме ПОЛЬЗОВАТЕЛЬ@ХОСТ, его две части проверяются отдельно, таким образом разрешая доступ только пользователям с указанными именами, подключающимся с указанных хостов.

DenyGroups — список шаблонов имён групп через пробел. Если параметр определён, регистрация в системе пользователям, чья главная или вспомогательная группа соответствуют содержащимся в списке шаблонам, не разрешается. Допустимы только имена групп; числовой идентификатор группы не распознаётся. По умолчанию регистрация в системе разрешена для всех групп.

AllowGroups — список шаблонов имён групп через пробел. Если параметр определён, регистрация в системе разрешается только пользователям, чья главная или вспомогательная группы соответствуют какому-либо из шаблонов. Допустимы только имена групп; числовой идентификатор группы не распознаётся. По умолчанию разрешена регистрация в системе для членов всех групп.

Для примера разрешим пользователю nokolay доступ по ssh с любого источника подключения, а доступ под учетной записью root только с ip-адресов 10.157.39.30 и 10.157.39.40:

/etc/ssh/sshd_config
AllowUsers nikolay root@10.157.39.30 root@10.157.39.40

Все изменения, как обычно, вступают в силу после перезагрузки службы sshd.

Отключить пустые пароли, список доверенных хостов

PermitEmptyPasswords no — допускать ли использование пустых паролей при аутентификации по паролю. По умолчанию - no. IgnoreRhosts yes — не учитывать содержимое файлов .rhosts и .shosts при аутентификации RhostsRSAAuthentication и HostbasedAuthentication. При этом будут учитываться только /etc/hosts.equiv и /etc/shosts.equiv. По умолчанию - yes. HostbasedAuthentication no — допускать ли аутентификацию по хостам, т.е. аутентификацию по rhosts или /etc/hosts.equiv в сочетании с открытым ключом клиента. Параметр схож с RhostsRSAAuthentication и применим только к протоколу версии 2 (в современных Linux уже включена только 2 версия протокола ssh). По умолчанию — no.

Отключение входа по паролю и root

Аутентификация по публичным ключам ssh даёт нам несколько преимуществ:

  • Бесполезен перебор паролей хакерами, если мы дополнительно выключим авторизацию по паролям на сервере (PasswordAuthentication no).
  • На сервер нельзя подключиться со случайных компьютеров, а только с тех, где есть файл с приватным ключем, подходящий к публичному ключу. Нельзя терять приватную часть ключа, нужно сохранить у себя её бэкап!
  • Не надо вводить пароль при подключении к серверу.
  • Удобство при добавлении учетных записей на сервер, т.к. публичную часть ключа ssh нет необходимости прятать — пользователь может передать файл с публичным ключем администратору.

Создадим свою пару ssh-ключей утилитой ssh-keygen.

Поддерживаемые типы шифрования: -t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa По умолчанию используется асимметричное шифрование RSA на основе криптографического алгоритма с открытым ключом, основывающемся на вычислительной сложности задачи факторизации больших целых чисел. Rivest, Shamir and Aldeman — создатели алгоритма. Можно не менять тип шифрования.

Асимметричное шифрование: посторонним лицам может быть известен алгоритм шифрования, и, возможно, открытый ключ, но неизвестен закрытый ключ, известный только получателю. Криптографические системы с открытым ключом в настоящее время широко применяются в различных сетевых протоколах, в частности, в протоколах TLS и его предшественнике SSL (лежащих в основе HTTPS), а так же SSH, PGP, S/MIME и т. д. Российский стандарт, использующий асимметричное шифрование - ГОСТ Р 34.10-2001.

-b 4096 — задаёт число битов в создаваемом ключе. Для ключей RSA минимальный размер 1024 бит, по умолчанию 3072 бит, что считается достаточным. Размер ключей DSA должен быть равен только 1024 бит, как задано в FIPS 186-2. Для ключей ECDSA флаг -b определяет длину ключа выбором одного из трех размеров эллиптических кривых: 256, 384 или 521 бит. При попытке указать другое значение для типа ECDSA команда не выполнится. ECDSA-SK, Ed25519 и Ed25519-SK ключи имеют фиксированную длину, и флаг -b будет проигнорирован.

Пароль можно не указывать и просто нажать Enter. Дополнительная защита паролем ключей ssh используется не так часто, но в особо важных случаях не помешает для дополнительного усиления безопасности.

[root@ol8 ~]# ssh-keygen -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/nikolay/.ssh/id_rsa): 
Created directory '/nikolay/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /nikolay/.ssh/id_rsa.
Your public key has been saved in /nikolay/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:W6AAL4Z/BnpzBewBeHMSHdpQgYqceZLUi1QRi5qvSos nikolay@ol8.hl.local
The key's randomart image is:
+---[RSA 4096]----+
| .B@Bo           |
|.+*B*.           |
|*+X*=.. .        |
|+% =.o . .       |
|+ * + . S .      |
| o =     o       |
| ..     .        |
|o..              |
|E.               |
+----[SHA256]-----+

Будет создано 2 файла: — /home/nikolay/.ssh/id_rsa — приватный ключ. Никому не показывать. Хранить только у себя. — /home/nikolay/.ssh/id_rsa.pub — публичный ключ. Можем отдавать администратору, копировать на серверы.

Копируем публичный ключ на сервер. Если мы заходим на сервер под своей же учетной записью с паролем, публичный ключ будет автоматически скопирован из своего домашнего каталога из файлах /home/nikolay/.ssh/id_rsa.pub.

ssh-copy-id nikolay@10.157.38.30

Авторизируемся, введя логин и пароль, после чего публичный ключ будет автоматически сохранен в файл /home/nikolay/.ssh/authorized_keys на сервере 10.157.38.30. Теперь можно заходить на сервер 10.157.38.30 без пароля.

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

ssh-copy-id -i /home/nikolay/.ssh/id_rsa.pub nikolay@10.157.38.30

Обычно в большой компании никто вручную не копирует ключи, а создается роль Ansible, с помощью которой ключи пользователей автоматически копируются в их домашние каталоги на необходимую группу серверов.

Настроим /etc/ssh/sshd_config на сервере 10.157.38.30:

AuthorizedKeysFile .ssh/authorized_keys — файл с открытыми ключами, которые могут быть использованы для аутентификации пользователей. Допустимо указание шаблонов, они преобразуются при настройке соединения: %% заменяется на символ %, %h заменяется на домашний каталог идентифицируемого пользователя, «%u» - на имя пользователя. После преобразования AuthorizedKeysFile интерпретируется либо как абсолютный путь, либо как путь относительно домашнего каталога пользователя. Значение по умолчанию - «.ssh/authorized_keys». Не меняем.

PasswordAuthentication no — допускать ли аутентификацию по паролю (для всех пользователей). По умолчанию — yes. Отключаем.

PermitRootLogin no — допускать ли вход в систему через ssh от лица root. Значения:

  • yes — можно зайти в систему как root используя пароль или ключ ssh. По умолчанию в CentOS7.
  • prohibit-password — войти в систему как root, указав для аутентификации пароль, нельзя. Но можно войти по ssh-ключу. По умолчанию в OracleLinux 8.
  • forced-commands-only — разрешена регистрация root по открытому ключу, но только если определён параметр command команда (что может быть полезно для удалённого создания резервных копий, даже если регистрация суперпользователя в системе в обычном режиме не разрешена). Все другие методы аутентификации для суперпользователя будут отключены.
  • no — вход в систему в качестве root полностью запрещён.

ChallengeResponseAuthentication no — разрешается ли беспарольная аутентификация «вызов-ответ». Поддерживаются все схемы аутентификации login.conf(5) или PAM. По умолчанию yes.

UsePAM no — Включить интерфейс модулей аутентификации Pluggable Authentication Module. При значении yes аутентификация PAM будет доступна через ChallengeResponseAuthentication и PasswordAuthentication в дополнение к учётной записи PAM и обработке модулей сеансов для всех типов аутентификации. Поскольку беспарольная аутентификация PAM «вызов-ответ» служит заменой аутентификации по паролю, необходимо отключить либо PasswordAuthentication, либо ChallengeResponseAuthentication. При включенном UsePAM службу sshd можно будет выполнять только с правами root. По умолчанию no. Проверить.

Дополнительные способы отключения входа root

В предыдущем пункте рассмотрен способ отключения входа root через sshd_config. Существует два дополнительных способа отключения входа root.

Способ 1. Действует только для удаленного входа по ssh, не действует при входе из консоли. Параметр PermitRootLogin no в файле /etc/ssh/sshd_config

Способ 2. в файле /etc/passwd у root указана стандартная оболочка bash, как и для обычных пользователей:

$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash

Надо заменить /bin/bash или /bin/sh (в некоторых дистрибутивах Linux) на оболочку /usr/sbin/nologin:

$ sudo chsh root
[sudo] password for nikolay: 
Changing the login shell for root
Enter the new value, or press ENTER for the default
	Login Shell [/bin/bash]: /usr/sbin/nologin        # ввели новую оболочку

Можно также изменить оболочку напрямую в файле /etc/passwd. Теперь при попытке входа от лица root будет ошибка:

This account is currently not available

Способ 3. Временно заблокировать пароль для аккаунта root.

sudo passwd -l root
sudo passwd -u root  # если необходимо будет разблокировать.