服务器开放哪些端口比较安全?常见服务端口与最小权限原则

新装好的一台云服务器,安全组里图省事勾了"放行全部端口",三天后你发现它开始对外疯狂发包;给客户装的 Redis 为了方便调试直接绑了 0.0.0.0:6379 且没设密码,第二天数据被清空、还多了一个陌生的定时任务。这类事故的共同点不是技术不够,而是暴露面太大。互联网上每一台公网服务器都在被自动化程序持续扫描,一个开放端口从暴露到被探测,通常只需要几分钟到几小时。本文讨论的不是"哪个端口绝对安全"——没有任何端口是靠"冷门"来保证安全的——而是如何用最小权限原则,把该开的端口开得可控、把不该开的端口彻底关掉。

一、最小权限原则:先把暴露面压到最小

最小权限原则在端口管理上的含义很直白:只开放业务必需的端口,只对必需的来源 IP 开放,并且默认拒绝其他一切。它之所以比"多装防护"更重要,有三个现实原因。

1.1 每一个开放端口都是一份长期负债

你开放一个端口,等于承诺要长期维护它背后那个服务的安全:跟进补丁、管理账号、审计日志、关注漏洞公告。Redis 未授权访问、Elasticsearch 未授权访问、Docker Remote API 未授权访问、etcd 未授权访问——这些年几乎所有大规模数据泄露事件,根因都不是"端口被爆破",而是"这个端口本来就不该出现在公网上"。关掉端口是零成本且一劳永逸的防护;加防护是有成本且需要持续维护的。

1.2 默认拒绝比逐个封禁可靠得多

很多人的防火墙策略是"默认放行,发现坏人再封",这在自动化扫描面前必输无疑。正确顺序是反过来:先 iptables -P INPUT DROP 或 ufw default deny incoming,再逐条放行真正需要的服务。这样即使你以后装了新软件、开了新服务,也不会意外暴露到公网。

1.3 纵深防御:三层都要设防

  • 第一层:服务本身。让服务只监听内网地址或 127.0.0.1,从源头不暴露。例如 Redis 配置 bind 127.0.0.1,MySQL 配置 bind-address = 127.0.0.1。
  • 第二层:主机防火墙。iptables / nftables / ufw / firewalld,做端口与来源 IP 的双重限制。
  • 第三层:网络安全组。云厂商提供的虚拟化层防火墙,优先级高于主机内部规则,是最外层的一道。

三层中任何一层生效都能挡住攻击,但只有三层都配置正确,你才能在某一层被误改时仍然安全。

二、常见服务端口速查:哪些能开、哪些绝不能开

下表按"是否建议暴露到公网"给出判断。请特别注意:不建议开放不等于服务不能用,绝大多数情况是"只在内网用"或"通过 SSH 隧道 / VPN 访问"。

端口服务是否建议公网开放主要风险建议做法
22SSH可以,但需严格限制暴力破解、弱口令、0day禁止 root 直登、禁用密码改用密钥、限制来源 IP、部署 fail2ban
80HTTP可以明文传输、中间人劫持仅做 443 跳转,不承载实际业务
443HTTPS可以应用层漏洞、CC 攻击强制 TLS 1.2 以上,配 WAF 或 CDN
21FTP不建议明文口令、匿名用户、历史漏洞多改用 SFTP(复用 22 端口)或对象存储
23Telnet绝不允许完全明文,口令可被直接嗅探卸载服务,用 SSH 替代
25SMTP视情况,常被限制被用作开放中继导致 IP 被拉黑关闭中继、配置 SPF/DKIM/DMARC,或改用 587/465
53DNS仅权威/递归服务器按需开放被利用做反射放大攻击递归与权威分离,限制递归来源,启用响应速率限制
111 / 2049rpcbind / NFS绝不允许信息泄露、未授权挂载仅内网使用并限定来源网段
445 / 139SMB绝不允许历史高危漏洞密集,勒索软件主要入口彻底关闭,跨网文件共享走 VPN
1433 / 1521MSSQL / Oracle绝不允许弱口令、提权、数据泄露仅内网监听,远程用 SSH 隧道
3306 / 5432MySQL / PostgreSQL绝不允许弱口令、未授权访问、数据被删勒索bind 到内网地址,限制来源 IP,强口令
6379Redis绝不允许未授权访问可导致任意文件写入与命令执行bind 127.0.0.1、设置 requirepass、rename-command 高危命令
11211Memcached绝不允许未授权访问且可被用于反射放大仅监听 127.0.0.1 或内网
2375 / 2376Docker Daemon绝不允许未授权访问等同于拿到宿主机 root2375 必须关闭;仅用本地 socket 或 2376 配 TLS 证书
2379 / 2380etcd绝不允许未授权访问泄露集群全部配置与密钥仅内网监听并开启证书认证
27017MongoDB绝不允许默认无认证,数据被勒索删除高发开启 auth,bind 内网,限制来源
9200 / 9300Elasticsearch绝不允许默认无认证,数据可被任意读写开启安全认证,仅内网监听
3389RDP强烈不建议直接开放暴力破解、勒索软件入口先连 VPN 再连 RDP,或限制来源 IP 并启用网络级别认证
5900VNC不建议认证薄弱、明文传输仅通过 SSH 隧道访问
8080 / 8888备用 HTTP / 管理面板视情况常被误配为无认证管理后台管理后台必须加认证并限制来源 IP
161SNMP不建议社区名泄露导致信息泄露改用 v3 并限制来源,或直接关闭
123NTP不建议对公网提供可被用于反射放大攻击作为客户端同步即可,不对外提供授时服务

三、盘点:我这台机器到底开了哪些端口

很多人以为自己只开了 80 和 443,实际一查有三十多个监听。原因通常是系统预装服务和容器、Docker、K8s 组件自动映射的端口。先用下面的命令做一次完整盘点。

3.1 本机视角

# 列出所有 TCP/UDP 监听端口及对应进程(-l 监听 -n 不解析 -t TCP -u UDP -p 进程)
ss -lntup

# 只看监听中的 TCP 端口及进程
ss -lntp

# 提取本地监听地址端口列表
ss -lnt | awk 'NR>1 {print $4}' | sort -u

# 用 lsof 交叉核对(部分系统上 ss 的 -p 需要 root 权限)
lsof -i -nP | grep LISTEN

看结果时重点关注三件事:监听地址是 0.0.0.0(所有网卡)还是 127.0.0.1(仅本机)或是具体内网 IP;进程名是否认识;是否有预期之外的高位端口(常见来源:Docker 容器映射、Node/Python 调试服务、各类 Agent)。

3.2 外部视角

本机看到的监听不等于外部能访问到——中间还隔着主机防火墙和云安全组。所以必须再从外部做一次核对。请仅对你拥有或已获授权的资产执行:

# 从另一台机器扫描自己的服务器,做外部视角验证(-Pn 跳过主机发现 -sV 识别服务版本)
nmap -Pn -sT -sV -T4 --top-ports 1000 203.0.113.10

# 只验证某一个端口是否可达
nc -vz -w 3 203.0.113.10 6379

# 检查防火墙当前放行情况
iptables -L INPUT -n -v --line-numbers
ufw status numbered
firewall-cmd --list-all

外部扫出来的端口如果比本机监听的还多,说明有容器或 NAT 映射在起作用;如果比本机少,说明防火墙生效了,这是正常且期望的结果。两边结果应当能对上账,对不上就要逐层排查。

四、按服务器角色给出端口白名单

服务器角色建议对外开放端口仅内网开放必须关闭
公网 Web 服务器80、443、22(限来源 IP)无其他全部
数据库服务器22(限来源 IP)3306 / 5432 / 27017 等,限应用服务器 IP公网暴露的所有数据端口
应用服务器(内网)无,或仅 22(限堡垒机 IP)8080 等业务端口,限负载均衡 IP公网暴露的任何业务端口
堡垒机 / 跳板机22(限办公出口 IP)无其他全部,且不应安装任何业务服务
缓存服务器(Redis/Memcached)无6379 / 11211,限应用服务器 IP公网暴露
邮件服务器25、587、465、993无必须关闭开放中继

五、用防火墙落地最小权限

5.1 ufw(Ubuntu/Debian 推荐)

# 先设默认策略:拒绝所有入站,允许所有出站
ufw default deny incoming
ufw default allow outgoing

# 放行 SSH,强烈建议限定来源网段,并对 22 启用连接速率限制
ufw allow from 203.0.113.0/24 to any port 22 proto tcp
ufw limit 22/tcp

# 放行 Web 端口
ufw allow 80/tcp
ufw allow 443/tcp

# 启用并查看带编号的规则(编号用于删除规则:ufw delete 3)
ufw enable
ufw status numbered

操作顺序有个坑:执行 ufw default deny incoming 之后、执行 ufw enable 之前,务必先放行 SSH。如果你是通过 SSH 远程操作的,一旦在没放行 22 的情况下启用 ufw,连接会立刻断开。建议首次操作时先在控制台的 VNC 里做,或者用 at 定时一个自动回滚任务兜底。

5.2 iptables(通用)

# 默认策略:入站丢弃
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 放行本地回环,否则很多本机服务会异常
iptables -A INPUT -i lo -j ACCEPT

# 放行已建立的连接与相关连接(这一条非常关键,否则出方向的响应包回不来)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SSH 仅允许办公出口网段
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT

# Web 端口对公网开放
iptables -A INPUT -p tcp --dport 80  -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 允许 ICMP 但限速,既保留 ping 排障能力又降低被洪水利用的风险
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/s -j ACCEPT

规则写完后不要忘记持久化,否则重启即失效。Debian/Ubuntu 用 netfilter-persistent save(需先 apt install iptables-persistent),RHEL 系可用 service iptables save 或 iptables-save > /etc/sysconfig/iptables。

5.3 firewalld(RHEL/CentOS/Rocky)

# 查看当前区域与放行内容
firewall-cmd --get-default-zone
firewall-cmd --list-all

# 先加一条仅允许指定来源访问 ssh 的富规则,再移除对全网开放的 ssh 服务
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" service name="ssh" accept'
firewall-cmd --permanent --remove-service=ssh

# 放行 Web
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https

# 重新加载并核对
firewall-cmd --reload
firewall-cmd --list-all

六、端口收敛的实施步骤

  1. 盘点现状:用 ss -lntup 列出全部监听,用 nmap 从外部核对,形成一张"端口—进程—用途—是否必需"的清单。
  2. 标记必需性:对每个端口标注"公网必需 / 内网必需 / 完全不需要"三类。判断不了就先标为不需要,观察一周看有没有人反馈。
  3. 先改服务监听地址:把数据库、缓存类服务改成监听 127.0.0.1 或内网地址,这一步不依赖防火墙,最彻底。
  4. 再配置主机防火墙:按角色白名单逐条放行,默认拒绝。优先用 ufw 或 firewalld 这类高层工具,减少出错概率。
  5. 最后收敛云安全组:把安全组改成同样的白名单,确保两层一致。注意先加后删,避免中间态断连。
  6. 灰度验证:从外部用 nc -vz 逐个验证该通的通、该断的断,同时观察业务监控至少 24 小时。
  7. 固化为基线:把最终规则写进配置管理(Ansible、cloud-init 或镜像模板),让新开的机器自动带上正确的端口策略。

小结

端口安全的核心不是记住"哪个端口危险",而是建立"默认拒绝、按需放行"的习惯。一台合格的公网 Web 服务器,对外开放端口应该只有 80、443 和严格限制来源的 22;数据库、缓存、容器管理端口一律只出现在内网。落地时按"服务监听地址 → 主机防火墙 → 云安全组"三层顺序推进,并用 ss -lntup 与 nmap 做本机与外部的双视角核对。把端口清单纳入基线管理,比事后补救要省心得多。

避坑建议

  • 不要靠"改个冷门端口"来保证安全:端口扫描是全端口的,改成 2222 或 54321 只能减少日志噪音,挡不住真正的攻击者,反而会让你放松口令和密钥管理。
  • 不要忽略 Docker 会绕过 iptables:docker run -p 8080:80 会直接写入 iptables 规则,可能让你的 ufw 策略失效,容器场景需要额外关注 DOCKER-USER 链。
  • 不要在远程 SSH 里直接 ufw enable:务必先放行 22,否则会当场把自己锁在门外。
  • 不要忘记放行 lo 回环:很多本机服务依赖 127.0.0.1 通信,INPUT 默认 DROP 后不放行 lo 会出现各种莫名其妙的故障。
  • 不要忘了 ESTABLISHED,RELATED 规则:没有这条,服务器主动向外发起连接的返回包会被自己挡掉,表现为"能 ping 通但打不开网页"之类怪问题。
  • 不要改完就走:每收敛一次端口都要观察 24 小时业务监控,有些内部依赖(监控采集、日志上报、授权校验回调)不会立刻暴露。