iptables的原理与配置详解

文章目录

  • iptables的原理与配置详解
    • 简介
    • 基本原理
      • 概念
      • rules的写法
      • 过程:进入本机的包
      • 过程:从本机出去的包
      • 过程:转发的包
    • 维护命令
    • 命令参考
      • 查看规则
      • 命令格式
      • 命令参数
    • 实际命令例子
      • 设置默认策略
      • 增删改规则
      • IP的屏蔽等操作
      • 端口相关
      • http相关
      • ssh相关
      • conntrack相关
      • nat相关(nat表)
      • PING相关
      • 其他

iptables的原理与配置详解

简介

linux的包过滤功能,即linux防火墙,它由netfilter (内核)和 iptables(用户空间) 两个组件组成。

linux防火墙工具变化如下:ipfirewall—>ipchains—>iptables

  • Linux 2.0版内核中,包过滤机制为ipfw,管理工具是ipfwadm。
  • Linux 2.2版内核中,包过滤机制为ipchain,管理工具是ipchains。
  • Linux 2.4版内核中,包过滤机制为netfilter,管理工具是iptables。
  • Linux 3.1版内核中,采取daemon动态管理防火墙,管理工具是firewalld。

CentOS的变化

  • centos6:防火墙由netfilter和iptables构成。其中iptables用于制定规则,又被称为防火墙的用户态;而netfilter实现防火墙的具体功能,又被称为内核态。简单地讲,iptables制定规则,而netfilter执行规则。
  • centos7:防火墙在6.X防火墙的基础之上提出了新的防火墙管理工具,提出了区域的概念,通过区域定义网络链接以及安全等级。

以上两者的区别在于:

  • centos6的防火墙模型(system-config-firewall)是静态的,策略被修改后需要重新加载策略配置才能生效;
  • centos7的firewalld工具则可以动态管理防火墙,不需要重新加载防火墙配置,直接生效。

注: 本文介绍的是iptables,firewalld不在本篇的范围。

基本原理

iptables由netfilter/iptables组成,其中netfilter位于内核心起到真正的防火墙作用,iptables位于用户空间作为命令行修改工具。

  • 所有访问都经过链(钩子),每个链里面有多个规则(rules),这些规则根据功能类型汇聚存放于表中(功能)。

  • 当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据 该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。

    注意:

    • IPTables中的规则是从上到下匹配的,一旦匹配成功(accept/reject)就不再继续往下匹配。
    • IPTables链的默认规则是所有的规则执行完才会执行的。
      iptables的原理与配置详解_第1张图片

概念

iptables规则由五张表五条链和规则组成。

tables(五张表):

  • filter 用于过滤,大多数是防火墙功能,不要用来修改。

  • nat 用于网络地址转换, 如SNAT, DNAT等。

  • mangle 给数据包做标记以修改分组数据的特定规则,如QoS,打tag等,其中Mark标记是记录于skbuf而不在包本身。

  • raw 独立于Netfilter连接跟踪子系统

  • security:表在Centos6里是没有的,它用于强制访问控制(MAC)的网络规则,用于security。

    说明:

    • tables由chains组成,而chains又由rules组成
    • 表是有优先级的,由高到低的顺序是==raw --> mangle --> nat --> filter==

chains(五条链,亦称hook勾子):

  • 每个表都有自己的一组内置链,用于还可以对链进行自定义。

  • 对filter表来说,最重要的内置链是INPUT/OUTPUT/FORWARD

  • 对于NAT来说,最重要的内置链是PREROUTINGPOSTROUTING

    包含关系: Netfilter -> iptables -> tables -> chains -> rule/policy

各个链会用到的表:

注: 自上而下顺序 prerouting链 input链 (本地) output链 (本地) forward链 (转发) postrouting链
raw表
mangle表
nat表 √ (DNAT,DMZ端口映射) √ (CentOS7 Only) √ (SNAT)
filter表

​ 说明: 按表优先级进行处理,即顺序是raw --> mangle --> nat --> filter

数据包流向视图:
iptables的原理与配置详解_第2张图片
说明:

  • 进入本机的包经过的链: PREROUTING -> INPUT
  • 转发出去的包经过的链: PREROUTING -> FORWARD -> POSTROUTING, 注意要打开ip-forward。
  • 从本机出去的包经过的链: OUTPUT -> POSTROUTING
  • 以进入本机的包经过的链为例 ,实际依次会经过raw表的PREROUTING、mangle表的PREROUTING、nat表的PREROUTING、mangle表的INPUT和filter表的INPUT的规则(rules)。
  • 注:CentOS的nat表里有INPUT链,而CentOS6没有。

iptables配置视图:
iptables的原理与配置详解_第3张图片

  • 一般来说,运维最常用到的是filter表(用于过滤包),其次是nat表(用于端口映射或NAT),raw表和mangle很少用于。
  • 配置时,需要先指定要修改哪个表,然后指定该表中的哪条链,再指定该链中的哪条规则。
  • 例如,常用的表链使用如下:
    • 入口的过滤是修改filter表INPUT链的rules(iptables里不需加-t参数,默认就是filter表)。
    • 出口的过滤是修改filter表OUTPUT链的rules(iptables里不需加-t参数,默认就是filter表)。
    • 转发的过滤是修改filter表FORWARD链的rules(iptables里不需加-t参数,默认就是filter表)。
    • DNAT是修改nat表的PREROUTING链的rules(iptables里需加-t nat参数,指定修改nat表)。
    • SNAT是修改nat表的POSTROUTING链的rules(iptables里需加-t nat参数,指定修改nat表)。

rules的写法

rules:

  • rules包括一个条件和一个目标(target) 。
  • rules是存放于某个表的某个链里面。
  • iptables执行规则时,是从从规则表中从上至下顺序执行的,如果没遇到匹配的规则,就一条一条往下执行,如果遇到匹配的规则后,那么就执行本规则,执行后根据本规则的动作(accept, reject, log等),决定下一步执行的情况。
  • 通常地,链的最后一条规则是拒绝所有包,也就是说拒绝所有其他不符合上述任何一条规则的数据包。需要确保该规则位于最后一行。

target:

  • ACCEPT – 允许防火墙接收数据包 ,停止在执行本链或本表的执行。
  • DROP – 防火墙丢弃包,不给任何回应。
  • REJECT - 拒绝数据包通过,必要时给发送端回一个响应的信息,客户端可收到拒绝的信息。
  • SNAT - 源地址转换,解决内网用户同一个公网地址上网的问题。
  • MASQUERADE - SNAT的一种特殊形式,适用于动态的、临时会变的IP上。
  • DNAT - 目标地址转换。
  • REDIRECT - 在本机做端口映射。
  • LOG - 在/var/log/messages中记录日志,然后把数据包传递给下一条规 。
  • RETURN – 防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)中。

contrack

  • conntrack是一种状态跟踪和记录的机制,本身并不能过滤数据包,只是提供包过滤的依据。 有状态是一种过滤依据,无状态实际也是一种过滤依据。

    conntrack共可以为连接标记五种状态,分别如下:

    • NEW:新建连接请求的数据包,且该数据包没有和任何已有连接相关联。判断的依据是conntrack当前“只看到一个方向数据包(UNREPLIED)”,没有回包。
    • ESTABLISHED:该连接是某NEW状态连接的回包,也就是完成了连接的双向关联。
    • RELATED:匹配那些属于helper模块定义的特殊协议的网络连接,该连接属于已经存在的一个ESTABLISHED连接的衍生连接。简而言之,A连接已经是ESTABLISHED,而B连接如果与A连接相关,那么B连接就是RELATED。
    • INVALID:匹配那些无法识别或没有任何状态的数据包。这可能是由于系统内存不足或收到不属于任何已知连接的ICMP错误消息,也就是垃圾包,一般情况下我们都会DROP此类状态的包。
    • UNTRACKED: 这是一种特殊状态,或者说并不是状态。它是管理员在raw表中,为连接设置NOTRACK规则后的状态。这样做,便于提高包过滤效率以及降低负载。
  • 说明:

    • tcp握手中(syn, syn/ack, ack),当反方向也出现包的时候,即认为是ESTABLISHED。因此第二次握手之后就是ESTABLISHED了。
    • 作为客户端时的应用程序所使用的端口多为动态端口,如果能够到达服务器,那么发送和接收双方向的udp/tcp/icmp数据包状态都是ESTABLISHED。

过程:进入本机的包

iptables的原理与配置详解_第4张图片
以本机为目标的包:

Step(步骤) Table(表) Chain(链) Comment(注释)
1 进入接口 (比如, eth0)
2 mangle PREROUTING 这个链用来mangle数据包,比如改变TOS等
3 nat PREROUTING 这个链主要用来做DNAT。不要在这个链做过虑操作,因为某 些情况下包会溜过去。
4 路由判断,比如,包是发往本地的,还是要转发的?
5 mangle INPUT 在路由之后,被送往本地程序之前,mangle数据包。
6 filter INPUT 所有以本地为目的的包都要经过这个链,不管它们从哪儿 来,对这些包的过滤条件就设在这里。
7 到达本地程序了(比如,服务程序或客户程序)

过程:从本机出去的包

iptables的原理与配置详解_第5张图片
从本机以出去的包(以本地为源):

Step Table Chain Comment
1 本地程序(比如,服务程序或客户程序)
2 路由判断,要使用源地址,外出接口,还有其他一些信息。
3 mangle OUTPUT 在这儿可以mangle包。建议不要在这儿做过滤,可能有副作用。
4 nat OUTPUT 这个链对从防火墙本身发出的包进行DNAT操作。
5 filter OUTPUT 对本地发出的包过滤。
6 mangle POSTROUTING 这条链主要在包DNAT之后进行实际的路由,离开本地之前,对包 mangle。有两种包会经过这里,防火墙所在机子本身产生的包,还有被转发的包。
7 nat POSTROUTING 在这里做SNAT。但不要在这里做过滤,因为有副作用,而且有些包是会溜过去的,即使你用了DROP策略。
8 离开接口(比如:eth0)

在OpenStack的网络管理中,通常一个虚拟机会有一个外网IP(如:115.100.XX.XX)和一个内网IP(如192.168.1.10),那么节点的iptables规则里面就会有类似这样的语句:

# 目标地址为115.100.XX.XX(外网IP)的数据包重定向到192.168.1.10(内网IP)
iptables -t nat -A PREROUTING -d 115.100.XX.XX -j DNAT --to-destination 192.168.1.10
# 从192.168.1.10发出的数据包,iptables会将其源地址修改为100.100.XX.XX
iptables -t nat -A POSTROUTING -s 192.168.1.10 -j SNAT --to-source 115.100.XX.XX

过程:转发的包

iptables的原理与配置详解_第6张图片
被转发的包:

Step Table Chain Comment
1 进入接口(比如,eth0)
2 mangle PREROUTING mangle数据包,,比如改变TOS等。
3 nat PREROUTING 这个链主要用来做DNAT。不要在这个链做过虑操作,因为某 些情况下包会溜过去。稍后会做SNAT。
4 路由判断,比如,包是发往本地的,还是要转发的。
5 mangle FORWARD 包继续被发送至mangle表的FORWARD链,这是非常特殊的情况才会用到的。在这里,mangle发生在最初的路由判断之后, 在最后一次更改包的目的之前。
6 filter FORWARD 包继续被发送至这条FORWARD链。只有需要转发的包才会走到这里,并且针对这些包的所有过滤也在这里进行。注意,所有要转发的包都要经过这里,不管是外网到内网的还是内网到外网的。
7 mangle POSTROUTING 这个链也是针对一些特殊类型的包。这一步mangle是在所有更改包的目的地址的操作完成之后做的,但这时包还在本地上。
8 nat POSTROUTING 这个链就是用来做SNAT的,当然也包括Masquerade(伪装)。但不要在这儿做过滤,因为某些包即使不满足条件也会通过。
9 离开接口(比如: eth0)

维护命令

service iptables start ##启动
service iptables stop  ##关闭
service iptables restart ##重启
service iptables status ##查看状态
service iptables save ##保存iptables配置到/etc/sysconfig/iptables
iptables -nvL ##查看规则

注意:

  • Iptables服务配置文件: /etc/sysconfig/iptables-config
  • Iptables规则保存文件: /etc/sysconfig/iptables
  • 打开iptables转发: echo “1”> /proc/sys/net/ipv4/ip_forward

命令参考

查看规则

iptables -nvL --line #默认是filter表的链和规则
iptables -nvL --line -t nat #查看nat表的链和规则

iptables的原理与配置详解_第7张图片

#INPUT表默认策略是ACCEPT
:INPUT ACCEPT [0:0]
#FORWARD表默认策略是ACCEPT 
:FORWARD ACCEPT [0:0]
#OUTPUT表默认策略是ACCEPT
:OUTPUT ACCEPT [0:0]
#允许进入的数据包只能是刚刚我发出去的数据包的回应,ESTABLISHED:已建立的链接状态。RELATED:该数据包与本机发出的数据包有关。
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#在INPUT表和FORWARD表中拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

命令格式

table command chain Parameter target
iptables -t filter
nat
-A/-D 增加/删除规则
-I num 插入L
-R num 替换
-P 默认策略
-F 清空
-X: 删除自定义空链
-Z 清空链和计数器
-n 用数字显示
-v 详细显示
-L 列出所有规则
INPUT
FORWARD
OUTPUT
PREROUTING
POSTROUTING
-p tcp
-s
-d
-i
-o
–sport
–dport
-m tcp
state
multiport
-j ACCEPT
DROP
REJECT
DNAT
SNAT

命令参数

命令:
iptables [ -t 表名] 命令选项 [链名] [条件匹配] [-j 目标动作或跳转] 
1. 表名
	表名: filter, nat, mangle, raw
	起包过滤功能的为表Filter,可以不填,不填默认为Filter
2. 命令选项
选项名	功能及特点
-A	在指定链的末尾添加(--append)一条新的规则
-D	删除(--delete)指定链中的某一条规则,按规则序号或内容确定要删除的规则
-I	在指定链中插入(--insert)一条新的规则,默认在链的开头插入
-R	修改、替换(--replace)指定链中的一条规则,按规则序号或内容确定
-L	列出(--list)指定链中的所有的规则进行查看,默认列出表中所有链的内容
-F	清空(--flush)指定链中的所有规则,默认清空表中所有链的内容
-N	新建(--new-chain)一条用户自己定义的规则链
-X	删除指定表中用户自定义的规则链(--delete-chain)
-P	设置指定链的默认策略(--policy)
-n	用数字形式(--numeric)显示输出结果,若显示主机的 IP地址而不是主机名
-v	查看规则列表时显示详细(--verbose)的信息
-V	查看iptables命令工具的版本(--Version)信息
-h	查看命令帮助信息(--help)
--line-number	查看规则列表时,同时显示规则在链中的顺序号
3. 链名
	可以根据数据流向来确定具体使用哪个链,在Filter中的使用情况如下:
		INPUT链 – 处理来自外部的数据。 
        OUTPUT链 – 处理向外发送的数据。 
        FORWARD链 – 将数据转发到本机的其他网卡设备上。
4. 条件匹配
    条件匹配分为基本匹配和扩展匹配,拓展匹配又分为隐式扩展和显示扩展。
    a)基本匹配包括:
		-p	协议: tcp, udp,icmp, all
		-s	源地址,可以使IP地址、网络地址、主机名
		-d	目的地址
		-i	输入接口
		-o	输出接口
    b)隐式扩展包括:
		--sport         源端口
		--dport         目标端口
		--tcp-flags     TCP标志: SYN,ACK,RST,FIN SYN
		--syn           SYN包
		--icmp-type 	8:echo-request  0:echo-reply
    c)常用显式扩展
		-m state --state NEW,ESTABLISHED,RELATED,INVALID    连接的状态检测(老版)
		-m conntrack --ctstate ESTABLISHED,RELATED          连接的状态检测(新版)
		-m multiport --source-ports                         多个源端口
		-m multiport --destination-ports                    多个目的端口
		-m multiport --ports                                源和目的端口
		-m limit --limit 3/minute                           限速,每分钟3个数据包
		-m limit --limit -burst 100                         限速,最大不能超过100个数据包
		-m connlimit --connlimit-above 10                   多于10个表示满足条件取反要在选项前加!
		-m iprange --src-range ip-ip                        源ip范围
		-m iprange --dst-range ip-ip                        目的ip范围
		-m mac --mac-source                                 mac地址限制
		-m string --algo [bm|kmp]                           匹配算法
		-m string --string “Pattern”                        要匹配的字符串
		-m recent --name                                    设定列表名称,默认为DEFAULT
		-m recent --rsource                                 源地址,此为默认
		-m recent --rdest                                   目的地址
		-m recent --set                                     添加源地址的包到列表中
		-m recent --update                                  每次建立连接都更新列表
		-m recent --rcheck                                  检查地址是否在列表
		-m recent --seconds                                 指定时间内,必须与—rcheck或—update同时使用
		-m recent --hitcount                                命中次数,必须与—rcheck或—update同时使用
        -m recent --remove                                  在列表种删除相应地址
5. 目标值(-j)
		数据包控制方式包括四种为:
		ACCEPT:允许数据包通过。 
		DROP:直接丢弃数据包,不给出任何回应信息。 
		REJECT:拒绝数据包通过,必须时会给数据发送端一个响应信息。 
		LOG:在/var/log/messages 文件中记录日志信息,然后将数据包传递给下一条规则。 
		QUEUE:防火墙将数据包移交到用户空间 
		RETURN:防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain) 
		
		LOG日志例子:
		        iptables -I INPUT 1 -j LOG
        tail -f /var/log/messages

实际命令例子

##查看iptables规则
iptables -nvL --line

设置默认策略

iptables -P INPUT DROP 
iptables -P FORWARD DROP 
iptables -P OUTPUT DROP

增删改规则

## 删除iptables现有规则
iptables -F
##增加一条规则到最后
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT 
##增加一条规则到最后到指定位置
iptables -I INPUT 2 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT 
##修改一条规则
iptables -R INPUT 3 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT 
##删除一条规则
iptabels -D INPUT 2 

IP的屏蔽等操作

##屏蔽某个IP地址
屏蔽具体IP地址:
iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP
##解封某个IP地址
要解封对IP地址的屏蔽,可以使用如下命令进行删除:
iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP
##在规则中使用IP地址范围
iptables -A OUTPUT -p tcp -d 192.168.100.0/24 --dport 22 -j ACCEPT
##屏蔽指定MAC地址
iptables -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j DROP
##限制ping 192.168.146.3主机的数据包数,平均2/s个,最多不能超过3个
iptables -A INPUT -i eth0 -d 192.168.146.3 -p icmp --icmp-type 8 -m limit --limit 2/second --limit-burst 3 -j ACCEPT 

端口相关

##阻止特定的传出连接:
iptables -A OUTPUT -p tcp --dport xxx -j DROP
##阻止特定的传入连接:
iptables -A INPUT -p tcp --dport xxx -j DROP
##使用Multiport控制多端口
使用 multiport 我们可以一次性在单条规则中写入多个端口,例如:
iptables -A INPUT  -p tcp -m multiport --dports 22,80,443 -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --sports 22,80,443 -j ACCEPT

http相关

##允许HTTP请求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT 
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT 
##屏蔽HTTP服务Flood攻击,将连接限制到每分钟100 个,上限设定为 200。
iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/minute --limit-burst 200 -j ACCEPT

ssh相关

##允许远程主机进行SSH连接
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT 
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT 
##允许本地主机进行SSH连接
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT 
iptables -A INTPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT 
##限制SSH连接速率(默认策略是DROP)
iptables -I INPUT 1 -p tcp --dport 22 -d 192.168.146.3 -m state --state ESTABLISHED -j ACCEPT  
iptables -I INPUT 2 -p tcp --dport 22 -d 192.168.146.3 -m limit --limit 2/minute --limit-burst 2 -m state --state NEW -j ACCEPT 

conntrack相关

##允许建立相关连接, 随着网络流量的进出分离,要允许建立传入相关连接,可以使用如下规则:
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
##允许建立传出相关连接的规则:
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
##丢弃无效数据包,很多网络攻击都会尝试用黑客自定义的非法数据包进行尝试,我们可以使用如下命令来丢弃无效数据包:
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

nat相关(nat表)

##SNAT(网域网主机隐藏内网IP,换为公网IP访问互联网,固定公网地址)
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source <公网IP>
##MASQUERADE(网域网主机隐藏内网IP,换为公网IP访问互联网)
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
##DNAT(公司只有一个公网IP但有多台服务器,需要从外面访问各个服务)
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination <私网IP>:<端口号>  
#进来时做DNAT
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source <公网IP>  #出去时能走公网
##在本地进行目标端口映射(外面访问本机80端口,重定向到本机8080上)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

PING相关

##禁止PING
iptables -A INPUT -p icmp -i eth0 -j DROP
##允许本机 ping 别的主机;但不开放别的主机 ping 本机;
iptables -I INPUT -p icmp --icmp-type echo-request -j DROP 
iptables -I INPUT -p icmp --icmp-type echo-reply -j ACCEPT 
iptables -I INPUT -p icmp --icmp-type destination-Unreachable -j ACCEPT

其他

##限制并发连接数
iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j REJECT
##周一不允许访问
iptables -A INPUT -p tcp --dport 80 -m time ! --weekdays Mon -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT
##web包含admin字符串的页面不允许访问,源端口:dport
iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string 'admin' -j REJECT
##在工作时间,即周一到周五的8:30-18:00,开放本机的ftp服务给192.168.1.0网络中的主机访问;
iptables -A INPUT -p tcp --dport 21 -s 192.168.1.0/24 -m time ! --weekdays 6,7 -m time --timestart 8:30 --timestop 18:00 -m connlimit --connlimit-above 5 -j ACCET

你可能感兴趣的:(Linux)