iptables

Category: network      Tags:  

cover-image

###1. iptables

iptables是linux中的L3防火墙(linux中还有L2的 arptables, ebtables), iptables 由 “ipfirewall -> ipchain -> iptables” 发展而来

iptable由userspace的iptables command 和 kernel 中的 iptables模块构成, iptables的内核模块基于netfilter框架开发, userspace中的iptables命令用于定义规则, 而kernel中的iptables模块则利用netfilter框架注册hook点, 根据定义的规则来过滤流经过滤点的数据包

###2. iptables的过滤点类型

iptables 基于netfilter框架来注册hook点, 在netfilter的相关章节中, 已经讲解过, netfilter中定义了5种类型的hook点 : “NF_INET_PRE_ROUTING, NF_INET_LOCAL_IN, NF_INET_FORWARD, NF_INET_LOCAL_OUT, NF_INET_POST_ROUTING”, 在iptables中, 为这5种类型hook点定义了别名

  • NF_IP_PRE_ROUTING : 数据包路由前, NF_INET_PRE_ROUTING 的别名
  • NF_IP_LOCAL_IN : 数据包流入, NF_INET_LOCAL_IN 的别名
  • NF_IP_FORWARD : 数据包转发, NF_INET_FORWARD 的别名
  • NF_IP_LOCAL_OUT : 数据包流出, NF_INET_LOCAL_OUT 的别名
  • NF_IP_POST_ROUTING : 数据包路由后, NF_INET_POST_ROUTING 的别名

在linux的tcp/ip协议栈中, 每一种hook类型只有一个hook点, 这几个hook点的关系如下:

iptables hooks

对于不同目的地的数据包, 其流经的hook点的顺序如下:

  • 从其它主机发送给本机的数据包 : PRE_ROUTING —> LOCAL_IN
  • 经本机转发的数据包 : PRE_ROUTING —> FORWARD —> POST_ROUTING
  • 从本机发往其它主机的数据包 : LOCAL_OUT —> POST_ROUTING

###3. iptables hook点在tcp/ip协议栈中的位置

iptables 中5种不同的hook点在tcp/ip协议栈源码中的位置如下图所示

iptables hook 点的位置

###4. iptables中的表和规则链

iptables中将上述的5个hook点称为5条规则链, 即

  • input chain : 对应 “LOCAL_IN” hook点
  • output chain : 对应 ”LOCAL_OUT“ hook点
  • forward chain : 对应 “FORWARD” hook点
  • prerouting chain : 对应 ”PRE_ROUTING“ hook点
  • postrouting chain : 对应 “POST_ROUTING” hook点

按照管理的内容不同, iptables还定义个4张内建的表

  • filter 表 : 用于处理数据包过滤, 工作在 “input” “output” “forward” 3个chain上
  • nat 表 : 用于处理网络地址转换, 工作在 “prerouting” “postrouting” “output” 3个chain上
  • mangle 表 : 用于修改数据包的内容, 工作在 “input” “output” “nat” “prerouting” “postrouting” 5个chain上
  • raw 表 : 用于处理异常, 工作在“prerouting” “output” 2个chain上
  • security 表 :

###5. iptables规则语法

用户空间的iptables命令用于配置规则, 内核中的iptables模块利用netfilter框架来注册hook函数, 在不同的hook点执行hook函数, 匹配设置好的规则, 执行不同的动作, 可见, 规则是iptable色核心

iptable定义规则的语法为

iptables [-t tbale] COMMAND chain CRETIRIA -j ACTION
  1. [-t table] : 指定要操作的table, 缺省为filter表
  2. COMMAND : 指定执行何种规则操作, 例如是添加规则,删除规则还是列出规则等, 可选的command在第5节会有详细介绍
  3. chain : 指定要操作的规则链, 缺省作用于该表中所有的规则链
  4. CRETIRIA : 匹配规则, 例如通过 tcp/udp 协议, 或者源地址/目的地址, 或者源端口/目的端口, 或者它们的组合来匹配数据包
  5. ACTION : 匹配设据包成功后要执行的操作, 可选的有
    • ACCEPT : 接受
    • DROP : 悄悄丢弃数据包
    • REJECT : 明确拒绝数据包
    • DNAT : 执行目的地址转换
    • SNAT : 执行源地址转换
    • MASQUERADE : 源地址伪装, 即自动根据dhcp分配的源地址进行源地址转换
    • REDIRECT : 重定向, 主要用于实现端口重定向
    • MARK : 打防火墙标记
    • customer_chain : 转向指定的自定义 chain
    • RETURN : 返回, 用于在自定义chain中返回到原来的chain中继续执行

根据COMMAND的不同, 可以分为“链管理命令”和“规则管理命令”

####5.1 链管理命令

链管理命令中支持如下命令

  • -F, –flush [chain] : 清除指定的规则链中的所有规则
  • -Z, –zero [chain [rulenum]] : 清零指定的chain中指定的规则链中的packet和byte计数器, 每一个规则都有两个计数器, 缺省为所有规则链中的所有规则
  • -N, –new-chain chain : 建立一个用户自定义的规则链
  • -X, –delete-chain [chain] : 删除一个用户自定义的规则链, 若有其它用户自定义的chain依赖该chain, 这需要先删除所有依赖chain的chain
  • -P, –policy chain target : 设置指定chain的默认策略
  • -E, –rename-chain old-chain new-chain : 将指定的用户自定义规则链重命名

还有如下2个链查看命令

  • -L, –list [chain] : 列出指定规则链中的所有规则, 若不指定规则链则列出指定的表中所有规则链中的规则, 该参数还可以附加其它参数
    • -n 以数字的新式显示ip, 否则反向解析成主机名
    • -v 显示详细信息, 例如byte计数, packet计数
    • -vv 比“-v”更详细
    • -vvv 比 “-vv”更详细
    • -x 计数器显示精确值
    • –line-numbers 显示规则的行号
  • -S, –list-rules [chain] : 列出所有生成指定的规则链中的当前状态的规则所需的command, 即通过给出的command可以将规则链中的规则恢复为当前状态, 常用于备份iptables的配置

####5.2 规则管理命令

规则管理命令中支持的命令如下

  • -A, –append chain rule-specification : 在指定的规则链的尾部添加一条或者多条规则
  • -C, –check chain rule-specification : 检查给出的规则在指定的规则链中是否存在
  • -D, –delete chain rulenum : 在指定的规则链中删除给出的规则, 给出规则的id
  • -D, –delete chain rule-specification : 在指定的规则链中删除给出的规则, 给出完整的规则
  • -I, –insert chain [rulenum] rule-specification : 在指定的规则链中指定的位置擦插入给出的规则, 不指定位置时, 缺省为1, 即该规则链的头部
  • -R, –replace chain rulenum rule-specification : 将指定的规则链中指定位置的规则替换为给出的规则

###6. iptables的匹配规则

iptables中设置的rule只会对匹配到的数据包其作用,在添加rule时, 需要指定数据包的匹配规则, 可以通过数据包协议, 源/目的地址等多种方式的组合来进行匹配

  • 通用匹配 : 源/目的地址的匹配
  • 隐含扩展匹配 : 协议匹配
  • 显示扩展匹配 : 模块匹配

####6.1 源/目的地址匹配

  • [!] -s, –source address[/mask][,…] : 指定源地址匹配(可以取非)
  • [!] -d, –destination address[/mask][,…] : 指定目的地址匹配(可以取非)
  • [!] -i, –in-interface name : 指定匹配入口的网络设备,例如 eth0, wlan0等, (可以取非)
  • [!] -o, –out-interface name : 指定匹配出口的网络设备,例如 eth0, wlan0等, (可以取非)

####6.2 协议匹配

可以匹配ipv4或者ip6

  • -4, –ipv4 : 匹配ipv4
  • -6, –ipv6 : 匹配ipv6

网络协议匹配的语法为, “其中可以使用!来做取非运算”

[!] -p, --protocol protocol

iptables可以支持多种协议匹配, 例如 tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh, 或者使用关键字“all”来代表所有的协议

”-p tcp“可以指定tcp协议匹配, tcp匹配可以使用如下3种扩展匹配

  • –dport xx-xx / –dport xx: 匹配目标地址端口, 指定多个连续的端口号或者单个端口号
  • –sport xx-xx / –sport xx: 匹配源地址端口, 指定多个连续的端口号或者单个端口号
  • –tcp-flags : TCP的标志位(SYN,ACK,FIN,PSH,RST,URG), 对于它,一般要跟两个参数:检查的标志位; 必须为1的标志位, 例如“-tcpflags syn,ack,fin,rst syn”指定要检查syn,ack,fin,rst, 且syn必须为1, 其它必须为0

”-p udp“可以指定udp协议匹配, udp匹配可以使用如下2种扩展匹配

  • –dport xx-xx / –dport xx: 匹配目标地址端口, 指定多个连续的端口号或者单个端口号
  • –sport xx-xx / –sport xx: 匹配源地址端口, 指定多个连续的端口号或者单个端口号

”-p icmp“可以指定icmp协议匹配, icmp匹配可以“–icmp-type”来扩展匹配icmp报文的类型, 例如“–icmp-type 8”

最常用的两个icmp type如下

  • 0 : Echo Reply——回显应答(Ping应答)
  • 8 : Echo request——回显请求(Ping请求)

其它的type如下:

  • 0 : Echo Reply——回显应答(Ping应答)
  • 3 : 不同的code的意义如下
    1. Network Unreachable——网络不可达
    2. Host Unreachable——主机不可达
    3. Protocol Unreachable——协议不可达
    4. Port Unreachable——端口不可达
    5. Fragmentation needed but no frag. bit set——需要进行分片但设置不分片比特
    6. Source routing failed——源站选路失败
    7. Destination network unknown——目的网络未知
    8. Destination host unknown——目的主机未知
    9. Source host isolated (obsolete)——源主机被隔离(作废不用)
    10. Destination network administratively prohibited——目的网络被强制禁止
    11. Destination host administratively prohibited——目的主机被强制禁止
    12. Network unreachable for TOS——由于服务类型TOS,网络不可达
    13. Host unreachable for TOS——由于服务类型TOS,主机不可达
    14. Communication administratively prohibited by filtering——由于过滤,通信被强制禁止
    15. Host precedence violation——主机越权
    16. Precedence cutoff in effect——优先中止生效
  • 4 : code 0 Source quench——源端被关闭(基本流控制)
  • 5 : 不同的code的意义如下
    1. Redirect for network——对网络重定向
    2. Redirect for host——对主机重定向
    3. Redirect for TOS and network——对服务类型和网络重定向
    4. Redirect for TOS and host——对服务类型和主机重定向
  • 8 : code 0 代表 Echo request——回显请求(Ping请求)
  • 9 : code 0 代表 Router advertisement——路由器通告
  • 10 : code 0 代表 Route solicitation——路由器请求
  • 11 :不同的code的意义如下
    1. TTL equals 0 during transit——传输期间生存时间为0
    2. TTL equals 0 during reassembly——在数据报组装期间生存时间为0
  • 12 : 不同的code的意义如下
    1. IP header bad (catchall error)——坏的IP首部(包括各种差错)
    2. Required options missing——缺少必需的选项
  • 13 : code 0 代表 Timestamp request (obsolete)——时间戳请求(作废不用)
  • 14 : code 0 代表 Timestamp reply (obsolete)——时间戳应答(作废不用
  • 15 : code 0 代表 Information request (obsolete)——信息请求(作废不用)
  • 16 : code 0 代表 Information reply (obsolete)——信息应答(作废不用
  • 17 : code 0 代表 Address mask request——地址掩码请求
  • 18 : code 0 代表 Address mask reply——地址掩码应答

####6.3 扩展模块匹配

例如, 启用多端口扩展

-m multiport

之后就可以指定非连续的端口, 例如

--dport 21,23,87

###7. iptables的默认策略

防火强可以使用2种默认策略:

  • 默认为开, 限定不能通过的数据包才不能通过
  • 默认为关, 限定可以通过的数据包才能通过

iptables中的默认策略有两种 ACCEPT (默认为开) 和 DROP (默认为关), 对于未匹配到的数据包, 执行默认策略, iptables可以分别设定指定表中指定规则链的默认策略, 例如设置filter表中INPUT chain的默认策略为DROP

iptables -t filter -P INPUT DROP

查看默认策略可以使用”-L” command

$ iptables -t nat -L OUTPUT
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

其中 “(policy ACCEPT)”表明默认策略为 ACCEPT

###8. NAT的实现

由于ip资源有限, 不可能为每一个设备都分配一个外网ip, 因此, 需要进行NAT转换将内网ip转换为外网ip,根据转换的地址不同可以分为:

  • SNAT : 源地址转换
  • DNAT : 目的地址转换

####8.1 SNAT

转换一般用在我们的许多内网用户通过一个外网的口上网的时候(例如在PC上通过多网卡共享上网的时候), 这时我们将我们内网的地址转换为一个外网的IP,我们就可以实现连接其他外网IP的功能

例如, 在一台PC上有2张网卡, eth0连接外网ip为 180.123.45.6, eth1用于共享网络个其它设备, ip为10.42.0.1/24, 则需要设置源地址转换, SNAT只能用在nat表的POSTROUTING链里

$ iptables -t nat -A POSTROUTING -s 10.42.0.1/24 -j SNAT --to-source 180.123.45.6

路由会自动选则eth0为外网出口设备, 在POSTROUTING时, 将 10.42.0.1/24 网段的源地址转换为外网ip地址 180.123.45.6, 在internet中的服务器看起来, 是180.123.45.6发出的数据包, 并不知道10.42.0.1/24 网段的存在, 则回应的数据包会发给 180.123.45.6, 而在SNAT时, 记录了SNAT的对应关系, 在接收到回应包时, 会做一次UN-SNAT, 即DNAT, ,将应答的数据包的目标ip转换为内网ip, 因此能够被eth1发送给内网的机器

有时候, eth0的ip不是固定的, 而是dhcp分配, 则可以使用

$ iptables -t nat -A POSTROUTING -s 10.42.0.1/24 -j MASQUERADE

指定MASQUERADE时, 可以自动寻找外网地址

####8.2 DNAT

当有多个服务器对外通过一个外网IP提供服务时, 可以使用DNAT

例如, 外网ip 180.123.45.6, 内网ip 10.42.0.100 的机器提供http服务, 则设置

iptables -t nat -A PREROUTING -p tcp -d 180.123.45.6 --dport 80 -j DNAT --to-destination 10.42.0.100

所有发往180.123.45.6:80 端口的请求均重定向到10.42.0.100上处理

当有多台服务器来提供相同的服务时, 利用DNAT还可一实现负载均衡

总结起来, SNAT可以隐藏客服端, DNAT可以隐藏服务器