惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Palo Alto Networks Blog
D
Docker
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
Schneier on Security
Engineering at Meta
Engineering at Meta
I
InfoQ
L
LangChain Blog
Cyberwarzone
Cyberwarzone
T
Tenable Blog
WordPress大学
WordPress大学
P
Privacy & Cybersecurity Law Blog
罗磊的独立博客
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Jina AI
Jina AI
C
CERT Recently Published Vulnerability Notes
Scott Helme
Scott Helme
博客园 - 三生石上(FineUI控件)
酷 壳 – CoolShell
酷 壳 – CoolShell
Know Your Adversary
Know Your Adversary
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Last Watchdog
The Last Watchdog
Last Week in AI
Last Week in AI
Cloudbric
Cloudbric
S
SegmentFault 最新的问题
爱范儿
爱范儿
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 叶小钗
AI
AI
T
Tor Project blog
I
Intezer
T
Threatpost
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V
Visual Studio Blog
N
News and Events Feed by Topic
Latest news
Latest news
S
Security Affairs
博客园 - Franky
Microsoft Security Blog
Microsoft Security Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
B
Blog RSS Feed
C
Cybersecurity and Infrastructure Security Agency CISA
Hugging Face - Blog
Hugging Face - Blog
小众软件
小众软件
S
Securelist

有意

生活三两事(3) 基于 PVE 的折腾之路(4)之 影音库云盘自动化 基于 PVE 的折腾之路(3)之 影音库自动化 基于 PVE 的折腾之路(2)之 安装群晖 基于 PVE 的折腾之路(1)之 Proxmox VE 的安装配置 折腾nas ——TimeMachine(修改) 日常吐槽(1) 初次自己全责的交通事故 Docker 部署 macvlan 网络下的 qBittorrent
Openwrt的一些小折腾(5)
痞子鱼 · 2023-12-19 · via 有意

前言

距离上一次折腾 OpenWrt 已经 3 年了,这段时间里偶尔也会对家里网络环境做一些小改动,现在主路由只负责拨号、DDNS和 DHCP 服务,其他事情交给 PVE 上的 OpenWrt 来负责。所以,为了主路由的稳定,一些任务尽可能的避免安装插件,用脚本来代替。

更新 DnsPod 和 CloudFlare 并发送通知

根据 serverchan 这个插件,搞了个脚本来代替,主要就是路由重启或者网络重拨后发送一些系统状态和网络信息到 Telegram,然后再更新 ddns。

1、首先在 /etc/hotplug.d/iface 创建 30-ddns-go 给予 755 权限,会在 WAN 口 发生变化的时候实时运行 serverchan 脚本。

#!/bin/sh
# wan ifup
[ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ]

sh /usr/share/watchdog/serverchan 

2、在/usr/share/watchdog/ 创建 serverchan 给予 755 权限

设置了一个参数,在直接运行 /usr/share/watchdog/serverchan send,就会发送一次标题为路由运行状况通知,方便定时任务调用。

脚本运行顺序:

当 WAN 口发生变化,就运行 serverchan ,WAN 口运行时间是否小于 60,如果大于 60 就结束脚本;

否则就进行下一个判断,WAN 口距离上一次发生变化是否大于 60,如果小于 60 就结束脚本;

否则就更新 DDNS,并做一次判断系统运行时间是否小于 60,小于60 就发送标题为 路由器重新启动;

否则就发送标题为 IP 地址变动通知;

通知都包含系统状态和网络信息。

另外需要注意,脚本在获取 IPV6 时,只是截取了前缀,所以 $wan_ipv6::1 的 ::1 是代表 路由上的 IP,可以更改成其他设备固定后缀。

脚本需要提前获取 Telegram 的 token 和 chat_id。

#!/bin/bash

# 发送 Telegram 消息
send_telegram_message() {
    local message=$1
    curl -s -X POST https://api.telegram.org/bot<token>/sendMessage -d "chat_id=<chat_id>" --data-binary "chat_id=$CHAT_ID&text=$message"
}

# 获取系统状态信息
get_system_status_message() {
    load_average=$(cut -d ' ' -f 1-3 /proc/loadavg)
    cpu_usage=$(get_cpu_usage)
    memory_usage=$(free | awk '/Mem:/ {printf "%.2f%", $3/($3+$4)*100}')
    uptime=$(cat /proc/uptime | awk '{print int($1/3600/24) "天" int($1/3600%24) "时" int($1%3600/60) "分" int($1%60) "秒"}')
    wan_info=$(ifstatus wan | jq -r '.uptime' | awk '{print int($1/3600/24) "天" int($1/3600%24) "时" int($1%3600/60) "分" int($1%60) "秒"}')
    wan_ipv4=$(ip -4 addr show dev pppoe-wan | grep inet | awk '{print $2}' | cut -d '/' -f 1)
    wan_ipv6=$(ip addr show br-lan | grep inet6 | sed 's/\/.*//g' | awk '{print $2}' | grep 240e | head -n 1 | awk -F '::' '{print $1}')

    system_status_message="系统状态:
--------
平均负载:$load_average
CPU 占用:$cpu_usage
内存占用:$memory_usage
运行时间:$uptime
--------
网络信息:
外网 IPv4: $wan_ipv4
外网 IPv6: $wan_ipv6::1
在线时间:$wan_info"
}

# 获取 CPU 占用
get_cpu_usage() {
    local AT=$(cat /proc/stat | grep "^cpu " | awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}')
    sleep 3
    local BT=$(cat /proc/stat | grep "^cpu " | awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}')
    printf "%.01f%%" $(echo ${AT} ${BT} | awk '{print (($4-$2)/($3-$1))*100}')
}

# 发送通知的函数
send_notification() {
    local notification_message=$1
    get_system_status_message
    send_telegram_message "$notification_message
--------

$system_status_message"
}

# 获取系统运行时间,单位为秒
uptime_seconds=$(cut -d '.' -f 1 /proc/uptime)

# 获取 WAN 口运行时间,单位为秒
wan_uptime_seconds=$(ifstatus wan | jq -r '.uptime')

# 从临时文件中获取上一次 WAN 口变动的时间
last_wan_change_time_file="/tmp/last_wan_change_time.txt"

# 如果临时文件存在,则从文件中读取上一次 WAN 口变动的时间,否则设置为0
last_wan_change_time=$(test -f "$last_wan_change_time_file" && cat "$last_wan_change_time_file" || echo 0)

# 跟踪 WAN 口变动时间,并更新临时文件
track_wan_change_time() {
    date +%s > "$last_wan_change_time_file"
}

# 检查 WAN 口通知条件
check_wan_notification() {
    current_time=$(date +%s)
    time_since_last_wan_change=$((current_time - last_wan_change_time))
    if [ "$time_since_last_wan_change" -gt 60 ]; then
        if [ "$uptime_seconds" -lt 60 ]; then
            send_notification "路由器重新启动"
        else
            send_notification "IP 地址变动通知"
        fi
        #更新 DnsPod DDNS
        sh /usr/share/watchdog/dnspod-go
        #更新 CloudFlare DDNS
        sh /usr/share/watchdog/cloudflare-go
        #更新时间戳
        track_wan_change_time
    fi
}

# 判断 WAN 是否启动,并发送通知
if [ "$wan_uptime_seconds" -lt 60 ]; then
    check_wan_notification
elif [ "$1" = "send" ]; then
    send_notification "路由运行状况通知"
fi

3、在/usr/share/watchdog/ 创建 cloudflare-go 给予 755 权限

进入 CloudFlare 的主页 -> 左侧网站-> 点击需要设置的域名。在右侧下方看到 区域 ID (ZoneID),另外需要点击 API 令牌去获取 Token。

ZoneID

添加 A 记录和 AAAA 记录并获取域名ID

获取域名ID

#!/bin/bash

# 更新 DNS 记录
cf_update_dns() {
    local record_id="$1"
    local record_type="$2"
    local record_name="$3"
    local record_content="$4"
    wan_ipv4=$(ip -4 addr show dev pppoe-wan | grep inet | awk '{print $2}' | cut -d '/' -f 1)
    wan_ipv6=$(ip addr show br-lan | grep inet6 | sed 's/\/.*//g' | awk '{print $2}' | grep 240e | head -n 1 | awk -F '::' '{print $1}')

    curl -X PUT "https://api.cloudflare.com/client/v4/zones/区域 ID/dns_records/$record_id" \
        -H "X-Auth-Email: Cloudflare的邮箱" \
        -H "X-Auth-Key: API 令牌" \
        -H "Content-Type: application/json" \
        --data "{\"type\":\"$record_type\",\"name\":\"$record_name\",\"content\":\"$record_content\",\"proxied\":false}"
}

# 更新 IPv4 地址的 DNS 记录
cf_update_dns "域名ID" "A" "test1.xxxnas.top" "$wan_ipv4"


# 更新 IPv6 地址的 DNS 记录
cf_update_dns "域名ID" "AAAA" "test2.xxxnas.top" "$wan_ipv6::1"

4、在/usr/share/watchdog/ 创建 dnspod-go 给予 755 权限

进入 dnspod 控制台 -> 我的域名

获取域名ID

点击域名进去,获取记录 ID,

记录 ID

获取 DNSPod TOKEN,然后将 下面的 LOGIN_TOKEN 替换成 222222,111111*0222222

DNSPod Token

#!/bin/bash

# 更新 DNS 记录函数
dp_update_dns() {
    local record_type=$1
    local sub_domain=$2
    local record_id=$3
    local value=$4
    wan_ipv4=$(ip -4 addr show dev pppoe-wan | grep inet | awk '{print $2}' | cut -d '/' -f 1)
    wan_ipv6=$(ip addr show br-lan | grep inet6 | sed 's/\/.*//g' | awk '{print $2}' | grep 240e | head -n 1 | awk -F '::' '{print $1}')

    local record_url="https://dnsapi.cn/Record.Modify"
    local record_params="login_token=LOGIN_TOKEN&format=json&domain_id=domain_id&record_id=$record_id&value=$value&record_type=$record_type&sub_domain=$sub_domain&record_line_id=0"

    curl -k -X POST "$record_url" -d "$record_params"
}


# 更新 IPv4 DNS 记录
dp_update_dns A "test1" "记录ID" $wan_ipv4


# 更新 IPv6 DNS 记录
dp_update_dns AAAA "test2" "记录ID" "$wan_ipv6::1"

网络故障重启网络和重启路由

另外还对上次的监控网络状态脚本做了一点小调整,连续重启 wan 口和路由两次还网络故障的话,更改检测间隔时间为 600 秒。不过根据最近的观察,觉得应该不是网络问题,而是弱电箱的电源功率不够导致的路由死机,所以也得考虑是否更换个电源来测试下。

#!/bin/sh

# 日志默认目录
LOG_DIR="/usr/share/watchdog"
# 连续计数
NETWORK_CHECK_COUNTER_FILE="${LOG_DIR}/network-counter.log"
# 执行日志
NETWORK_CHECK_LOG_FILE="${LOG_DIR}/network-check.log"
# 默认计数为0
COUNTER=0

# 连续失败计数大于该数值,则进行 RESTART_INTERVAL 秒等待,再执行重新检测
COUNTER_THRESHOLD=4
# 持续失败,后默认等待时间(秒),然后再重启
RESTART_INTERVAL=600

# 检查目录是否存在,不存在则创建
if [ ! -d "$LOG_DIR" ]; then
    echo "Creating directory $LOG_DIR"
    mkdir -p "$LOG_DIR"
fi

# 检查文件是否存在,如果不存在则创建文件
touch "$NETWORK_CHECK_LOG_FILE"

if [ ! -e "$NETWORK_CHECK_COUNTER_FILE" ]; then
    touch "$NETWORK_CHECK_COUNTER_FILE"
    echo "0" > "$NETWORK_CHECK_COUNTER_FILE"
fi
COUNTER=$(cat "$NETWORK_CHECK_COUNTER_FILE")

# 检测网络是否畅通
ping_domain() {
    # ping的域名或者DNS
    local domain="223.5.5.5"
    # ping的次数
    local tries=6
    # 请求成功次数
    local packets_responded=0

    for i in $(seq 1 "$tries"); do
        if ping -c 1 "$domain" >/dev/null; then
            packets_responded=$((packets_responded + 1))
            sleep 1
        fi
    done

    # 如果请求成功总次数大于等于2,则表示成功
    if [ "$packets_responded" -ge 2 ]; then
        echo "true"
    else
        echo "false"
    fi
}

# 检测网络连接函数
check_network() {
    # 如果ping 6次至少有2次包未响应,则执行以下代码
    if [ "$(ping_domain)" = "false" ]; then
        # 如果无法连接网络,则重启网络
        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接失败"
        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接失败" >> "$NETWORK_CHECK_LOG_FILE"

        /etc/init.d/network restart

        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络服务已重启"
        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络服务已重启" >> "$NETWORK_CHECK_LOG_FILE"
        echo "$(( $(cat "$NETWORK_CHECK_COUNTER_FILE") + 1 ))" > "$NETWORK_CHECK_COUNTER_FILE"

        sleep 60

        if [ "$(ping_domain)" = "false" ]; then
            # 如果仍无法连接网络,则重启路由服务
            echo "$(date '+%Y-%m-%d %H:%M:%S') 重启网络后,联网失败,准备重启路由"
            echo "$(date '+%Y-%m-%d %H:%M:%S') 重启网络后,联网失败,准备重启路由" >> "$NETWORK_CHECK_LOG_FILE"
            echo "$(( $(cat "$NETWORK_CHECK_COUNTER_FILE") + 1 ))" > "$NETWORK_CHECK_COUNTER_FILE"

            /sbin/reboot

        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') 重启路由后,连接已恢复"
            echo "$(date '+%Y-%m-%d %H:%M:%S') 重启路由后,连接已恢复" >> "$NETWORK_CHECK_LOG_FILE"
        fi
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接正常"
        echo "$(date '+%Y-%m-%d %H:%M:%S') 网络连接正常" >> "$NETWORK_CHECK_LOG_FILE"
        echo "0" > "$NETWORK_CHECK_COUNTER_FILE"
    fi
}

# 计数器检查函数
check_counter() {
    COUNTER=$(cat "$NETWORK_CHECK_COUNTER_FILE")
    if [ "$COUNTER" -ge "$COUNTER_THRESHOLD" ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') 计数器值大于等于 $COUNTER_THRESHOLD ,等待 $RESTART_INTERVAL 秒后重新检测网络连接"
        echo "$(date '+%Y-%m-%d %H:%M:%S') 计数器值大于等于 $COUNTER_THRESHOLD ,等待 $RESTART_INTERVAL 秒后重新检测网络连接" >> "$NETWORK_CHECK_LOG_FILE"
        sleep "$RESTART_INTERVAL" # 等待
        echo "$(date '+%Y-%m-%d %H:%M:%S') 等待 $RESTART_INTERVAL 秒后,开始重新检测网络" >> "$NETWORK_CHECK_LOG_FILE"
        check_network
    else
        check_network
    fi
}

check_counter

echo "$(date '+%Y-%m-%d %H:%M:%S') 网络检查完毕"

折腾 网络 openwrt