Linux

CentOS Linux 7.9 自行編譯、安裝 OpenSSH 9.0p1 伺服器教學與範例

本篇如何在過時的 CentOS Linux 7.9 系統上,自行編譯與安裝 OpenSSH,升級舊版的 sshd 伺服器。

檢查 OpenSSH 版本

在 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 的做法。

以手動方式自行編譯與安裝 OpenSSH,替換掉系統的 sshd 伺服器,存在一定的風險,操作前請做好必要的備份措施,以防萬一。

檢查 CentOS Linux 版本

以下指令可以檢查 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 原始碼套件,查看一下原始的編譯參數:

# 下載 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

編譯 OpenSSH 之前,根據自己選擇的編譯參數,安裝必要的開發套件,這裡我們安裝 pam-develzlib-develaudit-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 伺服器了。

SysV 啟動指令稿

由於新版的 sshdsystemd 不相容,所以要改用傳統的 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

參考資料

Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago