微分段要解决的问题很具体:一台办公电脑中了木马,攻击者能在几分钟内扫到数据库端口并尝试连接。绝大多数中小企业内网是平整的,一个 192.168.1.0/24 里塞着办公终端、财务系统、数据库和监控摄像头,任何一台设备都能和任何一台设备通信。微分段就是把这张大平面切成若干小区块,让跨区块的每一次访问都必须经过显式授权。
适用场景
三类环境收益最明显:一是终端数量超过五十台、且出现过终端被植入恶意程序的办公网;二是研发、财务、运维混在同一网段,彼此能随意访问对方主机的场景;三是接入了一批 IoT 设备(摄像头、门禁、打印机),这些设备固件老旧、几乎无法打补丁,必须靠网络层把它圈起来。如果内网只有几台服务器且已有物理隔离,做微分段的投入产出比并不高。
前置条件
- 一台可做三层转发的 Linux 主机作为区块间网关,或具备 VLAN 接口与 ACL 能力的三层交换机。
- 支持 802.1Q 的接入交换机,能划分 VLAN 并配置 Trunk。
- 完整的资产清单,包含 IP、用途、归属人、对外提供的端口。没有清单无法设计策略。
- 一次可接受短暂中断的维护窗口,VLAN 切换会重置现网连接。
原理说明:分段不是划 VLAN 就完事
VLAN 只解决二层广播域隔离,它让不同 VLAN 之间不能通过 ARP 直接通信。但只要三层设备上配了路由,跨 VLAN 的流量照样通。所以”划了 VLAN 就安全了”是典型误解——真正的控制点在三层转发路径上的访问控制。
完整的微分段是三层配合:VLAN 做粗粒度分区(办公、服务器、管理、IoT 各自独立),网关 ACL 做区块间策略(谁可以访问谁、访问哪个端口),主机防火墙做最后兜底(即使网关被绕过,主机自己也只接受白名单来源)。只做前两层,一旦有双网卡主机或配置错误的路由,隔离就会失效;只做第三层,则每台机器都要维护一份策略,规模一大必然失控。
策略设计的关键是”默认拒绝、按需放行”。传统内网习惯是默认允许、出问题再封,这在微分段里必须反过来:先设为 policy drop,然后按业务逐条开洞。开洞的过程中会有业务中断报障,所以规则日志必须先于拦截上线,用一周日志把真实流量摸清楚,再切换为拒绝。
操作步骤
第一步:测绘真实的东西向流量
不要凭想象写策略。先在网关上把转发的流量记下来,一周后按源、目的、端口聚合,这才是策略的原始输入。
# 在网关侧临时记录跨段新建连接,注意控制日志量
nft add table inet audit
nft add chain inet audit fwd '{ type filter hook forward priority -10 ; policy accept ; }'
nft add rule inet audit fwd ct state new log prefix "SEG_AUDIT " level info accept
# 落盘后按三元组聚合,取前 40 条高频组合
journalctl -k --since "7 days ago" | grep SEG_AUDIT \
| sed 's/.*SRC=//' | awk '{print $1, $4, $6, $7}' \
| sort | uniq -c | sort -rn | head -40
输出里出现的高频组合就是必须放行的业务关系,低频但关键的组合(例如备份任务每晚一次)需要单独确认,不能只按频次排序就丢掉。
第二步:划分 VLAN 并建立区块清单
按”信任等级 + 变更频率”分组,而不是按部门分组。部门分组会导致财务和研发各自一套策略,维护量翻倍。典型五分法如下:
- VLAN 10 办公终端:员工 PC,
192.168.10.0/24,只允许出向访问服务器指定端口。 - VLAN 20 业务服务器:应用与数据库,
192.168.20.0/24,按应用矩阵互相访问。 - VLAN 30 运维管理:跳板机与监控,
192.168.30.0/24,可访问其他区块管理端口。 - VLAN 40 IoT 设备:摄像头、门禁、打印机,
192.168.40.0/24,只允许被指定服务器访问,禁止主动外联。 - VLAN 99 隔离区:无法归类的新设备,默认只能访问补丁源,接入前必须登记。
网关侧创建对应的 VLAN 子接口:
ip link add link eth1 name eth1.10 type vlan id 10
ip link add link eth1 name eth1.20 type vlan id 20
ip link add link eth1 name eth1.40 type vlan id 40
ip addr add 192.168.10.1/24 dev eth1.10
ip addr add 192.168.20.1/24 dev eth1.20
ip addr add 192.168.40.1/24 dev eth1.40
ip link set eth1.10 up
ip link set eth1.20 up
ip link set eth1.40 up
ip -d link show eth1.10
交换机侧对应端口设为 access vlan 10/20/40,上联口设为 trunk 并放行全部 VLAN。不要在下发 VLAN 的同时留下默认路由互通,否则等于没分。
第三步:网关侧写东西向策略
核心是一个 policy drop 的 forward 链,配合 ipset 式的集合管理例外。下面这套规则实现了:办公只许访问业务服务器的 Web 端口,业务服务器之间按需互通,IoT 只能被监控服务器采集,其余一律拒绝并记日志。
nft add table inet seg
nft add set inet seg web_servers '{ type ipv4_addr ; flags interval ; }'
nft add element inet seg web_servers '{ 192.168.20.11-192.168.20.20 }'
nft add chain inet seg forward '{ type filter hook forward priority 0 ; policy drop ; }'
# 已建立连接直接放行,避免回包被丢
nft add rule inet seg forward ct state established,related accept
# 办公 -> 业务服务器 仅 80/443
nft add rule inet seg forward ip saddr 192.168.10.0/24 ip daddr @web_servers tcp dport '{ 80, 443 }' accept
# 办公 -> DNS 与补丁源
nft add rule inet seg forward ip saddr 192.168.10.0/24 ip daddr 192.168.20.5 udp dport 53 accept
# 运维管理段 -> 全部区块 SSH/RDP
nft add rule inet seg forward ip saddr 192.168.30.0/24 tcp dport '{ 22, 3389 }' accept
# IoT 只能被监控服务器采集,且禁止主动出网
nft add rule inet seg forward ip saddr 192.168.40.0/24 ip daddr 192.168.20.30 tcp dport 554 accept
nft add rule inet seg forward ip daddr 192.168.40.0/24 ct state new log prefix "IOT_IN " drop
# 其余新建连接记日志后丢弃
nft add rule inet seg forward ct state new limit rate 20/second log prefix "SEG_DENY " drop
nft list ruleset > /etc/nftables.seg.conf
注意 ct state established,related accept 必须放在最前面。少了它,所有回包都会被丢,表现为”能连上但立刻断开”,排查时很容易误判成应用故障。
第四步:主机侧兜底
网关策略挡不住同 VLAN 内的横向访问,所以每台服务器还要有自己的入站白名单。这一段用同一套 nftables 语法,但挂在 input 钩子上,默认拒绝入站。
nft add table inet host
nft add chain inet host input '{ type filter hook input priority 0 ; policy drop ; }'
nft add rule inet host input iif lo accept
nft add rule inet host input ct state established,related accept
nft add rule inet host input ip saddr 192.168.30.0/24 tcp dport 22 accept
nft add rule inet host input ip saddr 192.168.10.0/24 tcp dport '{ 80, 443 }' accept
nft add rule inet host input icmp type echo-request limit rate 5/second accept
nft add rule inet host input ct state new log prefix "HOST_DENY " drop
nft list chain inet host input
顺序原则:先放行回环与已建立连接,再放行业务端口,最后统一丢弃。千万不要写成默认 accept 再靠 deny 补,nftables 的 drop 一旦漏写一条就全通。
第五步:策略收敛与例外登记
上线两周内必然收到”某系统连不上”的报障。此时不要直接开全通,而是从日志里取证据:
journalctl -k --since "1 hour ago" | grep SEG_DENY | tail -20
# 统计被拒最多的目的端口,判断是策略缺失还是异常扫描
journalctl -k --since "24 hours ago" | grep SEG_DENY \
| grep -oP 'DPT=\K[0-9]+' | sort | uniq -c | sort -rn | head
如果某个端口在多个源地址上同时出现高频拒绝,大概率是策略缺项;如果集中在单一源地址且端口分散,那是扫描行为,应当处置主机而不是改策略。这个判断直接决定后续动作,不能只看”业务报障”就开口子。
配置验证
- 跨段探测:从办公段执行
nmap -Pn -p 22,3306,3389 192.168.20.0/24,除已放行端口外应全部filtered,不能出现open。 - IoT 外联阻断:从 IoT 段执行
curl -m 5 http://192.168.10.50,应超时,且网关日志出现IOT_IN。 - 业务连通:按策略矩阵逐条验证,每条放行规则都要有对应的一次成功访问记录,未验证的规则视为无效。
- 策略持久化:
systemctl restart nftables后重新执行一次探测,确认规则重启后仍在,否则说明没写进配置文件。
常见问题
Q1:划了 VLAN 之后打印机和摄像头都失联了,是不是策略写错了?
先查两件事。第一,IoT 设备通常不支持跨网段发现,它们靠二层广播找管理端,划到独立 VLAN 后广播被隔离,表现为”设备在线但平台看不到”。解决办法是把管理平台的一个网卡接入 IoT VLAN,或者改用设备的单播注册方式。第二,检查 DHCP 是否已在新区块生效——很多失联其实是设备拿不到地址,退回了 169.254 自分配地址。这两个原因的排查路径完全不同,先看设备 IP 再动策略。
Q2:分段之后东西向流量都过网关,网关会不会成为瓶颈和单点?
会,所以网关选型要按峰值转发量算,而不是按平均值。软件网关在千兆环境下通常能跑到几 Gbps 的转发,对几百台终端的内网足够;但如果区块间有大流量(备份、视频流),应当把这些流量用直连链路或独立 VLAN 旁路掉,不要让它穿过策略网关。单点问题用 VRRP 做双机,两台共享同一套规则,切换时策略不变。规模再大就应当把策略下沉到接入交换机或采用微隔离产品,Linux 网关方案适合 500 台终端以内的场景。
Q3:策略写了几百条之后怎么维护?
按”区块对区块”组织,而不是按单主机。每条规则必须带注释说明业务归属和责任人,nftables 支持 comment "..."。同时建立策略矩阵表:行是源区块,列是目的区块,格子里写允许的端口。规则与矩阵一一对应,新增业务先改矩阵再改规则,避免规则集变成无人敢动的历史包袱。每季度做一次收敛,把连续 90 天零命中的规则标记待删,用计数器 counter 统计命中数即可。
总结
微分段的落地顺序是固定的:先测绘流量,再划 VLAN 分区,然后在网关写默认拒绝的东西向策略,最后用主机防火墙兜底。四步里最容易跳过的是第一步,但跳过它的后果是策略靠猜,上线后大面积报障,最后不得不退回全通。
判断这套方案是否真的生效,只看一个指标:从任意一台办公终端发起内网扫描,能发现的开放端口数量应当降到个位数。这个数字降不下来,说明策略里还留着”为了方便”开的大口子,而那些口子正是攻击者横向移动时会走的路。