文字接口连接服务器:SSH服务器

在早期,远程连接服务器时常使用明文传输数据,这会存在安全问题。为了解决这些问题,SSH协议应运而生,逐渐取代了不安全的应用。SSH是secure Shell Protocol的简称,是一种基于安全加密协议的远程登录协议。它可以通过数据包加密技术将等待传输的数据包加密后再传输到网络上,因此,数据信息就比较安全。

在默认状态下,SSH协议本身就提供两个服务器功能

  • 一个是类似Telnet的远程连接使用 Shell 的服务器,即俗称的SSH
  • 另一个就是类似FTP服务的 Sftp-Server,提供更安全的FTP服务

连接加密技术简介

什么是"数据加密"呢?简单来说,数据加密是一种通过一些计算方法将原始电子数据变成乱码的过程,然后将加密后的数据传输到网络上。当用户需要查看这些数据时,再通过解密运算将这些加密数据转换回原始电子数据。由于加密后的数据已经被重新处理过,因此即使被黑客监听窃取,也很难对加密数据进行解密,从而获取原始数据内容。

目前常见的网络数据包加密技术通常采用非对称密钥系统进行处理。这种系统需要两把不同的钥匙,一把是公钥,一把是私钥,用于加密和解密数据。在同一个连接中,这两把钥匙需要成对出现,并且有各自的作用。

  • 公钥(Public Key)提供给远程主机进行数据加密行为,也就是说,大家都能取得你的公钥来讲数据加密的意思
  • 私钥(Private Key)远程主机使用你的公钥加密的数据,在本地端就能够使用私钥来进行解密。由于私钥很重要,因此私钥是不能够外流的,只能保护在自己的主机上。

每台主机都应该有自己的公钥和私钥,其中私钥必须保密不被泄露。在网络连接中,通信双方都需要对方的公钥,以便进行加密和解密操作。以SSH协议为例,客户端和服务器之间的连接是双向的,因此在加密过程中应该如下图所示进行

image-20240401153839794

如上图所示,如果我们站在客户端(Client)的角度来看,连接服务器的过程通常需要以下步骤:

  1. 客户端需要从服务器端获取公钥,以便将数据加密后发送给服务器。

  2. 客户端需要将自己的公钥发送给服务器,以便服务器能够使用客户端的公钥来加密发送给客户端的数据。

  3. 在客户端与服务器之间建立连接后,客户端会使用服务器的公钥和自己的私钥来进行加密和解密操作。客户端使用服务器的公钥对数据进行加密,然后使用自己的私钥对服务器发送的加密数据进行解密。

客户端的密钥是由服务器的公钥和客户端自己的私钥组成的,这样可以确保数据在传输过程中得到保护,同时保护了私钥的机密性,防止被黑客窃取。

那么这些公钥与私钥是如何产生的呢?如下图

image-20230614172356011

  1. 服务器建立公钥文件:每一次启动SSHD服务时,改服务会主动去找/etc/ssh/ssh_host*文件,若系统刚刚安装完成,由于没有这些公钥文件,因此SSHD会主动去计算出这些需要的公钥文件,同时也会计算出服务器自己需要的私钥文件

  2. 客户端主动连接要求:如果客户端想要连接到SSH服务器,需要使用适当的客户端程序进行连接。

  3. 服务器传送公钥文件给客户端:当客户端发送连接请求后,服务器会将第一步骤中生成的公钥文件传送给客户端。这个传送过程应该是明文传送的,因为公钥是可以公开使用的。

  4. 客户端记录/比对服务器的公钥数据及随机计算自己的公私钥:当客户端第一次连接服务器时,客户端会将服务器的公钥数据记录到客户端的用户主目录下的.ssh/known_hosts文件中。这个文件用于保存客户端已经连接过的服务器的公钥数据。如果客户端再次连接之前已经记录过该服务器的公钥数据,客户端会比对接收到的公钥数据与之前记录的数据是否相同。如果相同,客户端会接受该公钥数据,并开始计算客户端自己的公私钥数据。

  5. 返回客户端的公钥数据到服务器端:用户将自己的公钥传送给服务器。此时服务器具有服务器的私钥与客户端的公钥,而客户端则具有服务器的公钥以及客户端自己的私钥,你会看到,在此次连接的服务器与客户端的密钥系统(公钥+私钥)并不一样,所以才称为非对称式密钥系统

  6. 服务器接受私钥开始双向加解密

    (1)当服务器向客户端传输数据时:服务器会先使用客户端的公钥来对数据进行加密,然后再将加密后的数据发送给客户端。客户端收到数据后,会使用自己的私钥对数据进行解密,从而获取原始数据。(2)当客户端向服务器传输数据时:客户端会先使用服务器的公钥来对数据进行加密,然后将加密后的数据发送给服务器。服务器收到数据后,会使用自己的私钥对数据进行解密,从而获取原始数据。

例题

如何产生新的服务器端的SSH公钥与服务器自己使用的成对私钥?

[root@localhost ~]# rm -rf /etc/ssh/ssh_host_*
[root@localhost ~]# systemctl restart sshd
[root@localhost ~]# date; ll /etc/ssh/ssh_host*
2023年 06月 14日 星期三 17:51:23 CST
-rw-r-----. 1 root ssh_keys  227 614 17:51 /etc/ssh/ssh_host_ecdsa_key
-rw-r--r--. 1 root root      162 614 17:51 /etc/ssh/ssh_host_ecdsa_key.pub
-rw-r-----. 1 root ssh_keys  387 614 17:51 /etc/ssh/ssh_host_ed25519_key
-rw-r--r--. 1 root root       82 614 17:51 /etc/ssh/ssh_host_ed25519_key.pub
-rw-r-----. 1 root ssh_keys 1679 614 17:51 /etc/ssh/ssh_host_rsa_key
-rw-r--r--. 1 root root      382 614 17:51 /etc/ssh/ssh_host_rsa_key.pub
# 可以看到日期与文件的建立时间,刚刚建立的新的公钥、私钥系统。

启动SSH服务

事实上,我们使用Linux系统当中,默认就已经含有SSH所有需要的软件了,包含了可以产生密钥等协议的OpenSSL软件与OpenSSH软件,所以,要启动SSH非常简单,直接启动就行了。

[root@localhost ~]# systemctl restart sshd
[root@localhost ~]# netstat -tlnp | grep ssh
tcp        0      0 0.0.0.0:22       0.0.0.0:*         LISTEN      117093/sshd         
tcp6       0      0 :::22             :::*             LISTEN      117093/sshd   

SSH不仅提供了Shell,还提供了一个安全的FTP服务器(SSH-FTP Server),可以用作FTP的替代品。同时,这两种服务都是使用Port 22来进行通信的。那么怎么样由 Client 端连接上 Server端呢?如何以FTP服务来连接上Server并且使用FTP的功能呢?

SSH客户端连接程序

SSH:直接登录远程主机的指令

ssh [-f] [-o 参数项目] [-p 非标准端口] [账户@]IP [命令]
选项:
-f:需要配合后面的[命令],不登录远程主机直接发送一个命令过去而已
-o 参数项目:主要的参数项目有:
    ConnectTimeout=秒数 :连接等待的秒数,减少等待的时间
    StrictHostKeyChecking=[yes|no|ask]:默认是ask,若要让public key
                                       主动加入known_hosts,则可以设置为no即可
-p:如果ssh的服务启动在非标准的端口,需使用此项目
[命令]:不登录远程主机,直接发送命令过去
使用案例

直接连接到对方主机的方法(以登录本机为例)

[root@localhost ~]# ssh 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:RqzrG8xNGKffq5qmbutMp5lamqimrEb6P/W7pTdMa4M.
ECDSA key fingerprint is MD5:ac:18:e4:fe:0c:2b:27:4b:ff:35:8c:ce:56:b7:f0:5e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
root@127.0.0.1's password:    # 这里输入目标主机密码,这里是登录的是本机所以输入root密码即可
Last login: Wed Jun 14 23:01:58 2023 from 192.168.200.1
[root@localhost ~]# exit    # 离开这次的SSH连接
# 由于SSH后面没有加上账号,因此默认使用当前的账号来登录远程服务器

一般来说,SSH登录远程主机需要输入"SSH账号主机IP"的格式,其中账号是指登录远程主机所使用的用户名,主机IP是指远程主机的IP地址。但是,有些人并不喜欢输入账号,这时可以直接输入"SSH主机IP"的格式进行登录。需要注意的是,如果不输入账号,则会默认使用本地计算机的账号来尝试登录远程主机,如果本地和远程主机拥有相同的账号,则可以直接使用"SSH主机IP"的格式登录,不需要输入账号。建议形成良好的习惯,一开始就使用账号@IP的方式来登录远程主机,这样的行为习惯比较好。

注意到上面提示你输入YES来讲该指纹码写入服务器公钥记录文件(~/.ssh/known_hosts),以便对比该服务器的正确性。注意要写YES,单纯输入Y或y是不会被接收的。此外,由于该主机的公钥已记录,因此未来重复使用SSH登录此主机时,就不会出现这个指纹码提示了

使用csq账号登录本机

[root@localhost ~]# ssh csq@127.0.0.1
csq@127.0.0.1's password: 
Last login: Wed Jun 14 23:34:14 2023 from localhost
[csq@localhost ~]$ exit
# 由于有csq这个账号,因此切换身份成为了csq。因为127.0.0.1曾登录过
# 所以就不会再出现提示要添加主机公钥的信息了

登录csq的主机,执行命令后立刻离开的方式

[root@localhost ~]# ssh  csq@127.0.0.1 find / > ~/find1.log 2>&1
csq@127.0.0.1's password:
# 此时你会发现画面会卡顿,着是因为上面的命令造成的,你已经登录远程主机,但是执行的命令
# 尚未运行完,因此会再等待当中,那如何指定系统自己运行呢?

与上题相同,让对方主机自己运行该命令,你立刻回到本地端主机继续工作

[root@localhost ~]# ssh   -f csq@127.0.0.1 find / > ~/find1.log 2>&1
# 此时你会立刻注销 127.0.0.1 但 find 命令会自己在远程服务器运行
# 如果你想要让远程主机执行关机命令,加上-f参数 ssh -f root@IP shutdown -h now 

删除 known_hosts 后,重新使用 root 连接到本机,且自动加上公钥记录

[root@localhost ~]# rm -rf ~/.ssh/known_hosts
[root@localhost ~]# ssh -o StrictHostKeyChecking=no root@192.168.200.30
Warning: Permanently added '192.168.200.30' (ECDSA) to the list of known hosts.
root@192.168.200.30's password: 
# 如上所示,不会问你 YES或No了,直接写入到 ~/.ssh/known_hosts 中

服务器公钥记录文件:~/.ssh/known_hosts

当你登录远程服务器时,本机会主动利用接收到的服务器的公钥去比对~/.ssh/known_hosts有无相关的公钥,然后进行下面的操作:

  • 若接收的公钥未记录,本机会主动询问用户是否记录。若要记录(回答YES)则写入~/.ssh/known_hosts且执行后续工作:若不记录(回答No)则不写入该文件,并且退出登录工作
  • 若接收到的公钥已有记录,则比对记录是否相同,若相同则继续登录动作:若不相同,则出现警告信息,离开登录的动作。这是客户端的自我保护功能,以避免你的服务器被别人伪装。
报错解决

例题

测试服务器重新安装后,假设服务器使用相同的IP,造成相同IP的服务器公钥不同,产生的问题怎么解决?

利用前一小节讲过的方式,删除原有的系统公钥,重新启动SSH让你的公钥更新

[root@localhost ~]# rm -rf /etc/ssh/ssh_host_*
[root@localhost ~]# systemctl restart sshd

然后重新使用下面的方式来进行连接的操作

[root@localhost ~]# ssh root@192.168.200.20
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:htL+PjqB+l2KTbeVoP2gCewZeuhKiJWvcXRc9A9a35U.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /root/.ssh/known_hosts:1  # 冒号后面接的数字就算有问题的数据行号
ECDSA host key for 192.168.200.20 has changed and you have requested strict checking.
Host key verification failed.

解决方法很简单,可以使用 vim 到 /root/.ssh/known_hosts,并将1行删除,之后重试SSH,那系统就会重新询问你要不要加上公钥。

模拟FTP的文件传输方式:SFTP

SSH是登录远程服务器进行工作,如果你只是想上传或下载文件,SSH并不是最好的选择。相反,你可以使用SFTP或SCP来实现这个目的。这两个命令也是通过SSH通道(端口22)进行通信,但是它们模拟FTP和复制操作。SFTP和SSH的使用方法非常相似,只是SSH用于登录,而SFTP用于上传和下载文件。

[root@localhost ~]# sftp csq@localhost
csq@localhost's password:    # 输入csq用户的密码
Connected to localhost.      # 已经连接到了localhost
sftp> exit                   # 这里就是在等待你的输入FTP相关命令的地方

SFTP 这个接口可使用的指令

针对远程服务器主机(Server)的行为

解释命令
列出当前所在目录下的文件名ls
建立目录mkdir 目录名(dir)
删除目录rmdir 目录名
显示当前所在的目录pwd
更改文件或目录的属组chgrp groupname PATH
更改文件或目录的属主chown username PATH
更改文件或目录的权限chmod 644 PATH
建立连接文件ln oldname newname
删除文件或目录rm PATH
更改文件或目录名称rename oldname newname
离开远程主机exit或者bye或者quit

针对本机(Client)的行为(都加上l,L的小写)=

解释命令
切换目录到本机的PATH当中lcd PATH
列出当前本机所在目录下的文件名lls
在本机建立目录lmkdir
显示当前所在的本机目录lpwd

针对资料上传/下载的操作

解释命令
将文件由本机上传到远程主机put [本机目录或文件] [远程]
put [本机目录或文件]
最后这种格式,文件会存储到当前远程主机的目录下
将文件由远程主机下载回来get [远程主机目录或文件] [本机]
get [远程主机目录或文件]
若是最后一种格式,则文件会存储在当前本机所在的目录当中,可以使用通配符例如:get *,get *.txt 等
使用案例

假设192.168.200.20为远程服务器,且服务器上有zhw这个用户,你想要将本机的 /etc/hosts 上传到 zhw用户主目录,并将 zhw 的 .bashrc 复制到本机的 /tmp 下面

[root@localhost ~]# sftp zhw@192.168.200.20
zhw@192.168.200.20's password: 
Connected to 192.168.200.20.
sftp> lls /etc/hosts            # 先看本机有没有这个文件
/etc/hosts
sftp> put /etc/hosts            # 有就上传
Uploading /etc/hosts to /home/zhw/hosts
/etc/hosts                                                                                                                100%  158   163.8KB/s   00:00    
sftp> ls                        # 查看zhw目录下是否有这个文件
hosts  
sftp> ls -a                     # 看看有没有.bashrc文件
.              ..             .bash_logout   .bash_profile  .bashrc        hosts          
sftp> lcd /tmp/                 # 本机切换到/tmp下面
sftp> lpwd                      # 查看是否切换成功
Local working directory: /tmp
sftp> get .bashrc               # 没问题就复制.bashrc文件到本机
Fetching /home/zhw/.bashrc to .bashrc
/home/zhw/.bashrc                                                                                                         100%  231   134.5KB/s   00:00    
sftp> lls -al                   # 看本机是否有这个文件
总用量 4
drwxrwxrwt.  9 root root 221 615 17:09 .
dr-xr-xr-x. 17 root root 224 45 20:11 ..
-rw-r--r--.  1 root root 231 615 17:09 .bashrc
drwxrwxrwt.  2 root root   6 45 20:08 .font-unix
drwxrwxrwt.  2 root root   6 45 20:08 .ICE-unix
drwx------.  3 root root  17 615 16:06 systemd-private-8695af1948284db5b535bc5f312261ad-chronyd.service-aWFeRW
drwxrwxrwt.  2 root root   6 45 20:08 .Test-unix
drwx------.  2 root root   6 615 16:06 vmware-root_794-2991071843
drwxrwxrwt.  2 root root   6 45 20:08 .X11-unix
drwxrwxrwt.  2 root root   6 45 20:08 .XIM-unix
sftp> exit                     # 退出sftp

文件异地直接复制:SCP

通常使用SFTP是因为可能不知道服务器上面已存在的文件名信息,如果已经知道服务器上面的文件名,那么最简单的文件传输是通过 SCP 这个指令。最简单的SCP用法如下

scp [-pr] [-l 速率] file [账号@]主机IP:目录名   # 上传
scp [-pr] [-l 速率] [账号@]主机IP:file 目录名    # 下载
选项:
-p:保留文件原有的权限信息
-r:复制来源为目录时,可以复制整个目录(含子目录)
-l:可以限制传输的速率,单位为 Kbits/s ,例如 [-l 800]代表传输速率 100kbytes/s
使用案例

将本机的 /etc/hosts* 全部复制到 192.168.200.20 上面的 zhw用户主目录内

[root@localhost ~]# scp /etc/hosts* zhw@192.168.200.20:~
zhw@192.168.200.20's password: 
hosts          100%  158   150.6KB/s   00:00    
hosts.allow    100%  370   271.1KB/s   00:00    
hosts.deny     100%  460   405.8KB/s   00:00  
# 文件名       进度   容量   传输速率     剩余时间

将 192.168.200.20 这台远程主机的 /etc/bashrc 复制到本机的 /tmp 下面

[root@localhost ~]# scp 192.168.200.20:/etc/bashrc /tmp
root@192.168.200.20's password: 
bashrc        100% 2853     1.4MB/s   00:00    
[root@localhost ~]# ls /tmp/ |grep bashrc
bashrc

注意别上传和下载重点在于那个冒号(:)记得加上

SSHD服务详细配置

SSHD 服务的配置文件/etc/ssh/sshd_config。这个文件里面保存了 SSHD 服务的详细设置,比如登录时需要的用户名和密码,是否开启公钥认证等等。但是不同的 Linux 发行版可能会有不同的默认设置,所以我们需要了解每个设置的含义,并且注意到这个文件里面没有被注释的设置值都是默认值,你可以根据需要修改它们。

[root@localhost ~]# vim /etc/ssh/sshd_config 

关于SSH Server 的整体设置

  • port 22

SSH 默认使用 22这个Port,也可以使用多个 Port,即重复使用 Port 这个设置项目例如我想要开SSHD 在 22 与 443,则多家一行内容为:Port 443然后重新启动 SSHD就好了,不过不建议修改 Port

  • AddressFamily any

该项配置SSH服务器支持的网络地址类型,包括IPv4、IPv6等,注释掉该行表示支持任何地址类型

  • ListenAddress 0.0.0.0

该项配置SSH服务器监听的IPv6地址,::表示监听所有IPv6地址,注释掉该行表示监听所有IPv6地址

  • PidFile /var/run/sshd.pid

可以放置SSHD这个PID的文件,上述为默认值

  • Compression delayed

指定何时开始使用压缩数据模式进行传输

说明主机的 私钥 放置的文件

  • HostKey /etc/ssh/ssh_host_rsa_key

该项配置SSH服务器使用的RSA密钥文件路径,RSA密钥是SSH协议中非对称加密的一种方式,用于进行公钥认证和数据加密。

  • HostKey /etc/ssh/ssh_host_dsa_key

该项配置SSH服务器使用的DSA密钥文件路径,DSA密钥也是SSH协议中非对称加密的一种方式,但已经被认为不安全,因此通常不再使用。

  • HostKey /etc/ssh/ssh_host_ecdsa_key

该项配置SSH服务器使用的ECDSA密钥文件路径,ECDSA密钥是SSH协议中较新的一种非对称加密方式,具有更高的安全性和效率。

  • HostKey /etc/ssh/ssh_host_ed25519_key

该项配置SSH服务器使用的Ed25519密钥文件路径, Ed25519密钥也是SSH协议中较新的一种非对称加密方式,具有更高的安全性和效率

关于登录文件的信息数据放置

  • SyslogFacility AUTHPRIV

该项配置SSH服务器发送日志的设施和优先级,AUTHPRIV表示使用安全认证设施,即只记录身份验证相关的信息,其他可选值包括DAEMON(系统守护进程)、USER(普通用户进程)等

  • LogLevel INFO

日志的等级

如果忘记日志相关信息可以参考:rsyslog.service:记录日志文件的服务 这篇博客

安全设置项目

登录设置部分
  • LoginGraceTime 2m

当连上SSH Server 之后,会出现输入密码的界面,在该界面中,经过多长时间内没有成功连上 SSH Server 就强迫断开连接。若无单位默认时间为秒

  • PermitRootLogin yes

是否允许root登录。默认是允许的,但出于安全考虑,通常建议禁止root用户通过SSH登录,可以修改该项为no

  • StrictModes yes

是否让sshd 去检查用户主目录或相关文件的权限数据,这是为了担心用户将某些重要文件的权限设置错,可能会导致一些问题所致,例如用户的 ~.ssh/ 权限设错时,某些特殊情况下会不许用户登录

  • PubkeyAuthentication yes

该项配置SSH服务器是否启用公钥认证方式(就是密码验证)。默认情况下,该项为yes,表示启用公钥认证,要求用户在登录前必须先将公钥上传到服务器上。这可以提高SSH连接的安全性,避免密码被盗或猜测的风险

  • MaxSessions 10

该项配置SSH服务器最大的会话数。默认情况下,该项为10,表示同一用户最多可以创建10个会话,超过数量后连接将被自动断开。这可以避免恶意用户滥用服务器资源。

  • MaxAuthTries 6

该项配置SSH服务器最大的认证尝试次数。默认情况下,该项为6,表示用户最多可以尝试6次认证,超过次数后连接将被自动断开。这可以防止恶意攻击者通过暴力破解密码或密钥进行滥用。

  • AuthorizedKeysFile .ssh/authorized_keys

该项配置SSH服务器上存储用户公钥的文件路径。默认情况下,该项为.ssh/authorized_keys,表示用户公钥存储在用户主目录下的.ssh/authorized_keys文件中。

  • PasswordAuthentication yes

表示是否开启密码验证,默认是开启密码验证的

  • PermitEmptyPasswords no

是否允许空的密码登录,默认是不允许

认证部分
  • IgnoreRhosts yes

该项配置SSH服务器是否忽略用户主目录下的.rhosts和.shosts文件。默认情况下,该项为yes,表示SSH服务器不会读取这两个文件。这是为了避免恶意用户通过这两个文件进行滥用SSH连接。

  • IgnoreUserKnownHosts no

该项配置SSH服务器是否忽略用户主目录内的 ~/.ssh/known_hosts 这个文件所记录的主机内容,当人不忽略,默认为no

  • ChallengeResponseAuthentication no

允许任何的密码认证,所以,任何 login.conf 规定的认证方式均可使用,但目前使用PAM模块帮忙管理认证,因此这个选项可以设置为 no

  • UsePAM yes

利用PAM管理用户认证有很多好处,可以记录与管理,建议使用yes ChallengeResponseAuthentication 设置为no

登录后的项目
  • PrintMotd yes

登录后是否显示一些信息呢?例如上次的登录时间、地点默认是yes。也就是打印出/etc/motd这个文件的内容。如果为了安全考虑可以改为 no

  • PrintLastLog yes

显示上次登录的信息。默认yes

  • TCPKeepAlive yes

默认情况下,该项为yes。如果启用TCP KeepAlive功能,SSH服务器会定期向客户端发送TCP保活包,以检测连接状态。如果客户端在一定时间内没有响应,SSH服务器会自动关闭连接,以避免长时间处于半开连接状态,从而浪费网络资源。但如果网络或路由器常常不稳定,那么可以设置为no

  • UsePrivilegeSeparation sandbox

该项配置SSH服务器是否启用特权分离功能,并指定特权分离的方式为sandbox。默认情况下,该项为sandbox,表示启用特权分离功能,并将特权进程隔离在一个沙盒(sandbox)环境中运行。特权分离是一种安全机制,用于将SSH服务器进程分为两个部分:一个非特权进程和一个特权进程(就是root和非root)。非特权进程通常运行在一个受限制的环境中,仅能访问一些受限资源,如文件系统、网络等。特权进程则运行在一个特权环境中,可以访问所有资源,并执行一些敏感操作,如用户认证、密钥管理等。通过使用特权分离,可以避免特权进程被攻击者利用,从而提高SSH服务器的安全性。

  • MaxStartups 10:30:100

该项配置SSH服务器最大连接数的阈值。默认情况下,该项为10:30:100,表示最多允许10个并发连接,并且每分钟最多允许30个连接尝试,如果连接数超过30个,则有50%的概率拒绝连接,如果连接数超过100个,则拒绝所有连接。这个阈值可以根据需要进行调整,以控制SSH服务器的连接负载和安全性。

用户限制的设置项目
  • DenyUsers *

设置被限制的用户的名称,如果是全部的用户,那就全部阻挡,若是部分使用者,可以将该账号填入。

例如:DenyUsers test

  • DenyGroups test

与DenyUsers 相同,阻挡组的。

SFTP服务
  • Subsystem sftp /usr/libexec/openssh/sftp-server

该项配置SSH服务器的SFTP子系统,指定SFTP子系统的可执行文件路径为/usr/libexec/openssh/sftp-server。

制作不用密码可立即登录的SSH用户

SSH 服务可以使用密钥系统来比对数据,并且可以提供用户数据的加密功能。有没有可能利用这个密钥来让用户不需要输入密码就可以登录主机呢?答案是可以的。我们可以把客户端产生的密钥复制到服务器上,这样以后客户端登录服务器时,由于双方在 SSH 连接时已经比对过密钥,所以可以直接进入数据传输接口,而不需要再输入密码。

具体的实现步骤如下

  1. 客户端建立两把钥匙:在密钥系统中,是公钥比较重要还是私钥比较重要?当然是私钥比较重要,因此私钥才是解密的关键啊,所以,这两把钥匙当然得在发起连接的客户端配置才对,利用命令ssh-keygen

  2. 客户端放置好私钥文件:将私钥放在Client 上面的用户主目录中,也就是$HOME/.ssh/,并且要注意权限

  3. 将公钥放置到服务器端的正确目录于文件中:最后,将私钥放在任何一个你想要用来登录的服务器的某User用户主目录的.ssh/里面的认证文件中即可完成整个程序。

image-20230615211004257

客户端建立两把钥匙

建立的方法很简单,在Client中使用ssh-keygen建立两把钥匙即可

ssh-keygen [-t dsa | ecdsa | ed25519 | rsa | rsa1] # 选择密钥类型
[root@localhost ~]# ssh-keygen   # 用默认的方法建立密钥
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):  # 按enter
Created directory '/root/.ssh'.                           # 此目录若不存在则会主动和建立
Enter passphrase (empty for no passphrase):               # 按enter
Enter same passphrase again:                              # 按enter
Your identification has been saved in /root/.ssh/id_rsa.  # 私钥文件
Your public key has been saved in /root/.ssh/id_rsa.pub.  # 公钥文件
The key fingerprint is:
SHA256:QkgzBeCV+HbFx12EyLNBEv+HUqXLK5s10griL1yOnVk root@localhost.localdomain

[root@localhost ~]# ls -ld ~/.ssh/ ; ls -l ~/.ssh/
drwx------. 2 root root 38 615 21:23 /root/.ssh/
-rw-------. 1 root root 1679 615 21:23 id_rsa         # 私钥文件
-rw-r--r--. 1 root root  408 615 21:23 id_rsa.pub     # 公钥文件

当执行ssh-keygen时,才会在我的主目录下的.ssh/目录里面产生需要的两把Keys,分别是私钥(id_rsa)与公钥(id_rsa.pub)。~/.ssh/目录必须是700权限才行。

另外一个需要特别注意的就算那个id_rsa的文件权限,它必须是-rw-------且属于自己才行,否则在未来密钥比对的过程中,可能会被判断为危险而无法成功的以公私钥成对文件的机制来实现连接。默认权限其实是正确的,你检查一下即可。

将公钥文件数据上传到服务器上

有两种上传方法

  • 使用scp上传
  • 使用ssh-copy-id上传

第一种方法:

1. 上传至192.168.200.20的root主目录下面
[root@client ~]# scp .ssh/id_rsa.pub root@192.168.200.20:~
2. 创建~/.ssh文件,权限700
[root@server ~]# ls
anaconda-ks.cfg  id_rsa.pub
[root@server ~]# ls -ld .ssh
ls: 无法访问.ssh: 没有那个文件或目录
[root@server ~]# mkdir .ssh;chmod 700 .ssh
[root@server ~]# ls -ld .ssh/
drwx------. 2 root root 6 615 22:13 .ssh/
3. 将公钥文件内的数据使用cat 转存到authorized_keys内
[root@server ~]# ls -l *pub
-rw-r--r--. 1 root root 408 615 22:09 id_rsa.pub
[root@server ~]# cat id_rsa.pub >> .ssh/authorized_keys
[root@server ~]# chmod 644 .ssh/authorized_keys 
[root@server ~]# ls -l .ssh/
-rw-r--r--. 1 root root 408 615 22:15 authorized_keys
4. 测试
[root@client ~]# ssh root@192.168.200.20
Last login: Thu Jun 15 22:08:59 2023 from 192.168.200.10
[root@server ~]# exit
# 这种方法很复杂

第二种方法:

[root@client ~]# ssh-copy-id root@192.168.200.20
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.200.20 (192.168.200.20)' can't be established.
ECDSA key fingerprint is SHA256:x0zykxgczs8wCrJNmANfJQoD2BXKlvkvXu5S6L2jKkE.
ECDSA key fingerprint is MD5:39:44:23:20:cf:e8:ad:01:a4:91:df:d8:c9:69:7e:48.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.200.20's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.200.20'"
and check to make sure that only the key(s) you wanted were added.

[root@client ~]# ssh root@192.168.200.20
Last login: Thu Jun 15 22:15:58 2023 from 192.168.200.10
[root@server ~]# exit
# 推荐使用这种方法很迅速就配置完成了

两种方法选择一种即可,以后登录到 192.168.200.20就不需要密码了

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐