目录

ssh

SSH 协议:安全外壳协议。为 Secure Shell 的缩写。SSH 为建立在应用层和传输层基础上的安全协议。其开源实现有 OpenSSH,并且存在服务端 sshd 和 客户端 ssh

安全认证

基于密码的安全认证

基于密码的安全认证,登录的时候需要提供账号和密码;远程主机将自己的公钥分发给登录客户端,客户端访问主机使用该公钥加密;远程主机使用自己的私钥解密数据。

登录的流程如下:

  1. 远程主机收到用户登录请求,将自己的公钥发给用户
  2. 用户通过远程主机公钥的指纹确认主机的真实性,然后使用远程主机公钥将登录密码加密后,发送回远程主机
  3. 远程主机使用自己的私钥解码登录密码,验证密码正确后,允许用户登录

假设需要以用户名 user 登录远程主机 host:

1
2
3
4
5
ssh user@host
# 如果本地用户名与远程用户名一致,可以省略用户名:
ssh host
# SSH 默认端口号22,可以使用 p 参数来指定端口号:
ssh -p 2345 user@host

当第一次登录成功后,远程主机的公钥会被保存到文件 $HOME/.ssh/known_hosts 中,下次再连接这台主机就会跳过警告,直接提示输入密码。

基于密钥的安全认证

基于密钥的安全认证,客户端将将公钥上传到服务器。登录的时候,客户端向服务器发送登录请求;服务器收到请求后,向用户发送一段随机字符串;用户用自己的私钥加密后,再发送回服务器;服务器使用事先存储的公钥进行解密,如果解密成功,证明用户可信,允许登录。

这种方式,在登录服务器的过程中,不需要上传密码,增加了安全性。

上传公钥到服务端,即将公钥内容附加到服务器用户目录下的 $HOME/.ssh/authorized_keys 文件中

  1. 在远程主机用户目录下创建目录:~/.ssh
  2. 将本地主机文件 ~/.ssh/id_rsa.pub 拷贝到远程主机的文件 ~/.ssh/authorized_keys追加到文件末尾

也可使用 ssh-copy-id 完成上述操作

1
2
# 将公钥写入远程机器的 ~/.ssh/authorized_key 中
ssh-copy-id -i ~/.ssh/id_rsa.pub ynthm@10.0.0.111

然后重启服务即可

OpenSSH

OpenSSH 是使用 SSH 协议进行远程登录的首要连接工具。它加密所有流量以消除窃听、连接劫持和其他攻击。此外,OpenSSH 提供了大量的安全隧道功能、多种身份验证方法和复杂的配置选项。

  • ssh(1) — The basic rlogin/rsh-like client program
  • sshd(8) — The daemon that permits you to log in
  • ssh_config(5) — The client configuration file
  • sshd_config(5) — The daemon configuration file
  • ssh-agent(1) — An authentication agent that can store private keys
  • ssh-add(1) — Tool which adds keys to in the above agent
  • sftp(1) — FTP-like program that works over SSH1 and SSH2 protocol
  • scp(1) — File copy program that acts like rcp
  • ssh-keygen(1) — Key generation tool
  • sftp-server(8) — SFTP server subsystem (started automatically by sshd)
  • ssh-keyscan(1) — Utility for gathering public host keys from a number of hosts
  • ssh-keysign(8) — Helper program for host-based authentication
1
2
3
4
5
6
# 客户端安装 openssh-client 用以登录远程主机:
sudo apt-get install openssh-client
# 服务端安装 openssh-server 用以提供客户端登录:
sudo apt-get install openssh-server
# 版本
ssh -V

ssh-keygen

ssh-keygen,它是 OpenSSH 的组件,在 Linux 和 macOS 中一般都自带了。

如果你使用 Windows,安装 Git for Windows 时会一并安装 OpenSSH 到系统中。建议 Windows 用户使用 Git Bash 完成文中操作。

1
2
3
4
5
6
man ssh-keygen
ssh-keygen -t ed25519 -C "comment"
ssh-keygen -t ed25519 -f github  -C "ynthm.w@gmail.com"
# 密钥长度默认 2048 bits
ssh-keygen -t rsa -b 4096 -C "ynthm.w@gmail.com"
ls ~/.ssh

macOS 13 (Ventura) ships with OpenSSH_9.0p1. This release disables RSA signatures using the SHA-1 hash algorithm by default.

1
2
3
4
# ~/.ssh/config
Host *
  HostkeyAlgorithms +ssh-rsa
  PubkeyAcceptedAlgorithms +ssh-rsa

macOS 通过上面配置可以支持 RSA,但还是推荐使用 Ed25519 是一个数字签名算法,签名和验证的性能都极高

密码短语(Passphras):

密码短语(passphras)是一连串的单词或文本组成,用来控制对电脑系统的访问。它的用法类似于密码(Password),但是通常会比密码长度更长,这样就增加了破解的复杂度。密码短语不同于密码,它可以是有实际意义的一段话,便于用户记忆。

密码短语默认可以不创建,但是这会导致不安全性。私钥是未经加密存储在电脑上的,电脑遗失或被窃取后,任何人拿到你的私钥后都可以随意访问 SSH 服务器;另外,电脑的 root 用户有权限访问电脑上的任意文件,这也包括你的私钥文件。因此,为了提高安全性还是建议用户设置自己的密码短语。

已经生成的密钥对也可以修改密码短语。假设使用的是 RSA 加密的密钥对,存储到默认路径,输入以下命令即可:

1
ssh-keygen -f ~/.ssh/id_rsa -p
  • 私钥必须要有 passphrase。如果私钥文件遗失,没有 passphrase 也无法解锁(只能暴力破解)。不要偷懒,passphrase 一定要加。
  • 一对密钥只对应一个 Git 服务。一对密钥通吃各 Git 服务不太明智。
  • 严格来讲,你应该在不同的机器上用不同的密钥,出了问题好排查处理。但实际上复杂的管理反而更容易让人犯错,选择适合的方式更为重要。

ssh-agent

ssh-agent 是一种控制用来保存公钥身份验证所使用的私钥的程序。

ssh-agent是一个密钥管理器,运行ssh-agent以后,使用ssh-add将私钥交给ssh-agent保管,其他程序需要身份验证的时候可以将验证申请交给ssh-agent来完成整个认证过程。

当把私钥交给 ssh agent 管理的好处:

  • 当其他程序 需要身份验证的时候 可以将验证申请交给 ssh-agent 来完成整个认证过程。使用不同的密钥连接到不同的主机时,需要要手动指定对应的密钥,而ssh代理可以自动帮助我们选择对应的密钥进行认证。
  • 避免重复输入密码:如果您的私钥使用密码短语来加密了的话,每一次使用 SSH 密钥对进行登录的时候,您都必须输入正确的密码短语。而 SSH agent 程序能够将您的已解密的私钥缓存起来,在需要的时候提供给您的 SSH 客户端。这样子,您就只需要在使用 ssh-add 时将私钥加入 SSH agent 缓存的时候,输入一次密码短语就可以了。这为经常使用 SSH 连接用户提供了不少便利。
1
2
# 查看服务
eval "$(ssh-agent -s)"

在local上执行

1
2
3
4
5
ssh-agent
# 执行了之后就将私钥给ssh-agent保管了,ssh 登录需要私钥验证的时候直接找ssh-agent要就可以了。
ssh-add ~/.ssh/<private_key_file>
# macOS
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

ssh-add

  • -D:删除ssh-agent中的所有密钥.
  • -d:从ssh-agent中的删除密钥
  • -e pkcs11:删除PKCS#11共享库pkcs1提供的钥匙。
  • -s pkcs11:添加PKCS#11共享库pkcs1提供的钥匙。
  • -L:显示ssh-agent中的公钥
  • -l:显示ssh-agent中的密钥
  • -t life:对加载的密钥设置超时时间,超时ssh-agent将自动卸载密钥 -X:对ssh-agent进行解锁
  • -x:对ssh-agent进行加锁
1
2
# 查看 SSH agent 缓存密钥列表:
ssh-add -l

ssh 配置文件

  • 命令行选项
  • 用户配置文件 (~/.ssh/config)
  • 系统配置文件 (/etc/ssh/ssh_config)
1
2
cat /etc/ssh/ssh_config | grep '^Host'
# 这里有一些默认配置项,可以在用户配置文件中覆盖这些默认配置。
1
vim ~/.ssh/config
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Host work
  HostName github.com
  IdentityFile ~/.ssh/work_pc

Host github.com
  HostName github.com
  IdentityFile ~/.ssh/id_rsa

Host sshtest
    HostName ssh.test.com
    User user
    Port 2200
    IdentityFile ~/.ssh/id_rsa_test

Host btcc-uat-10
  HostName 10.231.45.10
  User centos
  IdentityFile ~/.ssh/gts2newkey.pem

Host 172.21.*
    User ethan
    HostName %h
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa_mobi
    ProxyCommand ssh jump -W %h:%p
# 代理
Host jump
    Hostname 172.21.100.36
    Port 22
    User ethan
    IdentityFile ~/.ssh/id_rsa_mobi
1
2
ssh-copy-id user@ssh.test.com
ssh sshtest

ssh 免密登陆 (SSH互信)

检查机器名和连通性

/etc/hostname 表示的是在LAN(局域网)内的唯一主机名。在局域网内,本机或者其他在同一局域网内的计算机,可以直接通过 hostname.local 可找到主机

/ect/hosts 是域名查找系统(DNS),只不过,它只是本地查找的,在本地建立一个ip <-> name的对应关系。计算机的寻址:应用 -> 应用缓存 -> hosts -> DNS -> 目的PC

对三台服务器分别设置:

1
2
3
4
ssh root@192.168.2.10
# vi /etc/hostname
sudo hostnamectl set-hostname node1
vim /etc/hosts
192.168.2.10 node1
192.168.2.20 node2
192.168.2.30 node3

检查连通性

1
2
ssh root@192.168.2.10
ping node2

开启ssh证书登录

sudo vim /etc/ssh/sshd_config

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile   .ssh/authorized_keys
1
systemctl restart sshd

建立相同用户

1
2
useradd ynthm -m
passwd ynthm

生产ssh证书文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# node01 执行 提示回车即可
su ynthm
ssh-keygen -t rsa -C "ynthm@live.com"
# 私钥id_rsa和公钥id_rsa.pub
# root账户 /root/.ssh/ su ynthm 文件会在/home/ynthm/.ssh/

# 将公钥写入远程机器的~/.ssh/authorized_key中
ssh-copy-id -i ~/.ssh/id_rsa.pub ynthm@node02
ssh-copy-id -i ~/.ssh/id_rsa.pub ynthm@node03
# ssh node02
ssh root@node02
1
2
3
4
5
# node02 执行 提示回车即可
ssh-keygen -t rsa -C "ynthm@live.com"
ssh-copy-id -i ~/.ssh/id_rsa.pub ynthm@node01
ssh-copy-id -i ~/.ssh/id_rsa.pub ynthm@node03
ssh root@node01
1
2
3
4
5
# node03 执行 提示回车即可
ssh-keygen -t rsa -C "ynthm@live.com"
ssh-copy-id -i ~/.ssh/id_rsa.pub ynthm@node01
ssh-copy-id -i ~/.ssh/id_rsa.pub ynthm@node02
ssh root@node01

scp 基于ssh的命令

文件权限问题

如果是拷贝过来的密钥对,需要对修改文件权限。

1
2
3
chmod 755 ~/.ssh/
chmod 600 ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/known_hosts

sshd 连接太慢

1
2
3
vi /etc/ssh/sshd_config
# 取消注释并修改值 UseDNS no 虽然被注释但缺省值为yes,所以需要显式指定no
systemctl restart sshd