[OpenSSH] Обновление OpenSSH до версии 8.5p1 на CentOS 7.x
Клиент попросил стороннюю компанию по обеспечению безопасности просканировать их сервер и обнаружил, что SSH имеет множество уязвимостей в системе безопасности. Причина в том, что даже самый свежий (на 2021 год) CentOS 7.9 использует более старую версию OpenSSH v7.4, и эти уязвимости были исправлены в новой версии OpenSSH, поэтому по соображениям безопасности требуется обновление.
В этой статье мы обновимся до самой последней версии OpenSSH. На момент написания статьи это версия 8.5p1.
В yum нет последней версии OpenSSH, соответственно нам нужно загрузить исходники OpenSSH из официальной компиляции и сделать установочный пакет rpm. Поскольку клиентский сервер не может подключиться к внешней сети, его необходимо преобразовать в пакет автономного обновления.
$ - значит выполнять команды под пользователем rpmbuilder
Скачиваем последнюю версию OpenSSH:
Всё распаковываем и копируем:
Даём права созданному пользователю rpmbuilder и переключаемся на него:
Вносим изменения в файл openssh.spec:
Переключаемся на root и вносим изменение в файл /usr/lib/rpm/macros:
Переключаемся на пользователя rpmbuilder и собираем rpm пакеты:
После компиляции в конце вывод должен быть примерно таким:
Теперь собранные пакеты находятся в /home/rpmbuilder/rpmbuild/RPMS/x86_64/:
Обновляем OpenSSH собранными пакетами:
Только что мы обновили OpenSSH с версии 6.4 до 8.5.
Возврашаемся на наш сервер, выполняем systemctl status sshd и видим, что сервис в статусе failed, а также проблемы с правами на файлы ключей (на скриншоте выделил белым)
Сначала мы думали, что у созданного нами пакета rpm возникла проблема. На самом деле конфигурация по умолчанию была неправильной.
Невозможно было войти в систему через SSH по ключам. Поэтому необходимо изменить разрешение файлов ключей!
Смотрим список ключей:
И меняем права на них:
Перезапускаем ssh и видим, что всё отлично:
А вот по паролю OpenSSH всё равно не пустит
Для этого необходимо изменить конфиг-файл sshd_config, а так же обновить динамическую библиотеку pam_stack.so, потому что старый OpenSSH использует старую библиотеку.
Делаем бекап конфиг-файла и вносим изменения:
Перезапускаем sshd и проверяем статус:
Всё отлично!
Но это еще не всё. Было обнаружено, что в качестве сценария запуска используется обновленная служба sshd, а не файл /usr/lib/systemd/system/sshd.service.
Фактически, в процессе обновления программа удалила /usr/lib/systemd/system/sshd.service и добавила сценарий запуска службы /etc/init.d/sshd
Кроме того, после обновления команда копирования открытого ключа ssh-copy-id, которую мы часто используем для входа в систему без секретов, исчезла!
На самом деле дело не в том, что файла больше нет, просто нужно скопировать файл ssh-copy-id из каталога распакованного исходника openssh-8.5p1, который мы скачали в самом начале статьи, в каталог /usr/bin/.
Копируем:
Вот теперь всё!
Создаём файл vi build.sh, вставляем код ниже и помечаем файл как исполняемый командой chmod +x build.sh. Запускаем скрипт ./build.sh
Скрипт:
[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 всё равно не пустит
Для этого необходимо изменить конфиг-файл 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
Вот теперь всё!
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