[OpenSSH] Обновление OpenSSH до версии 8.5p1 на CentOS 7.x

Клиент попросил стороннюю компанию по обеспечению безопасности просканировать их сервер и обнаружил, что SSH имеет множество уязвимостей в системе безопасности. Причина в том, что даже самый свежий (на 2021 год) CentOS 7.9 использует более старую версию OpenSSH v7.4, и эти уязвимости были исправлены в новой версии OpenSSH, поэтому по соображениям безопасности требуется обновление.

[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

[root@localhost ~]# rpm -qa | grep openssh
openssh-clients-7.4p1-21.el7.x86_64
openssh-server-7.4p1-21.el7.x86_64
openssh-7.4p1-21.el7.x86_64

В этой статье мы обновимся до самой последней версии OpenSSH. На момент написания статьи это версия 8.5p1.
В yum нет последней версии OpenSSH, соответственно нам нужно загрузить исходники OpenSSH из официальной компиляции и сделать установочный пакет rpm. Поскольку клиентский сервер не может подключиться к внешней сети, его необходимо преобразовать в пакет автономного обновления.

Ремарка

# - значит выполнять команды под рутом
- значит выполнять команды под пользователем rpmbuilder

Подготовка и сборка RPM

Создаём пользователя, под которым будем собирать пакеты, каталоги и устанавливаем необходимое ПО:
# useradd rpmbuilder
# mkdir -p /home/rpmbuilder/rpmbuild/{SOURCES,SPECS}
# yum -y install wget epel-release
# yum -y install rpm-build gcc make
# yum -y install openssl openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel gtk2-devel

Скачиваем последнюю версию OpenSSH:
# wget https://mirror.yandex.ru/pub/OpenBSD/OpenSSH/portable/openssh-8.5p1.tar.gz
# wget https://src.fedoraproject.org/lookaside/pkgs/openssh/x11-ssh-askpass-1.2.4.1.tar.gz/8f2e41f3f7eaa8543a2440454637f3c3/x11-ssh-askpass-1.2.4.1.tar.gz

Всё распаковываем и копируем:
# tar -zxf openssh-8.5p1.tar.gz
# cp ./openssh-8.5p1/contrib/redhat/openssh.spec /home/rpmbuilder/rpmbuild/SPECS/
# cp openssh-8.5p1.tar.gz /home/rpmbuilder/rpmbuild/SOURCES/
# cp x11-ssh-askpass-1.2.4.1.tar.gz /home/rpmbuilder/rpmbuild/SOURCES/

Даём права созданному пользователю rpmbuilder и переключаемся на него:
# chown -R rpmbuilder:rpmbuilder /home/rpmbuilder/
# su - rpmbuilder
$ cd /home/rpmbuilder/rpmbuild/SPECS/

Вносим изменения в файл openssh.spec:
$ sed -i "s/%global no_gnome_askpass 0/%global no_gnome_askpass 1/g" openssh.spec
$ sed -i "s/%global no_x11_askpass 0/%global no_x11_askpass 1/g" openssh.spec
$ sed -i "s/BuildRequires: openssl-devel >= 1.0.1/#BuildRequires: openssl-devel >= 1.0.1/g" openssh.spec
$ sed -i "s/BuildRequires: openssl-devel < 1.1/#BuildRequires: openssl-devel < 1.1/g" openssh.spec

Переключаемся на root и вносим изменение в файл /usr/lib/rpm/macros:
$ exit
# sed -i 's/^%__check_fil/#&/' /usr/lib/rpm/macros

Переключаемся на пользователя rpmbuilder и собираем rpm пакеты:
# su - rpmbuilder
$ cd /home/rpmbuilder/rpmbuild/SPECS/
$ rpmbuild -bb openssh.spec

После компиляции в конце вывод должен быть примерно таким:
ВНИМАНИЕ! После сборки пакетов не забудьте снова изменить файл /usr/lib/rpm/macros:
$ exit
# sed -i 's/^#%__check_files/%__check_files/g' /usr/lib/rpm/macros

Теперь собранные пакеты находятся в /home/rpmbuilder/rpmbuild/RPMS/x86_64/:
# ll /home/rpmbuilder/rpmbuild/RPMS/x86_64/
total 4648
-rw-rw-r--. 1 rpmbuilder rpmbuilder  610420 Mar 10 05:51 openssh-8.5p1-1.el7.x86_64.rpm
-rw-rw-r--. 1 rpmbuilder rpmbuilder  631844 Mar 10 05:51 openssh-clients-8.5p1-1.el7.x86_64.rpm
-rw-rw-r--. 1 rpmbuilder rpmbuilder 3043904 Mar 10 05:51 openssh-debuginfo-8.5p1-1.el7.x86_64.rpm
-rw-rw-r--. 1 rpmbuilder rpmbuilder  458900 Mar 10 05:51 openssh-server-8.5p1-1.el7.x86_64.rpm

Примечание: openssh-debuginfo-8.5p1-1.el7.x86_64.rpm является отладочным пакетом, который не нужен во время обновления и должен быть удален.

Обновляем OpenSSH собранными пакетами:
# cd /home/rpmbuilder/rpmbuild/RPMS/x86_64/
# rm -f openssh-debuginfo-*
# rpm -Uvh *.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:openssh-8.5p1-1.el7              ################################# [ 17%]
   2:openssh-clients-8.5p1-1.el7      ################################# [ 33%]
   3:openssh-server-8.5p1-1.el7       ################################# [ 50%]
Cleaning up / removing...
   4:openssh-server-7.4p1-16.el7      ################################# [ 67%]
   5:openssh-clients-7.4p1-16.el7     ################################# [ 83%]
   6:openssh-7.4p1-16.el7             ################################# [100%]

Только что мы обновили OpenSSH с версии 6.4 до 8.5.
# ssh -V
OpenSSH_8.5p1, OpenSSL 1.0.2k-fips  26 Jan 2017


# rpm -qa | grep openssh
openssh-clients-8.5p1-1.el7.x86_64
openssh-8.5p1-1.el7.x86_64
openssh-server-8.5p1-1.el7.x86_64

Восстановление работы OpenSSH

После того как OpenSSH установлен пробуем подключиться к серверу и терпим неудачу:


Возврашаемся на наш сервер, выполняем systemctl status sshd и видим, что сервис в статусе failed, а также проблемы с правами на файлы ключей (на скриншоте выделил белым)

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

Невозможно было войти в систему через SSH по ключам. Поэтому необходимо изменить разрешение файлов ключей!

Смотрим список ключей:
# ll /etc/ssh/ssh_host_*_key
-rw-------. 1 root root     1393 Mar  9 23:30 /etc/ssh/ssh_host_dsa_key
-rw-r-----. 1 root ssh_keys  227 Mar 28  2019 /etc/ssh/ssh_host_ecdsa_key
-rw-r-----. 1 root ssh_keys  387 Mar 28  2019 /etc/ssh/ssh_host_ed25519_key
-rw-r-----. 1 root ssh_keys 1679 Mar 28  2019 /etc/ssh/ssh_host_rsa_key

И меняем права на них:
# chmod 600  /etc/ssh/ssh_host_*_key
# ll  /etc/ssh/ssh_host_*_key
-rw-------. 1 root root     1393 Mar  9 23:30 /etc/ssh/ssh_host_dsa_key
-rw-------. 1 root ssh_keys  227 Mar 28  2019 /etc/ssh/ssh_host_ecdsa_key
-rw-------. 1 root ssh_keys  387 Mar 28  2019 /etc/ssh/ssh_host_ed25519_key
-rw-------. 1 root ssh_keys 1679 Mar 28  2019 /etc/ssh/ssh_host_rsa_key

Перезапускаем ssh и видим, что всё отлично:


А вот по паролю OpenSSH всё равно не пустит smile

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

Делаем бекап конфиг-файла и вносим изменения:
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sed -i -e "s/#PasswordAuthentication yes/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i -e "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
sed -i -e "s/#PermitEmptyPasswords no/PermitEmptyPasswords no/g" /etc/ssh/sshd_config
sed -i -e "s/#UsePAM no/UsePAM yes/g" /etc/ssh/sshd_config

cp /etc/pam.d/sshd /etc/pam.d/sshd.bak

cat > /etc/pam.d/sshd  <<EOF
#%PAM-1.0
auth required pam_sepermit.so
auth include password-auth
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session optional pam_keyinit.so force revoke
session include password-auth
EOF


Перезапускаем sshd и проверяем статус:

Всё отлично!

Но это еще не всё. Было обнаружено, что в качестве сценария запуска используется обновленная служба sshd, а не файл /usr/lib/systemd/system/sshd.service.

Фактически, в процессе обновления программа удалила /usr/lib/systemd/system/sshd.service и добавила сценарий запуска службы /etc/init.d/sshd

Кроме того, после обновления команда копирования открытого ключа ssh-copy-id, которую мы часто используем для входа в систему без секретов, исчезла!

ll /usr/bin/ssh*
-rwxr-xr-x. 1 root root   869240 Mar  9 23:04 /usr/bin/ssh
-rwxr-xr-x. 1 root root   390960 Mar  9 23:04 /usr/bin/ssh-add
-rwxr-sr-x. 1 root nobody 369816 Mar  9 23:04 /usr/bin/ssh-agent
-rwxr-xr-x. 1 root root   511056 Mar  9 23:04 /usr/bin/ssh-keygen
-rwxr-xr-x. 1 root root   483424 Mar  9 23:04 /usr/bin/ssh-keyscan

На самом деле дело не в том, что файла больше нет, просто нужно скопировать файл ssh-copy-id из каталога распакованного исходника openssh-8.5p1, который мы скачали в самом начале статьи, в каталог /usr/bin/.

ll /root/openssh-8.5p1/contrib/
total 68
drwxr-xr-x. 2 rpmbuilder rpmbuilder    75 Mar  2 05:31 aix
drwxr-xr-x. 2 rpmbuilder rpmbuilder   100 Mar  2 05:31 cygwin
-rw-r--r--. 1 rpmbuilder rpmbuilder  4797 Mar  2 05:31 findssl.sh
-rw-r--r--. 1 rpmbuilder rpmbuilder  5472 Mar  2 05:31 gnome-ssh-askpass1.c
-rw-r--r--. 1 rpmbuilder rpmbuilder  9637 Mar  2 05:31 gnome-ssh-askpass2.c
drwxr-xr-x. 2 rpmbuilder rpmbuilder    72 Mar  2 05:31 hpux
-rw-r--r--. 1 rpmbuilder rpmbuilder   696 Mar  2 05:31 Makefile
-rw-r--r--. 1 rpmbuilder rpmbuilder  1776 Mar  2 05:31 README
drwxr-xr-x. 2 rpmbuilder rpmbuilder   157 Mar  2 05:31 redhat
drwxr-xr-x. 2 rpmbuilder rpmbuilder    20 Mar  2 05:31 solaris
-rw-r--r--. 1 rpmbuilder rpmbuilder 12676 Mar  2 05:31 ssh-copy-id
-rw-r--r--. 1 rpmbuilder rpmbuilder  6887 Mar  2 05:31 ssh-copy-id.1
-rw-r--r--. 1 rpmbuilder rpmbuilder   183 Mar  2 05:31 sshd.pam.freebsd
-rw-r--r--. 1 rpmbuilder rpmbuilder   410 Mar  2 05:31 sshd.pam.generic
drwxr-xr-x. 2 rpmbuilder rpmbuilder    84 Mar  2 05:31 suse

Копируем:
cp /root/openssh-8.5p1/contrib/ssh-copy-id /usr/bin/
chmod 755 /usr/bin/ssh-copy-id

Вот теперь всё! grinning

bash-скрипт вышеописанных действий

Этот скрипт выполняет всё тоже самое, что описано выше. То есть достаточно его запустить и на выходе получите рабочий OpenSSH 8.5!
Создаём файл vi build.sh, вставляем код ниже и помечаем файл как исполняемый командой chmod +x build.sh. Запускаем скрипт ./build.sh

Скрипт:

#####################################################
#!/bin/bash

useradd rpmbuilder
mkdir -p /home/rpmbuilder/rpmbuild/{SOURCES,SPECS}

yum -y install wget epel-release
yum -y install rpm-build gcc make
yum -y install openssl openssl-devel krb5-devel pam-devel libX11-devel xmkmf libXt-devel gtk2-devel

wget  https://mirror.yandex.ru/pub/OpenBSD/OpenSSH/portable/openssh-8.5p1.tar.gz
wget  https://src.fedoraproject.org/lookaside/pkgs/openssh/x11-ssh-askpass-1.2.4.1.tar.gz/8f2e41f3f7eaa8543a2440454637f3c3/x11-ssh-askpass-1.2.4.1.tar.gz

tar -zxf openssh-8.5p1.tar.gz
cp ./openssh-8.5p1/contrib/redhat/openssh.spec /home/rpmbuilder/rpmbuild/SPECS/
cp openssh-8.5p1.tar.gz /home/rpmbuilder/rpmbuild/SOURCES/
cp x11-ssh-askpass-1.2.4.1.tar.gz /home/rpmbuilder/rpmbuild/SOURCES/

chown -R rpmbuilder:rpmbuilder /home/rpmbuilder/
su - rpmbuilder <<'EOF'
cd /home/rpmbuilder/rpmbuild/SPECS/

sed -i "s/%global no_gnome_askpass 0/%global no_gnome_askpass 1/g" openssh.spec
sed -i "s/%global no_x11_askpass 0/%global no_x11_askpass 1/g" openssh.spec
sed -i "s/BuildRequires: openssl-devel >= 1.0.1/#BuildRequires: openssl-devel >= 1.0.1/g" openssh.spec
sed -i "s/BuildRequires: openssl-devel < 1.1/#BuildRequires: openssl-devel < 1.1/g" openssh.spec
exit
EOF
sed -i 's/^%__check_fil/#&/' /usr/lib/rpm/macros

su - rpmbuilder <<'EOF'
cd /home/rpmbuilder/rpmbuild/SPECS/
rpmbuild -bb openssh.spec
exit
EOF

sed -i 's/^#%__check_files/%__check_files/g' /usr/lib/rpm/macros
cd /home/rpmbuilder/rpmbuild/RPMS/x86_64/ 
rm -f openssh-debuginfo-*
rpm -Uvh *.rpm

chmod 600 /etc/ssh/ssh_host_*_key

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sed -i -e "s/#PasswordAuthentication yes/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i -e "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
sed -i -e "s/#PermitEmptyPasswords no/PermitEmptyPasswords no/g" /etc/ssh/sshd_config
sed -i -e "s/#UsePAM no/UsePAM yes/g" /etc/ssh/sshd_config

cp /etc/pam.d/sshd /etc/pam.d/sshd.bak

cat > /etc/pam.d/sshd <

Этот же скрипт в моём репозитории GitHub: https://github.com/yatakoi/upgrade_OpenSSH_to_lastest_version_on_CentOS7.x

Добавить комментарий