Skip to content

元数据卡

  • 前置知识:Vol 4 网络(TCP/IP、HTTP、DNS)、第1章(加密与 TLS)
  • 预计时间:55 分钟
  • 核心难度:进阶
  • 完成标志:能解释防火墙的状态检测和默认 deny 原则,能区分 IDS 和 IPS,理解零信任的核心假设

你的进度

你已经加固了驿站本身的各个方面——应用层的输入净化咒语、操作法阵层的隔离符文。但还有一件事:驿站不是孤立的。它有七条魔法驿道通向其他法师塔,每天有魔力信使在驿道上奔波,还有跨塔法术信函在管道中穿梭。

协议栈的每一层都有对应的安全问题。网络层的问题更棘手——因为你不能控制别塔的代码,甚至不能完全确定魔力信源的笛卡尔坐标是否真实。

你在 Vol 4 中见过 TCP 三次握手和 IP 路由的原理。现在我们要在同样的魔法驿道上架设安全检查站。 你的任务

掌握网络安全的核心防御手段:防火墙的包过滤和状态检测、VPN 的隧道与加密、IDS/IPS 的入侵检测、以及零信任架构的理念转变。

本章分层

  • 必读:防火墙(包过滤/状态检测/NAT/DMZ)、VPN(TLS VPN/IPsec)
  • 选读:IDS/IPS 规则引擎、OSI 各层攻击模式
  • 进阶:零信任架构(NIST SP 800-207)、SASE、eBPF 在网络安全中的使用

破局 · 溯源

问题:要塞有七条驿道,每条路上都有不只友好的旅人。你怎么知道哪个数据包是攻击者,哪个是正常的侦察报告?

你不可能每收到一个包就去查它是否来自一个可信的源 IP。网络每秒可能经过成千上万的包,所以你需要自动化的、按规则工作的防御设施。

第一道屏障:防火墙

防火墙的本质是一个包过滤器——一组规则的集合:"什么样子的包可以通过,什么样子的被丢弃。"

最简单的是静态包过滤,检查每个包的:

  • 源 IP / 目的 IP
  • 源端口 / 目的端口
  • 协议(TCP / UDP / ICMP)

用 iptables(Linux 传统防火墙)配置:

bash
# 默认策略:丢弃所有输入包,允许所有输出
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# 允许已建立连接的回包
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT

# 开放 SSH(限 IP)
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT

# 开放 HTTP/HTTPS(从任何地方)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 记录并丢弃其他
iptables -A INPUT -j LOG --log-prefix "DROPPED: "
iptables -A INPUT -j DROP

状态检测(Stateful Inspection):

上面看到的关键一行:

bash
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

这就是状态防火墙的实质——它记住已经建立的连接。当一个包是已建立连接的一部分(ESTABLISHED),或者与已建立连接相关(RELATED,如 FTP 数据连接),就自动放行。你不需要显式写允许回包的规则。

这就是为什么防火墙能做到:你允许了向外的 DNS 查询(udp/53),DNS 回包也会被自动允许。但如果外部主动发一个 DNS 查询给你的机器,它会被拒绝。

nftables(iptables 的现代替代):

bash
# /etc/nftables.conf
table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # 允许已建立连接
        ct state established,related accept

        # 允许本地回环
        iif lo accept

        # 允许 SSH
        tcp dport 22 ip saddr 10.0.0.0/8 accept

        # 允许 HTTP/HTTPS
        tcp dport {80, 443} accept

        # 允许 ICMP(ping)
        icmp type {echo-request, echo-reply} accept
    }
}

NAT 与 DMZ:

防火墙不仅有包过滤,还可以做网络地址转换(NAT):

  • SNAT(源地址转换):内网设备访问外网时,把内网 IP 映射为公网 IP。这是家用路由器的核心功能。
  • DNAT(目的地址转换):外部请求访问某个公网 IP:端口时,转发到内部服务器。这是端口映射。
bash
# DNAT:外部 8443 转发到内部 Web 服务器 192.168.1.10:443
iptables -t nat -A PREROUTING -p tcp --dport 8443 \
  -j DNAT --to-destination 192.168.1.10:443

DMZ(Demilitarized Zone) 是一个安全设计模式:

          ┌──────────┐
  Internet ───┤  防火墙  ├─── DMZ(Web 服务器、邮件服务器)
               └──────────┘

                    ├─── 内部网络(数据库、内网应用)

                    └─── 管理网络(SSH、监控)

DMZ 中的服务器暴露给公网,但它们访问不了内部网络。即使 web 服务器被攻破,攻击者也无法直接访问数据库。如果确实需要访问,由防火墙明确配置特定规则。

第二道屏障:IDS / IPS

防火墙是基于预设规则的——"这些是好人,这些是坏人。"但有些攻击伪装成正常流量。比如一个 SQL 注入攻击看起来就是一个正常的 HTTP POST 请求,只是 body 里带了 ' OR 1=1 --

IDS(入侵检测系统) 监控流量,发现可疑模式时报警。

IPS(入侵预防系统) 除了检测,还能主动阻断。

特性IDSIPS
部署方式旁路(复制一份流量)串联(流量经过设备)
是否影响延迟是(会引入延迟)
误报影响产生告警阻断正常流量
更新策略相对宽松需要更可靠的规则

Snort 规则示例:

Snort 是最流行的开源 IDS/IPS 引擎。一条 Snort 规则:

# 检测到 SQL 注入尝试时告警
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS
  (msg:"SQL Injection - UNION SELECT";
   content:"UNION"; nocase;
   content:"SELECT"; nocase;
   distance:0;
   pcre:"/UNION\s+SELECT/i";
   sid:1000001;
   rev:1;)

解释:

  • 这个规则检查进出 HTTP 服务器的 TCP 流量
  • 查找包含 "UNION" + "SELECT" 模式的 payload
  • 用正则表达式 UNION\s+SELECT 做精确匹配
  • 命中时报警

检测方法:

方法原理优点缺点
特征检测匹配已知攻击签名准确率较高,性能好无法检测未知攻击(零日漏洞)
异常检测建立基线,偏离基线时报警能发现未知攻击误报率高
协议分析检查是否符合协议规范能发现协议层面的攻击需要深度协议解析

第三道屏障:VPN

VPN(Virtual Private Network)解决了两个核心问题:

  1. 通信安全: 在不安全的线路上建立加密隧道
  2. 网络可达: 让远程节点像在同一个局域网一样
┌─────────┐    加密隧道      ┌─────────┐
│ 远程哨站  │─────║═══════║──────│ 要塞总部  │
│(有 VPN  │     ║  VPN  ║      │(VPN 网关)│
│  客户端) │     ╚═══════╝      │           │
└─────────┘                    └─────────┘

                   Internet

VPN 的三种主要实现:

类型协议优点缺点
TLS VPNOpenVPN、WireGuard应用层,灵活,适合远程访问在网关间部署稍复杂
IPsec VPNIKEv2 + ESP/AH网络层,适合站点到站点配置复杂,MTU 问题
WireGuardNoise 协议框架代码量小(4000 行)、性能高、配置简单比较新,生态不如前两者丰富

WireGuard(作为现代 VPN 的代表):

WireGuard 的设计哲学和传统 VPN 截然不同——它只有 4000 行代码(对比 OpenVPN 的数十万行),使用最新的加密原语(Curve25519、ChaCha20、BLAKE2s),而且配置极其简单。

bash
# 服务端配置(/etc/wireguard/wg0.conf)
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server-private-key>

# 允许转发
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT

# 客户端(远程哨站)
[Peer]
PublicKey = <client-public-key>
AllowedIPs = 10.0.0.2/32

# 客户端配置(/etc/wireguard/wg0.conf)
[Interface]
Address = 10.0.0.2/24
PrivateKey = <client-private-key>

[Peer]
PublicKey = <server-public-key>
Endpoint = borderfortress.com:51820
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
PersistentKeepalive = 25

启动后,远程哨站可以通过 10.0.0.2 直接访问要塞总部的 192.168.1.x 资源。所有流量在 UDP 隧道中加密传输。

bash
# 启动 WireGuard
wg-quick up wg0

# 查看状态
wg show

# 输出示例:
# interface: wg0
#   public key: ...
#   private key: (hidden)
#   listening port: 51820
# peer: <client-public-key>
#   endpoint: 203.0.113.5:45678
#   allowed ips: 10.0.0.2/32
#   latest handshake: 1 minute ago
#   transfer: 1.2 MiB received, 3.4 MiB sent

第四道屏障:零信任架构

传统网络安全基于一个核心假设:"内网是安全的,外网是危险的。"

这条防线叫做城堡-护城河模型——你有一个坚固的外墙(防火墙),墙内的一切都是可信的。

但这个模型在 2020 年代已经被证明不够用了:

  • 攻击者通过钓鱼邮件获得内网访问权限后,可以在内网横向移动
  • 云服务和远程办公使得没有明确的"内外网"边界
  • 零日漏洞可以穿透外围防御

零信任(Zero Trust) 的核心原则:

永不信任,始终验证(Never Trust, Always Verify)

NIST SP 800-207 定义的零信任架构有七个核心原则:

  1. 所有数据源和计算服务都是资源。每个设备、每段流量都是待验证的。
  2. 所有通信都必须加密。不管是在内网还是外网。
  3. 按会话粒度授权。不是"登录了就可用所有资源",每个请求单独授权。
  4. 动态访问策略。基于用户身份、设备状态、位置、时间等多维度评估。
  5. 监控所有资源访问。审计所有流量,检测异常行为。
  6. 最小权限。用户和进程只获得完成任务所需的最小权限。
  7. 网络位置不等于信任。不能因为某个请求来自内网就自动放行。

零信任在实践中的体现:微隔离

传统防火墙保护的是数据中心边界。零信任下的**微隔离(Micro-segmentation)**把安全防线缩小到每个工作负载:

yaml
# Kubernetes NetworkPolicy 示例(微隔离)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: patrol-api-policy
spec:
  podSelector:
    matchLabels:
      app: patrol-api
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: patrol-db
    ports:
    - protocol: TCP
      port: 5432

这条策略说:

  • 只有 frontend 标签的 pod 可以访问 patrol-api 的 8080 端口
  • patrol-api 只能访问 patrol-db 的 5432 端口
  • 其他所有流量都被拒绝

——不需要配置防火墙规则,不需要声明内外网边界。每个服务只知道它需要通信的另一个服务。


常见陷阱

  • "防火墙可以检测所有攻击。 防火墙只能匹配已知规则。加密流量(HTTPS)中的攻击防火墙无法检测——需要 TLS 解密(Decryption/MITM)才能看到 payload。
  • 忘记默认 deny 原则。 "允许已知的,拒绝其他的"应该写在最后一行。只写"允许 SSH、HTTP"然后忘记写默认拒绝,等于没设防火墙。
  • VPN 隧道存在,但其他流量没有走隧道。 配置了 VPN,但 DNS 请求、IPv6 流量可能走的是物理网口(VPN split-tunnel 配置导致)。确认所有流量都经过加密隧道。
  • IDS 的误报让操作员疲劳。 如果 IDS 每天产生成千上万条告警,真正的攻击会被淹没在噪声中。定期调整规则,建立告警分级机制。
  • 对等网络环境下用传统防火墙。 在 Kubernetes 或跨云环境中,传统网络防火墙无法有效控制服务到服务的流量。需要微隔离或服务网格(如 istio 的 mTLS + authorization)。
  • TLS 卸载后给内网传明文。 负载均衡器解密 TLS,然后以明文 HTTP 传给后端。攻击者如果在内网做 ARP 欺骗,可以直接看到所有请求。确保后端之间的通信也用 TLS(TLS 全链路)。

通关挑战

  • 热身:在你的开发机上用 iptables -L -n -v 查看当前的防火墙规则。理解每条规则的计数器(packets / bytes)的含义——你能看出哪些规则被经常命中吗?
  • 挑战:用 Vagrant 或 Docker Compose 搭建一个小型网络拓扑:一个"外部客户端"、一个"防火墙"、一个"内部服务器"。在防火墙上配置 NAT 和端口转发,让外部客户端只能通过防火墙的特定端口访问内部服务器。
  • 观察:用 tcpdump -i any -n port 53 观察你的机器的 DNS 查询。防火墙是如何允许 DNS query 和 response 交互的?用 Wireshark 的 follow UDP stream 功能查看。
  • 排障:远程哨站通过 WireGuard VPN 能 ping 通总部服务器(10.0.0.1),但不能访问总部的 HTTP 服务(192.168.1.10:80)。诊断可能的原因(路由配置?iptables FORWARD 策略?网卡 IP 转发未开启?)。

旅人笔记

  • 防火墙是网络的第一道防线:基于 IP/端口的状态检测(默认 deny)
  • IDS 检测入侵(旁路),IPS 预防入侵(串联),两者都需要规则持续更新
  • VPN 在不安全的网络上建立加密隧道:WireGuard 是现代简单高效的选择
  • 零信任架构放弃"内网安全"假设,默认每个请求都需要验证
  • 微隔离把安全边界从数据中心缩小到每个工作负载

下一站预告

网络防御到位后,让我们把视角拉回工程流程本身。安全不是运维的补丁,而应该嵌入到开发的全生命周期。下一章,我们看安全开发生命周期(SDL)怎么做。

Built with VitePress | Software Systems Atlas