SSH 端口号是多少?默认 22、查看与修改步骤及改端口的影响
SSH 端口默认是 TCP 22,由服务端配置文件 sshd_config 里的 Port 决定,可以改成任何空闲端口,也可以同时监听多个。改端口能让日志里的自动扫描明显减少,但挡不住全端口扫描;动手前要把防火墙、SELinux、安全组、堡垒机和脚本里的端口一起改掉。
SSH 端口号是多少?默认是 TCP 22。22 是 IANA 为 SSH 登记的端口,OpenSSH 服务端 sshd 不做任何配置时就在 22 上监听,客户端不指定端口时也去连 22。这个值由服务器上 /etc/ssh/sshd_config(或 /etc/ssh/sshd_config.d/ 下的文件)里的 Port 决定,可以改成任何没被占用的端口,也可以同时监听多个端口。改端口本身只要改一行,麻烦在它牵动的东西:系统防火墙、SELinux、云安全组、机房 ACL、堡垒机里登记的资产、各种脚本和监控,漏掉一处就可能把自己关在门外或者让自动化任务失败。下面依次讲端口怎么选、怎么查看当前端口、按发行版修改的完整步骤、改完不生效的排查,以及改端口到底带来什么影响。
SSH 端口号可以改成多少
SSH 只用 TCP,不需要放行 UDP 22。客户端一侧使用的是系统随机分配的临时端口,防火墙规则只需按服务器的监听端口来写。新端口从下面几个范围里挑:
| 范围 | 名称 | 用作 SSH 端口 |
|---|---|---|
| 0–1023 | 系统端口 | 只有 root 能监听,大多已有固定用途(80、443、873 等),除 22 外一般不占用 |
| 1024–49151 | 注册端口 | 常见选择,挑一个本机和所在网络里都没有用到的 |
| 32768–60999 | Linux 默认的临时端口范围 | 避开:本机对外发起连接时会随机占用这段端口,sshd 重启时可能正好撞上而绑定失败 |
| 49152–65535 | 动态端口 | 同样容易和临时端口冲突 |
几条选择上的经验:
- 先确认空闲。
ss -tlnp 'sport = :22022'没有输出,说明本机没有程序在用;grep -w 22022 /etc/services看它是否是某个知名服务的端口。本机临时端口的实际范围用sysctl net.ipv4.ip_local_port_range查看。 - 不要挑“像 SSH”的端口。 2222、22222 这类端口常被扫描器顺带探测,降噪效果会打折扣。
- 1024 以下的空闲端口也是一种选择。 有人主张这样选,理由是普通用户无法监听 1024 以下的端口,即使 sshd 意外停止,也没有非 root 进程能冒充它占住这个端口。两种做法都可以,关键是全机房统一,并记录在资产信息里。
怎么查看服务器当前的 SSH 端口
“配置里写的端口”和“实际在监听的端口”可能不一致,比如改了配置还没重启。所以按这个顺序看:
# 1. 实际在监听的端口(需要 root 才能看到进程名)
ss -tlnp | grep -E 'sshd|systemd'
# 2. sshd 按当前配置文件算出来的端口和监听地址
sshd -T | grep -E '^(port|listenaddress) '
# 3. 是哪个文件里写的
grep -rn -i '^\s*Port' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/
# 4. Ubuntu 新版本:是否由 ssh.socket 代为监听
systemctl is-active ssh.socket && systemctl show ssh.socket -p Listen
第 1 条的输出类似下面这样,0.0.0.0:22022 和 [::]:22022 分别是 IPv4 和 IPv6 的监听,最后一列是进程:
LISTEN 0 128 0.0.0.0:22022 0.0.0.0:* users:(("sshd",pid=812,fd=3))
LISTEN 0 128 [::]:22022 [::]:* users:(("sshd",pid=812,fd=4))
进程显示为 systemd 而不是 sshd,说明这台机器用的是 socket 激活,监听端口由 ssh.socket 决定,第 4 条能看到它的 Listen 设置。
从外部确认端口,在你的电脑上执行 nc -v 服务器IP 22022,连上后应立刻返回一行以 SSH-2.0-OpenSSH_ 开头的版本信息。完全不知道端口被改成了多少、又登录不进去,可以对自己的服务器做一次全端口扫描 nmap -Pn -p- --open -sV 服务器IP,-sV 会识别出哪个端口上跑的是 ssh,65535 个端口扫完需要一些时间。客户端这边,ssh -G web01 | grep '^port ' 显示按 ~/.ssh/config 计算后,连 web01 时实际会用的端口。Windows Server 自带的 OpenSSH 服务端,配置文件在 C:\ProgramData\ssh\sshd_config,同样是 Port 一项。
修改 SSH 端口的完整步骤
先确认你的系统属于哪一类,几个关键差别都在这张表里:
| 发行版 | 服务名 | 谁负责监听端口 | 常用防火墙 | SELinux |
|---|---|---|---|---|
| RHEL、Rocky、AlmaLinux 8/9,CentOS 7 | sshd | sshd | firewalld | 默认开启,非 22 端口要登记 |
| Debian,Ubuntu 22.04 及更早 | ssh | sshd | ufw、nftables 或 iptables | 默认没有 |
| Ubuntu 24.04 及以后 | ssh | ssh.socket(systemd 代为监听) | ufw | 默认没有 |
同一发行版也可能被改过,以 systemctl is-active ssh.socket 的实际结果为准。动手之前准备好退路:保留当前的 SSH 窗口不关,并确认能打开服务器的 BMC 控制台或云平台的 VNC 控制台。下面以把端口从 22 改为 22022 为例。
- 先在外层放行新端口。 云服务器在安全组里加入方向 TCP 22022,源地址尽量填办公出口或堡垒机的 IP;机房服务器上游有 ACL 的,提前提交变更。这一层不放行,后面全部做对也连不上。
- 让 sshd 同时监听新旧两个端口。
Port和大多数 sshd 选项不同,不遵循“先读到的为准”,写几行就监听几个端口。主配置开头有Include /etc/ssh/sshd_config.d/*.conf的系统,新建一个文件:
# /etc/ssh/sshd_config.d/10-port.conf
Port 22
Port 22022
写之前用 grep -n '^\s*Port' /etc/ssh/sshd_config 看一眼主配置:里面已经有一行没注释的 Port 22,就不要在新文件里重复写 22。没有 Include 行的系统(CentOS 7、RHEL 8),直接在主配置里把 #Port 22 改成 Port 22,下面再加一行 Port 22022。注意改的是服务端的 sshd_config,不是客户端的 ssh_config。
- SELinux 登记新端口(RHEL 系):
getenforce # Enforcing 时必须做这一步
semanage port -l | grep -w ssh_port_t # 默认只有 tcp 22
semanage port -a -t ssh_port_t -p tcp 22022
semanage 由 policycoreutils-python-utils 软件包提供(CentOS 7 上是 policycoreutils-python)。如果提示 Port tcp/22022 already defined,说明这个端口已经登记给了别的类型,把 -a 换成 -m 改为 ssh_port_t,或者换一个端口。
- 系统防火墙放行新端口。 firewalld 有两种写法,第二种直接修改 ssh 服务的定义,所有引用了 ssh 服务的区域会一起生效:
# firewalld 写法一:单独放行端口
firewall-cmd --permanent --add-port=22022/tcp
# firewalld 写法二:给 ssh 服务加上新端口
firewall-cmd --permanent --service=ssh --add-port=22022/tcp
firewall-cmd --reload && firewall-cmd --list-all
# ufw
ufw allow 22022/tcp
# 直接用 iptables 的系统,加完要保存,否则重启后丢失
iptables -I INPUT -p tcp --dport 22022 -j ACCEPT
service iptables save # RHEL 系的 iptables-services
netfilter-persistent save # Debian 系的 iptables-persistent
- 检查语法并重启。
sshd -t # 没有输出就是语法正确
systemctl restart sshd # RHEL 系
systemctl restart ssh # Debian,Ubuntu 22.04 及更早
systemctl daemon-reload && systemctl restart ssh.socket # Ubuntu 24.04 及以后
ss -tlnp | grep -E ':22 |:22022 ' # 两个端口都应在监听
- 另开窗口测试新端口。
ssh -p 22022 运维账号@服务器IP,登录后再执行一次sudo -i,确认提权也正常。 - 关闭旧端口。 删掉配置里的
Port 22,再重启一次;撤掉 22 的放行规则:firewalld 用写法一的执行firewall-cmd --permanent --remove-service=ssh,用写法二的执行firewall-cmd --permanent --service=ssh --remove-port=22/tcp,然后 reload;ufw 用ufw status numbered找到 22 的规则编号后ufw delete 编号;安全组里删掉 22。最后从外部确认:nmap -Pn -p 22,22022 服务器IP显示 22 为 closed 或 filtered、22022 为 open,才算改完。
改完不生效或连不上:对照排查
| 现象 | 原因 | 处理 |
|---|---|---|
日志里有 Bind to port 22022 on 0.0.0.0 failed: Permission denied. |
SELinux 没有登记新端口 | 执行第 3 步后重启 sshd;用 journalctl -u sshd -n 20 查看日志 |
sshd -T 显示新端口,ss 里仍然只有 22 |
改完没有重启;或者是 socket 模式,只重启了 ssh 服务 | 按上表的发行版执行对应的重启命令 |
sshd -T 里看不到新端口 |
改错了文件,比如改成了客户端配置 /etc/ssh/ssh_config;或写在了没有被 Include 的目录里 |
确认改的是 sshd_config,主配置里有对应的 Include 行 |
服务器上监听正常,外部连接 Connection timed out |
安全组、机房 ACL 没放行;或者你所在的办公网只允许访问外部的常用端口 | 逐层核对;用手机热点连一次对比 |
Connection refused |
端口上没有 sshd 在监听,或者 iptables 用 REJECT 拒绝了连接 | 在服务器上核对 ss 的输出和防火墙规则 |
No route to host,但 ping 得通 |
firewalld 对没有放行的端口默认回复“管理禁止”,客户端显示为这条错误 | 回到第 4 步,用 firewall-cmd --list-all 确认新端口在列表里 |
启动失败,日志提示 Address already in use |
新端口已被别的程序占用 | 用 ss -tlnp 'sport = :22022' 找出占用者,换一个端口 |
| 连接新端口时又要求确认主机指纹 | known_hosts 对非 22 端口按 [地址]:端口 单独记录 |
核对指纹与原来一致后确认即可 |
改 SSH 端口有什么影响
改端口不是越改越安全,它的作用是降噪,代价是所有相关的地方都要同步。逐项看:
| 方面 | 影响 | 要做什么 |
|---|---|---|
| 自动扫描 | 只盯 22 端口的批量脚本扫不到,登录日志里的失败记录通常会明显减少,排查真正的异常更容易 | — |
| 定向攻击 | 全端口扫描很快就能找到新端口,连上后返回的 SSH-2.0- 版本信息直接表明这是 SSH |
安全仍然靠密钥登录、禁用密码和限定来源 |
| 安全组与 ACL | 每一层都要加新端口;云平台常见的默认安全组模板放行的是 22 | 改端口前先放行,确认后删除 22 |
| 堡垒机 | 堡垒机里登记的资产是“IP 加端口”,端口不同步,经堡垒机发起的会话会连接失败;会话审计本身不受影响 | 先在堡垒机里新增新端口的资产或修改端口,验证后再关旧端口 |
| 自动化与客户端 | ssh、scp、rsync、git、Ansible、监控、备份脚本里的端口都要跟着改 | 见下表 |
| 服务器主动连出去 | 不受影响,改的只是本机 sshd 的监听端口 | — |
| 带外控制台 | BMC 控制台、云平台 VNC 不经过 sshd,不受影响 | 留作改错时的退路 |
需要同步端口的常见位置:
| 工具 | 指定端口的写法 |
|---|---|
| ssh | ssh -p 22022 user@host |
~/.ssh/config |
在对应的 Host 下写 Port 22022,之后 ssh、scp、rsync、git 用别名连接都会自动带上 |
| scp、sftp | 大写的 -P 22022 |
| rsync | rsync -av -e 'ssh -p 22022' 源 目标 |
| git | ssh://git@host:22022/ops/app.git;git@host:路径 这种简写不能带端口 |
| Ansible | 清单里写 ansible_port=22022 |
| Zabbix 简单检查 | net.tcp.service[ssh,,22022] |
| fail2ban | jail 里写 port = 22022,过渡期写成 22,22022 |
关于堡垒机多说一句:如果服务器的 SSH 已经只对堡垒机的地址开放,外人连 TCP 握手都完成不了,这时再改端口几乎没有额外收益,反而增加了资产信息出错的机会。这种架构下保持 22、把来源限定死,比改端口更实在;真正暴露在公网上的是堡垒机自己的入口,该加固的是它。
在机房里怎么统一管理
机房里的服务器多了,SSH 端口最怕“每台不一样、只有当初改的人知道”。定一个统一的端口,写进装机后的初始化脚本,再把端口和管理地址一起记在资产信息里,后来的人才不会对着一台机器逐个端口去试。
改错了也不要慌,带外控制台就是为这种时候准备的。Toplink DCIM 的 IPMI 远程管理在浏览器里打开 VNC 控制台,走的是 BMC 通道,不依赖 sshd 的端口和系统防火墙,登录后把配置改回来即可;通过它发起的 SSH 会话全程录像,并记录命令级日志,经这些会话改过 sshd_config 的操作可以追溯。租用服务器的客户自己改端口把自己锁在外面时,可以在客户自助端打开 VNC 控制台自行修复,不必等工单。
常见问题
能不能让 SSH 只在内网地址上监听?
能。在 sshd_config 里写 ListenAddress 10.10.0.5,sshd 就只在这个地址上监听,公网地址上连端口都不存在;写成 ListenAddress 10.10.0.5:22022 还能指定端口。这个地址必须在 sshd 启动时已经配在网卡上,否则 sshd 会因为绑定不到地址而启动失败。
改了 SSH 端口,SFTP 和 SCP 的端口也会变吗?
会。SFTP、SCP 都跑在 SSH 连接里,和登录共用 sshd 的端口,没有单独的端口。FileZilla、WinSCP 等图形工具要在站点设置里把端口改成新值,协议仍然选 SFTP。
改 SSH 端口会断开当前的连接吗?
一般不会。已经建立的会话由各自的子进程维持,重启或重载 sshd 主进程不影响它们。但改端口时仍应保留当前窗口,另开一个窗口测试新端口,确认能登录之后再关闭旧端口。