场景: CentOS Stream 9 系统ssh默认版本一般是OpenSSH_8.7p1 ,安全漏洞扫描时会扫出版本过低,需要升级到最新的版本。
OpenSSH(OpenBSD Secure Shell)是加拿大OpenBSD计划组的一套用于安全访问远程计算机的连接工具。该工具是SSH协议的开源实现,支持对所有的传输进行加密,可有效阻止窃听、连接劫持以及其他网络级的攻击。 OpenSSH 8.7p1之前版本存在安全漏洞,该漏洞源于ssh-agent的PKCS11功能存在安全问题,攻击者可利用该漏洞执行远程代码。
[root@localhost ~]# ssh -V
OpenSSH_8.7p1, OpenSSL 3.0.7 1 Nov 2022
[root@localhost ~]# openssl version
OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)
# 系统openssl版本是 3.0.7 需要升级到 3.2.0
# 系统OpenssH版本是 8.7p1 需升级到 9.6.p1
# zlib 包是编译OpenssH时所需的
OpenssL 软件包 | zlib软件包 | OpenssH软件包 | 操作系统 | 需要更新的主机 | 操作机 |
---|---|---|---|---|---|
openssl-3.2.0.tar.gz | zlib-1.3.tar.gz | openssh-9.6p1.tar.gz | CentOS7/CentOS8/CentOS Stream9 | 10.10.10.162 | 10.10.10.156 |
也是可以在10.10.10.162主机上操作,多开几个终端,然后 top ,不能让终端关闭不然只能去机房操作啦!
[root@localhost ~]# cat /etc/redhat-release # 系统的版本信息
CentOS Stream release 9
[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# ls
centos-addons.repo centos.repo
[root@localhost yum.repos.d]# mkdir bak
[root@localhost yum.repos.d]# cp -r *.repo bak/
[root@localhost yum.repos.d]# pwd
/etc/yum.repos.d
[root@localhost yum.repos.d]# vim centos.repo
[baseos]
name=CentOS Stream $releasever - BaseOS
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/BaseOS/$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=1
[baseos-debug]
name=CentOS Stream $releasever - BaseOS - Debug
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/BaseOS/$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[baseos-source]
name=CentOS Stream $releasever - BaseOS - Source
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/BaseOS/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[appstream]
name=CentOS Stream $releasever - AppStream
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/AppStream/$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=1
[appstream-debug]
name=CentOS Stream $releasever - AppStream - Debug
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/AppStream/$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[appstream-source]
name=CentOS Stream $releasever - AppStream - Source
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/AppStream/$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[crb]
name=CentOS Stream $releasever - CRB
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/CRB/$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[crb-debug]
name=CentOS Stream $releasever - CRB - Debug
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/CRB/$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[crb-source]
name=CentOS Stream $releasever - CRB - Source
baseurl=https://mirrors.aliyun.com/centos-stream/$stream/CRB/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[root@localhost yum.repos.d]# pwd
/etc/yum.repos.d
[root@localhost yum.repos.d]# vim centos-addons.repo
[highavailability]
name=CentOS Stream $releasever - HighAvailability
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/HighAvailability/$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[highavailability-debug]
name=CentOS Stream $releasever - HighAvailability - Debug
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/HighAvailability/$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[highavailability-source]
name=CentOS Stream $releasever - HighAvailability - Source
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/HighAvailability/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[nfv]
name=CentOS Stream $releasever - NFV
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/NFV/$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[nfv-debug]
name=CentOS Stream $releasever - NFV - Debug
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/NFV/$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[nfv-source]
name=CentOS Stream $releasever - NFV - Source
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/NFV/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[rt]
name=CentOS Stream $releasever - RT
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/RT/$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[rt-debug]
name=CentOS Stream $releasever - RT - Debug
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/RT/$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[rt-source]
name=CentOS Stream $releasever - RT - Source
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/RT/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[resilientstorage]
name=CentOS Stream $releasever - ResilientStorage
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/ResilientStorage/$basearch/os/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=0
[resilientstorage-debug]
name=CentOS Stream $releasever - ResilientStorage - Debug
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/ResilientStorage/$basearch/debug/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[resilientstorage-source]
name=CentOS Stream $releasever - ResilientStorage - Source
baseurl=http://mirrors.aliyun.com/centos-stream/$stream/ResilientStorage/source/tree/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[extras-common]
name=CentOS Stream $releasever - Extras packages
baseurl=http://mirrors.aliyun.com/centos-stream/SIGs/$stream/extras/$basearch/extras-common/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
countme=1
enabled=1
[extras-common-source]
name=CentOS Stream $releasever - Extras packages - Source
baseurl=http://mirrors.aliyun.com/centos-stream/SIGs/$stream/extras/source/extras-common/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512
gpgcheck=1
repo_gpgcheck=0
metadata_expire=6h
enabled=0
[root@localhost yum.repos.d]# dnf clean all # 清除缓存
21 个文件已删除
[root@localhost yum.repos.d]#
[root@localhost yum.repos.d]# dnf makecache # 建立缓存
.......
[root@localhost yum.repos.d]# dnf update # 更新
[root@localhost ~]# systemctl disable --now firewalld
Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service".
Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service".
[root@localhost ~]# setenforce 0
[root@localhost ~]# sed -i '/SELINUX=enforcing/s/enforcing/disabled/' /etc/selinux/config
# 需更新的主机上操作 --> 10.10.10.162
[root@localhost ~]# dnf install -y telnet-server
......省略N
[root@localhost ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@localhost ~]# systemctl start telnet.socket ## 启动服务
[root@localhost ~]#
[root@localhost ~]# systemctl enable telnet.socket # 设置为开机自启
Created symlink /etc/systemd/system/sockets.target.wants/telnet.socket → /usr/lib/systemd/system/telnet.socket.
[root@localhost ~]#
# 查看 23 端口已启
[root@localhost ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 4096 *:23 *:*
[root@localhost ~]#
# 创建普通用户 agan
[root@localhost ~]# useradd agan
[root@localhost ~]# passwd agan # 设置密码
更改用户 agan 的密码 。
新的密码:
无效的密码: 密码少于 8 个字符
重新输入新的密码:
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# ip addr show ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:df:77:af brd ff:ff:ff:ff:ff:ff
altname enp3s0
inet 10.10.10.162/24 brd 10.10.10.255 scope global dynamic noprefixroute ens160
valid_lft 1197sec preferred_lft 1197sec
inet6 fe80::20c:29ff:fedf:77af/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@localhost ~]#
# 在操作机上操作 ---> 10.10.10.156
[root@localhost ~]# ip addr show ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:d3:d9:4e brd ff:ff:ff:ff:ff:ff
inet 10.10.10.156/24 brd 10.10.10.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::602c:6093:47b:c27e/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@localhost ~]#
# telnet 到更新openssh的主机上
[root@localhost ~]# telnet 10.10.10.162 23
Trying 10.10.10.162...
Connected to 10.10.10.162.
Escape character is '^]'.
Kernel 5.14.0-402.el9.x86_64 on an x86_64
localhost login: agan # 输入刚才创建的普通用户:agan
Password: # 输入密码
[agan@localhost ~]$ ip addr show ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:df:77:af brd ff:ff:ff:ff:ff:ff
altname enp3s0
inet 10.10.10.162/24 brd 10.10.10.255 scope global dynamic noprefixroute ens160
valid_lft 1444sec preferred_lft 1444sec
inet6 fe80::20c:29ff:fedf:77af/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[agan@localhost ~]$
[agan@localhost ~]$ su - root # 登录到root账号
密码: # 输入root密码
上一次登录: 五 1月 12 08:47:01 CST 2024 从 10.10.10.1 pts/2 上
[root@localhost ~]#
# 安装依赖包
[root@localhost ~]# yum install gcc gcc-c++ make -y perl-CPAN perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker
...省略N
# 下载zlib 或者 使用rpm的方式下载也行
[root@localhost ~]# cd /usr/src/
[root@localhost src]# wget https://www.zlib.net/zlib-1.3.tar.gz
...省略N
[root@localhost src]# tar xf zlib-1.3.tar.gz
[root@localhost src]# cd zlib-1.3
[root@localhost zlib-1.3]# pwd
/usr/src/zlib-1.3
[root@localhost zlib-1.3]# ./configure --prefix=/usr/local/zlib
...省略N
[root@localhost zlib-1.3]# pwd
/usr/src/zlib-1.3
[root@localhost zlib-1.3]# make
...省略N
[root@localhost zlib-1.3]# pwd
/usr/src/zlib-1.3
[root@localhost zlib-1.3]# make install
...省略N
访问OpenSSL官网资源,查看是否有最新的版本发布
# 查看主机openssl版本信息
## 查看路径
[root@localhost ~]# which openssl
/usr/bin/openssl
## 查看版本
[root@localhost ~]# openssl version
OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)
# 二、编译安装
### 下载
[root@localhost ~]# cd /usr/src/
[root@localhost src]# wget https://www.openssl.org/source/openssl-3.2.0.tar.gz
## 没有 wget 命令 使用 curl -O https://www.openssl.org/source/openssl-3.2.0.tar.gz
### 解压并切换目录
[root@localhost src]# pwd
/usr/src
[root@localhost src]# tar xf openssl-3.2.0.tar.gz
### 设定Openssl 安装,( --prefix )参数为欲安装之目录,也就是安装后的档案会出现在该目录下
[root@localhost src]# pwd
/usr/src
[root@localhost src]# cd openssl-3.2.0
[root@localhost openssl-3.2.0]# ./config --prefix=/usr/local/openssl
......
### make 编译
[root@localhost ~]# cd /usr/src/openssl-3.2.0
[root@localhost openssl-3.2.0]# nproc
2
[root@localhost openssl-3.2.0]# make -j 2
### 执行make install,编译安装 Openssl
[root@localhost ~]# cd /usr/src/openssl-3.2.0
[root@localhost openssl-3.2.0]# make install
[root@localhost ~]# ls /usr/local/openssl/
bin include lib64 share ssl
[root@localhost ~]#
### 切换openssl版本
[root@localhost ~]# mv /usr/bin/openssl /usr/bin/openssl.bak
# 软连接
[root@localhost ~]# ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
[root@localhost ~]# ls -l /usr/bin/openssl
lrwxrwxrwx. 1 root root 30 1月 12 09:37 /usr/bin/openssl -> /usr/local/openssl/bin/openssl
[root@localhost ~]# ln -s /usr/local/openssl/include/openssl /usr/include/openssl
[root@localhost ~]# ls -l /usr/include/openssl
lrwxrwxrwx. 1 root root 34 1月 12 09:38 /usr/include/openssl -> /usr/local/openssl/include/openssl
[root@localhost ~]#
[root@localhost ~]# echo '/usr/local/openssl/lib64' >> /etc/ld.so.conf
[root@localhost ~]# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/local/openssl/lib64
[root@localhost ~]# ldconfig # 让其生效
#注意:不能直接删除软链接
#如需使用新版本开发,则需替换原来的软链接指向,即替换原动态库,进行版本升级。
## 替换/lib(lib64)和/usr/lib(lib64)和/usr/local/lib(lib64)存在的相应动态库
### 查看版本
[root@localhost ~]# openssl version
OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)
# 下载 OpenssH
[root@localhost ~]# cd /usr/src/
[root@localhost src]# wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.6p1.tar.gz
......
# 备份旧 ssh 配置文件
[root@localhost ~]# cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
[root@localhost ~]# cp -p /usr/sbin/sshd /usr/sbin/sshd.bak
[root@localhost ~]# cp -p /usr/bin/ssh /usr/bin/ssh.bak
[root@localhost ~]# cp -p /usr/bin/ssh-keygen /usr/bin/ssh-keygen.bak
[root@localhost ~]# cp -p /etc/ssh/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub.bak
[root@localhost ~]#
# 停止ssh服务
[root@localhost ~]# systemctl stop sshd
[root@localhost ~]#
[root@localhost ~]# systemctl status sshd
○ sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
Active: inactive (dead) since Fri 2024-01-12 09:54:31 CST; 12s ago
Duration: 1h 20min 19.960s
Docs: man:sshd(8)
# 备份 ssh 目录
[root@localhost ~]# cp -r /etc/ssh /etc/ssh.bak
#查询原有ssh包并卸载
[root@localhost ~]# rpm -qa | grep openssh
openssh-8.7p1-35.el9.x86_64
openssh-clients-8.7p1-35.el9.x86_64
openssh-server-8.7p1-35.el9.x86_64
[root@localhost ~]#
[root@localhost ~]# rpm -qa | grep openssh | xargs -t rpm -evh --nodeps
rpm -evh --nodeps openssh-8.7p1-35.el9.x86_64 openssh-clients-8.7p1-35.el9.x86_64 openssh-server-8.7p1-35.el9.x86_64
准备中... ################################# [100%]
Removed "/etc/systemd/system/multi-user.target.wants/sshd.service".
正在清理/删除...
1:openssh-server-8.7p1-35.el9 ################################# [ 33%]
2:openssh-clients-8.7p1-35.el9 ################################# [ 67%]
3:openssh-8.7p1-35.el9 ################################# [100%]
[root@localhost ~]# rpm -qa | grep openssh
[root@localhost ~]#
[root@localhost openssh-9.6p1]# cd /usr/src/
[root@localhost src]# tar xf openssh-9.6p1.tar.gz
[root@localhost src]# cd openssh-9.6p1
[root@localhost openssh-9.6p1]# pwd
/usr/src/openssh-9.6p1
[root@localhost openssh-9.6p1]# ./configure --prefix=/usr/local/openssh --with-zlib=/usr/local/zlib --with-ssl-dir=/usr/local/openssl
...
[root@localhost openssh-9.6p1]# make
...
[root@localhost openssh-9.6p1]# make install
...
# ssh允许root登录、需要密码进行验证
[root@localhost ~]# grep 'PermitRootLogin' /usr/local/openssh/etc/sshd_config
#PermitRootLogin prohibit-password
# the setting of "PermitRootLogin prohibit-password".
[root@localhost ~]#
[root@localhost ~]# echo 'PermitRootLogin yes' >>/usr/local/openssh/etc/sshd_config # 追加
[root@localhost ~]# grep 'PubkeyAuthentication' /usr/local/openssh/etc/sshd_config
#PubkeyAuthentication yes
[root@localhost ~]# sed -i '/PubkeyAuthentication/s/#//' /usr/local/openssh/etc/sshd_config
[root@localhost ~]# grep 'PasswordAuthentication yes' /usr/local/openssh/etc/sshd_config
#PasswordAuthentication yes # 把注释取消掉
[root@localhost ~]# sed -i '/PasswordAuthentication yes/cPasswordAuthentication yes' /usr/local/openssh/etc/sshd_config
[root@localhost ~]# grep 'PasswordAuthentication yes' /usr/local/openssh/etc/sshd_config
PasswordAuthentication yes
[root@localhost ~]#
# 将编译安装的新配置文件 拷贝到原路径下
[root@localhost ~]# cp /usr/local/openssh/etc/sshd_config /etc/ssh/sshd_config
[root@localhost ~]# cp /usr/local/openssh/sbin/sshd /usr/sbin/sshd
[root@localhost ~]# cp /usr/local/openssh/bin/ssh /usr/bin/ssh
[root@localhost ~]# cp /usr/local/openssh/bin/ssh-keygen /usr/bin/ssh-keygen
[root@localhost ~]# cp /usr/local/openssh/etc/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub
cp:是否覆盖'/etc/ssh/ssh_host_ecdsa_key.pub'? y
[root@localhost ~]#
# 拷贝启动脚本
[root@localhost ~]# cp -a /usr/src/openssh-9.6p1/contrib/redhat/sshd.init /etc/rc.d/init.d/sshd
[root@localhost ~]#
[root@localhost ~]# chmod 755 /etc/rc.d/init.d/sshd
[root@localhost ~]#
[root@localhost ~]# ls -l /etc/rc.d/init.d/sshd
-rwxr-xr-x. 1 agan agan 1721 12月 18 22:59 /etc/rc.d/init.d/sshd
[root@localhost ~]#
[root@localhost ~]# systemctl status sshd # 查看 sshd 服务状态
Warning: The unit file, source configuration file or drop-ins of sshd.service changed on disk. Run 'sys>
○ sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
Active: inactive (dead) since Fri 2024-01-12 09:54:31 CST; 22min ago
Duration: 1h 20min 19.960s
Docs: man:sshd(8)
......
# 查看端口
[root@localhost redhat]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 *:23 *:*
[root@localhost redhat]# systemctl daemon-reload # 重新加载守护进程
[root@localhost redhat]#
[root@localhost redhat]# systemctl restart sshd # 重启服务
[root@localhost redhat]#
[root@localhost redhat]# systemctl status sshd # 查看状态
● sshd.service - SYSV: OpenSSH server daemon
Loaded: loaded (/etc/rc.d/init.d/sshd; generated)
Active: active (running) since Fri 2024-01-12 10:00:52 CST; 6s ago
Docs: man:systemd-sysv-generator(8)
Process: 53300 ExecStart=/etc/rc.d/init.d/sshd start (code=exited, status=0/SUCCESS)
Main PID: 53310 (sshd)
...
[root@localhost ~]# ss -antl # 查看端口:22 端口已启
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 4096 *:23 *:*
[root@localhost ~]#
[root@localhost ~]# ssh -V # 查看版本
OpenSSH_9.6p1, OpenSSL 3.2.0 23 Nov 2023
[root@localhost ~]#
# 启动 sshd 服务报错
[root@localhost ~]# systemctl restart sshd
Warning: The unit file, source configuration file or drop-ins of sshd.service changed on disk. Run 'systemctl daemon-reload' to reload units.
Job for sshd.service failed because a timeout was exceeded.
See "systemctl status sshd.service" and "journalctl -xeu sshd.service" for details.
# 解决 启动sshd 服务报错问题
[root@localhost init.d]# pwd
/etc/rc.d/init.d
[root@localhost init.d]# cat functions # 添加以下信息
# -*-Shell-script-*-
#
# functions This file contains functions to be used by most or all
# shell scripts in the /etc/init.d directory.
#
TEXTDOMAIN=initscripts
# Make sure umask is sane
umask 022
# Set up a default search path.
PATH="/sbin:/usr/sbin:/bin:/usr/bin"
export PATH
if [ $PPID -ne 1 -a -z "$SYSTEMCTL_SKIP_REDIRECT" ] && \
[ -d /run/systemd/system ] ; then
case "$0" in
/etc/init.d/*|/etc/rc.d/init.d/*)
_use_systemctl=1
;;
esac
fi
systemctl_redirect () {
local s
local prog=${1##*/}
local command=$2
local options=""
case "$command" in
start)
s=$"Starting $prog (via systemctl): "
;;
stop)
s=$"Stopping $prog (via systemctl): "
;;
reload|try-reload)
s=$"Reloading $prog configuration (via systemctl): "
;;
restart|try-restart|condrestart)
s=$"Restarting $prog (via systemctl): "
;;
esac
if [ -n "$SYSTEMCTL_IGNORE_DEPENDENCIES" ] ; then
options="--ignore-dependencies"
fi
if ! systemctl show "$prog.service" > /dev/null 2>&1 || \
systemctl show -p LoadState "$prog.service" | grep -q 'not-found' ; then
action $"Reloading systemd: " /bin/systemctl daemon-reload
fi
action "$s" /bin/systemctl $options $command "$prog.service"
}
# Get a sane screen width
[ -z "${COLUMNS:-}" ] && COLUMNS=80
if [ -z "${CONSOLETYPE:-}" ]; then
if [ -c "/dev/stderr" -a -r "/dev/stderr" ]; then
CONSOLETYPE="$(/sbin/consoletype < /dev/stderr 2>/dev/null)"
else
CONSOLETYPE="serial"
fi
fi
if [ -z "${NOLOCALE:-}" ] && [ -z "${LANGSH_SOURCED:-}" ] && \
[ -f /etc/sysconfig/i18n -o -f /etc/locale.conf ] ; then
. /etc/profile.d/lang.sh 2>/dev/null
# avoid propagating LANGSH_SOURCED any further
unset LANGSH_SOURCED
fi
# Read in our configuration
if [ -z "${BOOTUP:-}" ]; then
if [ -f /etc/sysconfig/init ]; then
. /etc/sysconfig/init
else
# This all seem confusing? Look in /etc/sysconfig/init,
# or in /usr/share/doc/initscripts-*/sysconfig.txt
BOOTUP=color
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"
LOGLEVEL=1
fi
if [ "$CONSOLETYPE" = "serial" ]; then
BOOTUP=serial
MOVE_TO_COL=
SETCOLOR_SUCCESS=
SETCOLOR_FAILURE=
SETCOLOR_WARNING=
SETCOLOR_NORMAL=
fi
fi
# Check if any of $pid (could be plural) are running
checkpid() {
local i
for i in $* ; do
[ -d "/proc/$i" ] && return 0
done
return 1
}
__kill_pids_term_kill_checkpids() {
local base_stime=$1
shift 1
local pid=
local pids=$*
local remaining=
local stat=
local stime=
for pid in $pids ; do
[ ! -e "/proc/$pid" ] && continue
read -r line < "/proc/$pid/stat" 2> /dev/null
stat=($line)
stime=${stat[21]}
[ -n "$stime" ] && [ "$base_stime" -lt "$stime" ] && continue
remaining+="$pid "
done
echo "$remaining"
[ -n "$remaining" ] && return 1
return 0
}
__kill_pids_term_kill() {
local try=0
local delay=3;
local pid=
local stat=
local base_stime=
# We can't initialize stat & base_stime on the same line where 'local'
# keyword is, otherwise the sourcing of this file will fail for ksh...
stat=($(< /proc/self/stat))
base_stime=${stat[21]}
if [ "$1" = "-d" ]; then
delay=$2
shift 2
fi
local kill_list=$*
kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
[ -z "$kill_list" ] && return 0
kill -TERM $kill_list >/dev/null 2>&1
sleep 0.1
kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
if [ -n "$kill_list" ] ; then
while [ $try -lt $delay ] ; do
sleep 1
kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
[ -z "$kill_list" ] && break
let try+=1
done
if [ -n "$kill_list" ] ; then
kill -KILL $kill_list >/dev/null 2>&1
sleep 0.1
kill_list=$(__kill_pids_term_kill_checkpids $base_stime $kill_list)
fi
fi
[ -n "$kill_list" ] && return 1
return 0
}
# __proc_pids {program} [pidfile]
# Set $pid to pids from /var/run* for {program}. $pid should be declared
# local in the caller.
# Returns LSB exit code for the 'status' action.
__pids_var_run() {
local base=${1##*/}
local pid_file=${2:-/var/run/$base.pid}
local pid_dir=$(/usr/bin/dirname $pid_file > /dev/null)
local binary=$3
[ -d "$pid_dir" -a ! -r "$pid_dir" ] && return 4
pid=
if [ -f "$pid_file" ] ; then
local line p
[ ! -r "$pid_file" ] && return 4 # "user had insufficient privilege"
while : ; do
read line
[ -z "$line" ] && break
for p in $line ; do
if [ -z "${p//[0-9]/}" ] && [ -d "/proc/$p" ] ; then
if [ -n "$binary" ] ; then
local b=$(readlink /proc/$p/exe | sed -e 's/\s*(deleted)$//')
[ "$b" != "$binary" ] && continue
fi
pid="$pid $p"
fi
done
done < "$pid_file"
if [ -n "$pid" ]; then
return 0
fi
return 1 # "Program is dead and /var/run pid file exists"
fi
return 3 # "Program is not running"
}
# Output PIDs of matching processes, found using pidof
__pids_pidof() {
pidof -c -m -o $$ -o $PPID -o %PPID -x "$1" || \
pidof -c -m -o $$ -o $PPID -o %PPID -x "${1##*/}"
}
# A function to start a program.
daemon() {
# Test syntax.
local gotbase= force= nicelevel corelimit
local pid base= user= nice= bg= pid_file=
local cgroup=
nicelevel=0
while [ "$1" != "${1##[-+]}" ]; do
case $1 in
'')
echo $"$0: Usage: daemon [+/-nicelevel] {program}" "[arg1]..."
return 1
;;
--check)
base=$2
gotbase="yes"
shift 2
;;
--check=?*)
base=${1#--check=}
gotbase="yes"
shift
;;
--user)
user=$2
shift 2
;;
--user=?*)
user=${1#--user=}
shift
;;
--pidfile)
pid_file=$2
shift 2
;;
--pidfile=?*)
pid_file=${1#--pidfile=}
shift
;;
--force)
force="force"
shift
;;
[-+][0-9]*)
nice="nice -n $1"
shift
;;
*)
echo $"$0: Usage: daemon [+/-nicelevel] {program}" "[arg1]..."
return 1
;;
esac
done
# Save basename.
[ -z "$gotbase" ] && base=${1##*/}
# See if it's already running. Look *only* at the pid file.
__pids_var_run "$base" "$pid_file"
[ -n "$pid" -a -z "$force" ] && return
# make sure it doesn't core dump anywhere unless requested
corelimit="ulimit -S -c ${DAEMON_COREFILE_LIMIT:-0}"
# if they set NICELEVEL in /etc/sysconfig/foo, honor it
[ -n "${NICELEVEL:-}" ] && nice="nice -n $NICELEVEL"
# if they set CGROUP_DAEMON in /etc/sysconfig/foo, honor it
if [ -n "${CGROUP_DAEMON}" ]; then
if [ ! -x /bin/cgexec ]; then
echo -n "Cgroups not installed"; warning
echo
else
cgroup="/bin/cgexec";
for i in $CGROUP_DAEMON; do
cgroup="$cgroup -g $i";
done
fi
fi
# Echo daemon
[ "${BOOTUP:-}" = "verbose" -a -z "${LSB:-}" ] && echo -n " $base"
# And start it up.
if [ -z "$user" ]; then
$cgroup $nice /bin/bash -c "$corelimit >/dev/null 2>&1 ; $*"
else
$cgroup $nice runuser -s /bin/bash $user -c "$corelimit >/dev/null 2>&1 ; $*"
fi
[ "$?" -eq 0 ] && success $"$base startup" || failure $"$base startup"
}
# A function to stop a program.
killproc() {
local RC killlevel= base pid pid_file= delay try binary=
RC=0; delay=3; try=0
# Test syntax.
if [ "$#" -eq 0 ]; then
echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
return 1
fi
if [ "$1" = "-p" ]; then
pid_file=$2
shift 2
fi
if [ "$1" = "-b" ]; then
if [ -z $pid_file ]; then
echo $"-b option can be used only with -p"
echo $"Usage: killproc -p pidfile -b binary program"
return 1
fi
binary=$2
shift 2
fi
if [ "$1" = "-d" ]; then
delay=$(echo $2 | awk -v RS=' ' -v IGNORECASE=1 '{if($1!~/^[0-9.]+[smhd]?$/) exit 1;d=$1~/s$|^[0-9.]*$/?1:$1~/m$/?60:$1~/h$/?60*60:$1~/d$/?24*60*60:-1;if(d==-1) exit 1;delay+=d*$1} END {printf("%d",delay+0.5)}')
if [ "$?" -eq 1 ]; then
echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
return 1
fi
shift 2
fi
# check for second arg to be kill level
[ -n "${2:-}" ] && killlevel=$2
# Save basename.
base=${1##*/}
# Find pid.
__pids_var_run "$1" "$pid_file" "$binary"
RC=$?
if [ -z "$pid" ]; then
if [ -z "$pid_file" ]; then
pid="$(__pids_pidof "$1")"
else
[ "$RC" = "4" ] && { failure $"$base shutdown" ; return $RC ;}
fi
fi
# Kill it.
if [ -n "$pid" ] ; then
[ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
if [ -z "$killlevel" ] ; then
__kill_pids_term_kill -d $delay $pid
RC=$?
[ "$RC" -eq 0 ] && success $"$base shutdown" || failure $"$base shutdown"
# use specified level only
else
if checkpid $pid; then
kill $killlevel $pid >/dev/null 2>&1
RC=$?
[ "$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
elif [ -n "${LSB:-}" ]; then
RC=7 # Program is not running
fi
fi
else
if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
RC=7 # Program is not running
else
failure $"$base shutdown"
RC=0
fi
fi
# Remove pid file if any.
if [ -z "$killlevel" ]; then
rm -f "${pid_file:-/var/run/$base.pid}"
fi
return $RC
}
# A function to find the pid of a program. Looks *only* at the pidfile
pidfileofproc() {
local pid
# Test syntax.
if [ "$#" = 0 ] ; then
echo $"Usage: pidfileofproc {program}"
return 1
fi
__pids_var_run "$1"
[ -n "$pid" ] && echo $pid
return 0
}
# A function to find the pid of a program.
pidofproc() {
local RC pid pid_file=
# Test syntax.
if [ "$#" = 0 ]; then
echo $"Usage: pidofproc [-p pidfile] {program}"
return 1
fi
if [ "$1" = "-p" ]; then
pid_file=$2
shift 2
fi
fail_code=3 # "Program is not running"
# First try "/var/run/*.pid" files
__pids_var_run "$1" "$pid_file"
RC=$?
if [ -n "$pid" ]; then
echo $pid
return 0
fi
[ -n "$pid_file" ] && return $RC
__pids_pidof "$1" || return $RC
}
status() {
local base pid lock_file= pid_file= binary=
# Test syntax.
if [ "$#" = 0 ] ; then
echo $"Usage: status [-p pidfile] {program}"
return 1
fi
if [ "$1" = "-p" ]; then
pid_file=$2
shift 2
fi
if [ "$1" = "-l" ]; then
lock_file=$2
shift 2
fi
if [ "$1" = "-b" ]; then
if [ -z $pid_file ]; then
echo $"-b option can be used only with -p"
echo $"Usage: status -p pidfile -b binary program"
return 1
fi
binary=$2
shift 2
fi
base=${1##*/}
if [ "$_use_systemctl" = "1" ]; then
systemctl status ${0##*/}.service
ret=$?
# LSB daemons that dies abnormally in systemd looks alive in systemd's eyes due to RemainAfterExit=yes
# lets adjust the reality a little bit
if systemctl show -p ActiveState ${0##*/}.service | grep -q '=active$' && \
systemctl show -p SubState ${0##*/}.service | grep -q '=exited$' ; then
ret=3
fi
return $ret
fi
# First try "pidof"
__pids_var_run "$1" "$pid_file" "$binary"
RC=$?
if [ -z "$pid_file" -a -z "$pid" ]; then
pid="$(__pids_pidof "$1")"
fi
if [ -n "$pid" ]; then
echo $"${base} (pid $pid) is running..."
return 0
fi
case "$RC" in
0)
echo $"${base} (pid $pid) is running..."
return 0
;;
1)
echo $"${base} dead but pid file exists"
return 1
;;
4)
echo $"${base} status unknown due to insufficient privileges."
return 4
;;
esac
if [ -z "${lock_file}" ]; then
lock_file=${base}
fi
# See if /var/lock/subsys/${lock_file} exists
if [ -f /var/lock/subsys/${lock_file} ]; then
echo $"${base} dead but subsys locked"
return 2
fi
echo $"${base} is stopped"
return 3
}
echo_success() {
[ "$BOOTUP" = "color" ] && $MOVE_TO_COL
echo -n "["
[ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS
echo -n $" OK "
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
echo -n "]"
echo -ne "\r"
return 0
}
echo_failure() {
[ "$BOOTUP" = "color" ] && $MOVE_TO_COL
echo -n "["
[ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
echo -n $"FAILED"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
echo -n "]"
echo -ne "\r"
return 1
}
echo_passed() {
[ "$BOOTUP" = "color" ] && $MOVE_TO_COL
echo -n "["
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo -n $"PASSED"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
echo -n "]"
echo -ne "\r"
return 1
}
echo_warning() {
[ "$BOOTUP" = "color" ] && $MOVE_TO_COL
echo -n "["
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo -n $"WARNING"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
echo -n "]"
echo -ne "\r"
return 1
}
# Inform the graphical boot of our current state
update_boot_stage() {
if [ -x /bin/plymouth ]; then
/bin/plymouth --update="$1"
fi
return 0
}
# Log that something succeeded
success() {
[ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_success
return 0
}
# Log that something failed
failure() {
local rc=$?
[ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_failure
[ -x /bin/plymouth ] && /bin/plymouth --details
return $rc
}
# Log that something passed, but may have had errors. Useful for fsck
passed() {
local rc=$?
[ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_passed
return $rc
}
# Log a warning
warning() {
local rc=$?
[ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && echo_warning
return $rc
}
# Run some action. Log its output.
action() {
local STRING rc
STRING=$1
echo -n "$STRING "
shift
"$@" && success $"$STRING" || failure $"$STRING"
rc=$?
echo
return $rc
}
# returns OK if $1 contains $2
strstr() {
[ "${1#*$2*}" = "$1" ] && return 1
return 0
}
# Check whether file $1 is a backup or rpm-generated file and should be ignored
is_ignored_file() {
case "$1" in
*~ | *.bak | *.old | *.orig | *.rpmnew | *.rpmorig | *.rpmsave)
return 0
;;
esac
return 1
}
# Convert the value ${1} of time unit ${2}-seconds into seconds:
convert2sec() {
local retval=""
case "${2}" in
deci) retval=$(awk "BEGIN {printf \"%.1f\", ${1} / 10}") ;;
centi) retval=$(awk "BEGIN {printf \"%.2f\", ${1} / 100}") ;;
mili) retval=$(awk "BEGIN {printf \"%.3f\", ${1} / 1000}") ;;
micro) retval=$(awk "BEGIN {printf \"%.6f\", ${1} / 1000000}") ;;
nano) retval=$(awk "BEGIN {printf \"%.9f\", ${1} / 1000000000}") ;;
piko) retval=$(awk "BEGIN {printf \"%.12f\", ${1} / 1000000000000}") ;;
esac
echo "${retval}"
}
# Evaluate shvar-style booleans
is_true() {
case "$1" in
[tT] | [yY] | [yY][eE][sS] | [oO][nN] | [tT][rR][uU][eE] | 1)
return 0
;;
esac
return 1
}
# Evaluate shvar-style booleans
is_false() {
case "$1" in
[fF] | [nN] | [nN][oO] | [oO][fF][fF] | [fF][aA][lL][sS][eE] | 0)
return 0
;;
esac
return 1
}
# Apply sysctl settings, including files in /etc/sysctl.d
apply_sysctl() {
if [ -x /lib/systemd/systemd-sysctl ]; then
/lib/systemd/systemd-sysctl
else
for file in /usr/lib/sysctl.d/*.conf ; do
is_ignored_file "$file" && continue
[ -f /run/sysctl.d/${file##*/} ] && continue
[ -f /etc/sysctl.d/${file##*/} ] && continue
test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
done
for file in /run/sysctl.d/*.conf ; do
is_ignored_file "$file" && continue
[ -f /etc/sysctl.d/${file##*/} ] && continue
test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
done
for file in /etc/sysctl.d/*.conf ; do
is_ignored_file "$file" && continue
test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
done
sysctl -e -p /etc/sysctl.conf >/dev/null 2>&1
fi
}
# A sed expression to filter out the files that is_ignored_file recognizes
__sed_discard_ignored_files='/\(~\|\.bak\|\.old\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'
if [ "$_use_systemctl" = "1" ]; then
if [ "x$1" = xstart -o \
"x$1" = xstop -o \
"x$1" = xrestart -o \
"x$1" = xreload -o \
"x$1" = xtry-restart -o \
"x$1" = xforce-reload -o \
"x$1" = xcondrestart ] ; then
systemctl_redirect $0 $1
exit $?
fi
fi
strstr "$(cat /proc/cmdline)" "rc.debug" && set -x
return 0
[root@localhost init.d]#
[root@localhost init.d]# cd /usr/src/openssh-9.6p1/contrib/redhat/
[root@localhost redhat]# ./sshd.init
Usage: ./sshd.init {start|stop|restart|reload|condrestart|status}
[root@localhost redhat]#
[root@localhost redhat]# ./sshd.init start # 启动服务
/sbin/restorecon: lstat(/etc/ssh/ssh_host_dsa_key.pub) failed: No such file or directory
Starting sshd: [ OK ]
[root@localhost redhat]#
[root@localhost redhat]# ss -antl # 查看端口
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 4096 *:23 *:*
[root@localhost redhat]# ./sshd.init stop # 停止服务
Stopping sshd: [ OK ]
[root@localhost redhat]#
[root@localhost redhat]# systemctl daemon-reload # 重新加载守护进程
[root@localhost redhat]#
[root@localhost redhat]# systemctl restart sshd # 重启服务
[root@localhost redhat]#
[root@localhost redhat]# systemctl status sshd # 查看状态
● sshd.service - SYSV: OpenSSH server daemon
Loaded: loaded (/etc/rc.d/init.d/sshd; generated)
Active: active (running) since Fri 2024-01-12 10:27:52 CST; 6s ago
Docs: man:systemd-sysv-generator(8)
Process: 53300 ExecStart=/etc/rc.d/init.d/sshd start (code=exited, status=0/SUCCESS)
Main PID: 53310 (sshd)
...