###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点的关系如下:
对于不同目的地的数据包, 其流经的hook点的顺序如下:
- 从其它主机发送给本机的数据包 : PRE_ROUTING —> LOCAL_IN
- 经本机转发的数据包 : PRE_ROUTING —> FORWARD —> POST_ROUTING
- 从本机发往其它主机的数据包 : LOCAL_OUT —> POST_ROUTING
###3. iptables hook点在tcp/ip协议栈中的位置
iptables 中5种不同的hook点在tcp/ip协议栈源码中的位置如下图所示
###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
- [-t table] : 指定要操作的table, 缺省为filter表
- COMMAND : 指定执行何种规则操作, 例如是添加规则,删除规则还是列出规则等, 可选的command在第5节会有详细介绍
- chain : 指定要操作的规则链, 缺省作用于该表中所有的规则链
- CRETIRIA : 匹配规则, 例如通过 tcp/udp 协议, 或者源地址/目的地址, 或者源端口/目的端口, 或者它们的组合来匹配数据包
- 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的意义如下
- Network Unreachable——网络不可达
- Host Unreachable——主机不可达
- Protocol Unreachable——协议不可达
- Port Unreachable——端口不可达
- Fragmentation needed but no frag. bit set——需要进行分片但设置不分片比特
- Source routing failed——源站选路失败
- Destination network unknown——目的网络未知
- Destination host unknown——目的主机未知
- Source host isolated (obsolete)——源主机被隔离(作废不用)
- Destination network administratively prohibited——目的网络被强制禁止
- Destination host administratively prohibited——目的主机被强制禁止
- Network unreachable for TOS——由于服务类型TOS,网络不可达
- Host unreachable for TOS——由于服务类型TOS,主机不可达
- Communication administratively prohibited by filtering——由于过滤,通信被强制禁止
- Host precedence violation——主机越权
- Precedence cutoff in effect——优先中止生效
- 4 : code 0 Source quench——源端被关闭(基本流控制)
- 5 : 不同的code的意义如下
- Redirect for network——对网络重定向
- Redirect for host——对主机重定向
- Redirect for TOS and network——对服务类型和网络重定向
- Redirect for TOS and host——对服务类型和主机重定向
- 8 : code 0 代表 Echo request——回显请求(Ping请求)
- 9 : code 0 代表 Router advertisement——路由器通告
- 10 : code 0 代表 Route solicitation——路由器请求
- 11 :不同的code的意义如下
- TTL equals 0 during transit——传输期间生存时间为0
- TTL equals 0 during reassembly——在数据报组装期间生存时间为0
- 12 : 不同的code的意义如下
- IP header bad (catchall error)——坏的IP首部(包括各种差错)
- 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可以隐藏服务器