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-agent
,ssh-agent
是一个帮助程序,用来追踪用户的私钥及私钥对应的密码。之后,agent
可以自己使用秘钥登录到其他服务器,不需要用户再次输入密码,是一种 SSO 形式。
手动启动 ssh-agent
:
$ eval `ssh-agent` |
向 agent
中添加 SSH 私钥:
# 添加私钥 |
代理转发
这个是 ssh-agent
一个特别方便的功能。假如用户登录通过 ssh-agent
登录至远程主机,在远程主机的 SSH 客户端访问其他主机的 SSH 服务端。
例如我通过 SSH 登录至远程测试机,在测试机上拉取公司 Gitlab 上的项目,而 Gitlab 上仅配置了我本地主机的公钥,如果不使用 ssh-agent
的话,此时是拉不下来代码的。
如果使用了 ssh-agent
并开启了代理转发,测试机上的 SSH 客户端会将请求转发至本地的 ssh-agent
来处理,
从而避免了将私钥上传至远程主机或者在 Gitlab 中新增远程主机的公钥这些麻烦事了(当然也不安全,私钥应该牢牢掌握在自己手中)。
在 gitlab-ci
中远程部署项目时使用代理转发很方便。
如何打开代理转发:
# 客户机上在配置 SSH 时需要打开 |
配置文件
可以在 ~/.ssh/config
中添加各种配置。文件没有就创建一个。
配置 Host
可以在配置文件中针对不同的 Host 使用不一样的配置项:
# 使用密码登录 |
如上配置就可以很方便的使用别名登录了:
$ ssh test-host-1 |
常见配置项说明
- 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-tunnel
在 123.1.1.1
这台主机上访问 10.0.0.1:8080
一些建议
- 尽量每个单独的服务(或主机)都用不一样的密钥对,通过 ssh config 来管理