文章目录
整理了一下iptables相关的理论知识,部分摘抄自骏马金龙的博客。
https://www.cnblogs.com/f-ck-need-u/p/7397146.html
有时间继续补充完善。
netfilter
netfilter:linux内核空间的网络管理模块。存放netfilter模块的目录有三个:/lib/modules/$kernel_ver/net/{netfilter,ipv4/netfilter,ipv6/netfilter}。$kernel_ver代表内核版本号。netfilter下放的是同时满足ipv4和ipv6的netfilter。
netfilter在数据包流向内核进程的路径中埋下了5个钩子:
- prerouting
- input
- forword
- output
- postrouting
报文流向:
- 流入本机:prerouting–>input–>用户空间进程
- 流出本机:用户空间进程–>output–>postrouting
- 转发:prerouting–>forward–>postrouting
iptables是什么
iptables:用户空间中管理netfilter的命令行工具
iptables的四表五链
要使netfilter能够工作,就需要将所有的规则读入内存中。netfilter自己维护一个内存块,在此内存块中有4个表:filter表、NAT表、mangle表和raw表。在每个表中有相应的链,链中存放的是一条条的规则,规则就是过滤防火的语句或者其他功能的语句。
四表:
- filter:过滤,防火墙
- mangle:拆解报文,按需修改
- nat:地址转换
- raw:关闭在nat表上启用的连接追踪机制
五条内置链:
- PREROUTING
- INPUT
- FORWARD
- OUTPUT
- POSTROUTING
自定义链:用于对内置链进行组织和管理
表可作用的链
- filter:INPUT FORWARD OUTPUT
- mangle:PREROUOTING INPUT FORWARD OUTPUT POSTING
- nat PREROUTING INPUT OUTPUT POSTROUTING
- raw: PREROUTING OUTPUT
各个钩子处的表规则优先级
- PREROUTING:raw>mangle>nat
- INPUT:mangle>filter
- FORWARD:mangle>filter
- OUTPUT:raw>mangle>nat>filter
- POSTROUTING:mangle>nat
总结:raw>mangle>nat>filter
iptables规则:
组成部分:
- 匹配条件:
- 基本匹配
- 扩展匹配
- 处理动作(target)
- 基本处理动作
- 扩展处理动作
- 自定义处理动作
命令格式
iptables [-t table] SUBCOMMAND chain [matches…] [-j target]
选项拆解
- -t table:指定表,如raw, mangle, nat, filter
- SUBCOMMAND 管理子选项,通常用作链管理、规则管理等
- chain 规则要作用的链名
- matches 匹配规则
- -j target 指明处理动作,如ACCEPT/DROP/REJECT/return等等
SUBCOMMAND:
- 链管理
- -N 新增一条自定义链;
- -X 删除自定义的空链;
- -P 设置链的默认策略
- ACCEPT 接受
- DROP 丢弃
- REJECT 拒绝
- -E rename 重命名自定义的未被引用的链
- 规则管理
- -A 追加,添加到链的尾部
- -I 插入,默认插入到第一条
- -D 删除
-
- 指明rule specification
-
- 指定rule number
-
- -R 替换,用法类似-D
- -F 清空规则,默认清空filter,可指定chain或者指定规则
- -Z 将计数器置零;(iptables的每条规则都有两个计数器:1.本规则匹配到的所有报文数量、2.由本规则匹配到的所有bytes)
- -S 显示指定链上的所有规则(命令格式),默认显示所有链的所有规则。通常用于持久化当前的规则
- 查看
- -n:不反解ip和端口,只显示数字
- -v 详细信息 -vv -vvv
- -x 显示计数信息
- –line-numebers 显示规则的编号
matches匹配条件
- 基本匹配:netfilter 自带的匹配机制
- [!]-s 原地址匹配
- [!]-d 目标地址匹配
- [!]-i 限制报文流入的接口,只能用于PREROUTING.INPUT FORWARD
- [!]-o 限制报文流出的接口,只能用于OUTPUT FORWARD POSTROUTING
- [!]-p 指明协议,通常只有tcp udp icmp
- 扩展匹配:通过扩展模块引入的匹配机制 -m matchname
- 隐式扩展:可以不使用-m选项加载模块,使用-p选项匹配协议
- 显示扩展:必须由-m选项专门加载相应模块
隐式扩展
支持的常见协议:tcp udp icmp icmpv6 esp ah sctp mh all
tcp子选项
- [!]–source-port,–sport,port[:port] 匹配源端口,可以是端口范围
- [!]–destination-port,–dport,port[:port] 匹配目的端口,可以是端口范围
- [!] --tcp-flags mask comp 检查报文中mask指明的tcp标志位,要求这些标志位comp中必须为1;
- [!]–syn
显示扩展
"-m"选项指定的是显式扩展。其实隐式扩展也是要指定扩展名的,只不过默认已经知道所使用的扩展,于是可以省略。例如:-p tcp --dport = -p tcp -m tcp --dport。
multiport 多端口匹配,以离散方式定义多端口匹配;最多指定15个端口;
[!] --source-ports,--sports port[,port|,port:port]...:指定多个源端口;
[!] --destination-ports,--dports port[,port|,port:port]...:指定多个目标端口;
[!] --ports port[,port|,port:port]...:指明多个端口;
8
~]# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.67 -p tcp -m multiport --dports 22,80 -j ACCEPT
iprange
iprange:指明一段连续的ip地址范围作为源地址或者目标地址
[!] --src-range from[-to]:匹配给定的源地址范围
[!] --dst-range from[-to]:匹配给定的目标地址范围
state
state:状态扩展。结合ip_conntrack追踪会话的状态。
[!] --state state
其中state有如下4种:
- INVALID:非法连接(如syn=1 fin=1)
- ESTABLISHED:数据包处于已建立的连接中,它和连接的两端都相关联
- NEW:新建连接请求的数据包,且该数据包没有和任何已有连接相关联
- RELATED:表示数据包正在新建连接, 但它和已有连接是相关联的(如被动模式的ftp的命令连接和数据连接)
这四种状态是数据包的状态,不是客户端或者服务器当时所处的状态。也可以认为是防火墙state模块的状态,因为state模块在收到对应状态的包时会设置为相同的状态。
NEW:为了建立一条连接,发送的第一个数据包(如tcp三次握手的第一次SYN数据包)的状态为NEW。如果第一次连接没建立成功,则第二个继续请求的数据包已经不是NEW数据包了。所以,如果不允许NEW状态的数据包表示不允许主动和对方建立连接,也不允许外界和本机建立连接。
ESTABLISHED:无论是tcp数据包、udp数据包还是icmp数据包,只要发送的请求数据包穿过了防火墙,那么接下来双方传输的数据包状态都是ESTABLISHED,也就是说发过去的和返回回来的都是ESTABLISHED状态数据包。
RELATED:
string:匹配报文中的字符串。
--algo {kmp|bm}:两种算法,随便指定一种
--string "string_pattern"
比如:
iptables -A OUTPUT -m string --algo bm --sting "taobao.com" -j DROP
mac
mac:匹配MAC地址,格式必须为XX:XX:XX:XX:XX:XX
[!] --mac-source address
limit
limit:使用令牌桶(token bucket)来限制过滤连接请求数。
--limit RATE[/second/minute/hour/day]:允许的平均数量。如每分钟允许10次ping,即6秒一次ping。默认为3/hour。
--limit-burst:允许第一次涌进的并发数量。第一次涌进超出后就按RATE指定数来给出响应。默认值为5。
例如:允许每分钟6次ping,但第一次可以ping 10次。10次之后按照RATE计算。所以,前10个ping包每秒能正常返回,从第11个ping包开始,每10秒允许一次ping:iptables -A INPUT -d ServerIP -p icmp --icmp-type 8 -m limit --limit 6/minute --limit-burst 10 -j ACCEPT
connlimit
connlimit:限制每个客户端的连接上限。
--connlimit-above n:连接数量高于上限n个时就执行TARGET
如最多只允许某ssh客户端建立3个ssh连接,超出就拒绝。两种写法:
iptables -A INPUT -d ServerIP -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
iptables -A INPUT -d ServerIP -p tcp --dport 22 -m connlimit ! --connlimit-above 3 -j ACCEPT
处理动作
通常用-j targername [per-target-options]来指定要对数据包做什么处理。 常见的处理动作如下
- ACCEPT
- DROP
- REJECT
- RETURN 用于自定义链,自定义链中匹配完毕后返回到自定义的前一个链中继续向下匹配
- REDIRECT 端口重定向
- LOG 日志
- MARK 防火墙标记
- DNAT 目标地址转换
- SNAT 原地址转换
- MASQERADE 地址伪装(源地址转换)
ip_conntrack功能和iptstate命令
ip_conntrack提供追踪功能,后来改称为nf_conntrack,由nf_conntrack模块提供。
只要一加载该模块,/proc/net/nf_conntrack文件中就会记录下追踪的连接状态。虽然会追踪TCP/UDP/ICMP的所有连接,但是在此文件中只保存tcp的连接状态。
[root@mail ~]# cat /proc/net/nf_conntrack
ipv4 2 tcp 6 431714 ESTABLISHED src=192.168.100.1 dst=192.168.100.8 sport=1586 dport=22 src=192.168.100.8 dst=192.168.100.1 sport=22 dport=1586 [ASSURED] mark=0 secmark=0 use=2
ipv4 2 tcp 6 427822 ESTABLISHED src=192.168.100.8 dst=192.168.100.1 sport=22 dport=1343 src=192.168.100.1 dst=192.168.100.8 sport=1343 dport=22 [ASSURED] mark=0 secmark=0 use=2
ipv4 2 tcp 6 299 ESTABLISHED src=192.168.100.1 dst=192.168.100.8 sport=1608 dport=22 src=192.168.100.8 dst=192.168.100.1 sport=22 dport=1608 [ASSURED] mark=0 secmark=0 use=2
也可以使用iptstate命令实时显示连接状态,它是像top工具一样的显示。该命令工具在iptstate包中,可能需要手动安装。
nf_conntrack也会消耗一定的资源,所以在设计的时候默认给出了其最大的追踪数量,最大追踪数量值由/proc/sys/net/netfilter/nf_conntrack_max文件决定。默认是31384个。这个值显然是无法满足较高并发量的服务器的,所以可以将其增大一些,否则追踪数达到了最大值后,后续的所有连接都将排队被阻塞。
规则的保存和管理
使用iptables-save保存到自定义位置。
iptables-save >/etc/sysconfig/iptables
iptables-save >/etc/sycofnig/iptables.20170103
恢复规则:
iptables-restore </etc/sysconfig/iptables
iptables-restore </etc/sysconfig/iptables.2170103
管理规则更好的方法是写成脚本。将这些规则全部写入到一个shell脚本中,并对多次重复的地址使用变量,例如服务器的地址或网段,内网的网段。
使用脚本的优点有:
1.管理的便捷。写成脚本可以直接修改该文件,要重新生效时只需执行一次该脚本文件即可。但是要注意脚本的第一条命令最好是iptables -F,这样每次运行脚本都会先清空已有规则再加载脚本中的其他规则。
2.可以在脚本中使用变量。这样以后某台服务器地址改变了只需修改该服务器地址对应的变量值即可。
3.容易阅读,因为可以加注释,并通过注释来对规则进行分类,未来修改就变得相对容易的多。
4.备份规则变得更容易。备份后,即使硬盘坏了导致现有的规则丢失了也可以简单的拷贝一个脚本过去运行即可,而不用再一条一条命令的敲。
5.也可以实现开机加载规则。只需在/etc/rc.d/rc.local中加上一条执行该脚本的命令即可。
6.可以将其加入任务计划
自定义链
自定义链是被主链引用的。引用位置由"-j"指定自定义链名称,表示跳转到自定义链并匹配其内规则列表。
转发与nat
转发
网络是内核空间中的内容,两个IP地址都属于主机而非属于网卡,内核知道eth0和eth1的存在。
内核开启转发功能:
echo 1 > /proc/sys/net/ipv4/ip_forward
SNAT与DNAT
NAT依赖于ip_forward,因此需要先开启它。NAT的基础是nf_conntrack,用来记录NAT表的映射关系。
NAT有三个作用:
-
地址转换。让内网(私有地址)可以共用一个或几个公网地址连接Internet。这是从内向外的,需要在网关式防火墙的POSTROUTING处修改源地址,这是SNAT功能。
-
保护内网服务器。内网主机连接Internet使用的是公网地址,对外界而言是看不到内网服务器地址的,所以外界想要访问内部主机只能经过防火墙主机的公网地址,然后将目标地址转换为内网服务器地址,这起到了保护内网服务器的作用。转换目标地址需要在网关式防火墙的PREROUTING链处修改,这是DNAT功能。
-
不仅可以修改目标地址,还可以使用端口映射功能。DNAT是修改目标地址,端口映射是修改目标端口。如将web服务器的8080端口映射为防火墙的80端口。
外网主机和内网主机通信有两种情况的数据包:一种情况是建立NEW状态的新请求连接数据包,一种是回应的数据包。无论哪种情况,在NEW状态数据包经过地址转换之后会在防火墙内存中维护一张NAT表,保存未完成连接的地址转换记录,这样在回应数据包到达防火墙时可以根据这些记录路由给正确的主机。
也就是说,SNAT主要应付的是内部主机连接到Internet的源地址转换,转换的位置是POSTROUTING链;DNAT主要应付的是外部主机连接内部服务器防止内部服务器被攻击的目标地址转换,转换位置在PREROUTING;端口映射可以在多个地方转换。