Chinaunix首页 | 论坛 | 博客
  • 博客访问: 695350
  • 博文数量: 79
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1338
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-12 08:51
个人简介

XMU->九天揽月->五湖抓鳖->DSP->driver->kernel/OpenWRT->ISP/RTOS

文章分类

全部博文(79)

文章存档

2020年(2)

2018年(3)

2016年(7)

2015年(42)

2014年(25)

分类: 网络与安全

2014-12-07 22:20:30

一 基本概念

在正式介绍 iptables 的使用之前,先来看一下和 iptables 相关的一些基本概念。

匹配(match):符合指定的条件,比如指定的 IP 地址和端口。

丢弃(drop):当一个包到达时,简单地丢弃,不做其它任何处理。

接受(accept):和丢弃相反,接受这个包,让这个包通过。

拒绝(reject):和丢弃相似,但它还会向发送这个包的源主机发送错误消息。这个错误消息可以指定,也可以自动产生。

目标(target):指定的动作,说明如何处理一个包,比如:丢弃,接受,或拒绝。

跳转(jump):和目标类似,不过它指定的不是一个具体的动作,而是另一个链,表示要跳转到那个链上。

规则(rule):一个或多个匹配及其对应的目标。

链(chain):每条链都包含有一系列的规则,这些规则会被依次应用到每个遍历该链的数据包上。每个链都有各自专门的用途, 这一点我们下面会详细讨论。

表(table):每个表包含有若干个不同的链,比如 filter 表默认包含有 INPUTFORWARDOUTPUT三个链。iptables 有四个表,分别是:rawnatmanglefilter,每个表都有自己专门的用处,比如最常用filter表就是专门用来做包过滤的,而 nat 表是专门用来做NAT的。

策略police):我们在这里提到的策略是指,对于 iptables 中某条链,当所有规则都匹配不成功时其默认的处理动作

连接跟踪(connection track):又称为动态过滤,可以根据指定连接的状态进行一些适当的过滤,是一个很强大的功能,但同时也比较消耗内存资源。


1.1 

           The decision whether to drop or to reject traffic should be done on a case-by-case basis.很多人认为DROPREJECT更具有安全优势,毕竟DROP对于攻击者来说可暴露的信息更少。当时DROP提升安全性的同时,也大大增加了网络问题的定位复杂性,并且也可能在客户端导致非预期的side-effects

基于REJECT策略的场景,主机会回应一个带有"destination port unreachable"错误信息的ICMP报文,同时立即断开连接。这意味着对每个REJECT连接都有一定数量的ICMP回应产生。这种机制在防火墙被许多类似的连接攻击时,ICMPREJECT回应报文会把带宽很快占满拥塞,此即DoS攻击。

基于DROP策略的场景,由于没有ICMP的回应包,访问发起端感知不到失败,所以会继续发送请求知道连接超时。客户端必须等待超时,取决软件的设计,这有可能会导致软件挂起。这篇有趣的文章也指出了DROP策略并不会是你的网络更安全 


DROP
●less information is exposed
less attack surface
client software may not cope well with it (hangs until connection times out)
may complicate network debugging (where was traffic dropped and why)

REJECT
may expose information (like the ip at which traffic was actually blocked)
client software can recover faster from rejected connection attempts
network debugging easier (routing and firewall issues clearly distinguishable)

1.2 


Table Command Chain

match and TARGET



iptables -t filter -A INPUT

-j ACCEPT -p tcp --dport 53 #------------------- accept all incoming packets on TCP port 53 (DNS)

iptables -t filter -A FORWARD

-j REJECT -p udp --dport 135:139 #---------------- Block outgoing NetBIOS (Windows Share)

iptables -t filter -A FORWARD

-p tcp --dport 22 -m physdev --physdev-in wlan0 --physdev-out eth0.3 -j LOG --log-prefix "22 on wlan" #---- log wlan-clients attempts on ssh

iptables -t nat -A PREROUTING

-i $LAN -p tcp --dport 53 -j REDIRECT --to-port 53 #---------------- redirect DNS queries to self on TCP

iptables -t nat -A PREROUTING

-i $LAN -p udp --dport 53 -j REDIRECT --to-port 53 #---------------- redirect DNS queries to self on UDP

iptables -t nat -A POSTROUTING

-o eth0.2 -d 169.254.1.0/24 -j SNAT --to-source 169.254.1.1 #------ Source-NAT packets with specified destination to specified IP address

iptables -t nat -A POSTROUTING

-o $IF_DSL -j MASQUERADE #------------ Source-NAT all Packet leaving on Interface $IF_DSL to the IP address of the router on that Interface

iptables -t mangle -A POSTROUTING

-o $IF_DSL -s $IP_USER2 -j TC_USER2 #------------------------------- jump to custom user chain TC_USER2

iptables -t mangle -A TC_USER4

-j CLASSIFY --set-class 1:101 -p udp -m length --length :400

iptables -t mangle -A TC_USER1

-j CLASSIFY --set-class 1:103 -m tos --tos Maximize-Throughput

iptables -t mangle -A POSTROUTING

-o $IF_DSL ! -s 192.168.0.0/16 -j TEE --gateway 192.168.1.254 #----- forward a copy to gateway-IP

iptables -t mangle -A PREROUTING

-i $IF_DSL -d 192.168.0.0/16 -j TEE --gateway 192.168.1.254 #------- forward a copy to gateway-IP

iptables -t mangle -A PREROUTING

-m connbytes --connbytes 504857: --connbytes-dir both --connbytes-mode bytes -j CLASSIFY --set-class 1:303 #---- count the Bytes of one connection

iptables -t raw -A INPUT

! -i $IF_DSL -j CT --notrack #-------------- don't track anything NOT incoming on interface in variable $IF_DSL

iptables -t raw -A INPUT

-i $IF_LAN -s $NET_LAN -p tcp --dport 32777:32780 -j CT --notrack #------ don't track NFS



二 包的旅行


openwrt wiki上的这张图片层次合流程比较清晰。


现在,让我们看看当一个数据包到达时它是怎么依次穿过各个链和表的。基本步骤如下:

1. 数据包到达网络接口,比如 eth0

2. 进入raw表的 PREROUTING 链,这个链的作用是赶在连接跟踪之前处理数据包。

3. 如果进行了连接跟踪,在此处理。

4. 进入 mangle 表的 PREROUTING 链,在此可以修改数据包,比如 TOS 等。

5. 进入 nat 表的 PREROUTING 链,可以在此做DNAT,但不要做过滤。

6. 决定路由,看是交给本地主机还是转发给其它主机。

到了这里我们就得分两种不同的情况进行讨论了,一种情况就是数据包要转发给其它主机,这时候它会依次经过:

7. 进入 mangle 表的 FORWARD 链,这里也比较特殊,这是在第一次路由决定之后,在进行最后的路由决定之前,我们仍然可以对数据包进行某些修改。

8. 进入 filter 表的 FORWARD 链,在这里我们可以对所有转发的数据包进行过滤。需要注意的是:经过这里的数据包是转发的,方向是双向的。

9. 进入 mangle 表的 POSTROUTING 链,到这里已经做完了所有的路由决定,但数据包仍然在本地主机,我们还可以进行某些修改。

10. 进入 nat 表的 POSTROUTING 链,在这里一般都是用来做 SNAT ,不要在这里进行过滤。

11. 进入出去的网络接口。完毕。


另一种情况是,数据包就是发给本地主机的,那么它会依次穿过:

7. 进入 mangle 表的 INPUT ,这里是在路由之后,交由本地主机之前,我们也可以进行一些相应的修改。

8. 进入 filter 表的 INPUT ,在这里我们可以对流入的所有数据包进行过滤,无论它来自哪个网络接口。

9. 交给本地主机的应用程序进行处理。

10. 处理完毕后进行路由决定,看该往那里发出。

11. 进入 raw 表的 OUTPUT 链,这里是在连接跟踪处理本地的数据包之前。

12. 连接跟踪对本地的数据包进行处理。

13. 进入 mangle 表的 OUTPUT 链,在这里我们可以修改数据包,但不要做过滤。

14. 进入 nat 表的 OUTPUT 链,可以对防火墙自己发出的数据做 NAT 

15. 再次进行路由决定。

16. 进入 filter 表的 OUTPUT 链,可以对本地出去的数据包进行过滤。

17. 进入 mangle 表的 POSTROUTING 链,同上一种情况的第9步。注意,这里不光对经过防火墙的数据包进行处理,还对防火墙自己产生的数据包进行处理。

18. 进入 nat 表的 POSTROUTING 链,同上一种情况的第10步。

19. 进入出去的网络接口。完毕。


概述上面的流程,总之

1.修改包都是在mangle表,pre post

2.过滤包都是在filter

3.NAT不应该做过滤,只做转 换

4.raw 必在前端


三 操作iptables

iptables 的基本用法:

iptables [-t table] -[AD] chain rule-specification [options]

iptables [-t table] -I chain [rulenum] rule-specification [options]

iptables [-t table] -R chain rulenum rule-specification [options]

iptables [-t table] -D chain rulenum [options]

iptables [-t table] -[LFZ] [chain] [options]

iptables [-t table] -N chain

iptables [-t table] -X [chain]

iptables [-t table] -P chain target [options]

iptables [-t table] -E old-chain-name new-chain-name

下面我们来详细看一下各个选项的作用:

3.1 操作表和chain

-t, --table table
对指定的表 table 进行操作, table 必须是 raw, natfiltermangle 中的一个。如果不指定此选项,默认的是filter 表。

-L, --list [chain]
列出链 chain 上面的所有规则,如果没有指定链,列出表上所有链的所有规则。例子:

# iptables -L INPUT

-F, --flush [chain]
清空指定链 chain 上面的所有规则。如果没有指定链,清空该表上所有链的所有规则。例子:

# iptables –t nat -F

-A, --append chain rule-specification

在指定链 chain 的末尾插入指定的规则,也就是说,这条规则会被放到最后,最后才会被执行。规则是由后面的匹配来指定。例子:

加规则总结:

-A chain :添加到chain的末

-I chain num:插入到chainnum,无num则为1,到第一个规则

# iptables -A INPUT -s 192.168.20.13 -d 192.168.1.1 -p TCP –dport 22 -j ACCEPT

-D, --delete chain rule-specification

-D, --delete chain rulenum在指定的链 chain 中删除一个或多个指定规则。如上所示,它有两种格式的用法。例子


    # iptables -D INPUT --dport 80 -j DROP
    # iptables -D INPUT 1
    
如何获得chainrulenum呢?
    
iptables –t nat –L --line-numbers
    
iptables –t nat –L zone_wan_postrouting --line-numbers
    
iptables –t nat –D zone_wan_postrouting 2

-I, --insert chain [rulenumrule-specification

在链 chain 中的指定位置插入一条或多条规则。如果指定的规则号是1,则在链的头部插入。这也是默认的情况,如果没有指定规则号。例子:

# iptables -I INPUT 1 --dport 80 -j ACCEPT

-R, --replace chain rulenum rule-specification
用新规则替换指定链 chain 上面的指定规则,规则号从1开始。例子:

# iptables -R INPUT 1 -s 192.168.1.41 -j DROP

-N, --new-chain chain
用指定的名字创建一个新的链。例子:

# iptables -N mychain

-X, --delete-chain [chain]
删除指定的链,这个链必须没有被其它任何规则引用,而且这条上必须没有任何规则。如果没有指定链名,则会删除该表中所有非内置的链。例子:

# iptables -X mychain

-E, --rename-chain old-chain new-chain
用指定的新名字去重命名指定的链。这并不会对链内部照成任何影响。例子:

# iptables -E mychain yourchain

-P, --policy chain target
为指定的链 chain 设置策略 target注意,只有内置的链才允许有策略,用户自定义的是不允许的。 策略是默认操作,内置的chain才能有策略。 INPUT OUTPUT FORWARD PREROUTING POSTROUTING

-A –N –I来的chain不能带-P

例子:

# iptables -P INPUT DROP

-Z, --zero [chain]
把指定链,或者表中的所有链上的所有计数器清零。例子:

# iptables -Z INPUT


3.2 操作rule

上面列出的都是对链或者表的操作,下面我们再来看一下对规则进行操作的基本选项:

-p, --protocol [!] proto
指定使用的协议为 proto ,其中 proto 必须为 tcp udp icmp 或者 all ,或者表示某个协议的数字。如果 proto前面有“!”,表示对取反。例子:

# iptables -A INPUT -p tcp [...]

-j, --jump target
指定目标,即满足某条件时该执行什么样的动作target 可以是内置的目标,比如 ACCEPT,也可以是用户自定义的链。例子:

# iptables -A INPUT -p tcp -j ACCEPT

-s, --source [!] address[/mask]
把指定的一个/一组地址作为源地址,按此规则进行过滤。当后面没有 mask 时,address 是一个地址,比如:192.168.1.1;当 mask 指定时,可以表示一组范围内的地址,比如:192.168.1.0/255.255.255.0。一个完整的例子:

iptables -A INPUT -s 192.168.1.1/24 -p tcp -j DROP

-d, --destination [!] address[/mask]
地址格式同上,但这里是指定地址为目的地址,按此进行过滤。例如:

# iptables -A INPUT -d 192.168.1.254 -p tcp -j ACCEPT

-i, --in-interface [!] name
指定数据包的来自来自网络接口,比如最常见的 eth0 。注意:它只对 INPUTFORWARDPREROUTING这三个链起作用。如果没有指定此选项,说明可以来自任何一个网络接口。同前面类似,"!" 表示取反。例子:

# iptables -A INPUT -i eth0

-o, --out-interface [!] name
指定数据包出去的网络接口。只对 OUTPUTFORWARDPOSTROUTING 三个链起作用。例如:

# iptables -A FORWARD -o eth0

--source-port,--sport port[:port]
在 tcp/udp/sctp 中,指定源端口。冒号分隔的两个 port 表示指定一段范围内的所有端口,大的小的哪个在前都可以,比如: “1:100” 表示从1号端口到100号(包含边界),而 “:100” 表示从 到 100,“100:”表示从10065535。一个完整的例子如下:

# iptables -A INPUT -p tcp --sport 22 -j REJECT

--destination-port,--dport port[,port]
指定目的端口,用法和上面类似,但如果要指定一组端口,格式可能会因协议不同而不同,注意浏览 iptables的手册页。例如:

# iptables -A INPUT -p tcp --dport 22 -j ACCEPT

另外,一些协议还有自己专有的选项,想了解更多请查看 iptables 的手册页。

3.3 saverestore,备份与还原

到这里,主要的选项已经介绍个差不多了,另一个问题随之也产生了,如何保存我们的 iptables 的规则呢?一个很容易想到的办法是把这些 iptables 命令做成脚本,然后执行脚本即可。不错,这的确可以完成我们的任务,但这样效率不高,因为每执行一条iptables 命令都要重新访问内核,如果规则很多很多,这会浪费比较多的时间。取而代之的方法是,使用 iptables-save 和 iptables-restore 这两条命令,它们访问一次内核就可以保存或读取所有规则。这两条命令很简单,我们下面就来看一下。

iptables-save 命令的格式很简单,如下:

iptables-save [-c] [-t table]


iptables-save 会把规则以某种格式打印到标准输出,通过重定向我们可以把它保存到某个文件。其中, -c告诉它也要保存计数器,如果我们想重启 iptables 但又不想丢弃当前的计数,我们可以加此选项。 -t 告诉它只保存指定的表,如果没有此选项则会保存所有的表。

iptables-save 的输出格式其实也很简单,一个示例如下:

# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
    
*filter
    
:INPUT DROP [1:229]
    :FORWARD DROP [0:0]
    :OUTPUT DROP [0:0]
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -i eth1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
    -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

        # Completed on Wed Apr 24 10:19:55 2002
    # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
    *mangle
    :PREROUTING ACCEPT [658:32445]
    :INPUT ACCEPT [658:32445]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [891:68234]
    :POSTROUTING ACCEPT [891:68234]

        
# Completed on Wed Apr 24 10:19:55 2002
        # Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
    *nat
    :PREROUTING ACCEPT [1:229]
    :POSTROUTING ACCEPT [3:450]
    :OUTPUT ACCEPT [3:450]
    -A POSTROUTING -o eth0 -j SNAT --to-source 195.233.192.1


四 iptable 使用实例

默认策略:

 iptables -P INPUT ACCEPT

 iptables -P OUTPUT DROP

 iptables -P FORWARD DROP

接受所有ssh连接:

    iptables -A INPUT -p tcp -m tcp -s 0/0 --dport 22 -j ACCEPT

管理FTP连接:

  iptables -A INPUT -p tcp -m tcp --dport 21 -j ACCEPT

    iptables -A INPUT -p tcp -s 127.0.0.1/8 -d 0/0 --destination-port 20 --syn -j ACCEPT

    iptables -A INPUT -p tcp -s 127.0.0.1/8 -d 0/0 --destination-port 21 --syn -j ACCEPT

监视SNMP:

   iptables -A INPUT -p udp -m udp --dport 161 -j ACCEPT

    iptables -A INPUT -p udp -m udp --sport 1023:2999 -j ACCEPT

管理POP电子邮件:

    iptables -A INPUT -p tcp -m tcp --dport 110 -j ACCEPT --syn

HTTPS服务:

  iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT --syn

SMTP连接:

   iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT --syn

管理HTTP:

   iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT --syn

管理MySQL数据库:

   iptables -A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT --syn

    iptables -A INPUT -p udp -m udp --dport 3306 -j ACCEPT

IMAP邮件服务:

   iptables -A INPUT -p tcp -m tcp --dport 143 -j ACCEPT --syn

管理DNS服务:

   iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT --syn

    iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT

    iptables -A INPUT -p udp -m udp -s 0/0 -d 0/0 --sport 53 -j ACCEPT

管理本地主机连接:

   iptables -A INPUT -i lo -j ACCEPT -m tcp

丢弃所有其它的新请求:

   iptables -A INPUT -p tcp -m tcp -j REJECT --syn

    iptables -A INPUT -p udp -m udp -j REJECT

防止SYN洪水攻击:

   iptables -A INPUT -p tcp --syn -m limit --limit 5/second -j ACCEPT

屏蔽恶意主机(比如,192.168.0.8):

   iptables -A INPUT -p tcp -m tcp -s 192.168.0.8 -j DROP

检查防火墙日志:

   iptables -A INPUT -j LOG --log-level alert

    iptables -A INPUT -j LOG --log-prefix "Dropped: "

做 NAT:

   iptables -A POSTROUTING -t nat -o eth0 -s 192.168.1.0/24 -d 0/0 -j MASQUERADE

    iptables -A FORWARD -t filter -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

    iptables -A FORWARD -t filter -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

清空所有规则:

   iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

阅读(4032) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~