SSH从入门到精通:密钥登录、config配置、跳板机

只要碰 Linux,SSH 就是你每天用最多的工具。但很多人对它的掌握停留在「ssh user@host + 输密码」,把大量时间浪费在重复输入长命令、记一堆 IP、来回跳机器上。这一篇把 SSH 从入门讲到进阶:密钥登录免密码、config 配置文件简化连接、ProxyJump 优雅跳板、端口转发打隧道,让你从「会用」升级到「用得飞起」。

一、SSH 基础:连接与验证

SSH(Secure Shell)通过加密通道远程登录和执行命令。基本用法:

复制代码
ssh user@host
ssh user@host -p 2222          # 指定端口
ssh user@host "ls -l /data"    # 执行单条命令后退出

第一次连接会提示确认主机指纹:

复制代码
The authenticity of host 'example.com (1.2.3.4)' can't be established.
ED25519 key fingerprint is SHA256:xxxxx.
Are you sure you want to continue connecting (yes/no)?

输入 yes 后,指纹被记入 ~/.ssh/known_hosts。

二、密钥登录:告别密码

密码登录有三个问题:服务器被暴力破解、每次输密码、自动化脚本没法用。密钥登录一次性解决。

生成密钥对

复制代码
ssh-keygen -t ed25519 -C "your_email@example.com"
  • -t ed25519:现代推荐算法,比 RSA 更安全更快
  • -C:注释,方便识别
  • 一路回车用默认路径(~/.ssh/id_ed25519),可设 passphrase 增强安全

生成的密钥对:

文件 用途 权限
~/.ssh/id_ed25519 私钥,绝不外泄 600
~/.ssh/id_ed25519.pub 公钥,发给服务器 644

分发公钥到服务器

复制代码
ssh-copy-id user@host

它会自动把公钥追加到服务器的 ~/.ssh/authorized_keys。手动方式:

复制代码
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

服务端权限要求(关键)

SSH 对权限极其敏感,不对就拒绝密钥登录:

复制代码
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519         # 私钥
chmod 644 ~/.ssh/id_ed25519.pub     # 公钥

家目录权限也不能太开放(不能是 777):

复制代码
chmod 755 ~          # 或 700

用指定私钥登录

复制代码
ssh -i ~/.ssh/mykey user@host

三、ssh_config:不再记长命令

每次敲一长串 ssh -i key -p 2222 user@ip 太累。写在 ~/.ssh/config 里,用别名一键连。

配置文件位置

文件 作用
~/.ssh/config 用户级(优先)
/etc/ssh/ssh_config 全局

基本配置

复制代码
vim ~/.ssh/config

Host web
    HostName 192.168.1.100
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

Host db
    HostName 192.168.1.200
    User admin

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

配置后,直接:

复制代码
ssh web      # 等价于 ssh -p 2222 -i ... deploy@192.168.1.100
ssh db

Host * 是通配,对所有主机生效,适合放通用参数(如心跳保活)。

常用配置项

配置项 作用
Host 别名(匹配模式)
HostName 真实 IP/域名
User 用户名
Port 端口
IdentityFile 私钥路径
ProxyJump 跳板机
ServerAliveInterval 保活间隔(秒),防断连
ForwardAgent 是否转发 agent

⚠️ config 文件权限

~/.ssh/config 权限也要正确:

复制代码
chmod 600 ~/.ssh/config

权限太开放,SSH 会忽略它。

四、sshd_config:服务端安全加固

服务端配置在 /etc/ssh/sshd_config(注意 d 是 daemon)。改完要 systemctl restart sshd。

关键安全项

复制代码
# 禁用 root 直接登录
PermitRootLogin no

# 禁用密码登录,只允许密钥
PasswordAuthentication no
PubkeyAuthentication yes

# 改默认端口(减少扫描)
Port 2222

# 限制可登录用户
AllowUsers deploy admin

# 禁止空密码
PermitEmptyPasswords no

# 登录超时
LoginGraceTime 30

# 限制认证尝试次数
MaxAuthTries 3

⚠️ 改 sshd 的保命姿势

动 sshd_config 前一定保留一个已连接的会话,并先测配置:

复制代码
# 1. 语法检查(不改动服务)
sudo sshd -t

# 2. 用新配置起一个测试实例(在另一端口)
sudo /usr/sbin/sshd -t -f /etc/ssh/sshd_config

# 3. 确认无误再重启
sudo systemctl restart sshd

最怕的是:禁用密码登录 + 密钥没配好,直接把自己锁在门外。 改之前先确认密钥能登录。

五、跳板机与 ProxyJump

生产环境常不允许从公网直连内网机器,必须先登录一台跳板机(bastion/jump host) ,再从它连内网。传统方式是手动两跳,麻烦。ProxyJump 一步搞定:

命令行方式

复制代码
ssh -J jumpuser@jump.example.com:22 user@internal.host

config 配置方式(推荐)

复制代码
Host jump
    HostName jump.example.com
    User jumpuser
    Port 22
    IdentityFile ~/.ssh/id_ed25519

Host internal
    HostName 10.0.0.50
    User deploy
    ProxyJump jump

之后直接:

复制代码
ssh internal     # 自动经 jump 跳转,命令、文件都透传

ProxyJump 的优势:

  • 一条命令完成两跳,不用手动中转
  • scp、rsync、端口转发都自动支持(因为它本质是 SSH 隧道)
  • 支持多级跳板 :-J jump1,jump2

多级跳板

复制代码
ssh -J user1@jump1,user2@jump2 user@target

六、端口转发:SSH 隧道

SSH 能把远程端口「搬」到本地,或把本地端口「推」到远程,用于访问内网服务、绕过网络限制。

本地转发(-L):本地端口 → 远程服务

复制代码
ssh -L 8080:localhost:80 user@server

含义:访问本机 8080 → 通过 SSH 隧道 → 在 server 上访问 localhost:80。

用途:server 上的服务只监听 127.0.0.1(如数据库),从本地安全访问。

复制代码
# 本地 13306 → server 上的 3306
ssh -L 13306:localhost:3306 user@server
# 本地连 mysql -h 127.0.0.1 -P 13306

远程转发(-R):远程端口 → 本地服务

复制代码
ssh -R 9000:localhost:3000 user@server

含义:访问 server 的 9000 → 转发到 本机 3000。常用于把本地开发服务临时暴露出去。

动态转发(-D):SOCKS 代理

复制代码
ssh -D 1080 user@server

在本机开一个 SOCKS5 代理(1080),用它可以把流量走 server 出去(爬墙/访问内网网段)。

常用附加参数

复制代码
ssh -L 8080:hostA:80 -N -f user@jumper
  • -N:不执行远程命令(纯转发)
  • -f:后台运行
  • -T:不分配终端

配合 config:

复制代码
Host tunnel
    HostName jumper.example.com
    User deploy
    LocalForward 13306 db.internal:3306
    LocalForward 16379 redis.internal:6379

七、免密与自动化

ssh-agent:缓存私钥

私钥有 passphrase 时每次都要输,ssh-agent 可以帮你记着:

复制代码
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

之后同一会话内再用私钥就不用输 passphrase。

转发 agent(跳板场景)

复制代码
Host jump
    ForwardAgent yes

连接跳板时把本地 agent 转发过去,跳板上再连其他机器就能用你本地的密钥,而私钥不落地到跳板机(更安全)。

用 SSH 跑命令/传文件

复制代码
# 执行远程命令
ssh web "df -h && free -h"

# 批量在多台机器执行
for h in web1 web2 web3; do ssh $h "uptime"; done

# 用 rsync 走 SSH
rsync -avz -e ssh /local/ user@host:/remote/

八、⚠️ 常见错误

  1. 权限太开放导致密钥登录被拒 。~/.ssh 必须 700、authorized_keys 必须 600、家目录不能 777。这是最高频的坑。
  2. 禁用密码前没验证密钥 。结果自己都进不去,只能去机房/控制台救。先确认密钥能登录,再禁用密码。
  3. sshd_config 改错直接重启 。先 sshd -t 语法检查,再保留一个活跃会话。
  4. config 里 Host 写成 IP 。Host 是别名(匹配你 ssh xxx 里的 xxx),真实地址放 HostName。写反了不生效。
  5. ProxyJump 写成 ProxyCommand 老语法 。新版本用 ProxyJump 更简洁,别照抄老教程。
  6. 忘记 host key 变化 。服务器重装后 host key 变了,报 REMOTE HOST IDENTIFICATION HAS CHANGED,要删掉 known_hosts 里对应行。
  7. 端口转发只监听 localhost 。默认 -L 只绑 127.0.0.1,想让同网段其他机器用要加 -g 或 -L 0.0.0.0:端口:...。
  8. SSH 连接卡住不退出 。加 ServerAliveInterval 和 ServerAliveCountMax 做保活。

九、原理探究:SSH 握手的五个阶段

SSH 不是简单加密,它有一整套握手协议。理解它,就能明白为什么 SSH「既安全又快」。

阶段一:TCP 连接

先建立 TCP 连接(三次握手),默认 22 端口。

阶段二:版本协商与算法协商

双方交换 SSH 版本,协商加密算法(如 chacha20-poly1305)、密钥交换算法(如 curve25519)、消息认证算法(HMAC)。

阶段三:密钥交换(KEX)

双方用 Diffie-Hellman (或 ECDH)在不安全信道上协商出一个共享密钥。关键点:即使有人全程监听,也算不出这个密钥------这就是 SSH 安全的基础。

协商出的密钥用于加密后续所有通信,同时计算出一个会话 ID。

阶段四:服务端认证(Host Key)

服务端用自己的主机密钥 签名,客户端验证这是不是「真要连的机器」。第一次连接时你看到的 fingerprint 确认,以及 known_hosts 机制,都是为了防止中间人攻击。

阶段五:用户认证

用户在加密通道内认证,方式有:

  • 密码认证:密码加密传输(但服务器还是要存密码哈希,易被爆破)
  • 公钥认证:客户端证明「我持有对应私钥」(不传输私钥),服务端用公钥验证签名

公钥认证的过程(为什么不传私钥也安全):

复制代码
1. 客户端说:我想用这个公钥登录
2. 服务端查 authorized_keys,找到对应公钥
3. 服务端发一个随机挑战
4. 客户端用私钥对挑战签名
5. 服务端用公钥验证签名 → 通过

全程私钥不出本地,只是「用私钥签了个名」,所以比密码安全得多,也难以暴力破解。

为什么密钥登录能防爆破

密码可以被枚举穷举,而公钥认证需要持有对应私钥才能通过。攻击者没有私钥,无论试多少次都过不了------这就是云服务器几乎都推荐密钥登录的原因。

十、SSH 速查表

复制代码
# 生成密钥
ssh-keygen -t ed25519 -C "comment"

# 分发公钥
ssh-copy-id user@host

# 用指定私钥/端口
ssh -i ~/.ssh/key -p 2222 user@host

# 跳板机
ssh -J jump@jumphost user@target

# 本地端口转发
ssh -L 8080:localhost:80 user@host -N -f

# 远程端口转发
ssh -R 9000:localhost:3000 user@host -N

# 动态 SOCKS 代理
ssh -D 1080 user@host

# 执行远程命令
ssh host "command"

# 保活(config 里)
# ServerAliveInterval 60
# ServerAliveCountMax 3

掌握 SSH 的三个关键升级点:密钥登录 (免密更安全)、config 别名 (省去重复输入)、ProxyJump 跳板 + 端口转发 (打通复杂网络拓扑)。把 ~/.ssh/config 维护好,你的每一次远程操作都会变得干净利落。下一篇讲远程传输,把 scp、sftp、rsync 三个命令讲透。

相关推荐
吹什么轩1 小时前
linux系统复习:从冯·诺依曼到操作系统:一切的开场
linux·运维·服务器
一条泥憨鱼1 小时前
【计算机网络】| 从 MAC 到 NAT 的跨网段通信全链路
服务器·网络·学习·计算机网络·macos
Elastic 中国社区官方博客1 小时前
Jina AI:Elasticsearch 集成
大数据·运维·人工智能·elasticsearch·搜索引擎·全文检索·jina
H.莓飛1 小时前
【Linux】自主 Shell
linux·运维·服务器·c语言·开发语言·visual studio
bigcarp1 小时前
Frida-dexdump 绕过app的Root检测
linux·运维·服务器
ggaofeng1 小时前
linux中的绿色版内存mysql
linux·运维·mysql
Lsetea1 小时前
curl访问HTTPS报28 Operation timed out:连接超时与总超时分层排查
运维·https·ssl证书·curl·tls
草莓熊Lotso2 小时前
【C++ 基于微服务的即时通讯系统】Elasticsearch 从安装到 C++ 客户端二次封装全落地
linux·网络·数据库·c++·elasticsearch·微服务
曦夜日长2 小时前
主从 Reactor 高并发服务器实战 (一):前置知识与功能目标
运维·服务器