Iptables工作原理使用详解

时间:2022-11-09 15:10:15

Iptables防火墙简介

Netfilter/Iptables(以下简称Iptables)是unix/linux自带的一款优秀且开放源代码的完全*的基于包过滤的防火墙工具,它的功能十分强大,使用非常灵活,可以对流入和流出服务器的数据包进行很精细的控制。特别是它可以在一台非常低的硬件配置下跑得非常好。IPtables是linux2.4及2.6内核中集成的服务。其功能与安全性比其老一辈ipfwadm,ipchains强大的多,Iptables主要工作在OSI七层的二、三、四层。

Iptables名词和术语

容器

用来形容包含或者说属于的关系

Netfilter/iptables是表的容器,iptables包含的各个表
表(table)

iptables的表又是链的容器

链(chains)

INPUT,OUTPUT,FORWARD,PREROUTING,POSTROUTING

链是规则的容器

规则(Policy)

一条条过滤的语句 Policy

filter表

主要和主机自身有关,真正负责主机防火墙功能的(过滤流入流出主机的数据包)。filter表是iptables默认使用的表。这个表定义了三个链(Chains);

  • INPUT: 负责过滤所有目标地址是主机地址的数据包。通俗的讲,就是过滤进入主机的数据包。

  • FORWARD:负责转发流经主机的数据包。起转发的作用,和Nat关系很大。LVS NAT模式。net.ipv4_forward = 1

  • OUTPUT:处理所有源地址是本机地址的数据包,通俗的讲,就是处理从主机发出去的数据包。

nat表

负责网络地址转换,即来源与目的ip地址和port的转换。
应用:和主机本身无关。一般用于局域网共享上网或者特殊的端口转换服务相关。

这个表定义了三个链(Chainc),nat功能就相当于网络的acl控制。和网络交换机acl类似。

  • OUTPUT:和主机发出去的数据包有关。改变主机发出数据包的目标地址。

  • PREROUTING:在数据包到达防火墙时进行路由判断之前执行的规则,作用是改变数据包的目的地址、目的端口等。

  • POSTROUTING:在数据包离开防火墙时进行路由判断之后执行的规则,作用改变数据包的源地址、源端口等,例如:我们现在的笔记本和虚拟机都是192.168.30.0/24,就是出网的时候被我们企业路由器把源地址改成了公网地址了。生产应用:局域网共享上网。

Iptables工作流程

Iptables工作原理使用详解
iptables工作流程

Iptables工作原理使用详解
排除mangle表

Iptables工作原理使用详解
数据包流向

规则从上往下匹配,只要匹配到就不往下匹配,如果没有匹配上就走默认规则。

  1. 防火墙是层层过滤的。实际上是按照配置规则的顺序从上到下,从前到后进行过滤的。

  2. 如果匹配上规则,则明确表明是阻止还是通过,数据包就不再匹配任何新规则了。

  3. 如果所有规则中没有明确表明是阻止还是通过,也就是没有匹配规则,向下进行匹配,直到匹配默认规则得到明确的阻止还是通过。

  4. 防火墙默认规则是对应链的所有的规则执行完才会执行的。

基本语法

Filter

Iptables启动方式
/etc/init.d/iptables restart
先来看几个常用对链的操作,常用的就那么几种
-I(插入) -A(追加) -R(替换) -D(删除) -L(列表显示)
这里要说明的就是-I将会把规则放在第一行,-A将会放在最后一行
举例:

iptables –t filter  -A INPUT  -p  tcp  --dport  22  -j DROP
   
   
iptables –t filter  -A INPUT  -p  tcp  --dport  3306  -j DROP
iptables –t filter  -I  INPUT  -p  tcp  --dport  80  -j DROP
iptables -t filter -A INPUT -i eth0 !-s 192.168.30.150 -j DROP

查看防火墙规则:
iptables -L -n
清除防火墙
--flush -F [chain] Delete all rules in chain or all chains
清除用户自定义的链
-X [chain] Delete a user-defined chain
创建一个新的自定义链
--new -N chain Create a new user-defined chain
把链中的计数器清零
--zero -Z [chain [rulenum]] Zero counters in chain or all chains
总结:
iptables –F / /清除所有规则,不会处理默认的规则
iptables –X / /删除用户自定义的链
iptables –Z / /链的计数器清零

iptables [-t filter] [-AI INPUT,OUTPUT,FORWARD] [-io interface] [-p tcp,udp.icmp,all] [-s ip/nerwork] [--sport ports] [-d ip/netword] [--dport ports] [-j ACCEPT DROP]
以上是iptables的基本语法
-A 是添加的意思
-I 是插入的意思
-i -o 指的是数据要进入或出去所要经过的网卡 如eth1 eth0等
-p 你所要指定的协议,如tcp、udp、icmp、all
-s 指源地址 可是单个IP如192.168.2.6 也可以是一个网络 192.168.2.0/24 还可以 是一个域名 如163.com 如果你填写的是域名,系统会自动解析出他的IP并在iptables里 显示
--sport 来源端口
-d 同-s相似 只不过他指的是目标地址 也可以是IP 域名 和网络
--dport 目标端口
-j 执行参数 ACCEPT DROP

参数说明

禁止10.0.0.0网段连入:
iptables -t filter -A INPUT -i eth0 -s 10.0.0.0/24 -j DROP iptables -A INPUT -i eth0 -s 10.0.0.0/24 -j DROP
-i:流量进入的接口,从eth0进入
-s:源地址
从eth0进入的流量,源地址是10.0.0.0网段的地址,拒绝连接。

源地址不是192.168.30.150的单个IP的禁止连接:
iptables -t filter -A INPUT -i eth0 !-s 192.168.30.150 -j DROP
禁用icmp协议:
iptables -t filter -A INPUT -p icmp --icmp-type 8 -i eth0 -s 192.168.30.0/24 -j DROP
封掉3306端口:
iptables –t filter -A INPUT -p tcp --dport 3306 -j DROP
匹配指定协议以外的所有协议:
iptables -A INPUT -p ! tcp iptables -A INPUT ! –p tcp –s 10.0.0.0/24 -j DROP
匹配主机源IP
iptables -A INPUT -s 10.0.0.14 iptable -A INPUT -s ! 10.0.0.13
匹配网段
iptables -A INPUT -s 10.0.0.0/24 iptables -A INPUT -s ! 10.0.0.0/24
禁用dns:
iptables -A INPUT -p tcp --sport 53 iptables -A INPUT -p udp --dport 53
匹配指定端口之外的端口:
iptables -A INPUT -p tcp --dport ! 22 iptables -I INPUT -p tcp ! --dport 22 -s 10.0.0.123 -j DROP
匹配端口范围
iptables -A INPUT -p tcp --sport 22:80 iptables -I INPUT -p tcp -m multiport --dport 21,22,23,24 -j ACEEPT iptables -I INPUT -p tcp –dport 3306:8809 -j ACCEPT
匹配icmp类型:
iptables –A INPUT -p icmp --icmp-type 8 -j DROP iptables -A FORWARD -s 192.168.30.0/24 -p icmp -m icmp --icmp-type any -j ACCEPT
匹配指定的网络接口:
iptables -A INPUT -i eth0 iptables -A FORWARD -o eth0
匹配网络状态
-m state --state
NEW:已经或将启动新的连接
ESTABLISHED:已建立的连接
RELATED:正在启动新链接
INVALID:非法或无法识别的
允许关联的状态包通过
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state -state ESTABLISHED,RELATED -j ACCEPT

-m limit --limit n/{second/minute/hour}:指定时间内的请求速率"n"为速率,后面为时间分别为:秒、分、时
--limit-burst [n]:在同一时间内允许通过的请求"n"为数字,不指定默认为5
fg:本机地址:172.16.14.1,允许172.16.0.0/16网络ping本机,但限制每分钟请求不能超过20,每次并发不能超过6个
iptables -A INPUT -s 172.16.0.0/16 -d 172.16.14.1 -p icmp --icmp-type 8 -m limit --limit 20/min --limit-burst 6 -j ACCEPT
iptables -A OUTPUT -s 172.16.14.1 -d 172.16.0.0/16 -p icmp --icmp-type 0 -j ACCEPT

指定TCP匹配扩展
使用 –tcp-flags 选项可以根据tcp包的标志位进行过滤。
#iptables -A INPUT -p tcp –tcp-flags SYN,FIN,ACK SYN #iptables -A FROWARD -p tcp –tcp-flags ALL SYN,ACK
上实例中第一个表示SYN、ACK、FIN的标志都检查,但是只有SYN匹配。第二个表示ALL(SYN,ACK,FIN,RST,URG,PSH)的标志都检查,但是只有设置了SYN和ACK的匹配。
#iptables -A FORWARD -p tcp --syn
选项—syn相当于”--tcp-flags SYN,RST,ACK SYN”的简写。

NAT表:

NAT我们一般用来做企业共享上网或外网端口映射。我们现在的笔记本和虚拟机都是192.168.30.0/24,就是出网的时候被我们企业路由器把源地址改成了公网地址了。
那么Linux如何做共享上网的呢?比如一个内网的10.1.1.11的pc访问www.baidu.com的一个web服务器,linux的内网接口10.1.1.1在收到这个包之后把原来的PC的 ip10.1.1.11改变为60.1.1.1(我们公司的出网ip)的合法地址然后送出,同时在自己的ip_conntrack表里面做一个记录,记住是内网的哪一个ip的哪个端口访问的这个web服务器,自己把它的源地址改成多少了,端口改成多少了,以便这个web服务器返回数据包的时候linux将它准确的送回给发送请求的这个pc
设置共享上网有两种方式:.  
方法1:适合有固定上网地址的:
iptables -t nat -A POSATROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-sorce 10.0.0.19
(1)-s 192.168.1.0/24 办公网或IDC内网网段
(2) -o eth0 为网关的外网卡接口
(3) –j SNAT --to-sorce 10.0.0.19 是网关外网卡IP地址
方法2:适合变化外网地址(ADSL)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUEREDE(伪装)
注:MASQUEREDE动态伪装成出网ip。
外部IP映射到内部服务器IP(包括端口):
iptables -t nat -A PREROUTING -d 10.0.0.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.8:9000

Icmp协议

在iptables看来,只有四种ICMP分组,这些分组类型可以被归为NEW、ESTABLISHED两类: 
ECHO请求(ping,8)和ECHO应答(pong,0)。 
时间戳请求(13)和应答(14)。 
信息请求(15)和应答(16)。 
地址掩码请求(17)和应答(18)。 
这些ICMP分组类型中,请求分组属于NEW,应答分组属于ESTABLISHED。而其它类型的ICMP分组不基于请求/应答方式,一律被归入RELATED。 
我们先看一个简单的例子: 
``iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED, RELATED -j ACCEPT 
iptables -A INPUT -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT ```
这链条规则进行如下的过滤: 
一个ICMP echo请求是一个NEW连接。因此,允许ICMP echo请求通过OUTPUT链。 
当对应的应答返回,此时连接的状态是ESTABLISED,因此允许通过INPUT链。而INPUT链没有NEW状态,因此不允许echo请求通过INPUT链。也就是说,这两条规则允许内部主机ping外部主机,而不允许外部主机ping内部主机。 
一个重定向ICMP(5)分组不是基于请求/应答方式的,因此属于RELATED。INPUT和OUTPUT链都允许RELATED状态的连接,因此重定向(5)分组可以通过INPUT和OUTPUT链。 

TCP FLAG 标记

基于标记的TCP包匹配经常被用于过滤试图打开新连接的TCP数据包。
TCP标记和他们的意义如下所列

  • F : FIN - 结束; 结束会话

  • S : SYN - 同步; 表示开始会话请求

  • R : RST - 复位;中断一个连接

  • P : PUSH - 推送; 数据包立即发送

  • A : ACK - 应答

  • U : URG - 紧急

  • E : ECE - 显式拥塞提醒回应

  • W : CWR - 拥塞窗口减少
    示例
    三次握手Three-way Handshake
    一个虚拟连接的建立是通过三次握手来实现的

  1. (B) --> [SYN] --> (A)
    假如有服务器A、客户机B. 当B要和A通信时,B首先向A发一个SYN (Synchronize) 标记的包,告诉A请求建立连接.
    注意: 一个 SYN包就是仅SYN标记设为1的TCP包(参见TCP包头Resources). 只有当A收到B发来的SYN包,才可建立连接,除此之外别无他法。

  2. (B) <-- [SYN/ACK] <--(A)
    接着,A收到后会发一个对SYN包的确认包(SYN/ACK)回去,表示对第一个SYN包的确认,并继续握手操作.
    注意: SYN/ACK包是仅SYN 和 ACK 标记为1的包.

  3. (B) --> [ACK] --> (A)
    B收到SYN/ACK 包,B发一个确认包(ACK),通知A连接已建立。至此,三次握手完成,一个TCP连接完成。
    注意: ACK包就是仅ACK 标记设为1的TCP包.
    特别注意:需要注意的是当三此握手完成、连接建立以后,TCP连接的每个包都会设置ACK位

    PS:这就是为何连接跟踪很重要的原因了. 没有连接跟踪,防火墙将无法判断收到的ACK包是否属于一个已经建立的连接.一般的包过滤(Ipchains)收到ACK包时,会让它通过(这绝对不是个好主意). 而当状态型防火墙收到此种包时,它会先在连接表中查找是否属于哪个已建连接,否则丢弃该包

四次握手Four-way Handshake
四次握手用来关闭已建立的TCP连接

  1. (B) --> ACK/FIN --> (A)

  2. (B) <-- ACK <-- (A)

  3. (B) <-- ACK/FIN <-- (A)

  4. (B) --> ACK --> (A)

注意: 由于TCP连接是双向连接, 因此关闭连接需要在两个方向上做。ACK/FIN 包(ACK 和FIN 标记设为1)通常被认为是FIN(终结)包.然而, 由于连接还没有关闭, FIN包总是打上ACK标记. 没有ACK标记而仅有FIN标记的包不是合法的包,并且通常被认为是恶意的
连接复位Resetting a connection
四次握手不是关闭TCP连接的唯一方法. 有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可达),RST (Reset)包将被发送. 注意在,由于RST包不是TCP连接中的必须部分, 可以只发送RST包(即不带ACK标记). 但在正常的TCP连接中RST包可以带ACK确认标记。

注意: RST包是可以不要收到方确认的

无效的TCP标记Invalid TCP Flags
到目前为止,你已经看到了 SYN, ACK, FIN, 和RST 标记. 另外,还有PSH (Push) 和URG (Urgent)标记.
最常见的非法组合是SYN/FIN 包. 注意:由于 SYN包是用来初始化连接的, 它不可能和 FIN和RST标记一起出现. 这也是一个恶意攻击.
由于现在大多数防火墙已知 SYN/FIN 包, 别的一些组合,例如SYN/FIN/PSH, SYN/FIN/RST, SYN/FIN/RST/PSH。很明显,当网络中出现这种包时,很你的网络肯定受到攻击了。
别的已知的非法包有FIN (无ACK标记)和"NULL"包。如同早先讨论的,由于ACK/FIN包的出现是为了关闭一个TCP连接,那么正常的FIN包总是带有 ACK 标记。"NULL"包就是没有任何TCP标记的包(URG,ACK,PSH,RST,SYN,FIN都为0)。
到目前为止,正常的网络活动下,TCP协议栈不可能产生带有上面提到的任何一种标记组合的TCP包。当你发现这些不正常的包时,肯定有人对你的网络不怀好意。

什么是状态检测

每个网络连接包括以下信息:源地址、目的地址、源端口和目的端口,叫作套接字对(socket pairs);协议类型、连接状态(TCP协议)和超时时间等。防火墙把这些信息叫作状态(stateful),能够检测每个连接状态的防火墙叫作状态包过滤防火墙。它除了能够完成简单包过滤防火墙的包过滤工作外,还在自己的内存中维护一个跟踪连接状态的表,比简单包过滤防火墙具有更大的安全性。 
iptables中的状态检测功能是由state选项来实现的。
--state state 
这里,state是一个用逗号分割的列表,表示要匹配的连接状态。有效的状态选项包括:INVAILD,表示分组对应的连接是未知的;
ESTABLISHED,表示分组对应的连接已经进行了双向的分组传输,也就是说连接已经建立;NEW,表示这个分组需要发起一个连接,或者说,分组对应的连接在两个方向上都没有进行过分组传输
RELATED,表示分组要发起一个新的连接,但是这个连接和一个现有的连接有关,例如:FTP的数据传输连接和控制连接之间就是RELATED关系。 

iptables的状态检测是如何工作的

如果要在两个网络接口之间转发一个分组,这个分组将以以下的顺序接收规则链的检查: 
iptables的状态检测机制将重组分组,并且以以下某种方式跟踪其状态: 
分组是否匹配状态表中的一个已经实现(ESTABLISHED)的连接。 
这个分组是否要发起一个新(NEW)的连接。 
如果分组和任何连接无关,就被认为是无效(INVALID)的。

iptables 自定义链实例

1、案例场景:将已建立连接和与一个现有连接有效的包放行。
2、配置步骤:
(1)创建自定义链block并添加规则:
#iptables -N block
#iptables -A block -m –state ESTABLISHED,RELATED -j ACCEPT
(2)将流经INPUT链的数据包跳转到block链处理数据包:
#iptables -A INPUT -j block
通过-j去跳转到自定义链,然后根据规则自上到下一条条执行,执行完毕后,回到原来执行的语句。

Iptables工作原理使用详解
自定义链

(附件: markdownFile.md)

来自为知笔记(Wiz)

附件列表