你是不是也有过这种经历?
公司有三台服务器,每台IP都不一样。每次连都要输入一长串命令,记不住。
某个服务跑在内网,外网访问不了。想从本地连过去调试,翻遍了文档也没找到办法。
远程操作到一半,网络突然断了。重连又要重新输入一堆参数。
这些问题,新手一般会去问运维,或者干脆放弃。但其实SSH早就提供了优雅的解决方案。
今天分享5个SSH进阶技巧。学完这些,你在远程连接上的效率至少提升三倍。
技巧一:SSH Config文件,一台服务器一个别名
场景: 你有三台服务器,IP分别是 1.2.3.4、5.6.7.8、9.10.11.12。每次连接都要输入:
ssh -p 2222 admin@1.2.3.4
ssh -p 2222 root@5.6.7.8
ssh -p 2222 deploy@9.10.11.12
记不住?用SSH Config文件。
配置方法
打开(或创建)~/.ssh/config,按以下格式写入:
Host prod
HostName 1.2.3.4
Port 2222
User admin
IdentityFile ~/.ssh/id_ed25519
Host staging
HostName 5.6.7.8
Port 22
User root
Host deploy
HostName 9.10.11.12
Port 2222
User deploy
IdentityFile ~/.ssh/deploy_key
配置完后,连接变成:
ssh prod # 连生产环境
ssh staging # 连测试环境
ssh deploy # 连部署服务器
一行命令,不用再记IP、端口、用户名。
进阶配置:设置默认参数
如果多台服务器用同一个密钥或同一个用户,可以设置全局默认值:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Host prod
HostName 1.2.3.4
User admin
Host staging
HostName 5.6.7.8
User admin
ServerAliveInterval 会让SSH每60秒发一次心跳包,防止连接因为超时被断。这招对移动网络或不稳定的WiFi特别有用。
技巧二:端口转发,内网服务本地访问
场景: 公司的数据库或内部管理系统跑在内网,外网访问不了。你人在家里,想调试接口或者查数据。
端口转发能帮你把内网服务"搬"到本地。
本地端口转发(最常用)
把远程服务器的某个端口,映射到你本地的端口:
ssh -L 5432:localhost:5432 prod
这行命令的意思是:把你本地的5432端口,转发到远程服务器(prod)的5432端口。
连接成功后,你在本地连 localhost:5432,实际上就是在连远程数据库。
常用场景:
# 连远程MySQL
ssh -L 3306:127.0.0.1:3306 prod
# 本地连:mysql -h 127.0.0.1 -u root -p
# 连远程Redis
ssh -L 6379:127.0.0.1:6379 prod
# 本地连:redis-cli -p 6379
# 访问内网管理后台(假设端口8080)
ssh -L 8080:10.0.0.5:8080 prod
# 浏览器打开 localhost:8080
远程端口转发
反过来,把本地的端口暴露到远程服务器:
ssh -R 8080:localhost:3000 prod
这会让远程服务器在8080端口监听,流量转发到你本地的3000端口。
适合给同事展示本地开发中的页面,或者让外网访问你本地跑的服务。
动态端口转发(SSH代理)
把SSH当成一个SOCKS代理,所有流量都走远程服务器:
ssh -D 1080 prod
配置浏览器代理为 socks5://127.0.0.1:1080,所有流量都经过远程服务器。
适合排查某些特定IP才能访问的服务,或者在远程服务器上下载东西。
排查连接问题
端口转发配置对了还是连不上?先用navbox的端口扫描模拟器看看目标端口是否在监听。再确认一下防火墙规则,很多时候问题出在安全组没开端口。
技巧三:跳板机,一层层穿透内网
场景: 你的服务器在内网深处,要经过跳板机(堡垒机)才能到达。每次连接要两步走:
ssh user@bastion # 先连跳板机
ssh user@10.0.0.5 # 再从跳板机连目标
麻烦死了。而且跳板机的密码经常换,还要到处问。
一步到位:ProxyJump
OpenSSH 7.3+ 支持 ProxyJump,一条命令穿透多层网络:
ssh -J user@bastion user@10.0.0.5
如果经过多层跳板机:
ssh -J user@bastion1,user@bastion2 user@10.0.0.5
在Config文件里配置
配合技巧一的Config文件,更优雅:
Host bastion
HostName bastion.example.com
User admin
IdentityFile ~/.ssh/id_ed25519
Host internal-*
ProxyJump bastion
User deploy
IdentityFile ~/.ssh/deploy_key
配置完后:
ssh internal-web01 # 自动经过bastion跳到内网web01
ssh internal-db01 # 自动经过bastion跳到内网数据库
internal-* 是通配符,所有以 internal- 开头的服务器都会走跳板机。
端口转发+跳板机组合
结合技巧二的端口转发,一步到位访问内网服务:
ssh -J bastion -L 5432:localhost:5432 internal-db
# 本地连localhost:5432就是内网数据库
这条命令做了三件事:经过跳板机 → 连上内网数据库服务器 → 把数据库端口映射到本地。
技巧四:持久连接,断网不断连
场景: 你在远程服务器上跑了个长时间任务(比如部署脚本、数据迁移)。 halfway,WiFi断了。重连之后发现任务已经停了,一切重来。
SSH持久连接(ControlMaster)能解决这个问题。
开启持久连接
在 ~/.ssh/config 里加:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
ControlMaster auto:第一个连接作为主连接,后续同配置的连接复用ControlPath:持久连接的socket文件路径(需要手动创建目录)ControlPersist 600:主连接关闭后,保持600秒(10分钟)
创建socket目录:
mkdir -p ~/.ssh/sockets
chmod 700 ~/.ssh/sockets
使用效果
第一次连接时,SSH会创建一个持久连接。之后所有相同配置的连接都会复用这个连接:
ssh prod # 第一次,创建持久连接
ssh prod # 第二次,复用已有连接,几乎瞬间完成
即使你关了终端窗口,持久连接还会在后台保持。10分钟内重连,之前的会话状态还在。
注意事项
- 持久连接只适用于相同用户、相同主机、相同端口的连接
- 如果需要强制新建连接,用
ssh -O exit prod关闭持久连接 - 在共享机器上慎用,可能会带来安全风险
技巧五:SSH密钥管理,告别密码烦恼
场景: 你有很多台服务器,每台都要输密码。或者密码忘了,到处找人问。
用SSH密钥对,一次配置,永久免密。
生成密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"
生成私钥(~/.ssh/id_ed25519)和公钥(~/.ssh/id_ed25519.pub)。
把公钥复制到服务器
ssh-copy-id user@host
或者手动复制:
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
保护私钥
私钥就是你的"数字身份证"。丢了或者被偷了,别人就能以你的身份登录所有服务器。
给私钥加密码短语(passphrase):
ssh-keygen -p -f ~/.ssh/id_ed25519
输入新的密码短语。之后每次使用这个密钥都会提示输入密码。
密码短语要足够长、足够复杂。可以用navbox的密码生成器生成一个随机强密码,然后用密码强度测试验证一下强度。
macOS用户:用Keychain存密码
macOS可以用系统钥匙串存SSH密钥密码,不用再手动输入:
# 在config里加上这两行
AddKeysToAgent yes
UseKeychain yes
之后用 ssh-add --apple-use-keychain ~/.ssh/id_ed25519 把密钥加入Keychain。
把这5个技巧串起来
单独用一个技巧,效果有限。把它们组合起来,就是一个完整的远程连接工作流:
- Config文件管理多服务器 → 配置所有服务器别名
- 跳板机穿透内网 → 一条命令连到目标服务器
- 端口转发 → 把内网服务映射到本地
- 持久连接 → 断网不断连,效率翻倍
- 密钥管理 → 告别密码,安全又方便
举个例子,你的完整Config文件可能是这样:
Host *
ServerAliveInterval 60
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Host bastion
HostName bastion.example.com
User admin
IdentityFile ~/.ssh/bastion_key
Host prod
HostName 1.2.3.4
User admin
ProxyJump bastion
LocalForward 5432 localhost:5432
LocalForward 6379 localhost:6379
Host internal-web
HostName 10.0.0.10
User deploy
ProxyJump bastion
配置一次,永久受益。以后连接服务器就变成:
ssh prod # 自动走跳板机,自带端口转发
ssh internal-web # 自动走跳板机
最后的小建议
SSH进阶技巧不难,但需要实践。建议从最简单的Config文件开始,逐步叠加其他技巧。
遇到问题别慌。先用 ssh -v prod 打开详细模式,看看连接过程中的每一行输出。大多数连接问题都能从这里定位到原因。
你的SSH连接有什么痛点?评论区聊聊,说不定下期就写。