ipatbles 是 Linux 下的网络防火墙规则管理/修改工具,通过控制 Linux 内核 netfilter 模块,来管理网络数据包的处理和转发。用来识别路由表中特定的流量然后执行设定的规则。只用于处理 IPv4 数据包;而对于 IPv6 数据包,则使用类似的 ip6tables 命令。

基本概念

netfilter 模型如下:
image.png

结构:

  • Tables 路由表:用来区分不同类型的数据包,如 filter,nat,mangle,每个表包含几个路由链
  • Chain 路由链:流量的类型,如 INPUT ,FORWARD ,OUTPUT ,每种类型流量可以设置不同规则
  • Rule 规则:用来匹配特定类型的流量,如匹配来自 192.168.1.230 的流量
  • Target 目标:用来处理匹配到的流量,如 ACCEPT, DROP, QUEUE.
  • Policy 策略:是默认的处理动作,用来处理没有匹配到的流量,如 ACCEPT or DROP.

iptables、ip6tables等都使用Xtables框架。存在“表(tables)”、“链(chain)”和“规则(rules)”三个层面。

每个“表”指的是不同类型的数据包处理流程,如filter表表示进行数据包过滤,而nat表针对连接进行地址转换操作。每个表中又可以存在多个“链”,系统按照预订的规则将数据包通过某个内建链,例如将从本机发出的数据通过OUTPUT链。在“链”中可以存在若干“规则”,这些规则会被逐一进行匹配,如果匹配,可以执行相应的动作,如修改数据包,或者跳转。跳转可以直接接受该数据包或拒绝该数据包,也可以跳转到其他链继续进行匹配,或者从当前链返回调用者链。当链中所有规则都执行完仍然没有跳转时,将根据该链的默认策略(“policy”)执行对应动作;如果也没有默认动作,则是返回调用者链。

假设使用路由器作为网关(即我们平时的上网方式),那么局域网设备通过路由器访问互联网的流量方向:

PREROUTING链->FORWARD链->POSTINGROUTING链

局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:

PREROUTING链->INPUT链->网关本机

路由器访问互联网的流量方向:

网关本机->OUTPUT链->POSTINGROUTING链

内建的路由表:

  • filter: 是默认的表,如果不指明表则使用此表。其通常用于过滤数据包。It includes chains like INPUT, OUTPUT and FORWARD.
  • nat : 用于地址转换操作。It includes PREROUTING and POSTROUTING chains.
  • mangle : 用于修改或标记数据包。
  • raw : 用于处理异常。Built-in chains are PREROUTING and OUTPUT.
  • security : Used for Mandatory Access Control

内建的路由链:

  • INPUT :输入链。发往本机的数据包通过此链
  • FORWARD :转发链。本机转发的数据包通过此链
  • OUTPUT :输出链。从本机发出的数据包通过此链
  • PREROUTING :路由前链,在处理路由规则前通过此链,通常用于目的地址转换(DNAT)
  • POSTROUTING :路由后链,完成路由规则后通过此链,通常用于源地址转换(SNAT)

Note: 用户可以创建自定义路由链

目标:

  • RETURN 允许并结束在 chains 里继续匹配
  • ACCEPT 允许但依然要在其他 chains 里继续进行匹配
  • REJECT 拒绝
  • DROP 丢弃
  • REDIRECT 重定向。只适用于 NAT 路由表的 PREROUTING 和 OUTPUT 路由链
  • MARK 只适用于 mangle 路由表。用来给特定流量做标记。
root@OpenWrt:~# iptables -h
iptables v1.8.3

Usage: iptables -[ACD] chain rule-specification [options]
       iptables -I chain [rulenum] rule-specification [options]
       iptables -R chain rulenum rule-specification [options]
       iptables -D chain rulenum [options]
       iptables -[LS] [chain [rulenum]] [options]
       iptables -[FZ] [chain] [options]
       iptables -[NX] chain
       iptables -E old-chain-name new-chain-name
       iptables -P chain target [options]
       iptables -h (print this help information)

Commands:
Either long or short options are allowed.
  --append  -A chain        Append to chain
  --check   -C chain        Check for the existence of a rule
  --delete  -D chain        Delete matching rule from chain
  --delete  -D chain rulenum
                Delete rule rulenum (1 = first) from chain
  --insert  -I chain [rulenum]
                Insert in chain as rulenum (default 1=first)
  --replace -R chain rulenum
                Replace rule rulenum (1 = first) in chain
  --list    -L [chain [rulenum]]
                List the rules in a chain or all chains
  --list-rules -S [chain [rulenum]]
                Print the rules in a chain or all chains
  --flush   -F [chain]        Delete all rules in  chain or all chains
  --zero    -Z [chain [rulenum]]
                Zero counters in chain or all chains
  --new     -N chain        Create a new user-defined chain
  --delete-chain
            -X [chain]        Delete a user-defined chain
  --policy  -P chain target
                Change policy on chain to target
  --rename-chain
            -E old-chain new-chain
                Change chain name, (moving any references)
Options:
    --ipv4    -4        Nothing (line is ignored by ip6tables-restore)
    --ipv6    -6        Error (line is ignored by iptables-restore)
[!] --protocol    -p proto    protocol: by number or name, eg. `tcp'
[!] --source    -s address[/mask][...]
                source specification
[!] --destination -d address[/mask][...]
                destination specification
[!] --in-interface -i input name[+]
                network interface name ([+] for wildcard)
 --jump    -j target
                target for rule (may load target extension)
  --goto      -g chain
                              jump to chain with no return
  --match    -m match
                extended match (may load extension)
  --numeric    -n        numeric output of addresses and ports
[!] --out-interface -o output name[+]
                network interface name ([+] for wildcard)
  --table    -t table    table to manipulate (default: `filter')
  --verbose    -v        verbose mode
  --wait    -w [seconds]    maximum wait to acquire xtables lock before give up
  --wait-interval -W [usecs]    wait time to try to acquire xtables lock
                default is 1 second
  --line-numbers        print line numbers when listing
  --exact    -x        expand numbers (display exact values)
[!] --fragment    -f        match second or further fragments only
  --modprobe=<command>        try to insert modules using this command
  --set-counters PKTS BYTES    set the counter during insert/append
[!] --version    -V        print package version.

语法结构:

iptables -t [TABLE] [-A/-C/-D...] [CHAIN] rule -j Target

路由链操作

-A 链添加规则

-A 在链表后添加规则和动作,新加的规则排在表的最后。

允许所有发往本机的流量:

iptables -t filter -A INPUT -j ACCEPT

-I 插入规则

-I 指令添加规则并可指定新规则在链表的位置,不指定排序数字的话默认插入的规则放置到路由链第一条。

新建规则并作为 INPUT 路由链第一条规则:

iptables -t filter -I INPUT -j ACCEPT

新建规则并作为 INPUT 路由链第二条规则:

iptables -t filter -I INPUT 2 -j ACCEPT

由于链表的规则是顺序读取的,所以将规则放在前面有时候会确保规则的正确执行,使用 -I 参数比较合适。

-D 链删除规则

删除设定的发往本机的编号为 2 的规则:

iptables -t filter -D INPUT 2

-C 链检查规则是否存在

检查是否有丢弃来自 192.168.1.123 的流量的规则:

iptables -t filter -C INPUT -s 192.168.1.123 -j DROP

-L 路由规则列表

列出当前设定的所有规则并按顺序排序:

iptables -L -n

列出特定路由表的规则:

iptbales -t [TABLE] -L

列出特定路由表的某条链的规则:

iptbales -t [TABLE] -L INPUT

举例说明

分别使用 -A -I 建立规则,然后 -L 查看规则,-D 删除规则:

$ iptables -I INPUT -s 192.168.1.101 -j ACCEPT
$ iptables -A INPUT -s 192.168.1.102 -j ACCEPT
$ iptables -I INPUT -s 192.168.1.103 -j ACCEPT
$ iptables -I INPUT 2 -s 192.168.1.104 -j ACCEPT

$ iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  192.168.1.103        anywhere            
ACCEPT     all  --  192.168.1.104        anywhere            
ACCEPT     all  --  192.168.1.101        anywhere            
ACCEPT     all  --  192.168.1.102        anywhere

$ iptables -D INPUT 2
$ iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  192.168.1.103        anywhere            
ACCEPT     all  --  192.168.1.101        anywhere            
ACCEPT     all  --  192.168.1.102        anywhere

规则匹配

-p 匹配特定协议的流量

可能的流量类型: tcp, udp, icmp, ssh etc.

屏蔽对本机的 ping 请求:

iptables -t filter -A INPUT -p icmp -j DROP

丢弃发往本机的 udp 流量:

iptables -t filter -A INPUT -p udp -j DROP

--dport 匹配特定端口

丢弃访问本机 1080 端口的 tcp 流量:(默认是 filter 路由表)

iptables -A INPUT -p tcp --dport 1080 -j DROP

-s 匹配源地址流量

接收来自 192.168.1.230 发往本机的流量:

iptables -t filter -A INPUT -s 192.168.1.230 -j ACCEPT

-d 目标地址的流量

丢弃发往 192.168.1.123 的流量:

iptables -t filter -A OUTPUT -d 192.168.1.123 -j DROP

-i 匹配特定网络入口的流量:

丢弃所有来自 wlan0 无线网口的流量:

iptables -t filter -A INPUT -i wlan0 -j DROP

-o 匹配特定网络出口的流量:

丢弃所有发往 eth0 网口的流量:

iptables -t filter -A OUTPUT -i eth0 -j DROP

允许 loopback 本地访问

允许来自本地的访问(127.0.0.1) 非常重要,应该保证为打开状态:(lo 表示本机网口-interface)

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

规则动作

-j 规则匹配后的动作

丢弃所有转发链流量:

iptables -t filter -A FORWARD -j DROP

-m 匹配参数的使用

-m multiport 同时处理多端口

允许访问本机的多个端口的 tcp 流量:(默认是 filter 路由表)

iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT

-m mac 匹配特定 mac 地址

丢弃某个 mac 地址对本地的访问:

iptables -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j DROP

路由转发

将特定的流量转发到另一个地方,需要用到 PREROUTING 路由表来预处理流量。

将来自 eth0 网口的访问本机 25 端口的 tcp 流量转发到 2525 端口:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25 -j REDIRECT --to-port 2525

新建路由链

通过新建自定义路由链,可以放入自定义的规则到里面。自定义规则并不能被直接使用,需要使用系统内置的 chains 然后 jump 到自定义 chain。

语法:

iptables -t [TABLE] -N [CHAIN]

在 NAT 路由表下新建路由链 custom-chain:

iptables -t nat -N custom-chain

查看新建的路由链:

iptables -L custom-chain

将流量转到自定义路由链:

iptables -A INPUT -p tcp -j custom-chain

删除路由链

语法:

iptables -t [TABLE] -X [CHAIN]

示例:

iptables -t nat -X custom-chain

注意,如果路由链里定义的有 rule 规则,则直接执行以上命令会报错:iptables: Directory not empty.,需要先删除链中所有的规则,在执行删除命令:

iptables -t nat -F custom-chain
iptables -t nat -X custom-chain

标记流量

MARK 目标用来给流量做标记,方便识别及处理。只适用于 mangle 路由表:

iptables -t mangle -A PREROUTING -p udp --dport 53 -j MARK --set-mark 1

常用命令

清除设置的规则,默认为 filter 路由表:

iptables -t [TABLE] -F

保存规则:

iptables-save > /path/to/file

恢复规则:

iptables-restore < /path/to/file

直接使用iptables命令修改防火墙配置的时候,防火墙规则只是保存在内存中,系统重启后就会失效。如需保存规则,需要使用以上命令保存和恢复。

参考文章

iptables command in Linux with Examples
25 Useful IPtable Firewall Rules Every Linux Administrator Should Know
iptables wikipedia
https://gist.github.com/mcastelino/c38e71eb0809d1427a6650d843c42ac2

标签:无

你的评论