iptables白名单配置及新增服务端口的方法

23次阅读
没有评论

iptables白名单配置及新增服务端口的方法

在 甲骨文(Oracle Cloud Infrastructure)云服务器上部署网站、管理面板或其他网络服务时,有一种比较常见的问题:

云平台安全规则明明已经放行了某个端口,但外部仍然无法正常访问。

这类问题很可能是因为服务器操作系统内部的 iptables / ip6tables 仍然存在入站限制。

云平台防火墙和服务器内部防火墙是两层独立的控制机制。

即使云平台允许某个端口,如果服务器内部的防火墙拒绝该连接,外部仍然无法访问。

本文不讨论具体的排查过程,只介绍一种简单、稳定、容易维护的解决方案:

使用 iptables 建立入站端口白名单,只开放真正需要公网访问的端口,其余入站连接默认拒绝。


一、什么是端口白名单?

端口白名单的核心思想非常简单:

只有明确允许的端口才能从公网访问,其他端口全部拒绝。

例如服务器上运行了多个服务:

服务 公网访问需求 防火墙处理
SSH 需要远程管理 开放对应端口
网站 需要公网访问 开放 HTTP/HTTPS 端口
管理面板 需要远程管理 根据实际需求开放
API 服务 需要公网访问 开放对应端口
数据库 仅服务器内部使用 不开放公网
内部服务 仅内部使用 不开放公网

这里最重要的原则是:

服务器上运行某个服务,并不代表这个服务必须对公网开放。

只有确实需要从互联网访问的服务,才应该开放对应端口。

二、配置 IPv4 防火墙白名单

首先清理当前 INPUT 链中的旧规则:

sudo iptables -F INPUT

允许已经建立的连接:

sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

允许本机回环:

sudo iptables -A INPUT -i lo -j ACCEPT

允许 ICMP:

sudo iptables -A INPUT -p icmp -j ACCEPT

然后开放实际需要公网访问的 TCP 端口:

sudo iptables -A INPUT -p tcp --dport <端口1> -j ACCEPT
sudo iptables -A INPUT -p tcp --dport <端口2> -j ACCEPT
sudo iptables -A INPUT -p tcp --dport <端口3> -j ACCEPT

如果某个服务使用 UDP,则添加 UDP 规则:

sudo iptables -A INPUT -p udp --dport <UDP端口> -j ACCEPT

最后增加一条统一拒绝规则:

sudo iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited

最终形成:

允许已经建立的连接
        ↓
允许本机通信
        ↓
允许 ICMP
        ↓
允许需要公网访问的 TCP/UDP 端口
        ↓
其他全部拒绝

三、IPv6 也要配置

如果服务器启用了 IPv6,只配置 IPv4 是不完整的。

首先清理 IPv6 INPUT 规则:

sudo ip6tables -F INPUT

允许已经建立的连接:

sudo ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

允许本机回环:

sudo ip6tables -A INPUT -i lo -j ACCEPT

允许 IPv6 ICMP:

sudo ip6tables -A INPUT -p ipv6-icmp -j ACCEPT

开放需要公网访问的 TCP 端口:

sudo ip6tables -A INPUT -p tcp --dport <端口1> -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport <端口2> -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport <端口3> -j ACCEPT

如果需要 UDP:

sudo ip6tables -A INPUT -p udp --dport <UDP端口> -j ACCEPT

最后:

sudo ip6tables -A INPUT -j REJECT --reject-with icmp6-port-unreachable

四、最重要的一点:REJECT 必须放在最后

iptables 按照规则从上到下依次匹配。

例如下面这种配置是错误的:

允许端口 A
允许端口 B
REJECT 所有其他连接
允许端口 C

端口 C 实际上无法访问。

因为数据包到达 REJECT 规则时已经被拒绝,后面的规则不会再执行。

正确结构应该是:

ACCEPT
ACCEPT
ACCEPT
ACCEPT
ACCEPT
REJECT

因此:

所有需要开放的端口,都必须位于最后一条 REJECT 规则之前。

五、保存防火墙规则

iptables 修改的是当前运行状态。

为了防止服务器重启后规则丢失,可以使用:

sudo netfilter-persistent save

然后设置开机自动加载:

sudo systemctl enable netfilter-persistent

检查服务:

sudo systemctl status netfilter-persistent

保存后的规则通常位于:

/etc/iptables/rules.v4
/etc/iptables/rules.v6

这样服务器重启之后,防火墙规则可以自动恢复。

六、以后新增服务如何开放端口?

这是这套方案最实用的地方。

假设以后服务器新增一个服务:

端口:45678
协议:TCP

只需要在防火墙白名单中增加这个端口即可。

IPv4:

sudo iptables -I INPUT 10 -p tcp --dport 45678 -j ACCEPT

如果需要 IPv6:

sudo ip6tables -I INPUT 10 -p tcp --dport 45678 -j ACCEPT

然后保存:

sudo netfilter-persistent save

这样新的服务端口就加入了公网访问白名单。

七、TCP 和 UDP 要区分

新增端口时,不仅要知道端口号,还要知道服务使用的是 TCP 还是 UDP。

TCP 示例:

sudo iptables -I INPUT 10 -p tcp --dport 45678 -j ACCEPT

UDP 示例:

sudo iptables -I INPUT 10 -p udp --dport 45678 -j ACCEPT

如果一个服务同时需要 TCP 和 UDP,那么需要分别添加两条规则:

sudo iptables -I INPUT 10 -p tcp --dport 45678 -j ACCEPT
sudo iptables -I INPUT 10 -p udp --dport 45678 -j ACCEPT

IPv6 同理。

八、为什么新增端口要使用 -I,而不是简单使用 -A?

如果当前 INPUT 链最后已经存在:

REJECT all

那么直接执行:

sudo iptables -A INPUT -p tcp --dport 45678 -j ACCEPT

会把新的 ACCEPT 规则放到 REJECT 后面。

这样新端口仍然会被前面的 REJECT 拒绝。

因此在这种白名单结构中,应该把新规则插入到 REJECT 前面,例如:

sudo iptables -I INPUT 10 -p tcp --dport 45678 -j ACCEPT

这里的数字 10 是示例位置。

实际操作时,建议先查看当前规则:

sudo iptables -L INPUT -n -v --line-numbers

找到最后的 REJECT 规则所在位置,然后将新的 ACCEPT 规则插入到 REJECT 之前。

九、新增端口后的完整操作流程

以后服务器增加任何需要公网访问的新服务,都可以按照下面的流程操作:

第一步:安装并启动新服务
        ↓
第二步:确认服务监听的端口
        ↓
第三步:确认使用 TCP 还是 UDP
        ↓
第四步:在 OCI 安全规则中允许该端口
        ↓
第五步:在 iptables 中加入白名单
        ↓
第六步:IPv6 环境同步配置 ip6tables
        ↓
第七步:保存 netfilter-persistent
        ↓
第八步:测试外部访问

这样以后无论新增什么服务,都不需要修改整个防火墙策略。

只需要增加对应的端口规则即可。

十、为什么推荐白名单,而不是开放所有端口?

有些服务器为了方便,会直接让:

INPUT ACCEPT

这样确实简单,但服务器上只要有服务监听某个端口,该服务就有可能直接暴露到公网。

例如服务器可能运行:

  • 数据库
  • FTP
  • RPC
  • 缓存服务
  • 内部管理服务
  • 其他系统服务

这些服务通常并不需要公网访问。

因此更加合理的做法是:

服务可以运行,但只有明确需要公网访问的端口才加入白名单。

这样即使某个服务意外启动并监听端口,也不会自动暴露到公网。

十一、只开放几个端口,会不会被扫描和暴力破解?

会。

需要明确:

端口白名单的作用是减少攻击面,而不是阻止公网扫描。

例如服务器开放了 SSH、网站和其他公网服务,那么这些开放端口仍然可能被互联网扫描器发现。

但是,与开放大量端口相比,白名单可以让大量不需要公网访问的服务直接处于不可访问状态。

可以简单理解为:

开放大量端口:

互联网
  ↓
大量端口
  ↓
发现各种服务
  ↓
针对不同服务进行攻击


端口白名单:

互联网
  ↓
少量必要端口
  ↓
其他端口直接拒绝

因此:

白名单不能防止扫描,但能够显著减少可被攻击的入口。

十二、管理入口需要重点保护

并不是所有开放端口的安全风险都一样。

例如 SSH、服务器管理面板等属于管理入口

如果攻击者成功获取管理账号,风险通常远高于单纯扫描普通业务端口。

因此建议:

  • SSH 使用 SSH Key
  • 尽可能关闭 SSH 密码登录
  • 禁止 root 直接远程登录
  • 使用强密码
  • 必要时限制管理入口的来源 IP
  • 可以使用 Fail2ban 等机制防止连续登录尝试
  • 管理面板及时更新

理想状态:

管理入口
   ↓
限制访问来源
   ↓
强身份认证
   ↓
必要时使用 SSH Key
   ↓
关闭不必要的密码登录

十三、网站端口无法避免公网扫描

如果服务器需要提供公网网站,HTTP/HTTPS 端口通常必须对公网开放。

因此网站可能会遇到:

  • 端口扫描
  • 漏洞扫描
  • 后台路径扫描
  • 登录尝试
  • 恶意请求

这是公网网站比较常见的现象。

网站本身应该做好:

  • 网站程序及时更新
  • 后台账号使用强密码
  • 不使用默认账号
  • 及时修复程序漏洞
  • 对重要后台增加额外保护
  • 根据实际情况使用 CDN/WAF 等安全服务

十四、OCI 安全规则和服务器防火墙是两层防护

需要特别注意:

OCI Security List / NSG 与服务器内部的 iptables 是两套独立的防火墙。

可以简单理解为:

互联网
   ↓
OCI Security List / NSG
   ↓
服务器网卡
   ↓
iptables / ip6tables
   ↓
具体服务

一个端口要能够正常访问,通常需要两个层面都允许。

例如新增一个服务:

新服务端口
   │
   ├── OCI 安全规则 → Allow
   │
   └── 服务器 iptables → ACCEPT

两个条件都满足,外部才能正常连接。

因此以后新增服务端口时,需要同时注意:

  1. OCI 安全规则是否允许
  2. IPv4 iptables 是否允许
  3. IPv6 ip6tables 是否允许(如果使用 IPv6)
  4. 服务是否真正监听该端口
  5. 端口使用的是 TCP 还是 UDP

十五、推荐的长期管理方式

对于个人服务器或者中小型服务器,推荐采用这种简单的结构:

OCI
 │
 └── 负责云平台层面的端口控制

服务器 iptables
 │
 └── 负责公网入站白名单

各种服务器服务
 │
 └── 负责实际业务

各自负责自己的事情:

组件 主要职责
OCI Security List / NSG 云平台层面的网络访问控制
iptables 服务器 IPv4 入站访问控制
ip6tables 服务器 IPv6 入站访问控制
具体服务 提供实际业务功能

这样职责清晰,出现问题时也更容易处理。

十六、日常只需要记住这些命令

查看 IPv4 防火墙:

sudo iptables -L INPUT -n -v --line-numbers

查看 IPv6:

sudo ip6tables -L INPUT -n -v --line-numbers

新增 TCP 端口:

sudo iptables -I INPUT 10 -p tcp --dport <端口号> -j ACCEPT

新增 UDP 端口:

sudo iptables -I INPUT 10 -p udp --dport <端口号> -j ACCEPT

IPv6 TCP:

sudo ip6tables -I INPUT 10 -p tcp --dport <端口号> -j ACCEPT

IPv6 UDP:

sudo ip6tables -I INPUT 10 -p udp --dport <端口号> -j ACCEPT

保存规则:

sudo netfilter-persistent save

设置开机自动恢复:

sudo systemctl enable netfilter-persistent

十七、总结

OCI 云服务器出现:

云平台端口已经放行,但外部仍然无法访问

时,除了 OCI 的安全规则之外,还需要考虑服务器内部的 iptables / ip6tables

一种简单、可靠并且容易维护的方案就是:

建立端口白名单 + 最后一条统一 REJECT + netfilter-persistent 持久化。

以后服务器增加新的公网服务,不需要重新设计整个防火墙。

只需要根据服务实际使用的协议和端口,增加对应的 ACCEPT 规则即可:

TCP 服务
    ↓
增加 TCP 端口

UDP 服务
    ↓
增加 UDP 端口

TCP + UDP 服务
    ↓
分别增加 TCP 和 UDP 规则

仅服务器内部使用的服务
    ↓
无需开放公网端口

最后保存:

sudo netfilter-persistent save

需要注意的是:

端口白名单不能阻止公网扫描,只能减少公网暴露面。

因此服务器安全应该采用多层防护:

OCI Security List / NSG
          ↓
iptables / ip6tables
          ↓
管理入口安全
          ↓
应用程序自身安全
          ↓
必要时增加 WAF / Fail2ban 等防护

最终原则只有一句话:

需要对公网开放的端口,明确加入白名单;没有明确开放的端口,默认拒绝。

这样既能保证服务器上的公网服务正常运行,也能最大限度减少不必要的公网暴露面。

正文完
 0
许君楠
版权声明:本站原创文章,由 许君楠 于2026-09-16发表,共计5412字。
转载说明:
1、转载请保留本文地址及链接,本站保留追究法律责任的权力。
2、部分文章来源于网络,仅作为学习展示之用,版权归原作者所有。
3、因部分文章网络流转次数较多,已无法追溯至原作者,若遗漏导致侵犯了您的权益,请您 留言给我 。
评论(没有评论)
验证码