linux升級openssh到7.9

  客戶linux主機ssh存在高危漏洞,須要進行升級修復。html

  linux聯網後,直接命令行:linux

[root@gw ~]# yum update openssl -y

  此命令只是小版本的升級,好比將openssl從1.0.1e-43版本升級到1.0.1e-57版本,但好多時候咱們須要升級的是大版本,而不是這種小的修復。git

  yum remove openssl命令執行時,能夠看到,很是很是多的軟件是依賴於openssl軟件。openssl是一個很是基礎的軟件。編譯安裝一個新版本的openssl覆蓋掉操做系統自帶的openssl。這就會致使那些依賴於openssl的軟件的openssl相關的功能變得不可用。shell

  ssh命令是openssh軟件的一部分。由於上面提出的現象咱們不直接升級操做系統的openssl,可是咱們能夠另外編譯一個openssl,放到單獨的應用目錄中,與操做系統的openssl互不影響。再基於新編譯出來的openssl,將新的openssh軟件編譯出來。 而操做系統的openssh是能夠被替換的。若是你嘗試執行 yum remove openssh* 命令就能夠看到,沒有其它軟件依賴於openssh。此外,openssh軟件提供了sshd服務。因此,咱們只要還要配置並搭建好sshd服務,就能夠替代操做系統自帶的openssh了。vim

  接下來咱們分析,如何升級openssh及其所依賴的openssl。緩存

從openssh官網下載openssh 7.9.p1源碼包,查看裏面的INSTALL文件,裏面有對它的依賴關係作說明 能夠依據blfs下載(http://www.linuxfromscratch.org/blfs/news.html安全

 

  openssh7.9p1下載安裝說明,可參考解壓後的install文件(http://www.linuxfromscratch.org/blfs/view/8.4/postlfs/openssh.htmlbash

1,提早檢查必須安裝的(Zlib、libcrypto或者(LibreSSL或OpenSSL))session

  • Zlib 1.1.4或1.2.1.2或更高版本(早期1.2.x版本有問題)  http://www.gzip.org/zlib/
  • libcrypto(LibreSSL或OpenSSL> = 1.0.1 <1.1.0),這個庫能夠用LibreSSL或OpenSSL替代,但應該將LibreSSL / OpenSSL編譯爲與位置無關的庫(即便用-fPIC)
    不然OpenSSH將沒法與之連接。若是您必須使用非位置無關的libcrypto,那麼您可能須要配置OpenSSH - without-pie。 請注意,因爲API更改,目前不支持OpenSSL 1.1.x.
    LibreSSL http://www.libressl.org/; 
    OpenSSL http://www.openssl.org/

2,還有一些是可選的安裝,例如PAM軟件等app

1. Prerequisites
----------------

A C compiler.  Any C89 or better compiler should work.  Where supported,
configure will attempt to enable the compiler's run-time integrity checking
options.  Some notes about specific compilers:
 - clang: -ftrapv and -sanitize=integer require the compiler-rt runtime
  (CC=clang LDFLAGS=--rtlib=compiler-rt ./configure)

You will need working installations of Zlib and libcrypto (LibreSSL /
OpenSSL)

Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems):
http://www.gzip.org/zlib/

libcrypto (LibreSSL or OpenSSL >= 1.0.1 < 1.1.0)
LibreSSL http://www.libressl.org/ ; or
OpenSSL http://www.openssl.org/

LibreSSL/OpenSSL should be compiled as a position-independent library
(i.e. with -fPIC) otherwise OpenSSH will not be able to link with it.
If you must use a non-position-independent libcrypto, then you may need
to configure OpenSSH --without-pie.  Note that because of API changes,
OpenSSL 1.1.x is not currently supported.

The remaining items are optional.

NB. If you operating system supports /dev/random, you should configure
libcrypto (LibreSSL/OpenSSL) to use it. OpenSSH relies on libcrypto's
direct support of /dev/random, or failing that, either prngd or egd

PRNGD:

If your system lacks kernel-based random collection, the use of Lutz
Jaenicke's PRNGd is recommended.

http://prngd.sourceforge.net/

EGD:

If the kernel lacks /dev/random the Entropy Gathering Daemon (EGD) is
supported only if libcrypto supports it.

http://egd.sourceforge.net/

PAM:

OpenSSH can utilise Pluggable Authentication Modules (PAM) if your
system supports it. PAM is standard most Linux distributions, Solaris,
HP-UX 11, AIX >= 5.2, FreeBSD and NetBSD.

Information about the various PAM implementations are available:

Solaris PAM:	http://www.sun.com/software/solaris/pam/
Linux PAM:	http://www.kernel.org/pub/linux/libs/pam/
OpenPAM:	http://www.openpam.org/

If you wish to build the GNOME passphrase requester, you will need the GNOME
libraries and headers.

GNOME:
http://www.gnome.org/

Alternatively, Jim Knoble <jmknoble@pobox.com> has written an excellent X11
passphrase requester. This is maintained separately at:

http://www.jmknoble.net/software/x11-ssh-askpass/

LibEdit:

sftp supports command-line editing via NetBSD's libedit.  If your platform
has it available natively you can use that, alternatively you might try
these multi-platform ports:

http://www.thrysoee.dk/editline/
http://sourceforge.net/projects/libedit/

LDNS:

LDNS is a DNS BSD-licensed resolver library which supports DNSSEC.

http://nlnetlabs.nl/projects/ldns/

Autoconf:

If you modify configure.ac or configure doesn't exist (eg if you checked
the code out of git yourself) then you will need autoconf-2.69 to rebuild
the automatically generated files by running "autoreconf".  Earlier
versions may also work but this is not guaranteed.

http://www.gnu.org/software/autoconf/

Basic Security Module (BSM):

Native BSM support is known to exist in Solaris from at least 2.5.1,
FreeBSD 6.1 and OS X.  Alternatively, you may use the OpenBSM
implementation (http://www.openbsm.org).

makedepend:

https://www.x.org/archive/individual/util/

If you are making significant changes to the code you may need to rebuild
the dependency (.depend) file using "make depend", which requires the
"makedepend" tool from the X11 distribution.

安裝Zlib

Zlib用於壓縮和解壓縮的功能。操做系統已經自帶了zlib,能夠查看是否符合要求。實際上,openssl和openssh都依賴於zlib。執行下面的命令,安裝zlib開發包:

 rpm -qa|grep zlib
yum -y install zlib-devel

安裝PAM

PAM(Pluggable Authentication Modules,可插拔認證模塊)用於提供安全控制。操做系統也已經自帶了PAM,版本也是能夠的。執行下面的命令,安裝PAM開發包:

rpm -qa|grep pam
yum -y install pam-devel

 

安裝tcp_wrappers

tcp_wrappers是一種安全工具,一般,咱們在/etc/hosts.allow或/etc/hosts.deny文件中配置的過濾規則就是使用的tcp_wrappers的功能了。openssh在編譯時的確是能夠選擇支持tcp_wrappers的。執行下面的命令,安裝tcp_wrappers開發包:

rpm -qa|grep tcp_wrappers
yum install tcp_wrappers-devel -y

系統最小化安裝時,須要安裝包

通常出現這個-bash: make: command not found提示,是由於安裝系統的時候使用的是最小化mini安裝,系統沒有安裝make、vim等經常使用命令,直接yum安裝下便可。

yum -y install gcc automake autoconf libtool make

 

安裝OpenSSL

因爲OpenSSH 7.9p1要求OpenSSL的版本> = 1.0.1 <1.1.0,所以,當前符合要求的最新OpenSSL版本爲1.0.2l https://www.openssl.org/source/old/1.0.2/

首先,從openssl官網下載源碼包openssl-fips-2.0.16.tar.gz(https://www.openssl.org/source/old/fips/)將其安裝到/opt/fips-2.0目錄下。

編譯安裝FIPS宏(https://bbs.csdn.net/wap/topics/390830236):

mkdir /opt/fips-2.0
# export FIPSDIR=/opt/fips-2.0                 --指定另外的安裝目錄,默認會安裝在/usr/local/ssl/fips­2.0目錄
# tar -xvf openssl-fips-2.0.16.tar.gz
# cd openssl-fips-2.0.16
# ./config
# make
# make install

從openssl官網下載源碼包openssl-1.0.2l.tar.gz,將其安裝到/opt/openssl1.0.2l_2019目錄下。將openssl安裝到專門的目錄,這是爲了不對操做系統自帶的openssl形成影響。

 編譯安裝OpenSSL

mkdir /opt/openssl1.0.2l_2019
# tar -xvf openssl-1.0.2l.tar.gz
# cd openssl-1.0.2l
# ./config --prefix=/opt/openssl1.0.2l_2019 --openssldir=/opt/openssl1.0.2l_2019/openssl fips --with-fipsdir=/opt/fips-2.0 zlib-dynamic shared -fPIC
# make depend
# make
# make test
# make install
  • --prefix:指定openssl的安裝目錄。按本例中的安裝方式,安裝完成後該目錄下會包含bin(含二進制程序)、lib(含動態庫文件)、include/openssl(含報頭文件)及openssl(--openssldir選項指定的)這些子目錄。

  • --openssldir:指定openssl文件的安裝目錄。按本例中的安裝方式,安裝完成後該目錄下會包括certs(存放證書文件)、man(存放man文件)、misc(存放各類腳本)、private(存放私鑰文件)這些子目錄及openssl.cnf配置文件。

  • fips:集成FIPS模塊。

  • --with-fipsdir:指向FIPS模塊的安裝目錄位置。

  • zlib-dynamic:編譯支持zlib壓縮/解壓縮,讓openssl加載zlib動態庫。該選項只在支持加載動態庫的操做系統上才支持。這是默認選項。

  • shared:除了靜態庫之外,讓openssl(在支持的平臺上)也編譯生成openssl動態庫。

  • -fPIC:將openssl動態庫編譯成位置無關(position-independent)的代碼。

安裝完成後,將OpenSSL的庫文件目錄添加到/etc/ld.so.conf文件中,並加載到系統內存緩存中:

# echo '/opt/openssl1.0.2l_2019/lib' >> /etc/ld.so.conf
# ldconfig

安裝OpenSSH

從openssl官網下載源碼包openssh-7.9p1.tar.gz,將其安裝到/opt/openssh7.9.p1_2019目錄下。將openssh安裝到專門的目錄,這是爲了不與操做系統自帶的openssh形成沒必要要的衝突。

編譯安裝OpenSSH:

mkdir /opt/openssh7.9.p1_2019
# tar -xvf openssh-7.9p1.tar.gz # cd openssh-7.9p1 # ./configure --prefix=/opt/openssh7.9.p1_2019 --with-ssl-dir=/opt/openssl1.0.2l_2019 --with-pam --with-tcp-wrappers # make # make install
  • --prefix:指定安裝目錄

  • --with-ssl-dir=DIR:指向LibreSSL/OpenSSL庫的安裝目錄的所在路徑。

  • --with-pam:啓用PAM支持。根據OpenSSH的安裝說明,若是在編譯時啓用了PAM,那麼在安裝完成後,也必須在sshd服務的配置文件sshd_config中啓用它(使用UsePAM指令)。

 

根據OpenSSH的安裝說明,若是有啓用PAM,那麼就須要手工安裝一個給sshd程序使用的PAM配置文件,不然安裝好OpenSSH後你可能會沒法使用密碼登陸系統。在編譯時,我使用 --with-pam 選項啓用了對PAM的支持,可是,編譯OpenSSH時並無編譯選項讓你指定PAM配置文件的位置,那麼咱們要怎麼提供這個配置文件呢?

事實上,OpenSSH有另一個編譯選項--with-pam-service=name能夠指定PAM服務名,它的默認值是sshd。而操做系統自帶的PAM軟件默認將全部PAM配置文件都放置在/etc/pam.d目錄下。結合這兩個信息,就可肯定OpenSSH的PAM配置文件應爲/etc/pam.d/sshd文件。而這個文件原來就有了,因此咱們不用額外手工建立一個。

 

設置PATH路徑:

# echo 'export PATH=/opt/openssh7.9.p1_2019/bin:/opt/openssh7.9.p1_2019/sbin:$PATH' >> /etc/profile.d/path.sh
# . /etc/profile.d/path.sh

此時,使用ssh -V命令就能夠看到新版本號了

ssh -V

 

配置OpenSSH

前面已經安裝好了openssh,可是咱們還須要配置它,以保證sshd服務能夠啓起來。咱們能夠先看一下原有的sshd服務(屬於openssh-server軟件包)都有哪些配置文件:

# rpm -ql openssh-server | grep -i --color etc
/etc/pam.d/ssh-keycat
/etc/pam.d/sshd
/etc/rc.d/init.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd

能夠看到,sshd服務的配置文件爲/etc/ssh/sshd_config,它的pam配置文件爲/etc/pam.d/sshd和/etc/pam.d/ssh-keycat,啓動腳本文件爲/etc/rc.d/init.d/sshd,啓動腳本里面有引用到文件/etc/sysconfig/sshd。

參照系統原有的配置文件修改咱們軟件的sshd_config配置文件,這是sshd服務的配置文件(紅色字體的爲新增或修改的部分):

# vim /opt/openssh7.9.p1_2019/etc/sshd_config
Protocol 2 SyslogFacility AUTHPRIV PermitRootLogin yes
AuthorizedKeysFile      .ssh/authorized_keys
PasswordAuthentication yes ChallengeResponseAuthentication no
#GSSAPIAuthentication yes                                                    //該選項目前還不支持
#GSSAPICleanupCredentials yes                                            //該選項目前還不支持
UsePAM yes
 
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE AcceptEnv XMODIFIERS X11Forwarding yes
Subsystem       sftp    /opt/openssh7.9.p1_2019/libexec/sftp-server

注意,UsePAM必定要啓用,OpenSSH的安裝說明裏有提到,若是編譯時啓用了PAM支持,那麼就必須在sshd_config文件中啓用它。

拷貝系統原有的配置文件/etc/sysconfig/sshd到咱們軟件下面,這個配置文件用於設置啓動sshd服務所需的環境變量,在sshd服務的啓動腳本里有調用到該配置文件:

# cp -a /etc/sysconfig/sshd /opt/openssh7.9.p1_2019/etc/sshd

接下來要修改sshd服務的啓動腳本/etc/rc.d/init.d/sshd。先將啓動腳本備份一份爲sshd.old,並添加至chkconfig管理: 

# cp /etc/rc.d/init.d/sshd /etc/rc.d/init.d/sshd.old
# chkconfig --add sshd.old

再根據咱們的OpenSSH的安裝路徑,來修改原有的啓動腳本(紅色字體爲有新增或修改的部分-注:linux7以後沒有這個文件,能夠本身新建一個啓動文件,手動添加這個服務,開機自啓動等啓動sshd):

修改配置文件權限

chmod u+x /etc/rc.d/init.d/sshdnew

添加sshd服務

chkconfig --add sshdnew
設置開機自啓動
chkconfig sshdnew on 驗證開機啓動 chkconfig
--list|grep sshdnew service sshdnew start systemctl is-active sshdnew

 

vim /etc/rc.d/init.d/sshd
#!/bin/bash
#
# sshd        Start up the OpenSSH server daemon
#
# chkconfig: 2345 55 25
# description: SSH is a protocol for secure remote shell access. \
#              This service starts up the OpenSSH server daemon.
#
# processname: sshd
# config: /etc/ssh/ssh_host_key
# config: /etc/ssh/ssh_host_key.pub
# config: /etc/ssh/ssh_random_seed
# config: /etc/ssh/sshd_config
# pidfile: /var/run/sshd.pid

### BEGIN INIT INFO
# Provides: sshd
# Required-Start: $local_fs $network $syslog
# Required-Stop: $local_fs $syslog
# Should-Start: $syslog
# Should-Stop: $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start up the OpenSSH server daemon
# Description:       SSH is a protocol for secure remote shell access.
#             This service starts up the OpenSSH server daemon.
### END INIT INFO

# source function library
. /etc/rc.d/init.d/functions

# pull in sysconfig settings
[ -f /opt/openssh7.9.p1_2019/etc/sshd ] && . /opt/openssh7.9.p1_2019/etc/sshd

RETVAL=0
prog="sshd"
lockfile=/var/lock/subsys/$prog

# Some functions to make the below more readable
KEYGEN=/opt/openssh7.9.p1_2019/bin/ssh-keygen
SSHD=/opt/openssh7.9.p1_2019/sbin/sshd
RSA1_KEY=/etc/ssh/ssh_host_key
RSA_KEY=/opt/openssh7.9.p1_2019/etc/ssh_host_rsa_key
DSA_KEY=/opt/openssh7.9.p1_2019/etc/ssh_host_dsa_key
PID_FILE=/var/run/sshd.pid     # PID文件的所在路徑,這個變量的值不要改

runlevel=$(set -- $(runlevel); eval "echo \$$#" )

fips_enabled() {
    if [ -r /proc/sys/crypto/fips_enabled ]; then
        cat /proc/sys/crypto/fips_enabled
    else
        echo 0
    fi
}

do_rsa1_keygen() {
    if [ ! -s $RSA1_KEY -a `fips_enabled` -eq 0 ]; then
        echo -n $"Generating SSH1 RSA host key: "
        rm -f $RSA1_KEY
        if test ! -f $RSA1_KEY && $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then
            chmod 600 $RSA1_KEY
            chmod 644 $RSA1_KEY.pub
            if [ -x /sbin/restorecon ]; then
                /sbin/restorecon $RSA1_KEY.pub
            fi
            success $"RSA1 key generation"
            echo
        else
            failure $"RSA1 key generation"
            echo
            exit 1
        fi
    fi
}

do_rsa_keygen() {
    if [ ! -s $RSA_KEY ]; then
        echo -n $"Generating SSH2 RSA host key: "
        rm -f $RSA_KEY
        if test ! -f $RSA_KEY && $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then
            chmod 600 $RSA_KEY
            chmod 644 $RSA_KEY.pub
            if [ -x /sbin/restorecon ]; then
                /sbin/restorecon $RSA_KEY.pub
            fi
            success $"RSA key generation"
            echo
        else
            failure $"RSA key generation"
            echo
            exit 1
        fi
    fi
}

do_dsa_keygen() {
    if [ ! -s $DSA_KEY ]; then
        echo -n $"Generating SSH2 DSA host key: "
        rm -f $DSA_KEY
        if test ! -f $DSA_KEY && $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then
            chmod 600 $DSA_KEY
            chmod 644 $DSA_KEY.pub
            if [ -x /sbin/restorecon ]; then
                /sbin/restorecon $DSA_KEY.pub
            fi
            success $"DSA key generation"
            echo
        else
            failure $"DSA key generation"
            echo
            exit 1
        fi
    fi
}

do_restart_sanity_check()
{
    $SSHD -t
    RETVAL=$?
    if [ $RETVAL -ne  0 ]; then
        failure $"Configuration file or keys are invalid"
        echo
    fi
}

start()
{
    [ -x $SSHD ] || exit 5
    [ -f /opt/openssh7.9.p1_2019/etc/sshd_config ] || exit 6
    # Create keys if necessary
    if [ "x${AUTOCREATE_SERVER_KEYS}" != xNO ]; then
    #    do_rsa1_keygen             # 註釋掉這條語句
        do_rsa_keygen
        do_dsa_keygen
    fi

    echo -n $"Starting $prog: "
    $SSHD $OPTIONS && success || failure
    RETVAL=$?
    [ $RETVAL -eq 0 ] && touch $lockfile
    echo
    return $RETVAL
}

stop()
{
    echo -n $"Stopping $prog: "
    killproc -p $PID_FILE $SSHD
    RETVAL=$?
    # if we are in halt or reboot runlevel kill all running sessions
    # so the TCP connections are closed cleanly
    if [ "x$runlevel" = x0 -o "x$runlevel" = x6 ] ; then
        trap '' TERM
        killall $prog 2>/dev/null
        trap TERM
    fi
    [ $RETVAL -eq 0 ] && rm -f $lockfile
    echo
}

reload()
{
    echo -n $"Reloading $prog: "
    killproc -p $PID_FILE $SSHD -HUP
    RETVAL=$?
    echo
}

restart() {
    stop
    start
}

force_reload() {
    restart
}

rh_status() {
    status -p $PID_FILE openssh-daemon
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        start
        ;;
    stop)
        if ! rh_status_q; then
            rm -f $lockfile
            exit 0
        fi
        stop
        ;;
    restart)
        restart
        ;;
    reload)
        rh_status_q || exit 7
        reload
        ;;
    force-reload)
        force_reload
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
        if [ -f $lockfile ] ; then
            do_restart_sanity_check
            if [ $RETVAL -eq 0 ] ; then
                stop
                # avoid race
                sleep 3
                start
            else
                RETVAL=6
            fi
        fi
        ;;
    status)
        rh_status
        RETVAL=$?
        if [ $RETVAL -eq 3 -a -f $lockfile ] ; then
            RETVAL=2
        fi
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
        RETVAL=2
esac
exit $RETVAL

 root輸入密碼登陸拒毫不成功能夠:

在$SSHD $OPTIONS && success || failure這句話前面加一句:

OPTIONS="-f /etc/ssh/sshd_config"

配置以下:

        echo -n $"Starting $prog:"
        OPTIONS="-f /opt/ssh7.9/etc/sshd_config"  --同上目錄/opt/openssh7.9.p1_2019/etc/sshd_config
 $SSHD $OPTIONS && success || failure RETVAL=$?

 

 因爲OpenSSH依賴的OpenSSL已不支持rsa1,因此我將啓動腳本中生成rsa1祕鑰的指令註釋掉了。

接下來,關鍵的一步來了,咱們要關閉舊的sshd服務,啓動新的sshd服務。這個操做若是失敗了,不會致使現有的ssh遠程鏈接斷開。因此咱們能夠先關閉舊的sshd程序,再啓動新的sshd程序:

# service sshd.old stop
# service sshd start

若是新的sshd服務啓動成功了,咱們能夠先簡單測試下,好比,看看普通用戶和root用戶是否能正常經過ssh登陸。若是沒有沒有問題,咱們能夠在測測其它的,好比scp、sftp是否正常等。固然,若是有條件的話,可使用漏洞掃描工具掃一下,看看有沒有什麼咱們沒有注意到的地方。 

最後,就能夠刪除掉舊sshd服務的啓動腳本了,以避免衝突:

# rm -f /etc/init.d/sshd.old

openssl和openssh的編譯選項基原本說我也只是使用了必要的選項,咱們編譯出來的openssl和openssh軟件在功能特性上只是儘量地接近原有的,安全性和性能可能也是有差別。

複用了操做系統原有的sshd服務的配置文件和啓動腳本,這可能沒法充分利用新版本openssh的特性。openssl和openssh原本也是挺複雜的東西,一時半會可能也很難徹底弄明白。

這種升級方式,應該會比強制升級openssl和openssh的方式好不少。

參考https://blog.51cto.com/techsnail/2138927,獨指蝸牛 只作平常積累,不作商業用途,侵權即刪。

相關文章
相關標籤/搜索