密钥
- 密钥是通过加密算法得到的一长串字符
- 对称加密只需要一个密钥 ( 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 root@192.168.100.103
# 连接服务端
ssh root@192.168.100.103
文件
客户端 ~/.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 root@192.168.100.103
服务端
安装
# 安装 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
文件中保存所有连接过的服务器的公钥指纹。
密码登录流程:
-
客户端输入
ssh user@hostname
发起登录请求。 -
服务端接收到请求,返回给客户端公钥以及公钥指纹。
-
客户端在本机的
~/.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 如果公钥指纹与服务端发送的相匹配,则不会提示信息,输入密码即可登录。
-
客户端用公钥对登录密码进行加密,然后将密文发送给服务端。
-
服务端使用私钥对密文进行解密,确认登录密码是否正确。
-
服务端将登录结果返回给客户端。
SSH 公钥登录
公钥登录又称作免密登录,登录的时候不需要输入服务器用户的密码。
公钥登录流程:
- 客户端通过
ssh-keygen
命令生成一对公钥和私钥,保存在客户端~/.ssh/
目录中。
# 程序会询问一系列问题,然后生成公钥和私钥,通常情况下直接按回车使用默认值就可以
ssh-keygen
# 可以使用 -t 参数,指定密钥的加密算法,默认使用 RSA 算法
ssh-keygen -t rsa
- 客户端通过
ssh-copy-id
命令将公钥上传到服务端,保存在服务端的~/.ssh/authorized_keys
文件,如果不存在则创建该文件。
ssh-copy-id root@192.168.100.103
# 可以通过 -i 参数指定公钥位置,不指定则使用默认值
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.100.103
-
客户端通过
ssh user@hostname
命令发起登录请求。 -
服务端接收到请求,生成随机数 R,并使用这个客户端的公钥对 R 加密,把密文返回给客户端。
-
客户端收到密文,使用私钥对密文解密得到 R。然后使用 MD5 对 R 和 SessionKey 加密生成摘要 A1,并把摘要 A1 发送给服务端。
-
服务端同样使用 MD5 对 R 和 SessionKey 加密生成摘要 A2,然后对比 A1 和 A2,完成登录确认。
为了安全性,启用公钥登录之后,最好关闭服务器的密码登录。修改服务端 sshd 的配置文件 /etc/ssh/sshd_config
,将 PasswordAuthentication 这一项设为 no
其他命令
scp
scp
是 SSH 提供的一个客户端程序,用来在两台主机之间加密传送文件(即复制文件),相当于先使用ssh
命令登录远程主机,然后再执行拷贝操作。
基本语法
scp source destination
客户端发起 ssh 连接后,会提示用户输入密码
本地复制到远程
scp ~/file.txt root@192.168.100.103:/mnt/www/
scp -r ~/data root@192.168.100.103:/mnt/www/
scp -r ~/data/* root@192.168.100.103:/mnt/www/data/
远程主机与文件之间要使用冒号(:)分隔
远程复制到本地
scp root@192.168.100.103:/mnt/www/file.txt ~/test/
scp -r root@192.168.100.103:/mnt/www/ ~/test/
scp -r root@192.168.100.103:/mnt/www/* ~/test/www/
远程复制到远程
scp -r root@192.168.100.103:/mnt/data root@192.168.100.104:/mnt/
系统将提示你输入两个远程帐户的密码。数据将直接从一个远程主机传输到另一个远程主机。
rsync
虽然 rsync 不是 SSH 工具集的一部分,但因为也涉及到远程操作,所以放在这里一起介绍。它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件(但不支持两台远程计算机之间的同步)。它也可以当作文件复制工具,替代cp
和mv
命令。
基本用法
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 root@192.168.100.103:/data
# 将远程同步到本地
rsync -a root@192.168.100.103:/data /image
rsync
默认使用 SSH 进行远程登录和数据传输。
sftp
sftp
是 SSH 提供的一个客户端应用程序,主要用来安全地访问 FTP。因为 FTP 是不加密协议,很不安全,sftp就相当于将 FTP 放入了 SSH。
基本命令
sftp username@hostname
执行上面的命令,会要求输入 FTP 的密码。密码验证成功以后,就会出现 FTP 的提示符 sftp>
,下面是一个例子。
$ sftp USER@penguin.example.com
USER@penguin.example.com's password:
Connected to penguin.example.com.
sftp>
FTP 的提示符下面,就可以输入各种 FTP 命令了,这部分完全跟传统的 FTP 用法完全一样。
网友评论