Iptables工作原理使用详解

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工作原理使用详解_第1张图片

 
iptables工作流程

 Iptables工作原理使用详解_第2张图片

                                                                                                  排除mangle表

 

 Iptables工作原理使用详解_第3张图片

                                                                                          数据包流向

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

  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工作原理使用详解_第4张图片

你可能感兴趣的:(linux运维)