iptables

一、四表五链理论

iptables 其实是多个表(table)的容器,每个表里包含不同的链(chain),链里边定义了不同的规则(policy),我们通过定义不同的规则,来控制数据包在防火墙的进出。

1、四表

filter表——过滤数据包
Nat表——用于网络地址转换(IP、端口)
Mangle表——修改数据包的服务类型、TTL、并且可以配置路由实现QOS
Raw表——决定数据包是否被状态跟踪机制处理

2、五链

INPUT链——进来的数据包应用此规则链中的策略
OUTPUT链——外出的数据包应用此规则链中的策略
FORWARD链——转发数据包时应用此规则链中的策略
PREROUTING链——对数据包作路由选择前应用此链中的规则(所有的数据包进来的时侯都先由这个链处理)
POSTROUTING链——对数据包作路由选择后应用此链中的规则(所有的数据包出来的时侯都先由这个链处理)

每一条链其实就是众多规则中的一个检查清单,每一条链中可以有一条或数条规则。当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据 该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。

3、表包含的链路

Filter 是默认的主机防火墙,过滤流入流出主机的数据包。里边包含INPUT,OUTPUT,FOWARD三个链

INPUT 过滤进入主机的数据包

OUTPUT 处理从本机发出去的数据包

FOWARD 处理流经本主机的数据包,与NAT有关系

Filter表是企业实现防火墙功能的重要手段

NAT  负责网络地址转换(来源于目的地址的IP与端口的转换),一般用于局域网的共享上网,与网络交换机acl类似,包含OUTPUT,PREROUTING,POSTROUTING三条链

OUTPUT 改变主机发出去的数据包的目标地址

PREROUTING 数据包到达防火墙时进行分路由判断之前执行的规则,改变数据包的目的地址,目的端口

POSTROUTING 数据包离开防火墙时进行分路由判断之前执行的规则,改变数据包的源的地址,源的端口

mangle 表的系统 chain: PREROUTING,OUTPUT

二、常用设置

1、放行ssh端口:

  1 iptables -A INPUT -p tcp –dport 22 -j ACCEPT
  2 iptables -A OUTPUT -p tcp –sport 22 -j ACCEPT

注:/etc/rc.d/init.d/iptables save,否则直接执行service iptables restart命令后, 刚才添加的将丢失.

2、解决iptables导致的脑裂问题

  1 iptables -A INPUT -i lo -j ACCEPT  允许来自于lo接口的数据包
  2 iptables -A OUTPUT -o lo -j ACCEPT  允许向lo接口发送数据包
  3 iptables  -A INPUT -s 192.168.1.0/24 -d 224.0.0.18 -j ACCEPT       #允许组播地址通信
  4 iptables  -A INPUT -s 192.168.1.0/24 -p vrrp -j ACCEPT       #允许VRRP(虚拟路由器冗余协)通信

lo 是 loopback 的缩写,也就是环回地址网卡,linux主机向自身发送数据包时,实际上的数据包是通过虚拟的lo接口来发送接受的,而不会通过你的物理网卡 eth0/eth1。

3、利用iptables将目的地址为192.168.1.189的80端口的数据包更改目的地址为内网机器的IP1.1.1.2,目的端口为80.

iptables -t nat -A PREROUTING -d 192.168.1.189 -p tcp --dport 80 -j DNAT --to-destination 1.1.1.2:80

iptables -t nat -A PREROUTING -d 192.168.1.189 -j DNAT --to-destination 1.1.1.2   将所有流量转发到内网主机

4、iptables命令选项介绍

-t  : 对指定的table进行操作。raw,nat,filter,mangle中的一个。默认是filter。

-A :追加防火墙规则

-D :删除规则

-I :插入规则

-F: 清空规则

-L :列出规则

-R:替换规则

-Z:清空计数

-P: 设置链默认规则

-N:创建新链

-X:删除用户自定义引用计数为0的空链

-E:自定义链重命名

-S: 列出选定链的规则

-n              # 以数字形式显示地址和端口
-v              # 在打印规则时显示详细信息
--line-numbers  # 在打印规则时显示规则序号

###反向匹配
# 只需在选项前面使用 ! 即可,如: ! -s 192.168.0.0/16 表示除 192.168/16 外的源 IP

-p:匹配协议 {tcp|udp|udplite|icmp|icmpv6|esp|ah|sctp|mh|all}  # 指定匹配的协议,all 表示所有

-s: 匹配源地址   # 源 IP,可以有多个,使用逗号隔开,有多少个地址就有多少条规则

-d:匹配目的地址   目的 IP,可以有多个,使用逗号隔开,有多少个地址就有多少条规则

-i: 匹配入站网卡地址

-o:匹配出站网卡地址

--sport: 匹配源端口

--dport:匹配目的端口

-j :满足某条件时执行什么样的动作。

触发动作:

​   ACCEPT  :允许数据包通过

​   DROP        :丢弃数据包

​   REJECT      :拒绝数据包通过

​   LOG     :将数据包信息记录syslog日志

​   DNAT    :目的地址转换

​   SNAT    :源地址转换

​   MASQUERADE :地址欺骗

​   REDIRRECT   :重定向

 如  iptables -S -t nat

-S: 列出选定链的规则-t : 对指定的table进行操作。raw,nat,filter,mangle中的一个。默认是filter

5、禁止、放行ip

要封停一个IP(-I :插入规则)

iptables  -I  INPUT  -s  IP地址  -j  DROP

要解封一个IP(-D :删除规则)

iptables  -D  INPUT  -s  IP地址  -j  DROP

三、iptables脚本

脚本1

# vim iptables.sh
#!/bin/bash

#清空 filter 表和 nat 表
iptables -F
iptables -t nat -F

#关掉 firewalld
systemctl stop firewalld &>/dev/null
systemctl disable firewalld &>/dev/null

#以下两行允许某些调用 localhost 的应用访问
iptables -A INPUT -i lo -j ACCEPT #规则1
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT #规则2

#以下一行允许从其他地方 ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT #规则3

#以下一行允许从其他主机、网络设备发送 MTU 调整的报文
#在一些情况下,例如通过 IPSec VPN 隧道时,主机的 MTU 需要动态减小
iptables -A INPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT #规则4

#以下两行分别允许所有来源访问 TCP 80,443 端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT #规则5
iptables -A INPUT -p tcp --dport 443 -j ACCEPT #规则6

#以下一行允许所有来源访问 UDP 80,443 端口
iptables -A INPUT -p udp -m multiport --dports 80,443 -j ACCEPT #规则7

#以下一行允许 192.168.1.63 来源的 IP 访问 TCP 22 端口(OpenSSH)
iptables -A INPUT -p tcp -s 192.168.1.63 --dport 22 -j ACCEPT #规则8

#以下一行允许 192.168.1.3(发起SSH连接的系统对应网卡的IP) 来源的 IP 访问 TCP 22 端口(OpenSSH)
#如果是在远程终端跑本脚本,最好开启以下一行以防被踢掉
#另一种更加简便的方式:iptables -I INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.1.3 --dport 22 -j ACCEPT #规则9

#以下一行允许 192.168.1.26 来源的 IP 访问 UDP 161 端口(SNMP)
iptables -A INPUT -p udp -s 192.168.1.26 --dport 161 -j ACCEPT #规则10

#配置 NAT
#启用内核路由转发功能
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.conf
sysctl -p &>/dev/null

#配置源地址转换 SNAT
#将 192.168.2.0/24 转换成 192.168.1.63
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j SNAT --to 192.168.1.63 #规则11

#配置目的地址转换 DNAT
#将 192.168.1.63 的 80 端口请求转发到 192.168.2.2 的 80 端口
iptables -t nat -A PREROUTING -d 192.168.1.63 -p tcp --dport 80 -j DNAT --to 192.168.2.2:80 #规则12

我们期望10.0.10.62为用户访问目标,而不是web服务192.168.0.110,但62上是没有web服务的,所以有人访问62的web服务必须将其转换到110上
iptables -t nat -A PREROUTING -d 10.0.10.62 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.110

#以下一行禁止所有其他的进入流量
iptables -A INPUT -j DROP #规则13

#以下一行允许本机响应规则编号为 1-12 的数据包发出
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT #规则14

#以下一行禁止本机主动发出外部连接
iptables -A OUTPUT -j DROP #规则15

#以下一行禁止本机转发数据包
iptables -A FORWARD -j DROP #规则16

#固化 iptables
iptables-save > /etc/sysconfig/iptables

脚本2

#!/bin/bash
#先允许
iptables -P INPUT ACCEPT

#清除规则
iptables -F
#清除用户自定义规则

iptables -X
#清除链的计数器

iptables -Z
#开启回环网络
iptables -A INPUT -i lo -j ACCEPT && iptables -A OUTPUT -o lo -j ACCEPT

#允许ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT 
iptables -A OUTPUT -p icmp --icmp-type  echo-reply  -j  ACCEPT

#允许2-7访问
iptables -A INPUT -p tcp -m iprange --src-range 192.168.202.2-192.168.202.7  -j ACCEPT

#允许163-168访问22端口(ssh连接)
iptables -A INPUT -p tcp -m iprange --src-range 137.64.70.163-137.64.70.168 --dport 22 -j ACCEPT

#4A地址
iptables -A INPUT -p tcp -m iprange --src-range 137.64.35.151-137.64.35.156 -j ACCEPT

#只允许主机共享rpc服务
iptables -A INPUT -p tcp -m iprange --src-range 192.168.202.2-192.168.202.7 --dport 111 -j
 ACCEPT

#只允许主机访问es
iptables -A INPUT -p tcp -m iprange --src-range 192.168.202.2-192.168.202.7 --dport 9200 -j ACCEPT

#允许主机访问2375端口
iptables -A INPUT -p tcp -m iprange --src-range 192.168.202.2-192.168.202.7 --dport 2375 -j ACCEPT

#只在164执行
iptables -A INPUT -p tcp -m iprange --src-range 137.64.76.179 --dport 28081 -j ACCEPT

#开发8080端口(只在164执行)
iptables -A INPUT -p tcp  --dport 8080 -j ACCEPT

#在屏蔽
iptables -P INPUT DROP

#所有出站一律绿灯
iptables -P OUTPUT ACCEPT

#所有转发一律丢弃
iptables -P FORWARD ACCEPT

#保存
iptables-save

四、iptables自动封查IP、解禁ip

iptables是采用数据包过滤机制工作的,所以它会对请求的数据包的包头数据进行分析,并根据我们预先设定的规则进行匹配来决定是否可以进入主机。

脚本1:# more nginx_ip.sh 

#!/bin/bash

. /etc/init.d/functions
conut=100 
Path=/usr/local/nginx/logs/access.log

function ipt(){ 
    awk  '{print $1}'$Path|sort|uniq -c|sort -rn >/tmp/tmp.log 
    exec < /tmp/tmp.log
    while read line
    do
        ip=echo $line|awk '{print $2}'
        if [ echo $line|awk '{print $1}' -ge $conut -a iptables -L -n|grep "$ip"|wc -l -lt 1 ]
        then
            iptables -I INPUT -s $ip -j DROP
            RETVAL=$?
            if [ $RETVAL -eq 0 ]
            then
                action "iptables -I INPUT -s $ip -j DROP" /bin/true
                echo "$ip" >>/tmp/ip_$(date +%F).log
            else
                action "iptables -I INPUT -s $ip -j DROP" /bin/false
            fi
        fi
    done
}
function del(){
[ -f /tmp/ip_$(date +%F -d '-1 day').log ]||{
    echo "log is not exist"
    exit 1} 
    exec </tmp/ip_$(date +%F -d '-1 day').log
    while read line
    do
        if [ iptables -L -n|grep "$line"|wc -l -ge 1 ]
        then
            iptables -D INPUT -s $line -j DROP
        fi
    done
}
function main(){
    flag=0
    while true
    do
        sleep 180
        ((falg++))
        ipt
        [ $flag -ge 480 ] && del && flag=0
    done
}
main

更好的方法:nginx+lua拦截IP,或者搭建软件防火强的方法。

脚本2:iptables自动屏蔽访问网站频繁的IP

场景:恶意访问,安全防范

1)屏蔽每分钟访问超过200的IP
方法1:根据访问日志(Nginx为例)
#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
ABNORMAL_IP=$(tail -n5000 access.log |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}')
#先tail防止文件过大,读取慢,数字可调整每分钟最大的访问量。awk不能直接过滤日志,因为包含特殊字符。
for IP in $ABNORMAL_IP; do
    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -I INPUT -s $IP -j DROP
    fi
done

方法2:通过TCP建立的连接
#!/bin/bash
ABNORMAL_IP=$(netstat -an |awk '$4~/:80$/ && $6~/ESTABLISHED/{gsub(/:[0-9]+/,"",$5);{a[$5]++}}END{for(i in a)if(a[i]>100)print i}')
#gsub是将第五列(客户端IP)的冒号和端口去掉
for IP in $ABNORMAL_IP; do
    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -I INPUT -s $IP -j DROP
    fi
done

2)屏蔽每分钟SSH尝试登录超过10次的IP
方法1:通过lastb获取登录状态:
#!/bin/bash
DATE=$(date +"%a %b %e %H:%M") #星期月天时分  %e单数字时显示7,而%d显示07
ABNORMAL_IP=$(lastb |grep "$DATE" |awk '{a[$3]++}END{for(i in a)if(a[i]>10)print i}')
for IP in $ABNORMAL_IP; do
    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -I INPUT -s $IP -j DROP
    fi
done

方法2:通过日志获取登录状态
#!/bin/bash
DATE=$(date +"%b %d %H")
ABNORMAL_IP="$(tail -n10000 /var/log/auth.log |grep "$DATE" |awk '/Failed/{a[$(NF-3)]++}END{for(i in a)if(a[i]>5)print i}')"
for IP in $ABNORMAL_IP; do
    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -A INPUT -s $IP -j DROP
        echo "$(date +"%F %T") - iptables -A INPUT -s $IP -j DROP" >>~/ssh-login-limit.log
    fi
done

脚本3:根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁

#!/bin/bash
####################################################################################
#根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁
####################################################################################
logfile=/data/log/access.log
#显示一分钟前的小时和分钟
d1=`date -d "-1 minute" +%H%M`
d2=`date +%M`
ipt=/sbin/iptables
ips=/tmp/ips.txt
block()
{
 #将一分钟前的日志全部过滤出来并提取IP以及统计访问次数
 grep '$d1:' $logfile|awk '{print $1}'|sort -n|uniq -c|sort -n > $ips
 #利用for循环将次数超过100的IP依次遍历出来并予以封禁
 for i in `awk '$1>100 {print $2}' $ips`
 do
 $ipt -I INPUT -p tcp --dport 80 -s $i -j REJECT
 echo "`date +%F-%T` $i" >> /tmp/badip.log
 done
}
unblock()
{
 #将封禁后所产生的pkts数量小于10的IP依次遍历予以解封
 for a in `$ipt -nvL INPUT --line-numbers |grep '0.0.0.0/0'|awk '$2<10 {print $1}'|sort -nr`
 do 
 $ipt -D INPUT $a
 done
 $ipt -Z
}
#当时间在00分以及30分时执行解封函数
if [ $d2 -eq "00" ] || [ $d2 -eq "30" ]
 then
 #要先解再封,因为刚刚封禁时产生的pkts数量很少
 unblock
 block
 else
 block
fi

五、shell知识补充(while读取文件)

while读取文件的方法

1、管道的方式

cat /tmp/a.log |while read LINE
do
    echo $LINE
done

2、重定向的方式(速度较快)

while read LINE
do
     echo $LINE
done < /tmp/a.log

3、文件描述符法

exec </tmp/a.log
 
while read line
do
    echo $line
done

https://blog.csdn.net/u011537073/article/details/82685586 

https://devopstack.cn/linux/871.html   Iptables 限制连接数(如SFTP) 以及 谨防CC/DDOS攻击的配置 ( connlimit模块)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塞北酒鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值