如何筛选出DNS中活动的主机记录?

Bash

1 前言

一个问题,一篇文章,一出故事
由于生产的服务器需要使用谷歌或华为推送,但是DNS解析出来的IP部分被连接因此通讯异常,于是产生使用shell脚本筛选DNS解析记录的想法,于是整理此章节。

2 最佳实践

2.1 安装脚本依赖的软件包

dnf install -y bind-utils nc

2.2 创建脚本

mkdir ~/scripts/
vim ~/scripts/checkSers.sh

加入如下代码,

#!/bin/bash

# 定义多个域名
checkSers=("fcm.googleapis.com" "api.push.hicloud.com")
hostsFile="/etc/hosts"
checkPort="443"
logFile="/var/log/checkSers.log"
checkPortTool="netcat"  # 可以设置为 "ncat" 或 "netcat"

# 创建日志文件,如果不存在
if [ ! -f "$logFile" ]; then
    touch "$logFile"
fi

# 遍历每个域名
for checkSer in "${checkSers[@]}"; do
    # 获取当前的 IP 地址列表
    if ! mapfile -t currentControllers < <(nslookup "$checkSer" | awk '/^Address: / { print $2 }'); then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - nslookup failed for $checkSer" >> "$logFile"
        continue
    fi

    # 获取现有的 IP 地址列表
    mapfile -t existingIPs < <(grep " ${checkSer}" "$hostsFile" | awk '{ print $1 }')

    # 找到并删除多出的 IP 地址
    for ip in "${existingIPs[@]}"; do
        if [[ ! " ${currentControllers[@]} " =~ " $ip " ]]; then
            sed -i "/$ip $checkSer/d" "$hostsFile"
            echo "$(date '+%Y-%m-%d %H:%M:%S') - Removed $ip $checkSer from $hostsFile" >> "$logFile"
        fi
    done

    # 遍历当前控制器 IP
    for ip in "${currentControllers[@]}"; do
        # 检查端口是否响应
        status=2
        if [[ "$checkPortTool" == "ncat" ]]; then
            ncat -v -w 5 "$ip" "$checkPort" < /dev/null
            status=$?
        elif [[ "$checkPortTool" == "netcat" ]]; then
            nc -z -w 5 "$ip" "$checkPort"
            status=$?
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') - Invalid checkPortTool value: $checkPortTool" >> "$logFile"
            continue
        fi

        if [[ $status -eq 0 ]]; then
            if ! grep -q "$ip $checkSer" "$hostsFile"; then
                echo "$ip $checkSer" >> "$hostsFile"
                echo "$(date '+%Y-%m-%d %H:%M:%S') - Added $ip $checkSer to $hostsFile" >> "$logFile"
            fi
        elif [[ $status -eq 1 ]]; then
            if grep -q "$ip $checkSer" "$hostsFile"; then
                sed -i "/$ip $checkSer/d" "$hostsFile"
                echo "$(date '+%Y-%m-%d %H:%M:%S') - Removed $ip $checkSer from $hostsFile" >> "$logFile"
            fi
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') - Port check failed for $ip $checkSer with status $status" >> "$logFile"
        fi
    done
done

2.2 测试脚本

 bash ~/scripts/checkSers.sh

2.3 配置脚本触发

crontab -e

加入如下触发脚本设置,

*/2 * * * * bash ~/scripts/checkSers.sh

2.4 用于测试AD的389端口时

vim ~/scripts/checkSers.sh

修改如下代码,

            #ncat -v -w 5 "$ip" "$checkPort" < /dev/null
            ncat -z -w 5 "$ip" "$checkPort" < /dev/null
没有评论

发表回复

Bash
如何根据条件输出MySQL表Insert行?

1 前言 一个问题,一篇文章,一出故事。 笔者执行NextCloud的维护任务,需要从数据表中删除用 …

Bash
如何函数代替Base Shell的命令别名?

1 前言 一个问题,一篇文章,一出故事。 之前的章节我们使用命令别名来缩写输入的命令,相见如下, 如 …

Bash
如何监视服务并自动通知?

1 前言 一个问题,一篇文章,一出故事。 最近笔者希望通过脚本实现监视服务并在服务异常是使用两种方式 …