Последняя версия OpenSSH на Centos7. HowTo и подводные камни

В репозиториях Centos находится довольно древняя версия OpenSSH, и никто не торопится ее обновлять. Может быть в этом и нет суровой необходимости, но почему бы и нет, раз сам OpenSSH развивается и обновляется? Тем более, что граждане жалуются на то, что со старым ssh система не проходит аудит безопасности. Итак, ставим!

И сейчас я пошагово расскажу как обновить OpenSSH, обходя подводные камни и не набивая шишек. Все нижеописанное тестировалось на виртуалках «из коробки» от SimpleCloud или vScale, и работает на сервере где размещен этот сайт.

За основу взято HowTo, изложенное вот здесь, однако работать с исходниками — тот еще геморрой, поэтому я упростил Вам задачу, собрав RPMы для Centos7 и положил их в свой репозиторий. На момент написания это 7.5p1, и я планирую добавлять пакеты по мере выхода новых версий.

Итак, начать надо с бэкапа системы. Верю, что Вы всегда так делаете, но мало ли! Помимо этого непосредственно перед установкой я настоятельно рекомендую отдельно сохранить в рабочий каталог два файла:

  • Конфигурацию sshd — /etc/ssh/sshd_config
  • Конфигурацию pam для sshd — /etc/pam.d/sshd

Кроме того, отдельное предупреждение: велика вероятность что sshd сразу после установки «в лоб» не заработает нормально, во всяком случае у меня ни разу такого не было!

Поэтому не закрывайте ssh-консоль, с которой вы производите все манипуляции и не перегружайте сервер до того момента, как убедитесь что новая версия sshd работает нормально, не войдете на сервер другой консолью обычным образом и не получите обычным же образом консоль root! Несмотря на любые рестарты sshd текущая сессия сохраняется, и если что-то пошло не так, то новую вы установить не сможете и начнутся танцы с бубном.

Все команды далее выполняются из под root или через sudo.

Итак, нам надо подключить репозиторий, копируем файл с его метаданными:

wget -P /etc/yum.repos.d/ repo.pavlyuts.ru/pavlyuts.repo

Теперь мой репозиторий подключен к Вашей системе. И обновляем пакеты:

yum upgrade openssh*

Yum покажет нам три обновляемых пакета и попросит подтверждения. Выдохнем, и подтверждаем. Казалось бы все, но не все так просто! Поэтому прежде чем делать рестарт sshd (systemctl restart sshd), надо кое-что проверить и поправить, ибо начинаются…

Подводные камни

Конфигурация sshd

Дело в том, что обновление может перезаписать sshd_config, а может не перезаписать. Определить это просто — если старая конфигурация сохранена, то рядом в каталоге появляется файл sshd_config.rpmnew. Если его нет, то скорее всего конфигурация перезаписана и стала «дефолтной». В обоих случаях я предлагаю, взяв за основу новую дефолтную конфигурацию, установить нужные Вам параметры, справляясь со старой, тем более, что там есть устаревшие опции.

Маленькие хитрости:

  • Получить из файла только незакомментированные строки, дабы не искать в тоннах комментариев установленные параметры: grep -v ^# <имя файла>
  • Проверить корректность конфигурации sshd и вывести все параметры конфигурации как их считал и понял демон, включая дефолты, т.е. итоговую конфигурацию: sshd -T.

Давайте считать, что конфигурацию мы сделали как надо, но радоваться рано.

Права на ключи

Новая версия при старте проверяет права на ключи сервера, а при попытках авторизации —  права на ключи пользователей.

Для ключей сервера она требует владельца root и права 0600. Если права другие — ключ не загружается! На одном из стоковых образов я столкнулся с тем, что права были шире на трех из четырех заданных ключей, в результате демон не дает сообщения об ошибке при рестарте, а «плохие» ключи не грузит, и пишет об этом в лог messages:

localhost sshd: Permissions 0640 for ‘/etc/ssh/ssh_host_rsa_key’ are too open.
localhost sshd: Could not load host key: /etc/ssh/ssh_host_rsa_key

Сессии не поднимаются, потому что ключа RSA нет! Чтобы не нарваться на эту мину — проще сразу выполнить одну команду:

chmod -v 0600 /etc/ssh/ssh_host_*_key

Она либо исправит ситуацию, либо просто ничего не сделает, а результат будет понятен из ее отчета.

Кроме того, при авторизации клиента по ключу она проверяет права на файл .ssh/authorized_keys, требуя чтобы ключ не был доступен по записи никому, кроме авторизуемого пользователя и/или root. Если оказывается, что файл принадлежит другому пользователю, или, к примеру, на него установлены права 0660, то идет отказ, в лог messages пишется сообщение, где вместо %user% имя пользователя:

localhost sshd[4503]: Authentication refused: bad ownership or modes for file /home/%user%/.ssh/authorized_keys

При этом совершенно не важно может ли sshd прочитать ключ. Лечится это понятным способом: владельцем /.ssh/authorized_keys должен быть именно тот пользователь чей это домашний каталог, а права на него должны быть не больше 0644. Есть подозрения, что это и раньше проверялось, и не новость в этой версии, но и это надо иметь ввиду, я столкнулся с этим в ходе своих экспериментов.

Сложности с PAM

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

Могу лишь сообщить, что при установке пакет удаляет /etc/pam.d/sshd и записывает на его место новый, со следующим содержимым:

#%PAM-1.0
auth       required     pam_stack.so service=system-auth
account    required     pam_nologin.so
account    required     pam_stack.so service=system-auth
password   required     pam_stack.so service=system-auth
session    required     pam_stack.so service=system-auth

И вот тут начинаются проблемы, потому что в Centos7 нет pam_stack.so, полагаю он исключен как устаревший. Если с такой конфигурацией мы поставим в sshd опцию «UsePAM yes», то все просто перестанет работать, при попытке авторизации сервер сбрасывает соединения, а в лог secure валятся ошибки:

localhost sshd[2111]: PAM adding faulty module: /usr/lib64/security/pam_stack.so
localhost sshd[2115]: PAM unable to dlopen(/usr/lib64/security/pam_stack.so): /usr/lib64/security/pam_stack.so: cannot open shared object file: No such file or directory

Гугл знает все, и решение нашлось, оно очень простое. Везде, где в /etc/pam.d/sshd было:
required     pam_stack.so service=system-auth
должно быть:
include      system-auth

И все начинает работать! Для полной ясности, /etc/pam.d/sshd должен выглядеть так:

#%PAM-1.0
auth       include      system-auth
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
session    include      system-auth

Повторю, если Вы «умеете готовить» PAM, то может быть для Вас будет лучше восстановить заблаговременно сохраненный собственный файл. Однако у меня такие попытки не привели ни к чему хорошему: я получил отказ в авторизации где-то в глубинах PAM, который так и не смог локализовать, так что будьте аккуратны с этим вопросом. Вот это точно работает.

Пользователи без пароля

Создавая пользователя, который будет ходить по ssh с открытым ключом, ему как правило не задают пароль вовсе. А зачем? Но именно здесь нас ожидает засада, потому что при некотором сочетании условий и конфигураций, которое мне не удалось достоверно определить, sshd запрещает таким пользователям авторизацию, при этом в лог messages пишутся сообщения:

localhost sshd[2073]: User %user% not allowed because account is locked

C этим тоже удалось разобраться. Оказалось, что при создании пользователя командой useradd без пароля  в /etc/shadow создаются вот такого вида строки, например для пользователя test:

test:!!:17298:0:99999:7:::

В том месте, где должен быть хэш пароля — два восклицательных знака. Однако, при входе по паролю с консоли один восклицательный знак означает, что у пользователя заблокирован пароль, а два — что заблокирован сам пользователь.  Разблокировать пользователя штатными средствами не задавая ему пароль — нельзя. А sshd не позволяет «заблокированным пользователям» удаленный вход.

Лечится эта проблема одним из трех способов:

  1. Пользователю задается пароль. Из под root команда passwd %user% и два раза ввести пароль.
  2. На место хэша пишется *, а не !!. Из под root команда usermod -p ‘*’ %user% и все. Плюс тут в том, что это не хэш пароля и пароля по прежнему нет. Но это и не признак блокировки, поэтому sshd работает нормально.
  3. Самый смешной способ — включить PAM директивой «UsePAM yes» в файле конфигурации sshd /etc/ssh/sshd_config. Если (если!!!) PAM настроен и работает нормально — то проблема уходит и sshd начинает авторизовать пользователей по ключу нормально. Что весьма парадоксально в свете выше описанных проблем с самим PAM.

А вот и финиш!

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

Самое главное — после «финишного» рестарта sshd тщательно проверить, что Вы можете из другого терминала войти привычным образом, все работает как надо, и, что самое главное, есть доступ к root.

Enjoy!


P.S. Последний вариант, если ничего не получается, а восстанавливаться из бэкапа не хочется — изменения можно откатить:

yum downgrade openssh*

Файлы конфигурации надо восстановить из того места, куда мы их хозяйственно сохранили в начале пути. После рестарта sshd мы вернемся в исходную точку. Но даже после этого — стоит, не закрывая консоль, проверить что все работает как надо.

И не забудьте в случае отката удалить ссылку на мой репозиторий, иначе при следующем обновлении системы последняя версия ssh опять установится сама:

 rm -f /etc/yum.repos.d/pavlyuts.repo