SSH 是什么意思?工作原理、22 端口与 Telnet 的区别
SSH 是 Secure Shell 的缩写,中文常叫安全外壳协议,是一种在不可信网络上加密传输的远程管理协议:所有内容先加密再发送,还能验证你连上的确实是那台服务器。它默认使用 TCP 22 端口,除了登录服务器和交换机执行命令,还用来传文件、做端口转发和自动化运维,已经全面取代明文传输的 Telnet。
SSH 是什么意思?SSH 是 Secure Shell 的缩写,可以理解为“安全的远程命令行”:它是一种网络协议,让你在自己的电脑上打开一个终端,就像坐在服务器前一样执行命令,而一路上传输的账号、密码、命令和输出全部是加密的。SSH 最早由芬兰的 Tatu Ylönen 在 1995 年设计,现行的 SSH-2 由 IETF 在 2006 年以 RFC 4251–4254 标准化;服务器上最常见的实现是 OpenSSH。服务端程序 sshd 默认监听 TCP 22 端口,客户端就是 Linux、macOS 和 Windows 10/11 都自带的 ssh 命令,以及各种图形化终端工具。
SSH 是干什么的:五种常见用途
| 用途 | 示例 | 说明 |
|---|---|---|
| 远程登录 | ssh [email protected] |
打开远程 shell,管理 Linux 服务器,以及交换机、BMC 的命令行 |
| 远程执行命令 | ssh [email protected] 'df -h' |
不进入交互界面,执行完就返回结果,适合脚本和巡检 |
| 传输文件 | sftp [email protected]、scp app.tar.gz [email protected]:/tmp/ |
SFTP、SCP 走同一条 SSH 连接、同一个端口;OpenSSH 9.0 起 scp 默认改用 SFTP 协议传输 |
| 端口转发与隧道 | ssh -L 8443:10.20.0.15:443 [email protected] |
把只在内网开放的服务,经过加密的 SSH 连接临时带出来 |
| 自动化与代码同步 | Ansible、git clone [email protected]:ops/scripts.git |
Ansible 默认通过 SSH 登录被管主机;Git 托管平台用 SSH 密钥认证 |
这五种用途都基于同一个能力:在两台机器之间建立一条经过身份验证的加密通道,然后在里面跑终端、命令、文件或任意 TCP 流量。
SSH 协议是怎么工作的:三层结构与连接过程
三层结构
SSH-2 由三个协议叠在一起组成,RFC 4251 描述了整体架构:
| 层 | 标准 | 负责什么 | 你在使用中会碰到的 |
|---|---|---|---|
| 传输层协议 | RFC 4253 | 在 TCP 之上协商算法、交换密钥、验证服务器身份,之后所有数据加密并做完整性校验 | 首次连接的指纹提示;no matching key exchange method 之类的报错 |
| 用户认证协议 | RFC 4252 | 在已加密的通道里验证“你是谁”:公钥、密码、键盘交互(可接动态口令)等 | Permission denied (publickey,password) |
| 连接协议 | RFC 4254 | 在一条连接里复用多个通道:交互式会话、远程命令、SFTP 子系统、端口转发 | 一条连接里同时开 shell、传文件和转发端口 |
顺序很关键:先建立加密通道、确认服务器身份,再做用户认证。用户名和密码都是在加密之后才发出去的。
一次连接的建立过程
- TCP 三次握手,连上服务器的 22 端口。
- 交换版本号:双方各发一行明文,如
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13,确认都使用 SSH-2。 - 协商算法:双方各列出自己支持的密钥交换、主机密钥、加密、完整性校验和压缩算法,按客户端列表的顺序取第一个双方都支持的。
- 密钥交换:用 Diffie-Hellman 类算法(如 curve25519-sha256,较新的 OpenSSH 默认使用加入了抗量子算法的混合方案),双方各生成一对临时密钥,只交换公钥部分,各自算出同一个共享密钥。窃听者看到全部交换内容,也算不出这个密钥。
- 服务器证明身份:服务器用自己的主机私钥,对这次密钥交换的摘要做签名;客户端用主机公钥验签,并与本地
known_hosts里记录的公钥比对。首次连接时“是否信任这个指纹”的提示,就发生在这一步。 - 启用加密:双方从共享密钥派生出加密和校验用的会话密钥,此后每个报文都加密,并带完整性校验。
- 用户认证:客户端申请认证服务,用公钥或密码证明身份。
- 打开通道:认证通过后打开一个会话通道,申请终端、启动 shell,出现命令提示符。
会话密钥由临时密钥派生,连接结束就丢弃。即使将来服务器的主机私钥泄露,之前被录下来的流量也无法解密,这叫前向保密。
用 ssh -v 看每一步
ssh -v 打印的调试信息正好对应上面的八步。下面是 OpenSSH 9.6 客户端连接同版本服务器的输出节选,不同版本的措辞略有差异:
ssh -v [email protected]
debug1: Connecting to 203.0.113.10 [203.0.113.10] port 22.
debug1: Connection established.
debug1: Local version string SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.6p1 Ubuntu-3ubuntu13
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: [email protected]
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Host '203.0.113.10' is known and matches the ED25519 host key.
debug1: SSH2_MSG_NEWKEYS sent
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
Authenticated to 203.0.113.10 ([203.0.113.10]:22) using "publickey".
debug1: Entering interactive session.
| 输出 | 对应步骤 |
|---|---|
Connecting to、Connection established. |
第 1 步,TCP 连上 22 端口 |
Local version string、Remote protocol version 2.0 |
第 2 步,交换版本号 |
KEXINIT 和几行 kex: |
第 3 步,协商出密钥交换、主机密钥和加密算法;chacha20-poly1305 自带完整性校验,所以 MAC 显示为 implicit |
KEX_ECDH_REPLY received、is known and matches |
第 4、5 步,完成密钥交换,主机公钥与 known_hosts 一致 |
NEWKEYS sent、NEWKEYS received |
第 6 步,从这里开始全部加密 |
Authentications that can continue、Authenticated to |
第 7 步,服务器允许公钥和密码两种方式,最终用公钥通过 |
Entering interactive session. |
第 8 步,打开会话通道 |
想知道本机支持哪些算法,用 ssh -Q kex、ssh -Q cipher;服务器端实际生效的配置,用 root 执行 sshd -T 查看。
公钥认证为什么不怕连到假服务器
密码认证时,客户端把密码本身(在加密通道里)交给服务器。如果你在第 5 步忽略了指纹告警、连上的其实是一台冒充的机器,它就直接拿到了你的明文密码。公钥认证时,客户端发出去的是用私钥对本次会话标识做的签名,私钥从不离开本机;冒充者拿到的签名只对它自己那次会话有效,拿去登录真服务器也通不过。所以在机房这类同一网段可能存在其他租户、存在 ARP 欺骗风险的环境里,公钥认证加上认真对待指纹告警,比单纯依赖密码安全得多。
SSH 端口是什么意思:22 端口是干嘛的
“SSH 端口”指服务器上 sshd 监听的 TCP 端口。22 是 IANA 分配给 SSH 的标准端口,客户端不指定端口时就连 22;客户端自己一侧用的是系统随机分配的临时端口。SSH 只用 TCP,放行时不需要 UDP 22。
在服务器上可以看到 sshd 在哪个端口监听,以及当前有哪些 SSH 连接:
ss -tlnp | grep sshd # 监听的地址和端口
ss -tnp state established '( sport = :22 )' # 当前每条 SSH 连接的客户端地址
关于 22 端口,运维中常遇到的几件事:
- 同一个端口承载多种功能。登录、SFTP、SCP、端口转发都走 22,放行了 22 就全部能用;只想开放文件传输、不想开放登录,要在 sshd 配置里限制,而不是靠端口。
- 不止服务器在用 22。交换机、路由器和服务器 BMC 开启 SSH 后,命令行同样用 22 端口;网络设备的 NETCONF 也跑在 SSH 上,标准端口是 830。
- 暴露在公网的 22 端口会被持续扫描和爆破。改端口能减少日志里的噪声,但不能代替访问控制:能登录的来源要在安全组或防火墙里限定,认证方式优先用密钥。
- 22 端口通不代表 SSH 正常。
nc 203.0.113.10 22连上后应该立刻收到一行SSH-2.0-开头的版本号;收不到,说明端口上跑的不是 sshd,或者中间有设备在干扰。
SSH 和 Telnet 的区别
Telnet 是更早的远程登录协议(RFC 854,1983 年),默认用 TCP 23 端口。它的问题不是老,而是从设计上就不提供任何保护:
| 对比项 | Telnet | SSH |
|---|---|---|
| 标准 | RFC 854(1983 年) | SSH-2:RFC 4251–4254(2006 年) |
| 默认端口 | TCP 23 | TCP 22 |
| 传输内容 | 明文,每个按键原样发送 | 加密,抓包只能看到版本号和算法名称 |
| 确认服务器身份 | 做不到,连上的是不是真设备无从得知 | 首次连接记下主机公钥,以后每次比对,不符就告警 |
| 防篡改 | 没有校验,报文可被修改或插入 | 每个报文附带校验码,途中被改动会被发现 |
| 认证方式 | 用户名和密码 | 密码、公钥、键盘交互(可接动态口令)、证书 |
| 附带能力 | 只有终端 | SFTP、端口转发、一条连接复用多个通道 |
| 自动化 | 少数工具支持 | Ansible、NETCONF 等以 SSH 为基础 |
| 现在用在哪里 | 不支持 SSH 的老设备、设备开局时临时使用;telnet IP 端口 测试 TCP 端口是否开放 |
服务器、网络设备、BMC 的标准远程管理方式 |
区别在抓包里看得最清楚。在服务器上分别抓一次 Telnet 和 SSH 登录,-A 参数把报文内容按文本打印:
tcpdump -i eth0 -nn -A 'tcp port 23'
tcpdump -i eth0 -nn -A 'tcp port 22'
Telnet 的输出里,login: 提示、你输入的用户名,以及密码的每一个字符,都按顺序出现在客户端发往服务器的报文里:密码虽然不回显在屏幕上,但发送的内容是原样的。SSH 的输出里,能读懂的文字只出现在最开始的几个包:双方的版本号,以及协商阶段列出的算法名称,如 curve25519-sha256、ssh-ed25519、[email protected];从 NEWKEYS 之后全是无法辨认的字节,用户名和密码都在其中。
Telnet 唯一还常用的场合,是拿 telnet 客户端测试一个 TCP 端口通不通,例如 telnet 203.0.113.10 443。Windows 默认没有安装 Telnet 客户端,用 Test-NetConnection 203.0.113.10 -Port 443 也能完成同样的测试。
机房服务器和交换机为什么都要用 SSH
在 IDC 机房里,远程管理流量经过的地方比想象中多:同一个二层网段里其他客户的服务器、交换机上的镜像端口、上联链路,以及运维人员在家远程办公时经过的公网。只要其中一个位置能看到 Telnet 流量,密码就泄露了。而交换机、路由器和 BMC 的账号权限极高:一个交换机管理员密码,影响的是这台交换机上的所有客户;一个 BMC 账号,可以开关机、挂载镜像、看控制台。
SSH 在这里解决的是三件事:传输加密,管理流量被看到也没有用;主机密钥校验,ARP 欺骗、地址被冒用时客户端会告警并拒绝连接,Telnet 对此毫无察觉;统一的管理入口,配置下发、批量巡检、堡垒机代理和会话录像都以 SSH 为基础。等级保护测评也会检查远程管理是否采取了防窃听措施。
逐类设备检查是否已经只用 SSH:
# Linux 服务器:sshd 实际生效的端口、root 登录和认证方式(需要 root 权限)
sshd -T | grep -E '^(port|permitrootlogin|passwordauthentication|pubkeyauthentication) '
# 确认没有程序在监听 Telnet 的 23 端口
ss -tlnp | grep ':23 '
# 华为、H3C 交换机:SSH 服务状态,以及 VTY 允许哪些协议登录
display ssh server status
display current-configuration | include protocol inbound
# 思科交换机:SSH 版本与 VTY 配置
show ip ssh
show running-config | section line vty
VTY 下出现 protocol inbound all、protocol inbound telnet(华为、H3C)或 transport input telnet ssh(思科),说明 Telnet 仍然可以登录,应改为只允许 SSH;改之前先确认 SSH 登录已经可用,避免把自己锁在外面。
在管理系统里怎么落地
一个机房有成百上千台服务器和几十台交换机,SSH 入口分散在各台设备上,谁登录过、执行了什么命令很难追溯。Toplink DCIM 把这些入口收拢到浏览器里:服务器的 SSH 命令行可以和 VNC、RDP 控制台一起在浏览器中打开,无需安装客户端,SSH 会话全程录像并记录命令级日志,管理员还能查看某台设备上的在线会话并踢出多余的连接(见 IPMI 远程管理)。交换机管理默认通过 SSH 或 Telnet 下发配置,排障时可以在浏览器里打开交换机的 SSH 终端,会话同样录像留痕;仍在用 Telnet 的老设备可以先纳管,再按上文逐台切换到 SSH。租用服务器的客户在客户自助端维护自己的 SSH 密钥和 API 密钥,也能直接打开 SSH 控制台登录名下的机器。
常见问题
SSH 和 SSL/TLS 是一回事吗?
不是。两者都用非对称密钥协商、对称加密传输,但是两套独立的协议:TLS 主要保护 HTTPS 等应用,靠 CA 签发的证书证明服务器身份;SSH 用于远程登录和管理,默认靠客户端首次连接时记下的主机公钥确认身份。
SFTP 和 FTP 有什么关系?
没有关系。SFTP 是运行在 SSH 连接里的文件传输子系统,和登录共用 22 端口与同一套认证;FTP 是另一个独立的协议,用 21 端口并另开数据连接,默认明文传输。给 FTP 加上 TLS 的叫 FTPS。
SSH 协议 1 还能用吗?
不能。SSH-1 存在设计缺陷,早已被 SSH-2 取代,OpenSSH 7.6 起彻底移除了对它的支持。现在说的 SSH 都是 SSH-2,用 ssh -v 连接时能看到 Remote protocol version 2.0。