shell脚本实战案例---安全脚本

例题:自动化禁止恶意IP访问
        应用场景:防止恶意IP尝试ssh登录。---暴力破解密码
        脚本说明:将密码输入错误超过4次的IP地址通过iptables防火墙阻止访问。

目录

1.脚本分析:

【1】首先ssh登录之后,产生的日志文件是哪个,模拟暴力破解密码会有什么提示,我们约定输错密码超过4次算暴力破解

【2】我们如何容日志中取出暴力破解密码的客户端IP

【3】在生产环境中我们经常使用iptables,所以我们使用iptables封堵IP

2.脚本:

3.多次执行脚本之后,通过查看iptables列表,发现V1版本有bug:相同的IP和端口多次封堵

4..如何获取已经封堵IP

【1】从iptables -L -n 命令行入手

【2】从防火墙保存文件/etc/sysconfig/iptables入手

 5.改进脚本

【1】利用临时文件解决bug

【2】使用临时变量来解决bug

【3】使用临时数组来解决bug

6.测试结果:


1.脚本分析:

【1】首先ssh登录之后,产生的日志文件是哪个,模拟暴力破解密码会有什么提示,我们约定输错密码超过4次算暴力破解

[root@node11 ~]# mkdir -p /server/scripts
[root@node11 scripts]# tail /var/log/secure
Nov 12 02:12:10 node11 sshd[1504]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Nov 12 02:12:12 node11 sshd[1504]: Failed password for root from 192.168.111.13 port 38136 ssh2
Nov 12 02:12:13 node11 sshd[1499]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Nov 12 02:12:14 node11 sshd[1499]: Failed password for root from 192.168.111.12 port 52866 ssh2

由代码可知,产生日志的文件是/var/log/secure,提示为Failed password

【2】我们如何容日志中取出暴力破解密码的客户端IP

1.这是我们取出登录过这台服务器的客户端IP
[root@node11 scripts]# awk '/Failed password/ {IP[$(NF-3)]++} END {for (k in IP) print IP[k],k }' /var/log/secure 
5 192.168.111.21
6 192.168.111.12
6 192.168.111.13
1 192.168.111.50

2.这是我们取出输错密码超过4次的客户端IP
[root@node11 scripts]# awk '/Failed password/ {IP[$(NF-3)]++} END {for (k in IP) if (IP[k]>4) print k }' /var/log/secure 
192.168.111.21
192.168.111.12
192.168.111.13

【3】在生产环境中我们经常使用iptables,所以我们使用iptables封堵IP

准备:

[root@node11 scripts]# yum whatprovides iptables    # 查看iptables命令是由哪个软件包提供
[root@node11 scripts]# yum install -y iptables-services
[root@node11 scripts]# systemctl start iptables.service    # 启动之后,会出现默认规则
[root@node11 scripts]# iptables -L -n    # 列出当前iptables防火墙规则中的所有规则
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-
...
[root@node11 scripts]# iptables -F    # 清除iptables防火墙规则中的所有规则
[root@node11 scripts]# iptables -L -n    # 再次进行查看
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

iptables封堵IP:

[root@node11 scripts]# iptables -I INPUT -s 192.168.111.13 -p tcp --dport 22 -j DROP     
[root@node11 scripts]# service iptables save    # 保存规则
[root@node11 scripts]# iptables -L -n    # 再次查看,看看是否保存
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  192.168.111.13       0.0.0.0/0            tcp dpt:22
......         
[root@node11 scripts]# more /etc/sysconfig/iptables    # 也可以查看文件
# Generated by iptables-save v1.4.21 on Sun Nov 12 02:55:39 2023
*filter
:INPUT ACCEPT [266:16148]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [156:12788]
-A INPUT -s 192.168.111.13/32 -p tcp -m tcp --dport 22 -j DROP
COMMIT
# Completed on Sun Nov 12 02:55:39 2023

因为要不断的测试脚本,所以我们每操作完一项,就可以清除iptables防火墙规则中的所有规则,方便我们下次进行测试。

2.脚本:

[root@node11 scripts]# vim deny_ip_v1.sh
#!/bin/bash

awk '/Failed password/ {IP[$(NF-3)]++} END {for (k in IP) if (IP[k]>4) print k }' /var/log/secure > deny_ip

while read line
do
    iptables -I INPUT -s $line -p tcp --dport 22 -j DROP
done < deny_ip

service iptables save

rm -rf deny_ip

 进行测试:

[root@node11 scripts]# sh deny_ip_v1.sh 
[root@node11 scripts]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  192.168.111.13       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.12       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.21       0.0.0.0/0            tcp dpt:22
......        
[root@node11 scripts]# sh deny_ip_v1.sh     # 再次执行脚本
[root@node11 scripts]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  192.168.111.13       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.12       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.21       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.13       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.12       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.21       0.0.0.0/0            tcp dpt:22
......

3.多次执行脚本之后,通过查看iptables列表,发现V1版本有bug:相同的IP和端口多次封堵

解决思路:让封堵的IP和端口不再封堵

4..如何获取已经封堵IP

【1】从iptables -L -n 命令行入手

[root@node11 scripts]# iptables -L -n | tr -s " " | awk -F"[ :]" '$1=="DROP" && $NF=22 {print $4}' 
192.168.111.13
192.168.111.12
192.168.111.21
192.168.111.13
192.168.111.12
192.168.111.21

【2】从防火墙保存文件/etc/sysconfig/iptables入手

[root@node11 scripts]# awk -F"[ /]" '$11=22 && $NF=="DROP" {print $4}' /etc/sysconfig/iptables
192.168.111.13
192.168.111.12
192.168.111.21
192.168.111.13
192.168.111.12
192.168.111.21

 5.改进脚本

【1】利用临时文件解决bug

[root@node11 scripts]# vim deny_ip_v2.sh
#!/bin/bash

awk '/Failed password/ {IP[$(NF-3)]++} END {for (k in IP) if (IP[k]>4) print k }' /var/log/secure > deny_ip
iptables -L -n | tr -s " " | awk -F"[ :]" '$1=="DROP" && $NF=22 {print $4}' > block_ip

while read line
do
    if ! grep -qw $line block_ip
    then
        iptables -I INPUT -s $line -p tcp --dport 22 -j DROP
    fi
done < deny_ip

service iptables save

rm -rf deny_ip block_ip

【2】使用临时变量来解决bug

[root@node11 scripts]# vim deny_ip_v3.sh
#!/bin/bash

awk '/Failed password/ {IP[$(NF-3)]++} END {for (k in IP) if (IP[k]>4) print k }' /var/log/secure > deny_ip
block_ip=$(iptables -L -n | tr -s " " | awk -F"[ :]" '$1=="DROP" && $NF=22 {print $4}')

while read line
do
    if ! echo $block_ip | grep -qw $line
    then
        iptables -I INPUT -s $line -p tcp --dport 22 -j DROP
    fi
done < deny_ip

service iptables save

rm -rf deny_ip
unset block_ip

【3】使用临时数组来解决bug

[root@node11 scripts]# vim deny_ip_v4.sh
#!/bin/bash

awk '/Failed password/ {IP[$(NF-3)]++} END {for (k in IP) if (IP[k]>4) print k }' /var/log/secure > deny_ip
block_ip=($(iptables -L -n | tr -s " " | awk -F"[ :]" '$1=="DROP" && $NF=22 {print $4}'))

while read line
do
    if ! echo ${block_ip[@]} | grep -qw $line
    then
        iptables -I INPUT -s $line -p tcp --dport 22 -j DROP
    fi
done < deny_ip

service iptables save

rm -rf deny_ip
unset block_ip

6.测试结果:

[root@node11 scripts]# sh deny_ip_v2.sh 
[root@node11 scripts]# iptables -L -n 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  192.168.111.13       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.12       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.21       0.0.0.0/0            tcp dpt:22
......       
[root@node11 scripts]# sh deny_ip_v2.sh     # 再次执行
[root@node11 scripts]# iptables -L -n 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  192.168.111.13       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.12       0.0.0.0/0            tcp dpt:22
DROP       tcp  --  192.168.111.21       0.0.0.0/0            tcp dpt:22
......

生产环境中会结合计划任务进行

你可能感兴趣的:(shell,安全,服务器,网络,运维,linux)