2MUCH

SSH学习

2023-05-28


概念知识

参考: https://codecharms.me/posts/security-ssh

SSH

SSH (Secure Shell)是一种连接加密机制,能够保证我们在传送数据时,会先进行加密,并且只有通过认证的才能解密。使用的是公钥加密技术

属于client-server模型,要建立一个ssh连接的条件:

  1. 远端服务器要跑一个SSH daemon,默认监听端口22的连接
  2. 本地要用一个SSH client程序,使用SSH protocol来传送数据

SSH使用形式:

SSH具体使用公钥加密的运行机制:

公钥(用于认证和让别人加密)和私钥(用于电子签名和解密)。举个例子:A要使用SSH传数据给B,此时他们都拥有了对方的公钥。过程包含5个步骤:

  1. A用自己的私钥给信息签名
  2. A用B的公钥给信息加密
  3. 信息传送给B
  4. B用自己的私钥解密
  5. B用A的公钥来确认签名来自A

其实SSH登陆有这三种方式:

OpenSSH

OpenSSH 是一個 SSH 協定的開源實作,也可以說是遵守 SSH 的一組工具。sshd 是 OpenSSH 的 server component,當出現一個連線請求,sshd 會根據 client 來建立對應的連線

主要包括几个部分:ssh(客户端)、sshd(主程序)、scp、sftp、ssh-keygen、ssh-agent、ssh-add等

SSL/TLS

HTTPS的核心技术(SSL/TLS):握手,以及使用CA进行身份认证。与SSH作用有些相似,都是为了保证安全连接。但前者主要用户资料传输,后者用于执行指令。

一个实例

来自 https://codecharms.me/posts/security-ssh 的关于github的一个ssh例子:

每當我們要送訊息(指令)給 GitHub (remote server) 時,我們就可以

  1. 用我們的私鑰加密指令。
  2. 用 Github 的公鑰加密指令。
  3. 傳送指令到 GitHub server。
  4. GitHub server 用它自己的私鑰解密。
  5. GitHub server 用我們的公鑰來驗證我們的身份。

SSH常用命令

登陆

# 没有指定用户名的登陆,默认用当前用户名登陆。第一次连接时,需要确认目标主机的真实性,通常需要输入yes
ssh 域名/ip
# 指定用户名登陆
ssh username@host
# 指定特定端口登陆(默认22端口)
ssh xxx -p 1234
# 用户名和主机名不用写一起
ssh -l username host

远程执行命令

# 如果只是想执行一条命令,直接在后面跟上命令即可
ssh xxx ls -l

服务器指纹

当ssh首次连接某个远程服务器时,会有这个确认提示:

The authenticity of host 'xxx' can't be established.
ECDSA key fingerprint is SHA256:Vybt22mVXuNuB5unE++yowF7lgA/9/2bLSiO3qmYWBY.
Are you sure you want to continue connecting (yes/no)?

# 输入yes后

Warning: Permanently added 'foo.com (192.168.121.111)' (RSA) to the list of known hosts

这里的sha256就是所谓的服务器指纹,也就是该远程服务器的公钥的哈希值。

这是因为首次连接时,对于本机来说远程服务器是陌生的,所以需要额外确认下服务器指纹。输入yes,就会将该指纹写入本机的~/.ssh/known_hosts中。每次连接时,服务器会判断欲连接的远程主机是否已在此known_hosts文件中,如果在,就不弹出确认提示。

此外,查看公钥的指纹命令:

$ ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub
256 da:24:43:0b:2e:c1:3f:a1:84:13:92:01:52:b4:84:ff   (ECDSA)

当远程服务器变更了公钥(比如重装SSH;或是通过虚拟地址可连接主备机中的主机,当主备切换时,连接实际主机的公钥信息也不同),此时需要会有这样的警告:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    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 the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
77:a5:69:81:9b:eb:40:76:7b:13:04:a9:6c:f4:9c:5d.
Please contact your system administrator.
Add correct host key in /home/me/.ssh/known_hosts to get rid of this message.
Offending key in /home/me/.ssh/known_hosts:36

在确认新的公钥可信任的情况下,可将原先的公钥指纹从~/.ssh/known_hosts中删掉,或直接vi进入文件删除对应行: ssh-keygen -R hostname

此后,再次尝试连接,并将新的公钥指纹添加进来即可。

参考:https://ronpad.com/docs/ssh/client-3.html

配置文件

sshd配置文件(服务端配置文件)

路径:/etc/ssh/sshd_config

格式:

修改完配置文件后:

# 可以用此命令检查语法错误(-t:test)
sshd -t
# 需要重启sshd才能生效
sudo systemctl restart sshd.service 

配置项

sshd配置文件中支持很多配置项,这里就先了解一些我认为常用的吧!

  1. AllowGroups 允许登陆的用户组
  2. AllowUsers 允许登陆的用户(也可用user@address的形式),用空格或多行指定(如果不指定,默认所有用户可登陆)
  3. AllowTCPForwarding 是否允许端口转发,默认yes。local表示只允许本地转发,remote表示只允许远程端口转发
  4. ClientAliveInterval 允许客户不输入的间隔时间,超过这段时间,用户没发任何信号的话会自动关闭SSH连接
  5. DenyGroups 指定不允许登陆的用户组
  6. DenyUsers 指定不允许登陆的用户
  7. PermitRootLogin 是否允许root用户登陆,默认yes,建议改为no
  8. Port 指定sshd监听的端口(默认22),可以通过配置多行来同时监听多个端口
  9. PubKeyAuthentication 是否允许公钥登陆,默认yes
  10. X11Forwarding 指定是否打开X window的转发,默认no

参考:https://ronpad.com/docs/ssh/server-2.html

ssh配置文件(客户端配置文件)

路径:/etc/ssh/ssh_config,用户个人的配置文件在~/.ssh/config,优先级高于全局的

个人连接配置文件设置

可以在~/.ssh/config中设置连接各个远程主机的默认连接参数,例如:

Host *
     Port 2222

Host remoteserver
     HostName remote.example.com
     User neo
     Port 2112

上面代码中,Host *表示对所有主机生效,后面的Port 2222表示所有主机的默认连接端口都是2222,这样就不用在登录时特别指定端口了。这里的缩进并不是必需的,只是为了视觉上,易于识别针对不同主机的设置。

配置项

同理,就先列举出一些我认为常用的吧!

端口转发

SSH除了作为登陆远程服务器的作用,还可以作为加密通信的中介。比如在两台无加密的服务器之间的充当加密通信的跳板。这个功能称为端口转发(port forwarding),也称为SSH 隧道(tunnel)。

StrictHostKeyChecking

用于ssh连接时指定是否要进行远程主机的公钥确认,可以有这三种取值:

该参数的配置在:

参考:https://www.cnblogs.com/aspirant/p/10654041.html