SSH 学习笔记

教程
总结

密钥

  • 密钥是通过加密算法得到的一长串字符
  • 对称加密只需要一个密钥 ( key )
  • 非对称加密需要两个密钥:公钥 ( public key ) 和私钥 ( private key )
  • 公钥和私钥一一对应,一台机器用公钥来加密信息,另一台机器用私钥来解密信息。
  • 公钥的 HASH 值被称作公钥指纹。公钥指纹的长度比公钥短,方便用肉眼进行辨认。

加密通信

明文通信缺点:

  • 窃听风险(eavesdropping):第三方可以获知通信内容。
  • 篡改风险(tampering):第三方可以修改通信内容。
  • 冒充风险(pretending):第三方可以冒充他人身份参与通信。

加密通信解决问题:

  • 防止窃听:客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
  • 防止篡改:服务器通过 HASH 函数将通信内容生成摘要,然后使用私钥对摘要加密生成数字签名,客户端使用公钥解密数字签名得到摘要,对比摘要确定内容是否被篡改。
  • 冒充风险:第三方提供数字证书,将服务器的公钥放在数字证书中。服务器将内容和数字证书一起发送给客户端,客户端从数字证书中得到服务器的公钥。

SSH 基本知识

  • SSH 是一种网络协议,通过非对称加密远程计算机之间的通信,并且支持身份验证。
  • OpenSSH 是 SSH 协议的一种实现,它分为客户端软件 ssh 和服务端软件 sshd。
  • OpenSSH 还提供一些辅助工具软件 (比如 ssh-keygen 、ssh-agent),以及一些专门的客户端工具 (比如 scp 和 sftp)。

客户端

安装

一般 Linux 系统和 MacOS 系统自带客户端 ssh 软件,如果没有需要安装。

yum -y install openssh-clients

命令

# 生成客户端公钥和私钥
ssh-keygen
# -F 参数检查某个服务端的公钥指纹是否在 known_hosts 文件里面
ssh-keygen -F 192.168.100.103
# -R 参数将指定服务端的公钥指纹移出 known_hosts 文件
ssh-keygen -R 192.168.100.103
# 将客户端公钥上传到服务端
ssh-copy-id [email protected]
# 连接服务端
ssh [email protected]

文件

客户端 ~/.ssh/ 目录下:

  • config:客户端配置文件
  • id_rsa:客户端私钥,最好修改权限 chmod 600 ~/.ssh/id_rsa
  • id_rsa.pub:客户端公钥,最好修改权限 chmod 600 ~/.ssh/id_rsa.pub
  • know_hosts:服务端公钥指纹

修改 ~/.ssh/config 配置文件

Host *
     Port 2222

# Host 后面自定义别名用来代替域名或IP地址
Host zeronic
     # 域名或IP地址
     HostName 192.168.100.103
     User root
     Port 22
ssh zeronic
# 相当于
ssh -p 22 [email protected]

服务端

安装

# 安装 sshd 软件
yum -y install openssh-server
# 启动 sshd 服务
systemctl start sshd.service
# 开机启动 sshd 服务
systemctl enable sshd.service

命令

# 在后台启动 sshd 服务
sshd
# 检查配置文件格式是否正确
sshd -t

文件

服务器 /root/.ssh/ 目录下:

  • authorized_keys:客户端公钥,最好修改权限 chmod 644 ~/.ssh/authorized_keys。注意,ssh-copy-id 是直接将公钥添加到 authorized_keys 文件的末尾。如果 authorized_keys 文件的末尾不是一个换行符,会导致新的公钥添加到前一个公钥的末尾,两个公钥连在一起,使得它们都无法生效。所以,如果 authorized_keys 文件已经存在,使用 ssh-copy-id 命令之前,务必保证 authorized_keys文件的末尾是换行符(假设该文件已经存在)。

服务器 /etc/ssh/ 目录下:

  • /etc/ssh/sshd_config:服务端配置文件
  • /etc/ssh/ssh_host_ecdsa_key:ECDSA 私钥
  • /etc/ssh/ssh_host_ecdsa_key.pub:ECDSA 公钥
  • /etc/ssh/ssh_host_key:用于 SSH 1 协议版本的 RSA 私钥
  • /etc/ssh/ssh_host_key.pub:用于 SSH 1 协议版本的 RSA 公钥
  • /etc/ssh/ssh_host_rsa_key:用于 SSH 2 协议版本的 RSA 私钥
  • /etc/ssh/ssh_host_rsa_key.pub:用于 SSH 2 协议版本的 RSA 公钥
  • /etc/pam.d/sshd:PAM 配置文件

修改 /etc/ssh/sshd_config 配置文件,修改之后需要重新启动 sshd 服务。

# 指定 sshd 监听端口,默认值为 22
Port 22
# 指定是否允许密码登录,默认值为 yes,建议改成 no,禁止密码登录,只允许密钥登录
PasswordAuthentication yes
# 指定是否允许公钥登录,默认值为 yes
PubkeyAuthentication yes
# 设置一个以秒记的时长,默认值 180,如果超过这么长时间没有收到客户端的任何数据,sshd(8) 将通过安全通道向客户端发送一个"alive"消息,并等候应答
ClientAliveInterval 180
# 在未收到任何客户端回应前最多允许发送多少个"alive"消息,默认值是 3
ClientAliveCountMax 3
# ClientAliveInterval 乘以 ClientAliveCountMax 即为ssh等待的秒数
# 经过测试发现把ClientAliveCountMax值调大了才管用

SSH 密码登录

正常情况下,通过 ssh 登录服务器的时候,需要输入服务器用户的密码。

每个客户端都会在本机的 ~/.ssh/known_hosts 文件中保存所有连接过的服务器的公钥指纹。

密码登录流程:

  1. 客户端输入 ssh user@hostname 发起登录请求。

  2. 服务端接收到请求,返回给客户端公钥以及公钥指纹

  3. 客户端在本机的 ~/.ssh/known_hosts 文件中查找是否有对应服务端公钥指纹。

    3.1 如果没有找到公钥指纹(第一次连接),就会在命令行提示不认识这台服务器。

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

    输入 yes,就可以将当前服务器的公钥指纹储存在本机 ~/.ssh/known_hosts 文件中,并显示下面的提示。以后再连接的时候,就不会再出现警告了。

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

    3.2 如果找到了公钥指纹,但是与服务端发送的公钥指纹不匹配(如果服务器重新安装了 sshd,就会在服务端生成新的公钥私钥对),就会中断连接,并且发出警告。

    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
    ...
    

    3.3 如果公钥指纹与服务端发送的相匹配,则不会提示信息,输入密码即可登录。

  4. 客户端用公钥对登录密码进行加密,然后将密文发送给服务端。

  5. 服务端使用私钥对密文进行解密,确认登录密码是否正确。

  6. 服务端将登录结果返回给客户端。

SSH 公钥登录

公钥登录又称作免密登录,登录的时候不需要输入服务器用户的密码。

公钥登录流程:

  1. 客户端通过 ssh-keygen 命令生成一对公钥和私钥,保存在客户端 ~/.ssh/ 目录中。
# 程序会询问一系列问题,然后生成公钥和私钥,通常情况下直接按回车使用默认值就可以
ssh-keygen
# 可以使用 -t 参数,指定密钥的加密算法,默认使用 RSA 算法
ssh-keygen -t rsa
  1. 客户端通过 ssh-copy-id 命令将公钥上传到服务端,保存在服务端的 ~/.ssh/authorized_keys 文件,如果不存在则创建该文件。
ssh-copy-id [email protected]
# 可以通过 -i 参数指定公钥位置,不指定则使用默认值
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
  1. 客户端通过 ssh user@hostname 命令发起登录请求。

  2. 服务端接收到请求,生成随机数 R,并使用这个客户端的公钥对 R 加密,把密文返回给客户端。

  3. 客户端收到密文,使用私钥对密文解密得到 R。然后使用 MD5 对 R 和 SessionKey 加密生成摘要 A1,并把摘要 A1 发送给服务端。

  4. 服务端同样使用 MD5 对 R 和 SessionKey 加密生成摘要 A2,然后对比 A1 和 A2,完成登录确认。

为了安全性,启用公钥登录之后,最好关闭服务器的密码登录。修改服务端 sshd 的配置文件 /etc/ssh/sshd_config,将 PasswordAuthentication 这一项设为 no

其他命令

scp

scp 是 SSH 提供的一个客户端程序,用来在两台主机之间加密传送文件(即复制文件),相当于先使用ssh 命令登录远程主机,然后再执行拷贝操作。

基本语法

scp source destination

客户端发起 ssh 连接后,会提示用户输入密码

本地复制到远程

scp ~/file.txt [email protected]:/mnt/www/
scp -r ~/data [email protected]:/mnt/www/
scp -r ~/data/* [email protected]:/mnt/www/data/

远程主机与文件之间要使用冒号(:)分隔

远程复制到本地

scp [email protected]:/mnt/www/file.txt ~/test/
scp -r [email protected]:/mnt/www/ ~/test/
scp -r [email protected]:/mnt/www/* ~/test/www/

远程复制到远程

scp -r [email protected]:/mnt/data [email protected]:/mnt/

系统将提示你输入两个远程帐户的密码。数据将直接从一个远程主机传输到另一个远程主机。

rsync

虽然 rsync 不是 SSH 工具集的一部分,但因为也涉及到远程操作,所以放在这里一起介绍。它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件(但不支持两台远程计算机之间的同步)。它也可以当作文件复制工具,替代cpmv命令。

基本用法

rsync source destination
# 递归
rsync -r source destination
# 递归且保留文件信息,-a 可以代替  -r
rsync -a source destination
# 将删除只存在于目标目录、不存在于源目录的文件
rsync -a --delete source destination

默认情况下,rsync 只确保源目录的所有内容(明确排除的文件除外)都复制到目标目录。它不会使两个目录保持相同,并且不会删除文件。如果要使得目标目录成为源目录的镜像副本,则必须使用 --delete 参数,这将删除只存在于目标目录、不存在于源目录的文件。

本地同步

# 将 file.txt 文件复制到 /data 目录里
rsync file.txt /data
# 将 /image 目录复制到 /data 目录里,形成 /data/image 目录
rsync -a /image /data
# 将 /image 目录下的内容复制到 /data 目录里
rsync -a /image/ /data

远程同步

# 将本地同步到远程
rsync -a /image [email protected]:/data
# 将远程同步到本地
rsync -a [email protected]:/data /image

rsync 默认使用 SSH 进行远程登录和数据传输。

sftp

sftp 是 SSH 提供的一个客户端应用程序,主要用来安全地访问 FTP。因为 FTP 是不加密协议,很不安全,sftp就相当于将 FTP 放入了 SSH。

基本命令

sftp username@hostname

执行上面的命令,会要求输入 FTP 的密码。密码验证成功以后,就会出现 FTP 的提示符 sftp>,下面是一个例子。

$ sftp [email protected]
[email protected]'s password:
Connected to penguin.example.com.
sftp>

FTP 的提示符下面,就可以输入各种 FTP 命令了,这部分完全跟传统的 FTP 用法完全一样。

你可能感兴趣的:(SSH 学习笔记)