SSH 用法总结

前言

SSH (Secure Shell) 是一种加密的网络传输协议。通过在网络中创建安全隧道来实现 SSH 客户端与服务端之间的连接。
最常见的用途就是远程登录。

简单使用

使用密码登录

以下命令是使用 user 通过 1234 端口登录 host :

$ ssh user@host -p 1234

成功后输入用户密码即可登录。第一次登录会提示无法确认主机的真实性,只知道公钥指纹,询问是否继续。如果决定接受这个远程主机的公钥,则会将该 host 的公钥保存至 ~/.ssh/known_hosts 中,下次再连接时,系统会自动识别自动跳过警告。

使用公钥登录

公钥登录的原理很简单。主要采用了非对称加密的方法,将公钥储存在远程主机上,登录时远程主机会发送一段随机字符串,收到字符串后用私钥加密再发送回去,远程主机用公钥进行解密,如果成功则直接登录。

本地生成好公钥后,可通过以下命令将公钥传输至远程主机:

$ ssh-copy-id user@host

这会在远程主机的 ~/.ssh/authorized_keys 写入发送的公钥。如果无法登录,需要检查远程主机 SSH 服务的配置文件,看是否开启了 RSAAuthentication PubkeyAuthentication 等选项。

使用代理(ssh-agent)

简单使用代理

首先要了解什么是 ssh-agentssh-agent 是一个帮助程序,用来追踪用户的私钥及私钥对应的密码。之后,agent 可以自己使用秘钥登录到其他服务器,不需要用户再次输入密码,是一种 SSO 形式。

手动启动 ssh-agent:

$ eval `ssh-agent`

agent 中添加 SSH 私钥:

# 添加私钥
$ ssh-add ~/.ssh/key

# 查看已添加的私钥
$ ssh-add -l

代理转发

这个是 ssh-agent 一个特别方便的功能。假如用户登录通过 ssh-agent 登录至远程主机,在远程主机的 SSH 客户端访问其他主机的 SSH 服务端。
例如我通过 SSH 登录至远程测试机,在测试机上拉取公司 Gitlab 上的项目,而 Gitlab 上仅配置了我本地主机的公钥,如果不使用 ssh-agent 的话,此时是拉不下来代码的。
如果使用了 ssh-agent 并开启了代理转发,测试机上的 SSH 客户端会将请求转发至本地的 ssh-agent 来处理,
从而避免了将私钥上传至远程主机或者在 Gitlab 中新增远程主机的公钥这些麻烦事了(当然也不安全,私钥应该牢牢掌握在自己手中)。

gitlab-ci 中远程部署项目时使用代理转发很方便。

如何打开代理转发:

# 客户机上在配置 SSH 时需要打开
ForwardAgent yes

# 服务机上在配置 SSH 时需要打开
AllowAgentForwarding yes

配置文件

可以在 ~/.ssh/config 中添加各种配置。文件没有就创建一个。

配置 Host

可以在配置文件中针对不同的 Host 使用不一样的配置项:

# 使用密码登录
Host test-host-1
HostName 123.123.123.123
User user
Port 222


# 使用密钥登录
Host test-host-2
HostName 123.123.123.111
User user
IdentityFile ~/.ssh/some-key

# 所有 Host 的共用配置
Host *
AddKeyToAgent yes
...

如上配置就可以很方便的使用别名登录了:

$ ssh test-host-1

$ ssh test-host-2

常见配置项说明

  • HostName:主机名,IP、域名皆可
  • User: 登录用户
  • IdentityFile: 私钥文件路径
  • ProxyCommand: 代理命令,例如指定本地的 sock5 端口以翻墙(nc -X 5 -x localhost:1086 %h %p)
  • ProxyJump: ssh tunnel 设置跳板机、堡垒机等
  • ForwardAgent: 是否开启代理转发
  • IdentitiesOnly: 只使用该选项指定的私钥,避免使用默认私钥
  • ServerAliveInterval: 心跳间隔
  • ServerAliveCountMax: 心跳重试次数
  • Compression: 是否启用压缩
  • TCPKeepAlive: TCP 保持连接不断开
  • UseRoaming: 是否允许漫游。即从 A 机连接至 B 机,后又用相同私钥在 C 机连接 B 机,会话保持不变
  • ControlMaster: 连接复用
  • ControlPath: 连接复用保存的地址
  • ControlPersist: 复用连接持续的时间

其他的配置项可以参考 SSH 配置手册

端口转发

有时为了安全起见,远程服务的某些端口仅限定的主机可以访问,而用户本地仅能访问那些限定的主机。这时就可以通过端口转发,通过限定的主机将远程服务的某些端口映射到本地的特定端口,从而可以在本地直接访问远程服务的某些端口。

例如:

$ ssh -C -f -N -g -L 18080:10.0.0.1:8080 ssh-tunnel@123.1.1.1

此时访问本地的 18080 端口就相当于用户 ssh-tunnel123.1.1.1 这台主机上访问 10.0.0.1:8080

一些建议

  • 尽量每个单独的服务(或主机)都用不一样的密钥对,通过 ssh config 来管理