iptables详细介绍及应用案例(推荐)

iptables能干什么事儿:

    1:帮助学习协议
        输出网络通信日志(到syslog/messages)
        返回指定的内容

    2:了解最基础的网络安全防护设备
        网络防火墙的作用,网络防火墙的原理
        防火墙的日志是IPS,IDS等高级安全设备的基础
        Netfilter是linux内核的功能,很多基于linux内核的安全设备都是使用Netfilter做的底层工作

    3:若是只想保护linux服务器本身的安全就使用filter表的INPUT和OUTPUT链就行了,不需要使用FORWARD链



网络过滤的分解步骤

    1:获取数据(嗅探,正常请求)
    2:识别数据(协议头,具体内容)
    3:过滤(丢弃,修改,放过,记录日志等)

iptables服务及配置文件基础

    #配置文件位置
    cat /etc/sysconfig/iptables

    #保存iptables规则(不输入绝对地址无法保存哦)
    /etc/rc.d/init.d/iptables save

    #将iptables规则另存为一个叫ss的文件
    iptables-save > ss  

    #将外部iptables规则文件导入到iptables规则中,并运行
    iptables-restore < ss

iptables语法

    -t<表>:  #指定要操纵的表;(不指明,默认就是filter表)

    链管理
    -N: #创建自定义规则链;(用于对内置链的扩展和补充)
    -X: #删除自定义规则链,
    -P: #定义规则链中的默认策略(filter表的默认策略是accept,允许);
    -E: #重命名自定义链,(引用计数不为0的自定义链,不能被重命名,也不能被删除)

    规则管理
    -A: #向链中'追加'规则条目;
    -I: #向链中'插入'规则条目;需要指明位置,默认表示第一条处
    -D: #从链中'删除'规则条目;后面跟要删除的规则序号
    -R: #'替换'链中的指定规则条目;后面跟要替换的规则序号
    -F: #清空规则
    -Z: #置零计数器'匹配到的报文个数'和'匹配到的所有报文大小之和';

    查看
    -L: #显示规则链中已有的条目;
        -n: #以数字格式显示地址和端口号
        -v: #显示详细信息
        -x: #显示计数器结果的精确值
        --line-numbers: #显示规则的序号

    基本匹配条件(无需加载任何模块,由iptables/netfilter自行提供)
    -p: #指定要匹配的数据包协议类型;[tcp|udp|icmp|gre|udplite|esp|sh|sctp|mh|all]
    -s: #指定要匹配的数据包源ip地址;
    -d: #指定要匹配的数据包目的ip地址;
    --sport:    #指定要匹配的数据包源端口;(端口范围表示方法 80:83)(表示端口范围是80到83)
    --dport:    #指定要匹配的数据包目的端口;
    -j<目标>: #指定要跳转的目标;
    -i<网络接口>:   #指定数据包进入本机的网络接口;(只能用于:PREROUTING,INPUT,FORWARD链)
    -o<网络接口>:   #指定数据包要离开本机所使用的网络接口。(只能用于:FORWARD,OUTPUT,POSTROUTING链)

iptables命令选项输入顺序:

iptables -t 表名 [-A|I|D|R] 规则链名 [规则号] [-i|o 网卡名] -p 协议名 [-s 源IP/源子网] --sport 源端口 [-d 目标IP/目标子网] --dport 目标端口 -j 动作

表名包括:( -t )

    raw:    #高级功能,如:网址过滤。(包含 PREROUTING,OUTPUT链)
    mangle: #数据包修改,用于实现服务质量(QoS),(包含 PREROUTING,FORWARD,INPUT,OUTPUT,POSTROUTING链)
    nat:    #地址转换,用于网关路由器,(包含 PREROUTING,OUTPUT,POSTROUTING链)
    filter: #包过滤,用于防火墙规则,(包含 INPUT,OUTPUT,FORWARD链)

内置规则链名包括:

    INPUT链: #处理输入数据包。
    OUTPUT链:    #处理输出数据包。
    PORWARD链:   #处理转发数据包。
    PREROUTING链:    #用于目标地址转换(DNAT)。
    POSTOUTING链:    #用于源地址转换(SNAT)。

动作包括:

    ACCEPT: #接收数据包。
    DROP:   #丢弃数据包。
    RETURN  #防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)中。
    REJECT: #拦截数据包,并可以指定返回值(目标主机不可到达,tcp-reset 关闭连接 等)。
    --reject-with [ tcp-restet | net-unreach | host-unreach | icmp-net-unreachable 等]

    REDIRECT:   #端口重定向、映射、透明代理。
    MARK:   #做防火墙标记
    SNAT:   #源地址转换。
    DNAT:   #目标地址转换。
    LOG:    #日志记录。
    --log-level 
    --log-prefix "da"   #在日志里加个da前缀,方便查看(/var/log/message)
    --log-ip-options    

    MASQUERADE: #IP伪装(NAT),用于ADSL。
    自定义链:

iptables常规用法(不指定,默认是filter表)(防火墙匹配是按序号进行匹配的)

    iptalbes -t filter -L   #查看filter表的规则
    iptalbes -t filter -L INPUT #查看filter表里INPUT链的规则
    iptalbes -L -nv #查看规则,带有地址和端口的输出

    iptables -L -n --line-numbers   #将所有iptables以序号标记显示,执行
    iptables -D INPUT 7     #删除INPUT里序号为7的规则
    iptables -t filter -P FORWARD DROP  #将filter表里的FORWARD链的默认策略改成拒绝
    iptables -t filter -R INPUT 2 -p icmp -j DROP   #将第二条规则,修改为丢弃icmp

    iptables -I INPUT -s 192.168.1.2/32 -j DROP #(插入一个规则,默认是最前面,变成1)屏蔽单个IP
    iptables -I INPUT 5 -s 10.20.20.0/24 -j DROP    #(在第5条规则后,插入一个规则)屏蔽某个段的IP
    iptables -t filter -R INPUT 2 -p icmp -j DROP   #将第二条规则,修改为丢弃icmp

    iptables -t filter -A INPUT -p icmp -j REJECT --reject-with host-unreach    #当有ping包到达时,返回主机不可达
    iptables -F #清空规则
    iptables -Z #清空计数器

    #注意,可以禁止本地网络访问www.baidu.com网站(注意,iptables会将其设置为禁止该域名解析的IP,若是不存在的解析则会添加失败)
    iptables -I OUTPUT -d www.baidu.com -j DROP

    自定义链的应用(注意:需要定义默认规则,或则返回规则)
    iptables -t filter -N ICMP      #创建自定义链
    iptables -t filter -E ICMP IN-ICMP  #重命名自定义链为IN-ICMP
    iptables -t filter -p icmp --icmp-type 8 -j ACCEPT  #为自定义IN-ICMP链添加规则
    iptables -t filter -A INPUT -j IN-ICMP  #将自定义IN-ICMP链依附于内置链INPUT上,(只有依附后才会生效)
    iptables -t filter -A IN-ICMP -j RETURN #若是自定义规则链未匹配到数据,或则链里没有规则,即使用依附的内置链的默认策略

使用扩展匹配选项 -m 选项介绍

    -m state    #实现基于状态检测的包过滤,指定检测哪种状态,(根据"连接追踪机制"去检查连接的状态)
        --state{NEW, ESTATBLISHED,INVALID,RELATED}
        {新会话,已经建立的会话,非法的会话(不确定的会话),相关会话(多通道协议ftp,h323)}

        #查看当前连接追踪功能,能够容纳的最大连接数量(我的centos6.9好像没有这个文件)
        cat /proc/net/nf_conntrack_max
        #查看已经追踪到并已经记录下来的连接
        cat /proc/net/nf_conntrack

        优化:增大连接追踪记录数量
        vi /etc/sysctl.conf
        net.nf_conntrack_max = 393216
        net.netfilter.nf_conntrack_max = 393216
        #使其修改生效
        sysctl -p

    -m icmp     #指定icmp类型
        --icmp-type{echo-request,echo-reply}    #前者类型为8(发送方发出的),后者类型为0(接收方返回的)

    -m iprange  #指定连续的ip地址范围,(但一般不用于整个网段)
        --src-range ip-ip
        --dst-range ip-ip

    -m multiport    #指定多端口号
        --sports
        --dports
        --ports

    -m limit    #限速,平均每秒,每分钟,每小时或则每天平均一次多少个包允许通过
        --limit 300/{second,minute,hour,day}
        --limit-burst 5     #指定瞬时流量(说明若是同时涌入超过5个数据包,超过的包将直接丢弃)(通常与 --limit 连用)

    -m mac 
        --mac-source  #用来限定源mac地址(注意:这个参数不能用在OUTPUT,POSTROUTING链中)

    -m connlimit    #限定连接数
        --connlimit-upto 2  #指定连接的数量小于等于2时,匹配
        --connlimit-above 5 #指定连接的数量大于5时,匹配

    -m length   #指定数据包长度,单位字节
        --length 1178

    -m string   #对报文中的应用层数据做字符串模式匹配检测
        --algo [bm|kmp]     #必须指定,字符串匹配
        --string 'sd'       #指定要检查的字符串为sd(当字符串为中文时,要先转码为UTF-8)
        --hex-string 'sd'   #指定要检测的字符串模式,16进制格式
        --from 40       #设置'起始'偏移位置,这里设为'起始偏移40',默认是0
        --to 57         #设置'结束'偏移位置

    -m time     #根据时间段限定
        --timestart 14:30   #每天的14:30开始
        --timestop 18:30    #每天的18:30结束
        --weekdays Sat,Sun  #每周的那几天(Mon,Tue,Wed,Thu,Fri,Sat,Sun)
        --monthdays 2:15,19 #每月的2到15号和19号
        --kerneltz      #使用内核上正在使用的时区(而不是使用默认的UTC时区)

扩展匹配选项 -m 的常见应用方式,和实现的功能

linux作为路由器时,不允许,源IP为192.168.31.110,向目的IP为192.168.1.25的主机发起连接(但是没有限制后者向前者发起连接)
    iptables -t filter -I FORWARD -s 192.168.31.110/32 -d 192.168.1.25/24 -m state --state NEW -j DROP

linux作为服务器时,不允许,向目的地址为192.168.31.110的主机发起会话连接
    iptables -t filter -I OUTPUT -d 192.168.31.110/32 -m state --state NEW -j DROP

拒绝192.168.10.0/24的主机ping通 192.168.80.0/24 段的主机
    iptables -t filter -I FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -p icmp -m icmp --icmp-type echo-request -j DROP

禁止其他计算机ping本地linux
    iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8 -j DROP

拒绝192.168.10.0/24 访问192.168.80.0/24的 1-1024还有3389端口
    iptables -t filter -I FORWARD -p tcp -s 192.168.10.0/24 -d 192.168.80.0/24 -m multiport --dports 1:1024,3389 -j DROP

禁止 192.168.1.2-192.168.1.10这些个地址访问 服务器的80端口
    iptables -t filter -A FORWARD -p tcp --dport 80 -m iprange --src-range 192.168.1.2-192.168.1.10 -j DROP

192.168.10.0/24网段每秒钟向192.168.80.0/24发送数据包不能超过300个(PS:按每个数据包1500字节算,1500*300=450000=450K)
    iptables -t filter -I FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -m limit --limit 300/second -j ACCEPT
    iptables -t filter -A FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -j DROP

允许192.168.10.2/32 ping 主机 192.168.80.2/32 4个包
    iptables -t filter -I FORWARD -s 192.168.10.2/32 -d 192.168.80.2/32 -p icmp -m limit --limit-burst 4 -j ACCEPT
    iptables -t filter -A FORWARD -s 192.168.10.2/32 -d 192.168.80.2/32 -p icmp -j DROP

拒绝源mac地址为00-0c-29-db-32-6f 的数据包访问 192.168.80.0/24
    iptables -t filter -I FORWARD -d 192.168.80.0/24 -m mac --mac-source 00-0c-29-db-32-6f -j DROP

限定192.168.10.2主机不允许与192.168.80.2发起 超过2个远程桌面连接,(默认策略是允许)
    iptables -t filter -I FORWARD -s 192.168.10.2/32 -d 192.168.80.2/32 -p tcp --dport 3389 -m connlimit --connlimit-above 2  -j DROP

当检测到出现'baidu'字符串时,进行拦截
    #iptables -t filter -I INPUT -p tcp --dport 80 -m string --algo bm --string 'baidu' -j REJECT
    iptables -t mangle -I INPUT -p tcp --dport 80 -m string --algo bm --string 'baidu' -j DROP

周日的下午2点半到6点半,拒绝源IP为192.168.1.2的主机访问服务的80端口
    iptables -t filter -A INPUT -s 192.168.1.2 --dport 80 -m time --timestart 14:30 --timestop 18:30 --weekdays Sun --kerneltz -j DROP

linux服务器生产应用示例

1:保护服务器安全(基础版)

    #web服务器的80端口对所有开放,22端口只允许特定IP(192.168.31.112)访问,其他的拒绝
    iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT
    iptables -t filter -I INPUT -p tcp --dport 22 -s 192.168.31.112/32 -j ACCEPT
    iptables -t filter -A INPUT -j DROP

2:在一定时间内限制ssh客户端连接的次数(使用recent模块限制同IP时间内新请求连接数)

    ssh连接,一个客户端在60秒内只允许连接2次
    iptables -t filter -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --rcheck --seconds 60 --hitcount 2 -j DROP
    iptables -t filter -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --set -j ACCEPT
    iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT  #已经建立的连接,都允许

3:如何开放被动模式的FTP服务

    #装载ftp连接追踪的专业模块
    modprobe nf_conntrack_ftp

    #放行命令连接(假设Server地址为192.168.1.2)
    iptables -t filter -A INPUT -d 192.168.1.2 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
    iptables -t filter -A OUTPUT -s 192.168.1.2 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT

    #放行数据连接(假设Server地址为192.168.1.2)
    iptables -t filter -A INPUT -d 192.168.1.2 -p tcp -m state RELATED,ESTABLISHED -j ACCEPT
    iptables -t filter -I OUTPUT -m state --state ESTABLISHED -j ACCEPT

使用recent扩展模块实现服务器网络安全(这个模块很有趣,用的好可以充分保证您服务器安全)

    --name      #设定列表名称,默认是DEFAULT
    --resource  #源地址,此为默认
    --rdest     #目的地址
    --seconds   #指定时间内
    --hitcount  #命中次数
    --set       #将地址添加进列表,并更新信息,包含地址加入的时间戳
    --rcheck    #检查地址是否在列表,以第一个匹配开始计算时间
    --update    #和rcheck类似,以最后一个匹配开始计算时间
    --remove    #在列表删除相应地址,后跟列表名称及地址

4:防止SYN洪水攻击

    #限制TCP 80端口60秒内每个IP只能发起10个连接,超过记录日志及丢弃数据包,可防CC,及非伪造IP的syn flood
    iptables -t filter -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j LOG --log-prefix "DDos" --log-ip-options
    iptables -t filter -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j DROP
    iptables -t filter -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --set -j ACCEPT
    iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT  #已经建立的连接,都允许

5:设置打开ssh服务22端口的钥匙(使用指定大小的ICMP报文当钥匙)

#记录ping数据包大小为1078和1178的icmp请求,并记录日志,前缀分别是SSHOPEN和SSHCLOSE
    iptables -t filter -A INPUT -p icmp --icmp-type 8 -m length --length 1078 -j LOG --log-prefix "SSHOPEN"
    iptables -t filter -A INPUT -p icmp --icmp-type 8 -m length --length 1178 -j LOG --log-prefix "SSHCLOSE"

#指定数据包为1078字节,加入sshopen列表(其中包含IP头部 20字节,icmp头部 8字节)
    iptables -t filter -A INPUT -p icmp --icmp-type 8 -m length --length 1078 -m recent --set --name sshopen --rsource -j ACCEPT

#检查sshopen表中 60秒内的记录,如果有源地址则允许这个源地址访问TCP的22 端口
    iptables -t filter -A INPUT -p tcp --dport 22 --syn -m recent --rcheck --seconds 60 --name sshopen --rsource -j ACCEPT

#发送ping包指定数据包大小为1178字节,将客户端地址从sshopen表中移除,客户端将不能对TCP的22端口建立新的连接
    iptables -t filter -A INPUT -p icmp --icmp-type 8 -m length --length 1178 -m recent --name sshopen --remove -j ACCEPT

#已经建立的会话连接,就放行
    iptables -t filter -A INPUT -p icmp -j ACCEPT   #放行所有的icmp数据包,方便检

#查服务器存活情况
    iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT  #已经建立的连接,都允许

#将默认的入策略修改为拒绝
    iptables -t filter -P INPUT DROP

    #打开,允许连接ssh,这个会在ping指定大小的数据包后,60秒内,可以任意多次连接ssh
    #(ping时指定数据包大小,为什么是1050,因为他会自动加上 IP头20字节,和ICMP头8 字节,即1050+20+8=1078)
    ping -s 1050 192.168.1.55   #linux下操作 
    ping -l 1050 192.168.1.55   #windows下操作

    #关闭,不允许连接ssh(ping时指定数据包大小,为什么是1050,因为他会自动加上 IP头20字节,和ICMP头8 字节,即1050+20+8=1078)
    ping -s 1150 192.168.1.55   #linux下操作 
    ping -l 1150 192.168.1.55   #windows下操作

6:iptables过滤特定字符串数据流

拒绝带有qq.com这个字符串的流量
    iptables -t mangle -I INPUT -p tcp -m string --string "qq.com" --algo bm -j DROP

    #算法有两种
        --algo bm   #基础算法,常用
        --algo kmp  #高级算法,我还未研究怎么玩

7:iptabes 变相实现 对流量进行限速(限制的是数据包数量pps)

    #192.168.10.0/24网段每秒钟向192.168.80.0/24发送数据包不能超过300个(PS:按每个数据包1500字节算,1500*300=450000=450K)
    iptables -t filter -I FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -m limit --limit 300/second -j ACCEPT
    iptables -t filter -A FORWARD -s 192.168.10.0/24 -d 192.168.80.0/24 -j DROP

linux路由器常规示例

1:配置NAT表实现网络地址转换(在路由器的外网口出设置规则,NAT表,POSTROUTING链中)

    #外网口是eth0,在网卡的出方向进行源地址转换,可用源地址是公网IP地址192.168.20.10和11
    #需求:让内网192.168.10.0/24段的所有主机使用外网地址192.168.20.10和11上互联网.(-o 指定出站接口)
    iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j SNAT --to-source 192.168.20.10-192.168.20.11
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

    #开启内核转发
    cat /etc/sysctl.conf
    net.ipv4.ip_forward = 1

2:配置NAT表进行端口映射(应用与内网有服务器向公网提供服务时,NAT表,PREROUTING链中)

    #外网口是eth0,在入方向进行转换,目的地址是公网接口上的地址,内网服务器ip是192.168.10.10,内网提供80端口
    #需求:将边界地址192.168.20.10的80端口映射到内网192.168.10.10的80端口上,实现公网可以访问内网的web站点(-i 指定入站接口)
    iptables -t nat -A PREROUTING -i eth0 -d 192.168.20.10/32 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.10:80
    iptables -t nat -A POSTROUTING -d 192.168.10.10/32 -p tcp --dport 80 -j SNAT --to-source 192.168.20.10
    #iptables -t nat -A POSTROUTING -d 192.168.10.10/24 -j SNAT --to-source 192.168.20.10

3:使用mangle表 (应用于修改数据包的首部中的值)迷惑跟踪者

    #注意windows的ttl 默认是128,linux是64,过一个路由器,就减1
    --ttl-inc 1 #ttl加1
    --ttl-dec 2 #ttl减2
    --ttl-set 45    #直接将ttl修改为45

    #迷惑原理,在中途某台路由器上,TTL先加1再减1(这样就跟踪不到这台路由器了)
    #在数据包进入eth0之前,将ttl加1
    iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1

附:路由跟踪原理(收集沿途返回数据的IP地址,这就是转发数据的路由器)

    #第一种:发送ping包,逐渐加大ttl的值
        ping 120.206.184.10 -t 1    #能知道本地网关是谁,本地网关会返回ttl耗尽数据
        ping 120.206.184.10 -t 2    #能知道本地网关是谁,
        .......
        ping 120.206.184.10 -t 10   #假设当ttl为10是120.206.184.10正常返回数据,说明经过了10个路由器
声明:本文为原创,作者为 辣条①号,转载时请保留本声明及附带文章链接:https://boke.wsfnk.com/archives/108.html
谢谢你请我吃辣条谢谢你请我吃辣条

如果文章对你有帮助,欢迎点击上方按钮打赏作者

最后编辑于:2022/11/28作者: 辣条①号

现在在做什么? 接下来打算做什么? 你的目标什么? 期限还有多少? 进度如何? 不负遇见,不谈亏欠!

暂无评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

arrow grin ! ? cool roll eek evil razz mrgreen smile oops lol mad twisted wink idea cry shock neutral sad ???

文章目录