新买一台云服务器,很多人第一件事就是"把需要的端口都开上",图个方便。结果几个月后回头一看,安全组里躺着一堆自己都不记得为什么开着的端口:数据库的 3306、缓存的 6379、管理界面的 8080,有的甚至把 22 和 3389 直接对着全网开放。服务器安全的很多麻烦,根源不在"被攻破的技术有多高深",而在于"暴露面本来就不该这么大"。这篇文章要做的就是帮你建立一套判断框架:哪些端口可以开、哪些绝对不该暴露在公网、怎么用最小化的方式把端口管起来。
文章会先讲清楚端口、监听、暴露面这几个概念之间的关系,再给出一张常见端口的用途与风险对照表,然后讲为什么改默认端口的安全收益有限,最后落到"怎么收敛暴露面"的具体做法上。所有命令区分 RHEL/CentOS/Rocky 与 Debian/Ubuntu 两套,涉及防火墙和高危端口的操作都会给出风险提示和回滚方式。
需要强调的前提:本文只从防御和运维角度看端口管理,教你怎么减少不必要的暴露、怎么限制谁能访问,不涉及任何探测或攻击手段。理解"敌人会怎么看你",是为了让自己少暴露,而不是去扫描别人。
一、端口、监听与暴露面:先把关系理清
端口是操作系统给网络程序准备的"门牌号",范围是 0 到 65535。一个服务要对外提供能力,就得在某个端口上"监听"(listen)。但"监听"和"能被公网访问"是两回事,这中间隔着好几层:程序是否监听、监听的是 127.0.0.1 还是 0.0.0.0、本机防火墙是否放行、云平台的安全组是否放行、公网路由是否可达。任何一层拦住,外部就进不来。
暴露面(attack surface)这个概念说的就是"从公网能摸到的入口总和"。它不仅仅是端口数量,还包括:一个端口背后跑的是什么服务、这个服务有没有已知漏洞、版本信息是否泄露、认证是否够强。把端口关掉是最直接的收敛方式,因为它连"让对方看到这里有个服务"的机会都不给。
理解这个分层模型,能解释很多日常困惑。比如"我明明防火墙关了 3306,为什么还担心数据库安全"——如果数据库监听的是 0.0.0.0,而云安全组开了 3306,那防火墙就形同虚设;反过来,如果数据库只监听 127.0.0.1,那么无论外层怎么配,公网都碰不到它。最稳的做法永远是两层一起做:程序只监听本机(或内网),外层的防火墙和安全组只放行真正需要的来源。
想看清本机到底在监听什么,用一条命令就够:
# 列出所有 TCP/UDP 监听端口,并显示对应的进程(需要 root 才能看全进程名)
sudo ss -lntup
# 只关心 TCP 监听
sudo ss -lntp
# 老系统如果没装 ss,可用 netstat(需 sysstat/net-tools 包)
# RHEL 系:sudo yum install net-tools
# Debian/Ubuntu:sudo apt install net-tools
sudo netstat -lntp
ss 的输出里,Local Address:Port 这一列最关键。如果显示 127.0.0.1:3306,说明只监听本机,公网碰不到;如果显示 0.0.0.0:3306 或 *:3306,说明监听所有网卡,是否危险就取决于防火墙和安全组的配置了。看到 0.0.0.0 上的数据库或缓存端口,就应该立刻警惕。
二、常见端口用途与风险对照表
下面这张表列出了服务器上最常遇到的端口。判断逻辑很简单:越是被全球自动化脚本盯上的端口,暴露在公网的风险就越高;越是后端基础设施端口,就越应该只对内网开放。
| 端口 | 服务 | 常见用途 | 公网暴露风险 | 建议 |
|---|---|---|---|---|
| 22 | SSH | 远程登录管理 | 高(爆破重灾区) | 尽量限制来源 IP;用密钥登录;必要时改端口降低噪声 |
| 3389 | RDP | Windows 远程桌面 | 极高(爆破+漏洞重灾区) | 绝不裸奔公网;走 VPN 或白名单 |
| 80 | HTTP | 明文 Web | 中(业务需要) | 正常开放;配合 301 跳转到 HTTPS |
| 443 | HTTPS | 加密 Web | 低(业务需要) | 正常开放;证书和 TLS 配置要规范 |
| 3306 | MySQL/MariaDB | 数据库 | 极高 | 只监听内网或本机;绝不公网开放 |
| 5432 | PostgreSQL | 数据库 | 极高 | 同上 |
| 6379 | Redis | 缓存 | 极高(历史上有未授权访问问题) | 只监听内网;务必设密码/ACL |
| 27017 | MongoDB | 文档数据库 | 极高 | 只监听内网;开启认证 |
| 9200 | Elasticsearch | 搜索/分析 | 极高 | 只监听内网;加认证与网络隔离 |
| 11211 | Memcached | 内存缓存 | 极高(UDP 放大滥用风险) | 只监听内网;禁止公网 |
| 21 | FTP | 文件传输 | 高(明文+匿名访问风险) | 尽量用 SFTP 替代;如必须用则限来源 |
| 25 | SMTP | 邮件发送 | 中高(开放中继风险) | 只给邮件服务本身用;避免开放中继 |
| 8080/8443 | 备用 Web/管理台 | 应用、管理后台 | 高 | 管理台走内网或白名单;避免公网裸奔 |
| 2375/2376 | Docker API | 容器管理 | 极高 | 绝不公网开放;优先用本地 socket |
这张表值得记住的核心结论只有一句:凡是数据库、缓存、搜索、管理接口这类"后端基础设施",天生就不该对公网开放。 它们的设计假设是"运行在可信内网里",很多默认配置甚至不带认证或认证很弱,一旦被暴露,后果往往是数据直接泄露。Web 业务需要对外的是 80 和 443,其余后端端口都应该是内网内部的通信。
三、高危端口为什么不能裸露公网
有人会问:我数据库设了强密码,为什么还不能开公网?密码强当然好,但把数据库端口放到公网,你等于同时暴露了三样东西——服务本身可能存在的漏洞、版本信息、以及巨大的爆破目标。密码只是最后一层,而前面这些漏洞你往往控制不了。
以 Redis 为例,早期版本默认不带任何认证,只要监听在公网,别人一连上就能读写数据,甚至利用它写文件来进一步控制机器。这不是"密码设得不够强"的问题,而是"门本来就不该开"。再比如 Elasticsearch,默认无认证、数据以明文形式提供,暴露在公网等于把数据目录直接公开。这类服务的共同点是:它们本是为内网设计的,你把它放到公网,等于给它换了使用场景,风险自然成倍上升。
风险还体现在"自动化程度"上。全球的扫描器全天候在扫全网 IP 的这些常见端口,一旦发现开放且可连,就会自动尝试利用。你不需要被"盯上",只需要"存在"就会被扫到。这也是为什么很多人觉得"我这服务器没名气,没人会攻击我"是错的:攻击不需要你有名气,只需要你的 IP 存在且端口开着。
# 想确认某个服务是否只监听本机,直接在服务器上看监听地址
sudo ss -lntp | grep -E ':(3306|6379|27017|9200|11211)\b'
# 若看到 0.0.0.0 或 :: 开头的监听,说明它对所有网卡开放,需要赶紧收窄
收窄的方式有两种:改服务配置让它只监听 127.0.0.1 或内网 IP,或者用防火墙只放行内网来源。两者最好一起做。以 MySQL 为例,bind-address 设为 127.0.0.1 是标准做法;Redis 用 bind 127.0.0.1 并配合 requirepass;MongoDB 用 bindIp 限定地址。这些都是配置一行的事,但能挡掉绝大部分风险。
四、安全组最小化:只放行"必要且可信"
云服务器都有一层"安全组"(有的叫网络安全组、防火墙策略),它是云平台层面的虚拟防火墙,和操作系统里的防火墙是两层独立的东西。配置安全组的时候,最容易犯的错就是"图省事,对来源填 0.0.0.0/0"。正确的心智模型应该是:默认拒绝,逐条放行,且每条都尽量限定来源和端口。
一个典型的、健康的安全组规则大致是这样的:
| 方向 | 协议 | 端口 | 来源 | 用途 |
|---|---|---|---|---|
| 入站 | TCP | 443 | 0.0.0.0/0 | 对外提供 HTTPS 网站 |
| 入站 | TCP | 80 | 0.0.0.0/0 | HTTP 跳转与证书校验 |
| 入站 | TCP | 22 | 办公/跳板机 IP 段 | 运维登录 |
| 入站 | TCP | 3306 | 应用服务器内网 IP | 应用访问数据库 |
| 入站 | 所有 | 所有 | 默认拒绝 | 兜底 |
规则表里的关键点有三个。第一,80 和 443 开放全网是业务需要,可以接受。第二,SSH 的 22 口来源应该是你自己的固定出口或跳板机网段,而不是 0.0.0.0/0;如果你的办公 IP 不固定,可以配合 VPN,把 SSH 藏在 VPN 网络里。第三,数据库端口只允许应用服务器的内网 IP 访问,绝不放公网。最后一定要有一条"默认拒绝一切"的兜底规则,确保没有漏网之鱼。
安全组和主机防火墙的职责要分清。安全组是云平台层的,即使服务器系统还没启动,它就已经在拦截了;主机防火墙(firewalld、ufw、nftables)是系统层的,能更精细地按进程和用户控制。两层都要配,且思路一致:默认拒绝,按需放行。不要因为"安全组已经配了"就完全不管主机防火墙,多一层纵深防御没有坏处。
# RHEL / CentOS / Rocky:firewalld 常用操作
sudo firewall-cmd --state # 查看运行状态
sudo firewall-cmd --list-all # 查看当前放行的服务/端口
# 放行 HTTPS(永久生效,需 reload 或 --runtime-to-permanent 固化)
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# 只允许某个网段访问某个端口(富规则)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" port port="3000" protocol="tcp" accept'
sudo firewall-cmd --reload
# Debian / Ubuntu:ufw 常用操作
sudo ufw status verbose # 查看状态与规则
sudo ufw default deny incoming # 入站默认拒绝(重要)
sudo ufw default allow outgoing # 出站默认放行
sudo ufw allow 443/tcp # 放行 HTTPS
sudo ufw allow from 198.51.100.0/24 to any port 22 proto tcp # 仅允许某网段访问 SSH
sudo ufw enable # 启用(会提示可能影响现有连接)
风险提示:ufw enable 或 firewalld 的收紧操作,如果当前没有把 SSH 端口放行,或者规则里漏掉了你的来源 IP,会立刻切断你正在使用的 SSH 连接,导致自己进不去。执行任何防火墙收紧操作之前,务必先确认 SSH 端口已放行、你的来源 IP 在允许范围内,并保留云控制台入口。回滚方式:firewalld 可用 sudo systemctl stop firewalld 临时恢复全部放行;ufw 可用 sudo ufw disable 临时关闭。
五、改默认端口:收益有限,别当主力
"把 SSH 从 22 改到某个高位端口就安全了"——这是流传很广的一个说法。它有部分道理,但远远不够,理解它的边界很重要。
改端口带来的实际收益只有一个:降低日志噪声。因为绝大多数自动化扫描默认只扫 22,你换到别的端口,这些扫描就碰不到你,登录日志会干净很多,也能减少 Fail2ban 的误报压力。这个收益是真实的,值得做。
但改端口不等于安全。如果对方是针对性目标,用一次全端口扫描(几分钟的事)就能发现你把 SSH 挪到了哪。所以改端口的效果本质上是"防君子不防小人"的隐蔽手段,它能过滤掉泛泛的机器扫描,但挡不住专门找你的人。把它的定位搞清楚,就不会产生"改了端口就高枕无忧"的错觉。
真正决定 SSH 安全的,是前面几篇文章讲的那些:只用密钥登录、关闭密码认证、限制来源 IP、必要时走 VPN。改端口可以作为这些措施之上的"减噪"补充,但绝不能替代它们。如果你时间有限,优先把密钥登录和来源限制做好,再去考虑要不要改端口;顺序反了,就是把精力花在了收益最小的那部分上。
# 如果要改 SSH 端口,改的是 sshd 配置:
sudo vi /etc/ssh/sshd_config
# 修改或添加:Port 22022
# 关键:改端口前必须在防火墙和安全组里先把新端口放行,否则会把自己锁在外面
# RHEL 系:sudo firewall-cmd --permanent --add-port=22022/tcp && sudo firewall-cmd --reload
# Debian/Ubuntu:sudo ufw allow 22022/tcp
# 校验语法后用 reload,不要 restart
sudo sshd -t && sudo systemctl reload sshd
# 打开一个【新】终端,用新端口验证能登录,通过后再关掉旧连接
ssh -p 22022 admin@198.51.100.20
如果你启用了 SELinux(RHEL 系默认),改 SSH 端口还需要告诉 SELinux 新端口允许的用途,否则 sshd 会起不来。
# 让 SELinux 允许 sshd 使用新端口
sudo semanage port -a -t ssh_port_t -p tcp 22022
# 查看当前允许的 ssh 端口
sudo semanage port -l | grep ssh
风险提示:改 SSH 端口是高风险的登录相关操作,回滚方式是把 sshd_config 里的 Port 改回 22 并 reload。改之前务必用 sudo ss -lntp | grep sshd 确认新的监听真正生效,并始终保留一条已建立的旧连接。
六、一种务实的端口收敛流程
把上面的内容串起来,一套可执行的收敛流程是这样的。
第一步,盘点。用 ss -lntup 列出所有监听端口,逐个问三个问题:这个端口是干什么的、它有没有必要被公网访问、它的来源应该是谁。把答案记下来,这就是你的端口清单。
第二步,定位高危项。凡是数据库、缓存、搜索、消息队列、Docker API、管理后台这类,一律标记为"不得公网开放"。只要发现它们在 0.0.0.0 上监听且安全组放行了公网,就是最高优先级要处理的问题。
第三步,收窄监听地址。能只监听本机的就只监听本机;需要被同机其他进程访问的,走本地 socket 或 127.0.0.1;需要被内网其他机器访问的,绑定内网 IP。
第四步,收紧防火墙与安全组。安全组改成"默认拒绝 + 逐条放行 + 限定来源",主机防火墙同步配置。管理类端口(SSH、控制台)优先走白名单或 VPN。
第五步,关停无用服务。很多服务器上跑着当年装了就没用过的服务,它们占着端口、消耗资源、增加暴露面。确认不需要的,直接停掉并禁止开机自启。
第六步,持续复查。端口清单不是一次性工作,业务变了,端口需求也会变。建议每季度或每次上线新服务时复查一遍安全组和监听列表。
# 查看并停用不需要的服务(示例:停掉并禁用某服务)
sudo systemctl stop <服务名>
sudo systemctl disable <服务名>
# 确认它的端口确实不再监听
sudo ss -lntp | grep <端口号>
风险提示:停用服务前要确认它没有被业务依赖,尤其是共享的中间件。建议先在非生产环境验证,或选在业务低峰期操作,并记下恢复命令(systemctl enable --now <服务名>)。
常见问题
Q:数据库必须让另一台服务器访问,又不能开公网,怎么办?
让两台机器处在同一内网(如 VPC 私有网络),数据库只绑定内网 IP,安全组只放行应用服务器的内网 IP。这样流量走内网,公网碰不到,是标准做法。跨地域的两地互访,则应该用 VPN 或专线把网络打通,而不是把数据库端口暴露到公网。
Q:怎么判断一个端口是不是"对外真的开放"?
在服务器上用 ss -lntp 看监听地址,再看云安全组是否放行,最后从你自己的电脑尝试连接。三者都通才叫真正对外可达。很多"我明明没开啊"的困惑,其实是安全组开着、或监听地址是 0.0.0.0 造成的。
Q:改了 SSH 端口以后,Fail2ban 还要改吗?
要。Fail2ban 的 sshd jail 有 port 配置项,改端口后同步更新即可;它主要靠日志工作,端口信息用于封禁规则的表述,改一下保持一致性就行。
Q:80 端口要不要关掉,只留 443?
从安全角度,只留 443 更干净。但从实际使用看,80 通常用于把 HTTP 请求 301 跳转到 HTTPS,以及 Let's Encrypt 的 HTTP-01 证书校验。多数场景保留 80、配置好跳转即可;如果确定不需要,也可以只留 443,改用 DNS-01 校验证书。
Q:安全组和系统防火墙都配了会不会冲突?
不会冲突,它们是两道独立的门,报文要穿过两道。规则不一致时,更严格的那道会先拦住流量。思路是让两者都遵循"默认拒绝、按需放行",保持规则一致,便于排查。
总结
端口管理的本质是暴露面管理。你不需要记住所有端口号,但必须建立一条判断原则:后端基础设施端口(数据库、缓存、搜索、管理接口)永远不该暴露公网,对外只需要开放业务真正需要的 80 和 443。
用 ss -lntup 盘点监听、用安全组和主机防火墙做"默认拒绝 + 逐条放行 + 限定来源",是收敛暴露面最直接有效的手段。留意监听地址是 127.0.0.1 还是 0.0.0.0,这一个细节就能决定端口到底能不能被公网摸到。
改 SSH 端口只能降低扫描噪声,不是安全措施本身。真正的安全来自密钥登录、来源限制、及时补丁和最小化服务,改端口只是锦上添花。
任何影响登录或防火墙的改动,都要先放行、再验证、留后路、备回滚。把云控制台入口和恢复命令准备好,你才能在收紧暴露面的同时,不把自己关在门外。养成定期复查端口清单的习惯,暴露面才不会随着时间慢慢膨胀回去。
企业QQ咨询




