• 【网络教程】IPtables官方教程--学习笔记4


    一、如何保存和恢复大型规则集

    iptables有两个非常实用的工具,特别是在处理大型规则集的时候。两个工具名称分别是"iptables-save"和"iptables-restore",用于将规则集爆出和恢复到特定的文件格式,这种格式与本教程其余部分将看到的标准shell代码有很大不同。

    Iptables-restore可以与脚本语言一起使用。最大的问题是,我们需要将结果输出到iptables-restore的stdin中。如果正在创建一个非常大的规则集(数千条规则),这可能是一个非常好的想法,因为它将更快地插入所有新规则。例如,我们可以运行make_rules.sh | iptables-restore。

    1.1 速度

    使用iptables-save和iptables-restore命令的最大原因之一是它们将大大加快大型规则集的加载和保存速度。运行包含iptables规则的shell脚本的主要问题是,脚本中对iptables的每次调用都会首先从Netfilter内核空间中提取整个规则集,然后,它会插入或追加规则,或者对这个特定命令所需的规则集进行任何更改。最后,它将从自己的内存中将新的规则集插入内核空间。通过使用一个shell脚本,可以对我们想要插入的每个规则执行此操作,并且每次执行此操作时,提取和插入规则集将花费更多的时间。

    为了解决这个问题,可以使用iptables-save and restore命令。iptables-save命令用于将规则集保存到一个特殊格式的文本文件中,iptables-restore命令用于将这个文本文件再次加载到内核中。这些命令最好的地方在于它们将在一个请求中加载和保存规则集。Iptables-save将从内核获取整个规则集,并将其保存到一个文件,只需一个动作。Iptables-restore将在每个表的单个动作中上传特定的规则集到内核。换句话说,比起将规则集从内核中删除30,000次,对于非常大的规则集,然后将其再次上传到内核中,我们现在可以在一个动作中保存整个内容到一个文件中,然后在三个动作中上传整个内容,这取决于你使用了多少表。

    1.2 iptables-restore的缺点

    iptables-restore不能处理任何类型的脚本,这是它的主要缺陷,因为我们不能对这些文件做大量的事情。例如,如果我们有一个具有动态分配IP地址的连接,并且希望在每次计算机启动时获取这个动态IP,然后在脚本中使用该值,该怎么办?使用iptables-restore是几乎不可能办到的。

    解决这个问题的一种可能是创建一个小脚本,让它获取我们想要在脚本中使用的值,然后设置iptables-restore文件用于特定的关键字,并将它们替换为通过小脚本收集的值。此时,我们可以将其保存到一个临时文件中,然后使用iptables-restore加载新值。这将导致许多问题,但是,我们将无法正确使用iptables-save,因为它可能会删除在恢复脚本中手动添加的关键字。换句话说,这是一个笨拙的解决方案。

    第二种可能是按照前面描述的那样做。编写一个脚本,以iptables-restore格式输出规则,然后根据iptables-restore的标准输入提供规则。对于非常大的规则集,这将比运行iptables本身更可取,因为它有一个坏习惯,即在非常大的规则集上使用大量的处理能力,就像本章前面描述的那样。

    另一种解决方案是先加载iptables-restore脚本,然后加载一个特定的shell脚本,该脚本在适当的位置插入更多的动态规则。当然,正如之前可以理解的那样,这与第一种解决方案一样笨拙。iptables-restore不太适合动态分配IP地址给防火墙的配置,也不适合根据配置选项等需要不同行为的配置。

    iptables-restore和iptables-save的另一个缺点是,在编写本文时,它的功能还不完全。问题在于,到目前为止,使用它的人并不多,因此也就没有多少人能找到漏洞,而一些匹配和目标可能会被错误地插入,这可能会导致一些你意想不到的奇怪行为。即使存在这些问题,还是强烈建议使用这些工具,只要它们不包含一些不知道如何正确处理的新目标或匹配,它们就应该对大多数规则集非常有效。

    1.3 iptables-save

    正如我们已经解释过的,iptables-save命令是一种将当前规则集保存到iptables-restore可以使用的文件中的工具。这个命令实际上非常简单,只接受两个参数。请查看下面的示例以理解该命令的语法。

    iptables -save [-c] [-t table]
    
    • 1

    参数-c告诉iptables-save保留字节计数器和数据包计数器中指定的值。例如,如果我们想重新启动主防火墙,这可能很有用,但不会丢失用于统计目的的字节和数据包计数器。然后,使用带-c参数的iptables-save命令将使我们能够在不破坏统计和计数例程(statistical and accounting routines)的情况下重新启动。当然,默认值是在发出此命令时不保持计数器完整。

    -t参数则表示需要保存的表,缺省则会保存所有的表。下面是一个示例,说明如果没有加载任何规则集,可以从iptables-save命令得到什么输出。

    # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002
    *filter
    :INPUT ACCEPT [404:19766]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [530:43376]
    COMMIT
    # Completed on Wed Apr 24 10:19:17 2002
    # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002
    *mangle
    :PREROUTING ACCEPT [451:22060]
    :INPUT ACCEPT [451:22060]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [594:47151]
    :POSTROUTING ACCEPT [594:47151]
    COMMIT
    # Completed on Wed Apr 24 10:19:17 2002
    # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002
    *nat
    :PREROUTING ACCEPT [0:0]
    :POSTROUTING ACCEPT [3:450]
    :OUTPUT ACCEPT [3:450]
    COMMIT
    # Completed on Wed Apr 24 10:19:17 2002
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    ‘#’ 开头的表示注释,每个表被标记为"*",例如:*mangle。然后在每个表中我们有链规范和规则。链规格如下: [:]。链的名称可以是PREROUTING,策略就是ACCEPT。最后包计数器和字节计数器与iptables -L-v 输出中的计数器相同。最后,每个表声明以’COMMIT’关键字结束。COMMIT关键字告诉我们,此时应该将管道中当前的所有规则提交到内核。

    上面的例子是一个非常基础的例子,如果我们在这里运行iptables-save,输出结果会是这样的:

    # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
    *filter
    :INPUT DROP [1:229]
    :FORWARD DROP [0:0]
    :OUTPUT DROP [0:0]
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
    -A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT 
    -A FORWARD -i eth1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 
    -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 
    COMMIT
    # Completed on Wed Apr 24 10:19:55 2002
    # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
    *mangle
    :PREROUTING ACCEPT [658:32445]
    :INPUT ACCEPT [658:32445]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [891:68234]
    :POSTROUTING ACCEPT [891:68234]
    COMMIT
    # Completed on Wed Apr 24 10:19:55 2002
    # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
    *nat
    :PREROUTING ACCEPT [1:229]
    :POSTROUTING ACCEPT [3:450]
    :OUTPUT ACCEPT [3:450]
    -A POSTROUTING -o eth0 -j SNAT --to-source 195.233.192.1 
    COMMIT
    # Completed on Wed Apr 24 10:19:55 2002
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    从上面的输出,我们可以看到,自从使用了-c参数后,每个命令现在都加上了字节计数器和数据包计数器的前缀。除此之外,命令行与脚本完全相同。通过’iptables-save -c > /etc/iptables-save ’ ,将输出保存到文件中。

    1.4 iptables-restore

    iptables-restore命令用于恢复使用iptables-save命令保存的iptables规则集。遗憾的是,它接受标准输入的所有输入,但在编写本文时还不能从文件中加载。这是iptables-restore的命令语法:

    iptables -restore [-c][-n]
    
    • 1

    参数-c恢复字节和数据包计数器,如果您想恢复以前使用iptables-save保存的计数器,则必须使用该参数。这个参数也可以写成它的长形式–counter。

    -n参数告诉iptables-restore不要覆盖它正在写入的表中先前写入的规则。iptables-restore的默认行为是刷新和销毁所有先前插入的规则。短的-n参数也可以被替换为较长的格式–noflush。

    使用iptables-restore命令恢复规则集,我们可以这样做:

    cat /etc/iptables-save | iptables-restore -c
    
    • 1

    也可以这样:

    iptables-restore -c < /etc/iptables-save
    
    • 1

    规则集现在应该被正确加载到内核,一切都应该工作。如果没有,我们可能在这些命令中遇到了错误。

    本章在一定程度上讨论了iptables-save和iptables-restore程序以及如何使用它们。这两个应用程序都是与iptables包一起发布的,可以用来快速保存大型规则集,然后再次将它们插入内核。

    下一章将看一看iptables规则的语法,以及如何编写正确格式化的规则集。根据需要,它还将显示一些基本的良好编码风格。

    二、如何制定规则?

    本章和接下来的三章将详细讨论如何建立你自己的规则。规则可以描述为当阻塞或允许特定链中的不同连接和数据包时,防火墙将遵循的方向。插入链中的每一行都应该被视为一条规则。我们还将讨论可用的基本匹配,以及如何使用它们,以及不同的目标,以及如何构建自己的新目标(即新的子链)。

    本章将讨论如何创建规则的基本知识,以及如何编写和输入规则,以便它能被用户空间程序iptables、不同的表所接受,以及你可以向iptables发出的命令。在此之后,我们将在下一章中研究所有可用于iptables的匹配,然后详细介绍每种类型的目标和跳转。

    2.1 基础iptables指令

    每个规则都是内核查看的一行,以找出对一个包做什么。如果满足所有条件(或匹配),则执行目标指令或跳转指令。通常我们会用这样的语法来编写规则:

    iptables [-t table] command [match] [target/jump]
    
    • 1

    并没有规定目标指令必须是该行中的最后一个函数。但是,通常会坚持这种语法以获得最佳的可读性。所以将看到的大多数规则都是以这种方式编写的。

    如果希望使用标准表以外的表,可以在指定[table]的位置插入表规范。但是,没有必要显式地说明使用什么表,因为在默认情况下,iptables使用过滤表来实现所有命令,我们没有必要在【table】位置进行说明,它可以在这行的任何位置,但是一般需要放在开始的地方,那样可读性更强。
    但是需要考虑的一件事是:命令(command)应该总是放在第一位,或者直接放在表规范之后。我们使用’command’来告诉程序要做什么,例如插入规则或将规则添加到链的末端,或删除规则。我们将在下面进一步研究这个问题。

    匹配(match)是我们发送给内核的规则的一部分,它详细说明了数据包的特定字符,使它不同于所有其他数据包。在这里,我们可以指定数据包来自哪个IP地址、来自哪个网络接口、预期的IP地址、端口、协议或其他任何东西。有一堆不同的匹配我们可以使用,我们将在本章中进一步仔细研究。

    最后我们有了数据包的目标。如果一个包的所有匹配都满足,我们就告诉内核如何处理它。例如,我们可以告诉内核将包发送到我们自己创建的另一个链,它是这个特定表的一部分。我们可以告诉内核丢弃数据包,不再做进一步的处理,或者我们可以告诉内核向发送者发送一个指定的回复。与本节的其他内容一样,我们将在本章中进一步仔细研究它。

    2.2 表(Tables)

    -t 选项定义选择哪种表,具体内容参考“遍历表和链”。下面简单概括四种表的主要内容:

    释义
    NATnat表主要用于网络地址转换。根据我们的规则,经过NAT转换的数据包的IP地址会被改变。流中的数据包只遍历该表一次。我们假设流的第一个包是允许的。在同一流中的其他数据包会自动被“NAT”或伪装等,并将受到与第一个数据包相同的操作。换句话说,这些包不会再遍历这个表,但仍然会被视为流中的第一个包。这就是为什么不应该在这个表中进行任何过滤的主要原因,我们将在后面更详细地讨论这个问题。PREROUTING链用于在信息包进入防火墙后立即更改信息包。OUTPUT链用于在本地生成的包到达路由决策之前更改它们(例如,在防火墙上)。最后是POSTROUTING链,它用于在包即将离开防火墙时更改包。
    MANGLE该表主要用于分组。此外,我们还可以更改不同数据包及其报头的内容。例如改变TTL、TOS或MARK。注意,MARK实际上不是对包的更改,而是在内核空间中设置了包的标记值。其他规则或程序可能会在防火墙中进一步使用这个标记来过滤或执行高级路由;Tc就是一个例子。该表由5个内建链组成,PREROUTING、POSTROUTING、OUTPUT、INPUT和FORWARD链。PREROUTING用于在包进入防火墙和到达路由决定之前更改包。POSTROUTING用于在所有路由决策完成后对数据包进行破坏。OUTPUT用于在本地生成的数据包进入路由决策后更改它们。INPUT用于在信息包被路由到本地计算机本身之后,但在用户空间应用程序实际看到数据之前更改信息包。FORWARD用于在报文命中第一个路由决策之后,但在它们真正命中最后一个路由决策之前,对报文进行破坏。请注意,mangle不能用于任何类型的网络地址转换或伪装,nat表是为这些类型的操作而制作的。
    FILTER过滤表只能用于对数据包进行过滤。例如,我们可以毫无问题地删除、LOG、ACCEPT或REJECT包,就像在其他表中一样。这个表中上有三条链。第一个名为FORWARD,用于所有非本地生成的数据包,这些数据包的目的地不是本地主机(换句话说,就是防火墙)。INPUT用于所有发送到本地主机(防火墙)的信息包,而OUTPUT最终用于所有本地生成的信息包。
    RAW在netfilter中,原始表及其链在任何其他表之前使用。引入它是为了使用NOTRACK目标。这个表相当新,只有在编译后的2.6或更晚版本的内核中才可用。原始表包含两个链。PREROUTING和OUTPUT链,它们将在数据包到达任何其他netfilter子系统之前处理数据包。PREROUTING链可用于到此机器的所有传入信息包或被转发的信息包,而OUTPUT链可用于在本地生成的信息包到达任何其他netfilter子系统之前更改它们。

    2.3 命令

    命令(command)-A, --append
    示例(example)iptables -A INPUT …
    释义(Explanation)在规则集的末尾添加规则
    命令(command)-D,–delete
    示例(example)iptables -D INPUT --dport 80 -j DROP, iptables -D INPUT 1
    释义(Explanation)删除链中的一条规则。可以用两种方式完成:适配整个规则,或者指定规则号来适配。如果用第一中方法,那我们的条目必须与链上的条目准确匹配。如果用第二种方法,我们必须匹配需要删除的规则序号,规则的序号都是从链的顶部开始排序的,从1开始排序
    命令(command)-R,–replace
    示例(example)iptables -R INPUT 1 -s 192.168.0.1 -j DROP
    释义(Explanation)替换掉指定行的条目。
    命令(command)-I, --insert
    示例(example)iptables -I INPUT 1 --dport 80 -j ACCEPT
    释义(Explanation)在链中指定位置插入一条规则,上例中表示在该链中第一条规则处插入一条新的规则
    命令(command)-L, --list
    示例(example)iptables -L INPUT
    释义(Explanation)列出指令链上所有的条目
    命令(command)-F, --flush
    示例(example)iptables -F INPUT
    释义(Explanation)刷新指定链中的所有规则,相当于逐个删除每个规则,但是速度要快得多。该命令可以不带任何选项,删除指定表中所有链里的所有规则
    命令(command)-Z, --zero
    示例(example)iptables -Z INPUT
    释义(Explanation)该命令告诉程序将特定链或所有链中的所有计数器归零。如果在-L命令中使用了-v选项,那么我们可能已经在每个字段的开头看到了数据包计数器。要将此数据包计数器归零,请使用-Z选项。该选项与-L相同,只是-Z不会列出规则。如果同时使用-L和-Z(这是合法的),链将首先被列出,然后数据包计数器归零。
    命令(command)-N, --new-chain
    示例(example)iptables -N allowed
    释义(Explanation)通知内核在指定的表里创建一条新链,新的链名不能和已存在的链名重名
    命令(command)-X, --delete-chain
    示例(example)iptables -X allowed
    释义(Explanation)该命令将从表中删除指定的链。要使此命令起作用,必须没有引用这条链的规则。换句话说,在实际删除链之前,必须替换或删除所有引用链的规则。如果使用此命令时不带任何选项,则除内置到指定表中的链外的所有链都将被删除。
    命令(command)-P, --policy
    示例(example)iptables -P INPUT DROP
    释义(Explanation)这个命令告诉内核在链上设置指定的默认目标(target)或策略(policy)。所有不匹配任何规则的信息包将被强制使用链的策略。合法的目标有DROP和ACCEPT
    命令(command)-E, --rename-chain
    示例(example)iptables -E allowed disallowed
    释义(Explanation)
    命令(command)
    示例(example)iptables
    释义(Explanation)
    命令(command)
    示例(example)iptables
    释义(Explanation)-E 命令告诉iptables将链的第一个名称更改为第二个名称。换句话说,在上面的例子中,我们将链的名称从allowed更改为disallowed。注意,这不会影响表的实际工作方式。换句话说,这只是对表的一个修饰性更改。

    如果只是想列出iptables的内置帮助或获取命令的版本。要获得版本,使用-v选项,要获得帮助消息,使用-h选项。换句话说,和往常一样。接下来是一些可用于各种不同命令的选项。请注意,我们告诉您可以使用哪些命令选项以及它们将产生什么效果。还要注意,我们在这里没有包括任何影响规则或匹配的选项。相反,我们将在本章后面的章节中讨论匹配和目标。

    命令的可选项参数

    选项(Options)-v, --verbose
    搭配的命令–list, --append, --insert, --delete, --replace
    释义该命令提供详细输出,主要与–list命令一起使用。如果与–list命令配合使用,则输出接口地址、规则选项和TOS掩码。如果设置了–verbose选项,–list命令还将为每个规则包含一个字节和数据包计数器。这些计数器使用K (x1000)、M (x1,000,000)和G (x1,000,000,000)乘数。要取消此操作并获得确切的输出,可以使用-x选项,稍后将介绍。如果该选项与–append、–insert、–delete或–replace命令一起使用,程序将输出关于规则如何解释以及是否正确插入的详细信息,等等。
    选项(Options)-x, --exact
    搭配的命令–list
    释义此选项展开数值。list的输出不包含K, M或G乘法器。相反,我们将从包和字节计数器中获得与所讨论的规则匹配的包和字节数的确切输出。注意,该选项仅在–list命令中可用,与其他任何命令都没有实际关系。
    选项(Options)-n, --numeric
    搭配的命令–list
    释义这个选项告诉iptables输出数值。IP地址和端口号将使用它们自己的数值打印,而不是主机名、网络名或应用程序名。此选项仅适用于–list命令。此选项覆盖将所有数字解析为主机和名称的默认值(在可能的情况下)。
    选项(Options)–line-numbers
    搭配的命令–list
    释义命令–line-numbers和命令–list用于输出行号。使用此选项,将输出每个规则及其编号。插入规则时,知道哪个规则有哪个数字会很方便。此选项仅适用于–list命令。
    选项(Options)-c, --set-counters
    搭配的命令–insert, --append, --replace
    释义该选项在创建规则或以某种方式修改规则时使用。然后,我们可以使用该选项初始化规则的数据包和字节计数器。语法应该类似于–set-counters 20 4000,这将告诉内核将包计数器设置为20,将字节计数器设置为4000。
    选项(Options)–modprobe
    搭配的命令ALL
    释义–modprobe选项用于告诉iptables在探测模块或将模块添加到内核时使用哪个模块。如果你的modprobe命令不在搜索路径的某个地方,它可以被使用。在这种情况下,可能需要指定此选项,以便程序知道在需要的模块未加载的情况下要做什么。此选项可用于所有命令。
  • 相关阅读:
    Linux介绍
    前端TypeScript学习day05-索引签名、映射与类型声明文件
    1688按关键字搜索商品 API 返回值说明
    哈希加盐算法
    Python---循环---while循环
    SSM框架学习——SpringBoot之整合第三方技术
    使用patch-package保存node_modules包修改
    C# OpenCvSharp Mat操作-操作符重载
    can-utils使用
    RuntimeError: ANTLR version mismatch
  • 原文地址:https://blog.csdn.net/jackhh1/article/details/126208070