尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

ip6tables-save详解:IPv6防火墙规则备份与恢复实战

发布时间:2026/9/17 15:33:50

资讯中心
01
ARTICLE

ip6tables-save详解:IPv6防火墙规则备份与恢复实战

ip6tables-save详解:IPv6防火墙规则备份与恢复实战
如果你在 Linux 上配置过 IPv6 防火墙大概率经历过这样的场景花半小时敲了一串ip6tables规则各种链、各种匹配条件好不容易调通了结果一不小心按了重启规则全没了又得从头再来。或者你在一台机器上把 IPv6 规则调好想在另一台机器上复现结果只能对着屏幕一条一条重新敲。这时候你就知道ip6tables-save有多香了。这个命令的作用很简单就是把当前内核里生效的 IPv6 防火墙规则整体导出来输出成可读的文本格式。注意关键词内核。你平时用ip6tables增删改查的是内核网络协议栈里正在运行的规则ip6tables-save做的就是把这些运行状态“拍照”下来存成一个你肉眼能看懂、机器也能恢复回去的文本文件。配合ip6tables-restore一套“导出—保存—恢复”的完整流程就有了。这篇文章我会从命令的基本用法讲起再到规则文件每一行怎么读、怎么写接着给出一套完整的实战操作流程最后把我实际运维中踩过的坑和排查思路一并列出来。适合谁看搞 Linux 运维的系统工程师、网络管理员以及嵌入式开发中需要处理 IPv6 网络的开发者。哪怕你对 iptables 还不熟只要跟着操作一遍也能很快上手。1. ip6tables-save 到底是干嘛的1.1 IPv6 防火墙管理的现实困境很多人对 IPv6 网络的态度是“先跑起来再说”地址配上、路由通掉就以为万事大吉。真正做网络安全的人都知道IPv6 环境下的防火墙策略复杂度和坑一点不比 IPv4 少。IPv6 无状态地址自动配置、邻居发现协议、扩展头处理每一项都会产生新的攻击面。这时候如果你还是守在 IPv4 的老思路里只用iptables管规则IPv6 的流量就处于裸奔状态。我之前在一台服务器上遇到过这样的情况IPv4 的防火墙策略做得密不透风端口全封了结果 IPv6 地址忘了处理攻击者直接通过 IPv6 地址绕了进来。原因很简单iptables只处理 IPv4 流量IPv6 流量由ip6tables单独管理。从技术层面上讲这两套工具读写的是内核里完全不同的两张规则表互不干扰。所以管理 IPv6 防火墙必须专门用ip6tables这套工具链ip6tables-save就是其中负责“导出快照”的那个角色。1.2 ip6tables 工具家族的分工ip6tables这个家族里大家配合得比较紧密的有四个命令。ip6tables本身负责增删改查配置规则ip6tables-save负责把当前内核里的规则导出成文本格式是可读的ip6tables-restore负责把导出文件重新加载回内核还有ip6tables-apply不过这个用的相对少主要是安全测试时临时应用规则检测有问题会自动回滚。这套分工其实是继承自 IPv4 时代的iptables工具链设计得很成熟。ip6tables-save作为“拍照”工具最大的好处在于它的输出格式是稳定的、机器可读的这意味着你不仅能手动查看规则内容还能在脚本里调用它做备份、做对比、做自动化部署。我在实际工作中最常用的一个做法就是写完一堆 IPv6 规则后马上执行ip6tables-save备份一份防止后面改坏了能快速回滚。2. 命令语法与核心参数一次讲透2.1 最常用的三种调用方式ip6tables-save的用法比ip6tables本身简单太多。它不像ip6tables那样有一大堆参数要记基本就是一个“查看”工具把内核里的规则导出来没有额外的复杂选项。最常见的三种方式如下。# 方式一直接输出全部规则到终端 ip6tables-save # 方式二导出到文件 ip6tables-save /etc/ip6tables-rules.v6 # 方式三只导出一张表比如 filter 表 ip6tables-save -t filter第一种方式适合快速看一眼当前规则状态第二种是实际运维中最常用的把规则备份下来第三种适合你只关心某一张表的时候用。默认情况下ip6tables-save会把内核中所有表的规则全部导出包括 filter、mangle、raw、security 这些常见的表。如果你想节省输出量或者排查方向很明确用-t指定表就能聚焦看某一类规则。2.2 参数细节-c、-t、-f虽然命令本身就三个参数但每个参数背后的含义和使用场景值得认真展开。-t参数上面提到了指定导出的表名。例如--table filter只会导出 filter 表的规则。做这个参数的时候有个容易忽略的细节-t和--table是等价的但如果你同时用了多个-t后面一个会覆盖前面一个不会有报错。我就遇到过在脚本里写了两遍-t结果导出结果和自己预想的不一样排查半天才发现是参数覆盖的问题。-c参数是用来导出计数器counter信息的。规则和计数器是绑定的计数器记录该规则匹配了多少个包、多少字节。默认情况下ip6tables-save不会输出计数器加上-c之后每条规则前面会出现类似[12:3456]形式的计数。这个参数在性能分析和流量统计场景下很有用但要注意的是计数器导出后再恢复会把当前的计数也一并恢复进去这可能会干扰你对流量变化趋势的判断。-f参数在部分版本中可用含义是“过滤掉特定规则”比如按照规则编号或者特定表项来过滤。不过说实话这个参数在ip6tables-save上的使用率不高不同 Linux 发行版的内核版本对这个参数的支持也不完全一致。我在 CentOS 7 和 Ubuntu 20.04 上测试过有些老版本对-f的解析就是简单的通配符匹配不太稳定所以如果你只想导出某类特定规则我的建议是直接用grep过滤输出结果而不是依赖-f。2.3 导出文件的字段含义ip6tables-save导出的文件看到的人第一反应可能是这什么玩意儿一堆符号和字母。其实它的格式非常规整读懂之后你会发现这就是一套“规则描述语言”。文件的第一行是一串注释以#开头记录了生成该文件的时间大概是这样的# Generated by ip6tables-save v1.8.2 on Fri Jan 6 10:30:00 2024这一行纯粹是给人类看的恢复规则的时候会被自动忽略。接着是按表分组的规则段每一段的开头是*表名比如*filter就表示接下来是 filter 表的规则。表名之后是链的定义格式是这样的:INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0]冒号后面是链名紧接着是这条链的默认策略方括号里是计数器。比如:INPUT ACCEPT [0:0]的意思就是INPUT 链的默认策略是 ACCEPT当前匹配了 0 个包、0 字节。这个计数如果加了-c参数才会被包括在输出中但链定义的这一行不管加不加都会显示计数器。再往下就是具体的规则条目了每一行以-A开头表示追加到某条链后面的-s、-p、-j等标志和你平时敲ip6tables命令时用的完全一样。比如-A INPUT -s 2001:db8::/32 -p tcp -m tcp --dport 22 -j ACCEPT这条规则的意思是来自2001:db8::/32网段的 TCP 流量目标是 22 端口放行。文件末尾是COMMIT表示这一段规则结束恢复操作执行到COMMIT时才会真正把这一整段规则提交到内核中。3. 实战演示导出、检查、恢复一条龙3.1 实操环境说明我这里以一台 Ubuntu 20.04 的服务器为例演示。系统自带ip6tables和ip6tables-save版本是 iptables v1.8.4。要确认你的环境里有没有这两个命令可以执行which ip6tables-save如果有输出就说明已经装了。如果没有在 Ubuntu/Debian 上安装 iptables 工具包即可在 CentOS/RHEL 上则是yum install iptables-services。这里我补充一个容易踩的坑很多精简安装的 Linux 系统默认只装了iptables但ip6tables-save不在其中需要额外安装iptables的完整套件才能使用。在开始之前我先往内核里添加几条 IPv6 规则模拟一个真实场景允许回环接口流量允许本网段的 SSH 访问其他外部 IPv6 访问默认拒绝。下面的命令里我故意把规则写得规范和复杂一点方便后面展示导出文件的样子。# 清空现有规则注意这条会清空所有 IPv6 规则慎用 ip6tables -F # 设置默认策略 ip6tables -P INPUT DROP ip6tables -P FORWARD DROP ip6tables -P OUTPUT ACCEPT # 允许回环接口 ip6tables -A INPUT -i lo -j ACCEPT # 允许本网段 SSH 访问假设网段是 2001:db8:1::/64 ip6tables -A INPUT -s 2001:db8:1::/64 -p tcp --dport 22 -m state --state NEW -j ACCEPT # 允许已建立的连接和相关的回包流量 ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT3.2 把规则导出到文件规则添加好以后导出就非常简单了。直接执行ip6tables-save my-firewall.rules然后查看文件内容cat my-firewall.rules输出大概是这个样子的# Generated by ip6tables-save v1.8.4 on Sat Feb 3 14:22:11 2024 *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -s 2001:db8:1::/64 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT COMMIT注意看-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT这一行我敲命令的时候写的是ESTABLISHED,RELATED但保存后它自动变成了RELATED,ESTABLISHED。这是内核处理规则时对状态匹配顺序做了归一化不影响实际效果但理解这一点有助于你在手写规则文件时不要过度纠结顺序。导出的文件里表的顺序也是固定的一般 filter 表排在最前面然后是 mangle、raw、security 等这是由内核中表的初始化顺序决定的不是随机排列。3.3 恢复规则到内核恢复操作利用的是ip6tables-restore它读取ip6tables-save导出的文件把规则重新加载进内核。命令格式如下ip6tables-restore my-firewall.rules执行完以后可以再调用ip6tables-save检查一遍看看恢复结果是否和预期一致。这里有个细节值得说明ip6tables-restore默认会先清空对应表里的所有规则再加载文件中的规则也就是说它做的是一个“整表替换”的操作不是增量追加。这个特性既是优点也是风险。优点是恢复前不用手动清空缺点是如果文件里的规则不完整恢复后可能丢失部分策略。如果你希望恢复时清空所有规则再重建可以加-F参数不过默认情况下 restore 执行到COMMIT时也会把未包含在文件里的链重置。我个人的习惯是恢复之前先手动执行一次ip6tables -F清空再用ip6tables-restore加载这样整个状态是最干净的。尤其在多张表并存的情况下避免旧规则残留导致行为怪异。3.4 让规则开机自动加载规则恢复是一次性操作重新启动后又会丢失。要解决这个问题最简单的办法是把规则文件放在固定位置然后用 systemd 服务在开机时自动恢复。不同发行版内置的机制不太一样我重点说 Ubuntu 和 CentOS 的两种常见做法。在 Ubuntu 上很多人会写一个 systemd service。我先创建一个服务文件[Unit] DescriptionRestore IPv6 firewall rules Beforenetwork-pre.target Wantsnetwork-pre.target [Service] Typeoneshot ExecStart/usr/sbin/ip6tables-restore /etc/ip6tables-rules.v6 RemainAfterExityes [Install] WantedBymulti-user.target然后启用服务sudo systemctl enable ip6tables-restore.service sudo systemctl start ip6tables-restore.service在 CentOS 7/8 上如果装了iptables-services包通常会有现成的ip6tables服务规则文件放在/etc/sysconfig/ip6tables直接用systemctl enable ip6tables systemctl start ip6tables即可。这里有一个很重要的注意点systemd 服务设置Beforenetwork-pre.target是有讲究的。防火墙规则要在网络接口配置前就位否则接口配置阶段产生的 IPv6 邻居发现广播等流量可能绕过防火墙。虽然 IPv6 邻居发现报文走的是链路层的特殊通道不会被 filter 表拦截但整体顺序还是越早加载越好。4. 规则文件格式深度拆解4.1 行结构逐段解读有些场景下你可能不满足于只在命令行交互式操作而是希望直接修改规则文件、批量添加规则然后一次性恢复进去。这时候就需要彻底读懂ip6tables-save生成的每一行。前面已经提过规则文件由*表名开始链定义、规则条目、COMMIT结束。我来逐段拆解一下一个实际文件。第一段是标题和注释信息# Generated by ip6tables-save v1.8.4 on Sat Feb 3 14:22:11 2024这些注释行在恢复时会被忽略。但我在实际调试中经常故意往规则文件里加自己的注释用#开头标注这条规则是干嘛的、什么时候加的、针对什么问题添加的。因为ip6tables-restore会自动跳过所有注释行这种“留痕”做法对团队协作非常友好相当于给规则写了一份免费文档。接下来是链定义*filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0]这三行的含义前面已经解释过。补充一个容易忽略的点链定义里的默认策略可以是ACCEPT、DROP、QUEUE或RETURN。如果你写了一个自定义链它也会出现在这里默认策略通常是-。比如你创建过MYCHAIN这个自定义链在保存文件里就是:MYCHAIN - [0:0]。再往下是规则条目每一条规则的格式其实和你在终端敲命令时几乎一样只是少了命令本身。举个例子-A INPUT -s 2001:db8:1::/64 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT这一行对应你敲的命令是ip6tables -A INPUT -s 2001:db8:1::/64 -p tcp --dport 22 -m state --state NEW -j ACCEPT你会发现保存文件里多了-m tcp这是ip6tables在匹配 TCP 协议时自动加载的扩展模块属于输出规范化的一部分。另外顺序上也有些微调比如-m state --state NEW会被移动到--dport 22后面。理解了这些细小的差异你在手写规则文件时就不会被看似“多出来”的片段搞懵。4.2 手工编辑规则文件的安全姿势既然规则文件是纯文本自然可以手工编辑。但手工编辑有风险稍有不慎就会导致恢复失败。我给出手工编辑时的三个原则。第一编辑前先备份原文件。这一步看似多余但关键时刻能救命。我吃过一次亏编辑规则文件时不小心删掉了一行-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT恢复规则后 SSH 连接直接断掉因为已经建立的连接也不通了。如果没有备份就得去物理控制台或者带外管理系统恢复网络非常狼狈。第二修改规则后先用ip6tables-restore --test尝试验证文件格式。这个参数会解析文件如果语法有问题会直接报错不会真正修改内核规则。我在 Ubuntu 20.04 上测试过--test能发现大部分常见的格式错误比如缺少COMMIT、链名拼写不对、匹配条件写错。不过要提醒一句--test只负责语法检查不检查规则是否存在逻辑错误比如你把端口写成 22 口而不是 22如果格式正确它不会报错这就需要自己多留个心眼。第三编辑完成后恢复前先临时开启一个额外的 “逃生通道”。最稳妥的做法是如果你是通过 SSH 远程管理的不要直接把规则文件里的 SSH 端口规则删掉或改掉可以先在规则文件里多留一条临时放行规则恢复成功后再调整。或者使用screen或tmux会话执行恢复操作万一断连还能重连回去看状态。这些习惯是真的能救命的。4.3 多张表并存时的处理一个完整的ip6tables-save输出往往不止 filter 表还包含 mangle、raw、security 等表。如果你用ip6tables-save不做任何参数导出全部表文件里会包含多段。每段各自以*表名开头以COMMIT结束。恢复多张表时ip6tables-restore会按文件的顺序依次处理各张表。需要注意如果你在raw表里配置了NOTRACK规则它会影响到后面 filter 表的连接跟踪状态只有当整个文件全部恢复完成后所有表才同时生效。所以如果你发现某条规则没有生效不要只看 filter 表还要检查 mangle 和 raw 表是否有相关跳转或标记操作。这类问题隐蔽性很强我在一次 IPv6 网关配置中排查了半天最后发现是 mangle 表里的一条MARK规则把流量打上了标记filter 表的规则基于这个标记做了不同处理逻辑链条是这样的mangle 的规则比想象中影响更大。还有一个经验多次导出。如果你想快速比较当前内核规则和文件规则的区别可以分别执行ip6tables-save并输出到两个文件再用diff比较。比如ip6tables-save now.rules diff now.rules my-firewall.rules这样就能清楚地看到哪些规则是后来添加的哪些被删除了。这个技巧在我审计规则变更时帮了大忙特别是多人共同维护服务器时有了 diff 结果就能知道某条规则是谁在什么时候改的。当然前提是前面说的养成在规则文件里写注释的习惯。5. 常见问题与排查技巧实录5.1 命令不存在或权限不足最典型的问题就是执行ip6tables-save时报错提示command not found。这和之前提到的精简安装有关。就算系统里有ip6tables也不一定有ip6tables-save。如果你用的是 Ubuntu/Debian执行下面命令安装sudo apt update sudo apt install iptables ip6tables如果是 CentOS/RHEL执行sudo yum install iptables-services安装完成后ip6tables-save和ip6tables-restore都会出现。再强调一次ip6tables-save需要 root 权限执行因为要读取内核中的规则表。普通用户执行会遇到Permission denied不过好消息是即使是 root 身份执行ip6tables-save不会对内核规则做任何修改它只是读取这一点可以放心。5.2 导出的规则恢复时报错恢复时报错最常遇到的场景是ip6tables-restore: line 10 failed之类的提示。这种报错说明文件第 10 行附近有问题。常见的原因有以下几种文件格式混合了 IPv4 的语法。比如你误把iptables-save的输出和ip6tables-save的输出拼在了一个文件里。IPv4 地址如192.168.1.0/24放在 IPv6 规则里ip6tables-restore肯定不认。链定义和规则条的链名不一致。比如链定义写的是:INPUT DROP [0:0]规则条却写成了-A INPT -s ...那明显拼接错了。缺少COMMIT。如果没有COMMITip6tables-restore会一直等待最后报错。排查的思路是用ip6tables-restore --test做语法验证它会告诉你具体哪一行有问题。如果没有--test你也可以把规则文件分段恢复比如先用编辑器删掉一部分看哪一段恢复失败用二分法快速定位。5.3 IPv6 规则莫名丢失我有段时间很困惑明明恢复了规则过了一阵子再去执行ip6tables-save发现规则少了几条。最后发现是两个原因。第一个原因是其他脚本也在操作ip6tables比如某些服务启动时会调用ip6tables -F清空规则或者安全软件会在自己启动时接管防火墙。第二个原因是有人用了ip6tables-restore恢复了一个不完整的文件整表替换后旧规则全部被冲掉了。这个问题在容器化环境里尤其常见。Docker、Kubernetes 这些容器网络组件会动态修改 iptables/ip6tables 规则如果规则文件和它们的操作冲突就会出现“规则被覆盖”的现象。排查思路是在规则丢失的时间点查看系统日志里有没有相关操作记录同时检查有没有其他守护进程在调用 ip6tables 工具。我的建议是如果你在公司内部使用容器平台对 IPv6 防火墙规则的变更尽量做变更评审走过流程避免规则被半路截胡。5.4 常见问题速查表问题可能原因解决办法ip6tables-save提示 command not found未安装 iptables 工具包安装 iptables/ip6tables 软件包提示 Permission denied非 root 用户执行sudo 执行恢复报 line x failed语法错误、表名错误或缺少 COMMIT用--test验证文件定位出错行规则恢复后马上失效其他进程调用 ip6tables 修改规则检查系统服务和容器网络组件确认是否冲突导出的文件是空的内核中确实没有已加载的 IPv6 规则先查看ip6tables -L确认是否存在规则IPv4 规则里的数据出现在 IPv6 文件里混用了 iptables-save 导出内容确认使用 ip6tables-save 输出而非 iptables-save6. 实际运维中的扩展玩法6.1 定时备份防火墙规则规则备份是个好习惯尤其是生产环境。我习惯用 cron 每天备份一次规则保留最近几份历史这样如果哪天发现规则被改动、网络行为异常可以在历史备份里找到“正常时期”的规则进行对比。#!/bin/bash # /usr/local/sbin/backup-ip6tables.sh BACKUP_DIR/var/backups/firewall STAMP$(date %Y%m%d-%H%M%S) mkdir -p $BACKUP_DIR ip6tables-save $BACKUP_DIR/ip6tables-$STAMP.rules find $BACKUP_DIR -name ip6tables-*.rules -mtime 7 -delete然后在 crontab 里加一行0 2 * * * /usr/local/sbin/backup-ip6tables.sh注意备份文件的权限。防火墙规则里可能包含内部网段信息虽然不是密码级别但属于敏感的配置数据建议chmod 600限制只有 root 能读取。6.2 与 systemd 集成实现可靠加载前面提到的 systemd service 方案可以做得更精细。如果你有多张表、多个配置文件的需求可以编写一个支持通配符加载的脚本。我写过一个加载器它会扫描某个目录下的所有.rules文件按文件名字母顺序依次恢复。这样做的好处是你可以把规则按业务模块拆分成不同文件例如99-drop-all.rules、10-allow-ssh.rules方便单独调整而不影响其他部分。我提醒一个实践中的细节ip6tables-restore默认是“整表替换”如果你按文件拆分就要特别注意每个文件包含的是不同的表或者不同逻辑段的规则。比如一个文件只管理 filter 表另一个文件只管理 mangle 表这样恢复时才不会互相覆盖。如果两个文件都对 filter 表做了操作后加载的文件很可能会把先加载文件的规则清掉产生难以察觉的规则缺失。6.3 在脚本中动态修改规则很多自动化场景下运维脚本会临时添加规则比如某个安全加固任务需要临时封禁某个 IPv6 地址。脚本里常见做法是先ip6tables-save把当前规则保存到变量再添加临时规则等任务完成后用ip6tables-restore把原规则恢复回来。# 封禁临时 IP ORIGINAL_RULES$(ip6tables-save) ip6tables -A INPUT -s $BAD_IP -j DROP # 业务逻辑处理... # 处理完毕恢复原有规则 echo $ORIGINAL_RULES | ip6tables-restore这种基于“保存—修改—恢复”的脚本模式比手动记录增删的规则要可靠得多因为你不需要精确知道加了多少条规则、删了多少条整体恢复就好。要注意的是变量里如果包含特殊字符恢复时 echo 加管道的方式要注意引号最好直接用printf输出。这里我踩过坑脚本里用了echo $ORIGINAL_RULES结果某些环境变量里带了斜杠echo 解析时没处理好导致恢复失败。后面改成printf %s\n $ORIGINAL_RULES | ip6tables-restore执行效果很稳。6.4 和 IPv4 规则联动的思路虽然iptables-save和ip6tables-save是两套独立工具但在实际项目中IPv4 和 IPv6 的防火墙策略往往需要一起规划和审计。你可以分别导出两份规则文件统一命名备份并在变更文档里注明哪些规则是同时影响双栈的。比如某条规则在 IPv4 里放行了 80 端口但在 IPv6 里忘了配就会导致 IPv6 用户访问不了网站。这类“双栈一致性”问题靠人工对着两份文件检查效率很低建议写一段小脚本把两个文件里相同策略的部分做归一化比对。如果你在配置 IPv6 访问控制时参考过类似于“华三 IPv6 ACL 配置实验”的流程你就会理解为什么这类一致性检查如此重要。很多网络设备上IPv4 和 IPv6 的 ACL 是分开配置的漏配任何一端都会造成访问异常。我个人在实际操作中有一个小习惯任何 IPv6 防火墙规则变更完成后一定顺手执行一次ip6tables-save /etc/ip6tables-rules.v6把最新状态固化下来。这不只是为了备份更像是一种“工作闭环”的仪式感。改完规则不保存你永远不知道自己哪一天会因为这个懒散动作付出代价。说到底ip6tables-save这个命令本身简单到不能再简单但把它用好的关键是你在多大程度上愿意为自己的网络环境建立起“规则即代码、规则可追溯、规则可回滚”的工程化意识。这条经验是我在多次半夜爬起来抢救防火墙配置之后总结出来的最真心的一句体会。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。