本篇如何在過時的 CentOS Linux 7.9 系統上,自行編譯與安裝 OpenSSH,升級舊版的 sshd
伺服器。
在 Linux 中若要查看系統上目前 OpenSSH 的版本,可以執行:
# 檢查 OpenSSH 版本 ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
舊版的 OpenSSH 雖然還是可以正常使用,但是對於比較新的功能就不支援,像是 FIDO/U2F 認證機制就必須將 OpenSSH 升級到 8.2 以後的版本才能使用,如果遇到比較舊的 Linux 系統,當官方套件庫停止更新時,想升級 OpenSSH 就必須自行手動編譯與安裝,以下將介紹在 CentOS Linux 7.9 系統上自行編譯與安裝 OpenSSH 的做法。
sshd
伺服器,存在一定的風險,操作前請做好必要的備份措施,以防萬一。以下指令可以檢查 CentOS Linux 的詳細版本:
# 檢查 CentOS Linux 版本
cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
在 CentOS Linux 7.9 的官方套件庫中,OpenSSH 的版本到了 7.4p1
之後就沒有再繼續更新上去了:
# 查詢 openssh 套件版本
yum info openssh
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: ftp.iij.ad.jp * centos-sclo-rh: ftp.iij.ad.jp * centos-sclo-sclo: ftp.iij.ad.jp * epel: ftp.riken.jp * extras: ftp.iij.ad.jp * updates: ftp.iij.ad.jp Installed Packages Name : openssh Arch : x86_64 Version : 7.4p1 Release : 22.el7_9 Size : 1.9 M Repo : installed From repo : updates Summary : An open source implementation of SSH protocol versions 1 and 2 URL : http://www.openssh.com/portable.html License : BSD Description : SSH (Secure SHell) is a program for logging into and executing : commands on a remote machine. SSH is intended to replace rlogin and : rsh, and to provide secure encrypted communications between two : untrusted hosts over an insecure network. X11 connections and : arbitrary TCP/IP ports can also be forwarded over the secure channel. : : OpenSSH is OpenBSD's version of the last free version of SSH, bringing : it up to date in terms of security and features. : : This package includes the core files necessary for both the OpenSSH : client and server. To make this package useful, you should also : install openssh-clients, openssh-server, or both.
由於我們希望以自行編譯的 OpenSSH 來替換系統上的舊的 OpenSSH,所以兩者之間的編譯參數越接近越好,在進行編譯之前,先下載 openssh
原始碼套件,查看一下原始的編譯參數:
# 下載 openssh 套件原始碼 yumdownloader --source openssh # 解開 rpm 套件 mkdir openssh-7.401-src cd openssh-7.401-src/ rpm2cpio ../openssh-7.4p1-22.el7_9.src.rpm | cpio -ivdm
在原始碼套件的 openssh.spec
檔案中,我們可以看到原始套件的編譯參數:
%configure \ --sysconfdir=%{_sysconfdir}/ssh \ --libexecdir=%{_libexecdir}/openssh \ --datadir=%{_datadir}/openssh \ --with-tcp-wrappers \ --with-default-path=/usr/local/bin:/usr/bin \ --with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ --with-privsep-path=%{_var}/empty/sshd \ --enable-vendor-patchlevel="RHEL7-%{openssh_ver}-%{openssh_rel}" \ --disable-strip \ --without-zlib-version-check \ --with-ssl-engine \ --with-ipaddr-display \ --with-systemd \ --with-ssh1 \ %if %{ldap} --with-ldap \ %endif %if %{rescue} --without-pam \ %else --with-pam \ %endif %if %{WITH_SELINUX} --with-selinux --with-audit=linux \ %ifnarch ppc --with-sandbox=seccomp_filter \ %else --with-sandbox=rlimit \ %endif %endif %if %{kerberos5} --with-kerberos5${krb5_prefix:+=${krb5_prefix}} \ %else --without-kerberos5 \ %endif
除了原始碼的 RPM,OpenSSH 原始碼中的 contrib/redhat/openssh.spec
也有附帶類似的設定參數可以參考。
編譯 OpenSSH 之前,根據自己選擇的編譯參數,安裝必要的開發套件,這裡我們安裝 pam-devel
、zlib-devel
與 audit-libs-devel
套件:
# 安裝 pam-devel、zlib-devel 與 audit-libs-devel 套件
sudo yum install pam-devel zlib-devel audit-libs-devel
從 OpenSSL 官方網站下載 OpenSSL 1.1.1o 原始碼:
# 下載 OpenSSL 1.1.1o 原始碼
wget https://www.openssl.org/source/openssl-1.1.1o.tar.gz
tar zxvf openssl-1.1.1o.tar.gz
從 OpenSSH 官方的鏡像站下載 OpenSSH 9.0p1 原始碼:
# 下載 OpenSSH 9.0p1 原始碼
wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.0p1.tar.gz
tar zxvf openssh-9.0p1.tar.gz
進入 OpenSSH 原始碼目錄,設定編譯的參數,這裡請參考上面的 openssh.spec
設定,並根據自己的需求修改:
# 設定 OpenSSH 編譯參數 cd openssh-9.0p1 ./configure \ --sysconfdir=/usr/local/etc/ssh \ --with-default-path=/usr/local/bin:/usr/bin \ --with-superuser-path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \ --with-privsep-path=/var/empty/sshd \ --with-pam \ --with-ssl-dir=~/openssl-1.1.1o \ --with-audit=linux \ --with-ipaddr-display \ --with-ssl-engine
編譯與安裝 OpenSSH:
# 編譯 OpenSSH make # 安裝 OpenSSH sudo make install
新安裝的 OpenSSH 都放在 /usr/local/
路徑之下,接著對照系統上原本的 /etc/ssh/sshd_config
設定檔,修改新的 /usr/local/etc/ssh/sshd_config
後,手動執行 sshd
伺服器進行測試,並以 -p
參數指定一個臨時的連接埠(避免跟系統既有的 sshd
伺服器衝突):
# 手動執行 sshd 伺服器 sudo /usr/local/sbin/sshd -D -p 10022
這時候就可以測試從其他台電腦連線至這個新的 sshd
伺服器了。
由於新版的 sshd
與 systemd
不相容,所以要改用傳統的 SysV 啟動指令稿來啟動 sshd
。
在確定新的 sshd
可以正常運作之後,將既有的 sshd
停止,並移除 systemd
相關設定:
# 停止 sshd 伺服器 sudo systemctl stop sshd sudo systemctl disable sshd # 移除既有的 sshd 服務設定 mv /usr/lib/systemd/system/sshd.service{,.backup} mv /usr/lib/systemd/system/sshd@.service{,.backup} mv /usr/lib/systemd/system/sshd.socket{,.backup} mv /usr/lib/systemd/system/sshd-keygen.service{,.backup} # 重新載入 systemd 設定檔 sudo systemctl daemon-reload
將 OpenSSH 原始碼中附帶的 sshd.init
指令稿,複製到 /etc/rc.d/init.d/sshd
:
# 複製 init 指令稿
sudo cp contrib/redhat/sshd.init /etc/rc.d/init.d/sshd
修改 /etc/rc.d/init.d/sshd
啟動指令稿,將其中的 /usr/sbin/
路徑改為 /usr/local/sbin/
,而 /etc/ssh/
則改為 /usr/local/etc/ssh/
。另外在呼叫 ssh-keygen
的部分,建議加上新的 ssh_host_ed25519_key.pub
。
修改好啟動指令稿之後,即可啟動 sshd
伺服器,並設定開機自動啟動:
# 啟動 sshd 伺服器 systemctl start sshd # 開機自動啟動 sshd 伺服器 sudo systemctl enable sshd
以下指令可以檢查目前運行的 sshd
伺服器版本:
# 檢查 sshd 版本 ssh -v localhost
這裡的輸出訊息非常多,其中有一行輸出會顯示 sshd
伺服器的 SSH 版本與 OpenSSH 版本:
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.0