本文最后更新于 2025-04-02,文章内容可能已经过时。

w800.png

(弃用)安装Entware管理第三方软件

注意:由于新版华硕官方固件以系统安全为由禁用了nvram中的script_usbmount和script_unsbmount,用Entware官方的方法安装不可以实现插件开机自启。

查看路由CPU架构 uname -m(华硕AX4200q为filogic830 armv8 aarch64)

Entware官方文档:https://github.com/Entware/Entware/wiki

Entware官方对于在华硕路由官方固件的安装文档:

详细步骤:https://github.com/Entware/Entware/wiki/Install-on-Asus-stock-firmware

(采用)精简步骤:https://github.com/Entware/Entware/wiki/Install-on-ASUSWRT-step-by-step

安装开机自启动脚本

脚本项目地址:

https://github.com/jacklul/asuswrt-scripts/tree/master?tab=readme-ov-file#user-content-usb-mountsh

安装步骤:

  • 准备U盘

  • 格式化U盘为ext4

  • 插入华硕路由

  • 准备环境

  • 安装sftp工具,与winscp软件连接,方便文件管理:ipkg update && install openssh-sftp-server

  • 华硕路由页面的Usb相关应用中安装下载大师(用来初始化U盘环境)

  • 按照脚本项目指导下载Workaround并解压到U盘上(不要覆盖U盘上原来的文件,而是要手动追加内容到原来的文件上)(没有尝试过解压文件后再安装下载大师)

https://github.com/jacklul/asuswrt-scripts/tree/master/asusware-usbmount

  • 安装脚本

  • 在持久性存储区中建立脚本目录:chmod 0775 /jffs && mkdir -pv /jffs/scripts

  • 设置脚本目录可执行权限:chmod 0775 /jffs/scripts

  • 下载并部署自启动脚本(代理地址可改):

curl -fsSL "https://gh-proxy.ygxz.in/https://raw.githubusercontent.com/jacklul/asuswrt-scripts/master/scripts/scripts-startup.sh" -o /jffs/scripts/scripts-startup.sh
  • 设置启动脚本的可执行权限:chmod +x /jffs/scripts/scripts-startup.sh

  • 修改脚本内容

    • PRIORITIES 末尾添加 adguard-start.sh(这个是待会手动创建的adguardhome启动脚本)

      • 示例:PRIORITIES="service-event.sh hotplug-event.sh custom-configs.sh cron-queue.sh adguard-start.sh"

  • 安装脚本:sh /jffs/scripts/scripts-startup.sh install(若提示需要安装workaround,则说明第<二>步骤安装不正确(但还是可以测试一下能否成功自启动))

安装AdGuardHome

  • 下载软件包

  • 官方Github网站上下载AdGuardHome_linux_arm64.tar.gz软件包,解压缩后整个文件夹拷贝进 /tmp/mnt/ENTWARE/asusware.arm/bin/ 目录下(ENTWARE为U盘格式化为ext4是分配的卷标,如有不同,则需要修改下方的 adguard-start 脚本)

  • 上传adguard-start.sh运行脚本到 /jffs/scripts 目录下

  • 添加可执行权限:chmod +x /jffs/scripts/adguard-start.sh

路由运行优化与重置

SSH常用命令

网络相关

查看防火墙转发规则

(IPv4)iptables -t nat -L PREROUTING

(IPv6)ip6tables -t nat -L PREROUTING

重启防火墙(重启后手动设置的转发规则失效)

service restart_firewall

查看端口

netstat -tunlp | grep ":5553"

参数说明:-t -显示TCP端口。-u -显示UDP端口。-n -显示数字地址而不是解析主机。-l -仅显示监听端口。-p -显示监听进程的PID和名称。仅当以root用户或 sudo 用户身份运行命令时,才会显示此信息。

系统相关

重启:reboot

查看进程:ps | grep "AdGuardHome"

磁盘相关

查看挂载情况:mount

查看分区信息:df -h

显示块设备(U盘等)信息:blkid

优化

关闭USB软件中的文件共享以节省内存

关闭路由DNS重绑定保护,DNS隐私等功能

关闭下载大师(不是卸载)

重置

华硕路由器强制重置恢复出厂设置(Hard Factory Reset)方式:https://www.asus.com.cn/support/faq/1039074/

(方法二) ASUS 路由器强制重置还原默认值(Hard Factory Reset)

1.将路由器关机
2.长按WPS按键不放并开机
3.路由器上的电源灯号开启(不要放开WPS按键)
4.当看到电源灯号关闭时即完成重置动作, 可放开WPS按键.
5.手动重启路由器

Q&A

  • IPv6的防火墙端口重定向不能填回环地址(Passthrough模式下)

只能填路由公网地址作为转发的目的 ip,见 adguard脚本

网络协议栈特性

IPv6协议栈对回环地址有严格隔离机制

从外部接口(br0)进入的包禁止访问lo接口地址

即使服务监听在0.0.0.0:5553,也无法接收来自DNAT到[::1]的包

  • 使用Windows终端SSH访问时出现无法连接

通常出现在路由重置后,删除之前使用ssh命令时的目录下的.ssh文件,(Windows终端默认打开位置为C:\\Users\\<username>)

附件

AdGuardHome的启动脚本 adguard-start.sh

#!/bin/sh

CONFIG_DIR="/tmp/mnt/ENTWARE/asusware.arm/bin/AdGuardHome"
LOG_DIR="$CONFIG_DIR/script_logs"
PID_FILE="/var/run/adguard.pid"

# 初始化日志文件路径
current_log_date=$(date '+%Y-%m-%d')
LOG_FILE="$LOG_DIR/script_${current_log_date}.log"

# 安全创建日志目录
mkdir -p "$LOG_DIR"

# 旧日志清理(每天执行一次)
delete_old_logs() {
    # 查找30天前的日志文件(按文件名日期判断)
    find "$LOG_DIR" -name 'script_*.log' -mtime +30 | grep -E 'script_[0-9]{4}-[0-9]{2}-[0-9]{2}.log' | xargs rm -f
}

# 增强型日志记录
log() {
    # 检测日期变化
    today=$(date '+%Y-%m-%d')
    
    # 每天首次写入时执行清理
    if [ "$today" != "$current_log_date" ]; then
        current_log_date=$today
        LOG_FILE="$LOG_DIR/script_${today}.log"
        delete_old_logs
    fi

    # 写入日志
    echo "[$(date '+%H:%M:%S')] $1" >> "$LOG_FILE"
}


# 替代crontab的监控方案
start_monitor() {
    while true; do
        sleep 300  # 5分钟间隔
        $0 check >> $LOG_FILE 2>&1
    done &
    echo $! > $PID_FILE
    log "Monitor started with PID $(cat $PID_FILE)"
}

# 增强型进程管理
get_pid() {
    ps -w | grep "$CONFIG_DIR/AdGuardHome" | grep -v grep | awk '{print $1}'
}

# 检测并修复规则
check_rules() {
    # IPv4规则检测
    if ! iptables -t nat -C PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5553 >/dev/null 2>&1; then
        iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5553
        log "Repaired IPv4 UDP rule"
    fi

    if ! iptables -t nat -C PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 5553 >/dev/null 2>&1; then
        iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 5553
        log "Repaired IPv4 TCP rule"
    fi

    # 获取实时IPv6地址(带重试机制)
    CURRENT_IP=$(ip -6 addr show dev br0 scope global | awk '/inet6/{split($2,addr,"/"); print addr[1]; exit}')
    
    # 地址变化检测逻辑
    if [ -s /tmp/ipv6_address ]; then
        STORED_IP=$(cat /tmp/ipv6_address)
        
        # 检测到地址变化
        if [ "$STORED_IP" != "$CURRENT_IP" ] && [ -n "$CURRENT_IP" ]; then
            log "IPv6 address changed from $STORED_IP to $CURRENT_IP"
            
            # 清理旧规则
            ip6tables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to-destination "[$STORED_IP]:5553" 2>/dev/null
            ip6tables -t nat -D PREROUTING -p tcp --dport 53 -j DNAT --to-destination "[$STORED_IP]:5553" 2>/dev/null
            
            # 更新地址存储
            echo "$CURRENT_IP" > /tmp/ipv6_address
            
            # 添加新规则
            ip6tables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553"
            ip6tables -t nat -A PREROUTING -p tcp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553"
            log "Updated IPv6 rules with new address"
        fi
    fi

    # 常规规则修复(兼容地址未变化的情况)
    if [ -n "$CURRENT_IP" ]; then
        # UDP规则检测
        if ! ip6tables -t nat -C PREROUTING -p udp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553" >/dev/null 2>&1; then
            ip6tables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553"
            log "Repaired IPv6 UDP rule"
        fi
        
        # TCP规则检测
        if ! ip6tables -t nat -C PREROUTING -p tcp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553" >/dev/null 2>&1; then
            ip6tables -t nat -A PREROUTING -p tcp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553"
            log "Repaired IPv6 TCP rule"
        fi
    else
        # 清理已失效的IPv6规则
        if [ -s /tmp/ipv6_address ]; then
            STORED_IP=$(cat /tmp/ipv6_address)
            ip6tables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to-destination "[$STORED_IP]:5553" 2>/dev/null
            ip6tables -t nat -D PREROUTING -p tcp --dport 53 -j DNAT --to-destination "[$STORED_IP]:5553" 2>/dev/null
            rm -f /tmp/ipv6_address
            log "Cleared invalid IPv6 rules"
        fi
    fi
}

case "$1" in
    "start")
        log "===== Starting Service ====="
        
        # 等待网络初始化
        sleep 15

        # 启动AdGuardHome
        # 进程启动(兼容性写法)
        if [ -z "$(get_pid)" ]; then
            $CONFIG_DIR/AdGuardHome -l $CONFIG_DIR/logs >/dev/null 2>&1 &
            log "AdGuardHome started"
        else
            log "AdGuardHome already running (PID $(get_pid))"
        fi

        # 设置IPv4规则
        iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5553
        iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 5553
        log "IPv4 rules added"

        # 检测IPv6地址(最多等待10秒)
        IPV6_ATTEMPTS=0
        while [ $IPV6_ATTEMPTS -lt 5 ]; do
            CURRENT_IP=$(ip -6 addr show dev br0 scope global | awk '/inet6/{split($2,addr,"/"); print addr[1]; exit}')
            if [ -n "$CURRENT_IP" ]; then
                echo "$CURRENT_IP" > /tmp/ipv6_address
                ip6tables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553"
                ip6tables -t nat -A PREROUTING -p tcp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553"
                log "IPv6 rules added with address: $CURRENT_IP"
                break
            fi
            IPV6_ATTEMPTS=$((IPV6_ATTEMPTS+1))
            sleep 2
        done

        # 启动监控后台进程
        start_monitor

        ;;
    "stop")
        log "===== Stopping Service ====="
        
        # 增强型进程终止
        if [ -n "$(get_pid)" ]; then
            kill $(get_pid) 2>/dev/null
            log "AdGuardHome stopped"
        fi
        
        # 清理防火墙规则
        iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5553 2>/dev/null
        iptables -t nat -D PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 5553 2>/dev/null
        
        if [ -s /tmp/ipv6_address ]; then
            CURRENT_IP=$(cat /tmp/ipv6_address)
            ip6tables -t nat -D PREROUTING -p udp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553" 2>/dev/null
            ip6tables -t nat -D PREROUTING -p tcp --dport 53 -j DNAT --to-destination "[$CURRENT_IP]:5553" 2>/dev/null
        fi
        rm -f /tmp/ipv6_address
        log "Firewall rules removed"

        # 终止监控进程
        if [ -f "$PID_FILE" ]; then
            kill -9 $(cat "$PID_FILE") 2>/dev/null
            rm -f "$PID_FILE"
            log "Monitor stopped"
        fi
        ;;

    "restart")
        $0 stop
        sleep 2
        $0 start
        ;;

    "check")
        # 进程存活检测(兼容性改进)
        if [ -z "$(get_pid)" ]; then
            log "Process not running, restarting..."
            $0 start
        else
            check_rules
        fi
        ;;

    *)
        echo "Usage: $0 start|stop|restart|check"
        exit 1
esac

exit 0