前言:
日常系统运维工作中,经常性的需要开通系统内以及和第三方系统的防火墙,数量少可以直接登录到源服务器进行验证,数量一多就比较折腾,于是就弄了下批量验证防火墙的脚本。大概思路如下:
1.防火墙验证文件格式:源IP地址;目标IP地址;目标端口
2.SHELL脚本读取防火墙文件,循环取出源IP地址,目标IP地址和目标端口
3.执行ansible登录源IP地址服务器,执行telnet 命令,并将执行结果显示
4.查看最终验证结果
前提条件:
1.linux系统服务器,已安装ansible
2.部署脚本的服务器能ssh到需验证的源IP地址服务器
具体步骤如下:
1.设置ansible的hosts
## hosts文件:/etc/ansible/hosts-check-telnet
[test_hosts]
192.168.XX.XX
192.168.XX.XX
[test_hosts:vars]
ansible_ssh_user="root"
ansible_ssh_pass="password"
2.验证防火墙目录涉及文件:
check_telnet.sh
firewall.txt
result.log
telnet.yml
3.编辑需验证防火墙清单
firewall.txt
#格式样例:源IP地址,目标IP地址,目标端口
#实例:192.168.1.2,baidu.com,443
192.168.XX.XX,baidu.com,443
192.168.XX.XX,baidu.com,443
4.执行验证脚本
sh check_telnet.sh
5. 查看执行结果
cat result.log |grep msg
"msg": "源IP: 192.168.XX.XX 目标IP: baidu.com 目标端口:443 ,验证结果: 验证通过 "
"msg": "源IP: 192.168.XX.XX 目标IP: baidu.com 目标端口:443 ,验证结果: 不通 "
6. 相关脚本
telnet.yml
---
- hosts: all
remote_user: root
gather_facts: false
tasks:
- name: check telnet
shell:
cmd: 'echo -e "\n" | timeout --signal=9 3 telnet {{ target_ip }} {{ target_port }} | grep Connected | wc -l'
register: telnet_result
when: inventory_hostname == source_ip
- name: get telnet_result
debug:
msg: "源IP: {{ source_ip }} 目标IP: {{ target_ip }} 目标端口:{{ target_port }} ,验证结果: {{ '验证通过' if telnet_result.stdout_lines[0] == '1' else '不通' }} "
when: inventory_hostname == source_ip
check_telnet.sh
#!/bin/bash
# 获取当前执行文件所在目录
current_directory=$(dirname "$0")
check_telnet(){
for ip_port in $(cat $current_directory/firewall.txt|grep -v '^#')
do
source_ip=$(echo $ip_port|awk -F, '{print $1}')
target_ip=$(echo $ip_port|awk -F, '{print $2}')
target_port=$(echo $ip_port|awk -F, '{print $3}')
# echo "源IP地址是:$source_ip 目标IP地址是:$target_ip 目标端口是:$target_port "
ansible-playbook -i /etc/ansible/hosts-check-telnet -e source_ip=$source_ip -e target_ip=$target_ip -e target_port=$target_port $current_directory/telnet.yml
done
}
check_telnet >$current_directory/result.log
7.优化
优化了下,shell脚本直接调用ansible,并根据ansible执行的结果来判断防火墙是否是通的,并输出结果,check_telnet.sh脚本如下:
#!/bin/bash
# 获取当前执行文件所在目录
current_directory=$(dirname "$0")
check_telnet(){
for ip_port in $(cat $current_directory/firewall.txt|grep -v '^#')
do
source_ip=$(echo $ip_port|awk -F, '{print $1}')
target_ip=$(echo $ip_port|awk -F, '{print $2}')
target_port=$(echo $ip_port|awk -F, '{print $3}')
#执行telnet.yml脚本来验证
#ansible-playbook -i /etc/ansible/hosts-check-telnet -e source_ip=$source_ip -e target_ip=$target_ip -e target_port=$target_port telnet.yml
#优化成直接执行ansible,并根据执行结果判断
output=$( ansible -i /etc/ansible/hosts-check-telnet $source_ip -m shell -a "echo -e '\n' | timeout --signal=9 3 telnet $target_ip $target_port | grep Connected | wc -l")
#根据ansible执行结果来输出防火墙是否验证通
#echo "执行telnet结果: $output"
#方法1:根据output返回的信息来判断防火墙是否验证通过
if [[ $output =~ "Connection closed by foreign host" ]]; then
echo "源IP地址:$source_ip 目标IP地址:$target_ip 目标端口:$target_port 验证通过"
elif [[ $output =~ "Connection refused" ]]; then
echo "源IP地址:$source_ip 目标IP地址:$target_ip 目标端口:$target_port 验证返回refused,请检查目标服务器的端口服务是否开启"
else
echo "源IP地址:$source_ip 目标IP地址:$target_ip 目标端口:$target_port 验证不通"
fi
#方法2:获取执行结果的第二行第一个字符,即wc -l的结果,如果为1,则验证通过,其他为不通过
#first_char=""
#first_char=$(echo "$output" | awk 'NR==2{print substr($0,1,1)}')
#if [[ $first_char -eq "1" ]]; then
# echo "源IP地址:$source_ip 目标IP地址:$target_ip 目标端口:$target_port 验证通过"
#else
# echo "源IP地址:$source_ip 目标IP地址:$target_ip 目标端口:$target_port 验证不通"
#fi
done
}
check_telnet