强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

iptables 完全指南 / 第 13 章:IPv6 防火墙 ip6tables

第 13 章:IPv6 防火墙 ip6tables

本章目标:掌握 ip6tables 的使用方法,理解 IPv6 与 IPv4 防火墙的差异,能够为双栈服务器配置完整的防火墙策略。


13.1 为什么需要 IPv6 防火墙

13.1.1 常见误区

“IPv6 地址空间大,不需要防火墙”
事实:IPv6 地址虽然大,但通过 DNS、扫描工具(如 ZMapv6)和 IPv6 邻居发现协议,攻击者仍能发现目标。

“我在 iptables 中配了规则,IPv6 也自动生效了”
事实:iptables 只处理 IPv4,ip6tables 才处理 IPv6,两者完全独立。

“我的服务器没有 IPv6 地址,不需要管”
事实:大多数现代 Linux 发行版默认启用 IPv6,可能已经有 link-local 地址甚至全局地址。

13.1.2 检查 IPv6 状态

# 查看 IPv6 地址
ip -6 addr show

# 查看 IPv6 路由
ip -6 route show

# 检查 IPv6 是否启用
cat /proc/sys/net/ipv6/conf/all/disable_ipv6
# 0 = 启用,1 = 禁用

# 测试 IPv6 连通性
ping6 ::1                    # 回环地址
ping6 fe80::1%eth0           # link-local 地址
ping6 2001:db8::1            # 全局地址

13.2 ip6tables 语法

13.2.1 与 iptables 的相似性

ip6tables 的语法与 iptables 几乎完全相同,主要区别在于:

差异iptables (IPv4)ip6tables (IPv6)
命令iptablesip6tables
地址格式IPv4(192.168.1.1)IPv6(2001:db8::1)
网段格式CIDR(/24)CIDR(/64)
ICMP-p icmp-p ipv6-icmp
特殊地址127.0.0.0/8::1/128, fe80::/10
NAT支持有限支持(见下文)

13.2.2 基本操作

# 查看所有链
sudo ip6tables -L -n -v --line-numbers

# 添加规则
sudo ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT

# 删除规则
sudo ip6tables -D INPUT 1

# 设置默认策略
sudo ip6tables -P INPUT DROP

# 清空规则
sudo ip6tables -F

# 导出/导入规则
sudo ip6tables-save > /tmp/ip6tables.rules
sudo ip6tables-restore < /tmp/ip6tables.rules

13.3 IPv6 特有的协议差异

13.3.1 ICMPv6 的重要性

在 IPv6 中,ICMPv6(Internet Control Message Protocol for IPv6)比 IPv4 中的 ICMP 更加重要,它承担了多项关键功能:

功能说明不允许的后果
邻居发现(NDP)类似 IPv4 的 ARP无法解析链路层地址
路由通告(RA)路由器通告前缀无法获取 IPv6 地址
路由请求(RS)主机请求路由通告延迟获取地址
路径 MTU 发现确定最大传输单元数据包被分片或丢弃
重定向路由优化路由次优
# ⚠️ 不要完全阻止 ICMPv6,这会导致 IPv6 网络瘫痪
# ❌ 错误做法
# ip6tables -A INPUT -p ipv6-icmp -j DROP

# ✅ 正确做法:允许必要的 ICMPv6 类型

13.3.2 ICMPv6 类型白名单

#!/bin/bash
# ═══════════════════════════════════════════════════
# ICMPv6 安全配置
# ═══════════════════════════════════════════════════

# 邻居请求(135)和邻居通告(136)- 必须允许
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbor-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbor-advertisement -j ACCEPT

# 路由请求(133)和路由通告(134)- 如果不是路由器,可以限制
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement \
  -s fe80::/10 -j ACCEPT

# 回显请求(128)和回显回复(129)- ping
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type echo-request \
  -m limit --limit 5/sec -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type echo-reply -j ACCEPT

# 目标不可达(1)- 路径 MTU 发现需要
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type destination-unreachable -j ACCEPT

# 数据包过大(2)- 路径 MTU 发现必须
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT

# 超时(3)
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT

# 参数问题(4)
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type parameter-problem -j ACCEPT

# 记录并丢弃其他 ICMPv6
ip6tables -A INPUT -p ipv6-icmp \
  -m limit --limit 5/min \
  -j LOG --log-prefix "ICMPV6-OTHER: "
ip6tables -A INPUT -p ipv6-icmp -j DROP

13.4 双栈服务器防火墙配置

13.4.1 统一防火墙脚本

#!/bin/bash
# ═══════════════════════════════════════════════════
# IPv4/IPv6 双栈防火墙配置
# ═══════════════════════════════════════════════════

# ─── 辅助函数 ───
apply_rules() {
    local cmd=$1  # iptables 或 ip6tables

    $cmd -F
    $cmd -P INPUT DROP
    $cmd -P FORWARD DROP
    $cmd -P OUTPUT ACCEPT

    # 已建立的连接
    $cmd -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

    # 无效包
    $cmd -A INPUT -m conntrack --ctstate INVALID -j DROP

    # 回环接口
    $cmd -A INPUT -i lo -j ACCEPT

    # SSH
    $cmd -A INPUT -p tcp --dport 22 \
      -m hashlimit \
      --hashlimit-above 4/minute \
      --hashlimit-burst 4 \
      --hashlimit-mode srcip \
      --hashlimit-name ssh_${cmd} \
      -j DROP
    $cmd -A INPUT -p tcp --dport 22 \
      -m connlimit --connlimit-above 3 -j DROP
    $cmd -A INPUT -p tcp --dport 22 -j ACCEPT

    # HTTP/HTTPS
    $cmd -A INPUT -p tcp -m multiport --dports 80,443 \
      -m hashlimit \
      --hashlimit-above 30/sec \
      --hashlimit-burst 60 \
      --hashlimit-mode srcip \
      --hashlimit-name web_${cmd} \
      -j DROP
    $cmd -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

    # 防端口扫描
    $cmd -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
    $cmd -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
    $cmd -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
    $cmd -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

    # 日志
    $cmd -A INPUT \
      -m limit --limit 10/min --limit-burst 30 \
      -j LOG --log-prefix "${cmd}-DROP: "
}

# ─── 应用 IPv4 规则 ───
echo "Configuring iptables (IPv4)..."
apply_rules iptables

# ICMP(IPv4)
iptables -A INPUT -p icmp --icmp-type echo-request \
  -m limit --limit 5/sec -j ACCEPT

# ─── 应用 IPv6 规则 ───
echo "Configuring ip6tables (IPv6)..."
apply_rules ip6tables

# ICMPv6(IPv6)
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbor-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbor-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement \
  -s fe80::/10 -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type echo-request \
  -m limit --limit 5/sec -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type echo-reply -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type destination-unreachable -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type parameter-problem -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -j DROP

echo "Dual-stack firewall configured."

13.5 IPv6 特有安全问题

13.5.1 IPv6 隐私扩展

IPv6 的 SLAAC(无状态地址自动配置)会基于 MAC 地址生成接口标识符,导致设备隐私泄露。隐私扩展(Privacy Extensions)会生成随机的临时地址。

# 检查隐私扩展状态
cat /proc/sys/net/ipv6/conf/all/use_tempaddr

# 启用隐私扩展
# 0 = 禁用
# 1 = 启用(优先临时地址,但也使用固定地址)
# 2 = 启用(只使用临时地址)
sysctl -w net.ipv6.conf.all.use_tempaddr=2
sysctl -w net.ipv6.conf.default.use_tempaddr=2

# 持久化
echo "net.ipv6.conf.all.use_tempaddr = 2" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.use_tempaddr = 2" >> /etc/sysctl.conf

13.5.2 IPv6 路由通告安全

# 防止恶意路由通告(RA 攻击)
# 只接受来自已知路由器的 RA

# 方法 1:ip6tables 过滤
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement \
  -s fe80::1 -j ACCEPT  # 只接受网关的 RA
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -j DROP

# 方法 2:内核参数
sysctl -w net.ipv6.conf.all.accept_ra=0   # 完全禁用 RA
sysctl -w net.ipv6.conf.eth0.accept_ra=1  # 只接受来自默认网关的 RA
sysctl -w net.ipv6.conf.all.accept_ra_defrtr=1
sysctl -w net.ipv6.conf.all.accept_ra_pinfo=1

13.5.3 IPv6 隧道安全

IPv6 隧道(如 6to4、Teredo、ISATAP)可能被用于绕过 IPv4 防火墙:

# 如果不需要 IPv6 隧道,禁用它们
ip6tables -A INPUT -p 41 -j DROP   # 6to4 隧道
ip6tables -A INPUT -p 4 -j DROP    # IPv4 封装

# 禁用 IPv6 隧道内核模块
echo "install sit /bin/true" >> /etc/modprobe.d/disable-ipv6-tunnels.conf
echo "install ip6_tunnel /bin/true" >> /etc/modprobe.d/disable-ipv6-tunnels.conf

13.6 NAT 与 IPv6

13.6.1 IPv6 NAT 的现状

在 IPv6 中,NAT 不再是必需的(因为地址充足),但某些场景仍有需求:

场景是否需要 NAT说明
地址转换IPv6 地址充足,不需要 NAT
网络隐藏可选防火墙比 NAT 更好
负载均衡可选有 DNAT 的替代方案
地址重编号可能站点多宿主场景

13.6.2 IPv6 NAT 配置

# ip6tables 支持 IPv6 NAT(内核 ≥ 3.7)
# 需要加载 nf_nat_ipv6 模块
modprobe nf_nat_ipv6

# IPv6 DNAT
ip6tables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 \
  -j DNAT --to-destination [2001:db8::10]:80

# IPv6 SNAT
ip6tables -t nat -A POSTROUTING -o eth0 -s 2001:db8:1::/48 \
  -j SNAT --to-source 2001:db8::1

# IPv6 MASQUERADE
ip6tables -t nat -A POSTROUTING -o eth0 -s 2001:db8:1::/48 \
  -j MASQUERADE

13.7 完整业务场景:Web 服务器双栈防火墙

#!/bin/bash
# ═══════════════════════════════════════════════════
# Web 服务器 IPv4/IPv6 双栈防火墙
# 环境:公网 Web 服务器,双栈接入
# ═══════════════════════════════════════════════════

# ─── 清空规则 ───
iptables -F && iptables -t nat -F && iptables -X
ip6tables -F && ip6tables -X

# ─── IPv4 规则 ───

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -i lo -j ACCEPT

# SSH(限管理网段)
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT

# HTTP/HTTPS
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# ICMP
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/s -j ACCEPT

# 防扫描
iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

# NAT
iptables -t nat -A POSTROUTING -o eth0 -s 10.0.0.0/24 -j MASQUERADE

# ─── IPv6 规则 ───

ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT

ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
ip6tables -A INPUT -m conntrack --ctstate INVALID -j DROP
ip6tables -A INPUT -i lo -j ACCEPT

# ICMPv6(必须允许关键类型)
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbor-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbor-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type echo-request -m limit --limit 5/s -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type destination-unreachable -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp -j DROP

# SSH
ip6tables -A INPUT -p tcp --dport 22 -s 2001:db8:1::/48 -j ACCEPT

# HTTP/HTTPS
ip6tables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# 防扫描
ip6tables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
ip6tables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
ip6tables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

# 日志
ip6tables -A INPUT -m limit --limit 10/min -j LOG --log-prefix "IP6-DROP: "

echo "Dual-stack firewall configured."

13.8 注意事项

⚠️ 不要阻止所有 ICMPv6:ICMPv6 对 IPv6 网络运行至关重要。阻止 ICMPv6 会导致邻居发现、路径 MTU 发现等功能失效,IPv6 网络将无法正常工作。

⚠️ IPv6 没有广播,只有多播:IPv6 使用多播代替广播,邻居发现使用多播地址(ff02::1, ff02::2 等)。

⚠️ 同时配置 iptables 和 ip6tables:防火墙脚本中应同时包含两套规则,避免 IPv6 成为安全盲区。

⚠️ 禁用不需要的 IPv6 功能:如果不需要 IPv6 隧道,应该禁用 6to4、Teredo 等隧道协议。


13.9 扩展阅读

资源说明
RFC 4890 - ICMPv6 FilteringICMPv6 过滤建议
man ip6tablesip6tables 手册
IPv6 Security (Scott Hogg)IPv6 安全专著
NIST SP 800-119IPv6 安全指南

本章小结

要点说明
ip6tables语法与 iptables 几乎相同
ICMPv6必须允许关键类型,否则 IPv6 网络瘫痪
双栈同时配置 iptables 和 ip6tables
隐私扩展启用 use_tempaddr 保护隐私
RA 安全过滤恶意路由通告
IPv6 隧道不需要时应禁用

下一章第 14 章:规则持久化,将学习如何使防火墙规则在重启后仍然生效。