iptables

一. 背景知识

1. 相关网络背景知识

(1) Linux 主机内部路由

Linux 在 内核中维护由一个路由表, 报文进入本机后, 由该路由表判断目标地址; 报文离开本机之前, 判断经由那个接口发出.

(2) TCP 报文格式

erg : 紧急指针是否有效.
ack : 确认号是否有效.
psh : 不再缓冲中停留, 直接发往内核.
rst : reset, 重置.
syn : 同步, 请求建立连接.
fin : 结束, 请求关闭连接.

(3) TCP 协议的三次握手和四次断开

(4) TCP 的有限状态机

2. iptables 简介

iptables 是 Linux 主机上的防火墙软件, 由两部分构成:

  1. iptables : 命令行工具, 用于编写 规则, 并可以实现规则的语法检查.
  2. netfilter : 网络过滤器, 内核中工作为 TCP/IP 协议栈上的框架.

3. netfilter 的四表五链

(0) 表与链

每个钩子函数上可以防止 n 条规则, 数据包在每条规则上依次匹配, 对应于每个钩子上的多条规则成为一个 链(CHAIN);

每个功能(表)有多个链, 所以成为

(1) 四表

  • filter : 包过滤
    input --> forward --> output

  • NAT : 地址转换
    prerouting --> output --> postrouting

  • mangle : 修改报文首部中的某些信息;
    prerouting --> input --> forward --> output --> postrouting

  • raw : 关闭 nat 表上启动的链接追踪功能.
    prerouting --> output

(2) 五链(5 个 hooks functions)

  • prerouting : 进入本机后, 路由功能发生之前
  • input : 到达本机内部
  • output : 由本机发出
  • forward : 由本机转发
  • postrouting : 路由功能发生之后, 即将离开本机之前.

(3) 报文流向经由的位置

  • 到本机内部
    prerouting --> input

  • 由本机发出
    output --> postrouting

  • 由本机转发
    prerouting --> forward --> postrouting

(4) 链上规则的检查次序

匹配的内部机制 : 检查 IP 首部, 检查 TCP,UDP,ICMP 首部; 同时, 基于扩展机制, 可以进行额外的检查, 例如做链接追踪等.

  • 每个 链 上的规则检查为依次检查;
  • 当某个链上的某个规则被匹配之后, 则执行该规则的 target, 该链上的其他规则不再执行;
  • 钩子函数(表)的优先级
    在每个钩子(链)上, 规则是按不同的功能(表), 分别存放的. 每个数据包到来之后, 按表的优先级, 依次检查每一个链, 完成之后, 转到下一个链.

    优先级 : raw > mangle > nat > filter

(5) 规则编写最佳实践

写作规则的最佳实践:

  • 同类规则 : 匹配范围的放在最前面;
  • 同类规则, 如果能合并, 则尽量合并;
  • 不同类规则 : 匹配范围几率较大的放前面;
  • 应该为每个链, 设置默认规则;

二. iptables 规则编写

1. 添加规则时的考量点

  1. 要实现的功能 --> 判断添加到哪个表上;
  2. 报文流向及经由路径 --> 判断添加到哪个链上;

2. 规则和链的计数器

  • pkts: 由规则或链匹配到的报文的个数;
  • bytes:由规则或链匹配到的所有报文大小之和;

3. 规则的编写.

如果同时指定多个匹配条件, 则默认多个条件需要同时被满足.

iptables [-t TABLE] SUBCOMMAND CHAIN CRETERIA -j TARGET

    -t TABLE:
        默认为filter, 共有filter, nat, mangle, raw四个可用;

    SUBCOMMAND:
        链:
            -F:flush,清空指定表的指定链上所有规则;省略链名时,清空表中的所有链;

            -N:new, 新建一个用户自定义的链;自定义链只能作为默认链上的跳转对象,即在默认链通过引用来生效自定义链;

            -X:drop,删除用户自定义的空链;非空自定义链和内置链无法删除;

            -Z:zero,将规则的计数器置0;

            -P:policy,设置链的默认处理机制;当所有都无法匹配或有匹配有无法做出有效处理机制时,默认策略即生效;
                filter表的可用策略:ACCEPT, DROP, REJECT

            -E:rename,重命名自定义链;

            注意:被引用中的链,无法删除和改名

        规则:
            -A:append,在链尾追加一条规则;

            -I:insert,在指定位置插入一条规则;

            -D:delete,删除指定的规则;rule or rulenum

            -R:replace,替换指定的规则;

                $ iptable -t filter -R INPUT 1 -s 172.16.100.2 -d 172.16.100.11 -p tcp -i eth0 -j ACCEPT

        查看:
            -L:list,列出指定链上的所有规则;
                -n: numeric,以数字格式显示地址和端口号,即不反解;

                -v: verbose,详细格式,显示规则的详细信息,包括规则计数器等;

                -vv:

                -vvv:

                --line-numbers: 显示规则编号;

                -x: exactly,显示计数器的精确值;

            pkts bytes target     prot opt in     out     source               destination
                pkts: 被本规则所匹配到的包个数;
                bytes:被本规则所匹配到的所包的大小之和;
                target: 处理目标 (目标可以为用户自定义的链)
                prot: 协议 {tcp, udp, icmp}
                opt: 可选项
                in: 数据包流入接口
                out: 数据包流出接口
                source: 源地址
                destination: 目标地址;
    CHAIN :
        指定要添加规则的链;

        可以是自定义链. 注意:报文不可能经由自定义链(不再内核中),只有在被内置链上的引用才能生效(即做为自定义目标)

    CRETERIA :
        指定匹配条件.

        1. 通用匹配

            -s, --src, --source  IP|Network:检查报文中的源IP地址;

            -d, --dst, --destination:检查报文中的目标IP地址/网段

            -p, --protocol:检查报文中的协议,即ip首部中的protocols所标识的协议;tcp、udp或icmp三者之一;

            -i, --in-interface:数据报文的流入接口;通常只用于PREROUTING, INPUT, FORWARD链上的规则;

            -o, --out-interface:检查报文的流出接口;通常只用于FORWARD, OUTPUT, POSTROUTING链上的规则;

        2. 扩展匹配: 使用 iptables 的模块实现扩展检查机制.
            (1) 隐式扩展 :
                ** 如果在通用匹配上使用 -p 选项指明了协议的话,则使用-m选项指明对其协议的扩展就变得可有可无了;

                1) tcp: -m tcp
                    --dport PORT[-PORT]     # 必须是连续的端口
                    --sport
                    --tcp-flags LIST1 LIST2
                        LIST1: 要检查的标志位;
                        LIST2:在LIST1中出现过的,且必须为1标记位;而余下的则必须为0;
                        例如:--tcp-flags syn,ack,fin,rst syn # 表示 三次握手的第一次. 等同 --syn
                    --syn:用于匹配tcp会话三次握手的第一次;新建连接.

                    $ iptable -A INPUT 1 -s 172.16.100.2 -d 172.16.100.11 -p tcp [-m tcp] --dport 80 -j REJECT  # -m tcp 可省略, 因为 -p tcp 指明了协议.

                2) udp: -m udp
                    --sport
                    --dport

                3) icmp: -m icmp
                    --icmp[-type]  # ICMP TYPE CODE 表
                        8: echo request, ping 请求
                        0:echo reply, ping 响应

                        # 允许自己 ping 别人. 本机地址 为 172.16.100.11 .
                        $ iptables -A OUTPUT -s 172.16.100.11 -p icmp --icmp-type 8 -j ACCEPT
                        $ iptables -A INPUT -d 172.16.100.11 -p icmp --icmp-type 0 -j ACCEPT

            (2) 显式扩展: 必须指明使用的扩展机制.

                0) 通用语法格式:

                    -m 模块名称
                        每个模块会引入新的匹配机制;

                查看可用模块:

                    小写字母,以.so结尾;
                    大写通常指 处理方式.

                1) multiport扩展:以离散定义多端口匹配;最多指定15个端口;

                    专用选项:
                        --source-ports, --sports PORT[,PORT,...]
                        --destination-ports, --dports PORT[,PORT,...]
                        --ports PORT[,PORT,...]     # 源和目标端口.

                    例子:
                        $ iptables -I INPUT 1 -d 172.16.100.11 -p tcp -m multiport --dports 22,80,443 -j ACCEPT
                        $ iptables -I OUTPUT 1 -s 172.16.100.11 -p tcp -m multiport --sports 22,80,443 -j ACCEPT

                2) iprange扩展:指定连续的ip地址范围;在匹配非整个网络地址时使用;

                    专用选项:
                        [!] --src-range IP[-IP]     # 也支持单个 ip
                        [!] --dst-range IP[-IP]     # 也支持单个 ip

                    示例:
                        $ iptables -A INPUT -d 172.16.100.11 -p tcp --dport 23 -m iprange --src-range 172.16.100.1-172.16.100.100 -j ACCEPT
                        $ iptables -A OUTPUT -s 172.16.100.11 -p tcp --sport 23 -m iprange --dst-range 172.16.100.1-172.16.100.100 -j ACCEPT

                3) string扩展:对应用层首部和数据进行检查. 检查报文中出现的字符串,与给定的字符串作匹配;

                    字符串匹配检查算法:实现高效匹配. 两者相近.
                        kmp :
                        bm : 

                    专用选项:
                        --algo {kmp|bm}
                        --string "STRING"
                        --hex-string "HEX_STRING":HEX_STRING为编码成16进制格式的字串;

                    示例:
                        $ iptables -I OUTPUT 1 -s 172.16.100.11 -p tcp --sport 80 -m string --string "sex" --algo kmp -j REJECT

                4) time扩展:基于时间区间做访问控制

                    专用选项:
                        --datestart YYYY[-MM][-DD][hh[:mm[:ss]]]
                        --dattestop YYYY[-MM][-DD][hh[:mm[:ss]]]

                        --timestart
                        --timestop

                        --weekdays DAY1[,DAY2,...]

                    示例:
                        $ iptables -R INPUT 1 -d 172.16.100.11 -p tcp --dport 80 -m time --timestart 08:30 --timestop 18:30 --weekdays Mon,Tue,Thu,Fri -j REJECT

                5) connlimit扩展:基于连接数作限制;对每个IP能够发起的并发连接数作限制;

                    专用选项:
                        --connlimit-above [n]   # 包含 n .

                    $ iptables -I INPUT 2 -d 172.16.100.11 -p tcp --dport 22 -m connlimit --connlimit-above 5 -j REJECT

                6) limit扩展:基于令牌桶算法实现的.基于发包速率作限制;

                    专用选项:令牌桶算法
                        --limit  n[/second|/min|/hour|/day]
                        --limit-burst n  # 突发速率时, 最大速率. 

                    $ iptables -R INPUT 3 -d 172.16.100.11 -p icmp --icmp-type 8 -m limit --limit 10/minute --limit-burst 5 -j ACCEPT   

                    ** limit 仅按一定速率匹配数据, 若限制, 先放过一定速率的数据, 然后阻断.
                        $ iptables -A FORWARD -p icmp -s 172.16.11.0/24 -m limit --limit 10/s -j ACCEPT
                        $ iptables -A FORWARD -p icmp -s 172.16.11.0/24 -j DROP                       

                7) state扩展:启用连接追踪模板记录连接,并根据连接匹配连接状态的扩展;
                    启用连接追踪功能之前:简单包过滤防火墙;
                    启用连接追踪功能:带状态检测的包过滤防火墙;
                        # 反弹式木马: 木马可以探测主机开放的端口, 并使用该端口作为客户端,想外发送请求, 从而出入的连接成为 ESTABLISHED 状态.

                    专用选项:
                        --state STATE

                    $ iptables -I INPUT 1 -d 172.16.100.11 -p tcp -m multiport --dport 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT

                    $ iptables -I OUTPUT 1 -d 172.16.100.11 -m state --state ESTABLISHED -j ACCEPT 

                    调整连接追踪功能所能容纳的连接的最大数目:

                        $cat /proc/sys/net/nf_conntrack_max

                        $ lsmod | grep nf_conntrack  # 查看是否打开连接追踪功能.
                        $ modprobe -r nf_conntrack
                        $ modprobe -r nf_conntrack_ipv4

                    当前追踪的所有连接:

                        /proc/net/nf_conntrack

                    不同协议或连接类型追踪时的时长属性:

                        /proc/sys/net/netfilter/

                    如何放行被动模式下的ftp服务:

                        (1) 装载模块:
                            # modprobe nf_conntrack_ftp

                        (2) 放行请求报文
                            放行入站请求端口为21的请求报文;
                            放行所有状态为ESTABLISHED和RELATED状态的入站报文;

                        (3) 放行出站响应报文
                            放行所有状态为ESTABLISHED的出站报文;

                8) recent 扩展 : 利用iptables的recent模块来抵御DOS攻击.
                    示例:
                        iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH # SSH 只是个名字, 用于日志记录 /var/log/messages .

                        iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attack: "

                        iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

                        1.利用connlimit模块将单IP的并发设置为3;会误杀使用NAT上网的用户,可以根据实际情况增大该值;

                        2.利用recent和state模块限制单IP在300s内只能与本机建立2个新连接。被限制五分钟后即可恢复访问。

                        下面对最后两句做一个说明:

                        1.第二句是记录访问tcp 22端口的新连接,记录名称为SSH
                        --set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目

                        2.第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。
                        --update 是指每次建立连接都更新列表;
                        --seconds必须与--rcheck或者--update同时使用
                        --hitcount必须与--rcheck或者--update同时使用

                        3.iptables的记录:/proc/net/xt_recent/SSH

                    # 防止被探测 SSH 密码
                        $ iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH --rsource -m recent --name SSH --update --seconds 10 --hitcount 4 --rsource -j DROP

    TARGET:

        -j: jump,跳转目标

            内置目标:

                ACCEPT : 接受
                DROP : 丢弃
                REJECT : 拒绝

                SNAT
                DNAT
                MASQUERADE

                LOG:日志
                REDIRECT:端口重定向;
                RETURN: 返回至调用者;
                MARK:防火墙标记, 用于 mangle 表中. 见 LVS.

4. NAT : Network Address Translation

(1) 分类:

NAT : 工作于 3 和 4 层. 并非是用户空间运行的进程完成转换功能,靠的是内核中地址转换规则;

仅从请求报文判断,地址转换:

  • 源地址转换:SNAT
    SNAT: CIP --> SIP: CIP --> SNAT(PIP) --> SIP
    CIP: 本地客户端地址

  • 目标地址转换:DNAT
    DNAT:RemoteIP --> PIP: RemoteIP --> DNAT(SIP) --> SIP
    RemoteIP:远程客户端地址;

  • 端口转换:PNAT
    通常在 DNAT 中实现.

(2) SNAT:主要用于实现让内网客户端访问外部主机时使用;

注意

  • 要定义在POSTROUTING链;也可以在OUTPUT上使用(较少);
  • 需要打开网络间转发:

    echo 1 > /proc/sys/net /ipv4/ip_forward

定义方法:

$ iptables -t nat -A POSTROUTING -s 内网网络或主机地址 -j SNAT --to-source NAT服务器上的某外网地址

另一个TARGET:
    MASQUERADE:地址伪装;
        能自行判断该转为哪个源地址;

    iptables -t nat -A POSTROUTING -s 内网网络或主机地址 -j MASQUERADE

示例:

$ iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.11     # 172.16.100.11 为本机的一个接口.

(3) DNAT:主要用于发布内部服务器,让内网中的服务器在外网中可以被访问到;

注意

  • 要定义在PREROUTING链;

定义方法:

$ iptables -t nat -A PREROUTING -d NAT服务器的某外网地址 -p 某协议 --dport 某端口 -j DNAT --to-destination 内网某服务器地址[:PORT]

示例:

$ iptables -t nat -A PREROUTING -d 172.16.100.11 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.7

(4) FULLNAT: 全地址转换, 见 LVS.

在请求报文到时:既修改源地址,又修改目标地址; 响应报文也是.

5. 规则的保存与重载.

保存:

service iptables save   # 保存到 /etc/sysconfig/iptables 文件;

iptables-save > /PATH/TO/SOMEFILE   # 自定义保存文件

重载:

service iptables reload     # 使用默认保存文件

iptables-restore < /PATH/FROM/SOMEFILE  # 使用自定义保存文件.

三. 其他相关

REDIRECT 与 DNAT 的区别?

$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to 3128

$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 172.16.11.1:3128

$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 3389 -j DNAT --to-destination 172.16.11.250

结论

  • REDIRECT 是 DNAT 的一个特例.
  • DNAT的功能更强大.

MASQUEREAD 与 SNAT 的区别?

$ iptables -t nat -s 172.16.11.0/24 -o eth0 -j MASQUERADE

$ iptables -t nat -s 172.l6.11.0/24 -o eth0 -j SNAT --to 123.123.123.123
$ iptables -t nat -s 172.l6.11.0/24 -o eth0 -j SNAT --to 123.123.123.1-123.123.123.10

结论:

  • MASQUERADE 自动根据路由选择出口;
  • SNAT 适用于固定 IP 的环境, 负责小; 例外, 可实现地址面积映射.

-j 与 -g 的区别

$ iptables -N TESTA
$ iptables -N TESTB
$ iptables -A FORWARD -s 172.16.11.1 -j TESTA
$ iptables -A FORWARD -s 172.16.11.2 -j TESTB
$ iptables -A TESTA -j MARK --set-mark 1
$ iptables -A TESTB -j MARK --set-mark 2
$ iptables -A FORWARD -m mark --mark 1 -j DROP
$ iptables -A FORWARD -m mark --mark 2 -j DROP

结论

  • -j(jump) 相当于调用, 自定链结束后返回
  • -g(goto) 一去不复返.

raw 表的用途

$ iptables -t raw -A PREROUTING -i eth0 -s 172.16.11.250 -j DROP

结论

  • raw 表工作于最前端, 在 conntrack 之前 可以明确对某些数据不进行链接追踪;
  • raw 可以提前 DROP 数据, 有效降低负载.

如何防止被 tracert ?

tracert == TTL 试探

$ iptables -A INPUT -m ttl --ttl-eq 1 -j DROP
$ iptables -A INPUT -m ttl --ttl-lt 4 -j DROP
$ iptables -A FORWARD -m ttl --ttl-lt 6 -j DROP

iptables 汇总的更多相关文章

  1. RedHat 和 Mirantis OpenStack 产品的版本和功能汇总和对比(持续更新)

    Mirantis 和 Red Hat 作为 OpenStack 商业化产品领域的两大领军企业,在行业内有重要的地位.因此,研究其产品版本发布周期和所支持的功能,对制定 OpenStack 产品的版本和 ...

  2. 【转】IPtables学习笔记

    写在前面,大家测试玩iptables时要记得自己配置了那些东西,测试完成后记得删除啊,博主忘了删除一个input REJECT链的一条记录,后续测试搭建了apache服务器,始终无法访问,最后抓包发现 ...

  3. Linux基础命令介绍七:网络传输与安全 wget curl rsync iptables

    本篇接着介绍网络相关命令:wget 文件下载工具.curl 网络数据传输工具.rsync 文件传输工具等. 本篇接着介绍网络相关命令 1.wget 文件下载工具 wget [option]... [U ...

  4. openstackM版本常见问题汇总

    汇总下常见的问题以及解释下一些比较容易让人萌的参数配置等等 问题汇总1.使用纯文本模式进行复制粘贴,打死不要用word!!!可以解决绝大多数问题,如果你依然执迷不悟,那么就好自为之吧 2.创建路由器时 ...

  5. shell脚本语法基础汇总

    shell脚本语法基础汇总 将命令的输出读入一个变量中,可以将它放入双引号中,即可保留空格和换行符(\n) out=$(cat text.txt) 输出1 2 3 out="$(cat te ...

  6. iptables工作常用操作

    正确的设置iptables命令汇总 iptables -P INPUT ACCEPT iptables -F iptables -X iptables -Z iptables -I INPUT -p ...

  7. [转帖]CentOS 查看系统信息汇总

    CentOS 查看系统信息汇总 http://blog.itpub.net/15498/viewspace-2637493/ 感觉应该是 centos相关的 改了下名字 日志文件说明 /var/log ...

  8. [转] Linux运维常见故障排查和处理的技巧汇总

    作为linux运维,多多少少会碰见这样那样的问题或故障,从中总结经验,查找问题,汇总并分析故障的原因,这是一个Linux运维工程师良好的习惯.每一次技术的突破,都经历着苦闷,伴随着快乐,可我们还是执着 ...

  9. centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总

    centos平台基于snort.barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总 原创 2016年12月19日 01:20:03 标签: centos / snort  ...

随机推荐

  1. crontab定时任务不执行的原因

    1.重启crontab若是遇见"You (cloudlogin) are not allowed to use this program (crontab)                 ...

  2. kafka java使用

    首先添加maven依赖 Kafka <dependency> <groupId>org.apache.kafka</groupId> <artifactId& ...

  3. Linux下Hadoop2.7.1集群环境的搭建(超详细版)

                                本文旨在提供最基本的,可以用于在生产环境进行Hadoop.HDFS分布式环境的搭建,对自己是个总结和整理,也能方便新人学习使用. 一.基础环境 ...

  4. 白话C#语法新特性之元组

    1.元组(Tuples) 元组(Tuple)在4.0 的时候就有了,但元组也有些缺点,如: 1)Tuple 会影响代码的可读性,因为它的属性名都是:Item1,Item2.. . 2)Tuple 还不 ...

  5. FAILED: SemanticException [Error 10096]: Dynamic partition strict mode

    因为动态分区只能在非严格模式进行... 修改为非严格模式后即可! set hive.exec.dynamic.partition.mode

  6. git pull冲突:commit your changes or stash them before you can merge.

    今天用git pull来更新代码,遇到了下面的问题: error: Your local changes to the following files would be overwritten by ...

  7. jquery之属性操作

    jQuery之属性操作 相信属性这个词对大家都不陌生.今天我就给大家简单地介绍一下JQuery一些属性的操作 属性一共分三大类 一.基本属性 1.attr 2.removeAttr 3.prop 4. ...

  8. Micro 架构与设计

    Micro 架构与设计 翻译自 Micro architecture & design patterns for microservices 注: 原文作者即 Micro 框架的开发者. 过去 ...

  9. 多线程编程-- part 3 多线程同步->synchronized关键字

    多线程同时访问一个资源,可以会产生不可预料的结果,所以为这个资源加锁,访问资源的第一个线程为其加锁后,其他线程便不能在使用那个资源,直到锁被解除. 举个例子: 存款1000元,能取出800的时候我就取 ...

  10. 【webpack】webpack-dev-server生猛上手——让我们来搭一个webpack的微服务器吧!

      [前言]:因为最近在搞百度地图API的时候到了webpack的externals,才发现我之前都只是用webpack做一些搭建完项目后的"收尾工作"--即打包,而没有把它纳入到 ...