1 - 规避DNS污染问题

通过修改 hosts 文件来规避DNS污染

ssh 登录 openwrt ,修改 hosts 文件:

vi /etc/hosts

添加如下内容:

199.232.68.133 raw.githubusercontent.com

目前已知的有明显影响的地方:

  • raw.githubusercontent.com 被污染之后,会导致很多下载失败,比如 openclash / clash 启动时都要下载文件,另外各种在线下载也会失败。
  • 待收集

2 - 设置OpenWRT的远程管理

通过外网来访问OpenWRT的web管理页面。

容许外部访问

打开 openwrt 的 系统 -》web 管理页面:

http://192.168.0.1/cgi-bin/luci/admin/system/webadmin

默认是勾选了"只允许内网访问"的。

取消勾选,保存&应用。

开启端口映射

由于电信屏蔽了 80 端口的访问,因此我们需要映射一个端口到 80 端口。网络 -》防火墙 -》端口转发:

http://192.168.0.1/cgi-bin/luci/admin/network/firewall/forwards

添加端口转发:

  • 名称:openwrt-web
  • 传输协议: tcp+udp
  • 外部区域:wan
  • 外部端口: 18888
  • 内部区域:lan
  • 内部 ip 地址: 192.168.0.1
  • 内部端口:80

这样就可以在外网通过 18888 端口来访问了。

备注:不要使用 10080 这样的端口,会被主流的浏览器如 edge ,chrome,firefox 报错 ERR_UNSAFE_PORT ,换成 18888 这种就可以了。

配合 ddns

由于公网ip是每次拨号都不一样的,因此需要配置 ddns 一起使用,如:

http://dev.skyao.net:18888/

3 - 设置OpenWRT的远程ssh登录

通过外网来远程ssh登录OpenWRT

容许远程SSH

打开 openwrt 的 系统 -》管理权 页面:

http://192.168.0.1/cgi-bin/luci/admin/system/admin

Dropbear 实例设置中,默认是没有勾选"网关端口"的。

选择勾选,保存&应用。

开启端口映射

由于电信屏蔽了 22 端口的访问,因此我们需要映射一个端口到 22 端口。网络 -》防火墙 -》端口转发:

http://192.168.0.1/cgi-bin/luci/admin/network/firewall/forwards

添加端口转发:

  • 名称:openwrt-ssh
  • 传输协议: tcp+udp
  • 外部区域:wan
  • 外部端口: 18822
  • 内部区域:lan
  • 内部 ip 地址: 192.168.0.1
  • 内部端口:22

这样就可以在外网通过 18822 端口来远程ssh了。

配合 ddns

由于公网ip是每次拨号都不一样的,因此需要配置 ddns 一起使用,如:

ssh root@dev.skyao.net -p 18822

4 - 设置OpenWRT的定时重启

通过定时重启来减少问题的概率

虽然说 openwrt 挺稳定的,但是考虑到长期运行容易积累问题,因此还是定期重启一次会比较好。

打开 系统 -》 定时重启:

http://192.168.0.1/cgi-bin/luci/admin/system/autoreboot

设置为每周一的早上4点重启一次。

一周重启一次应该够用了。

5 - 备份和还原OpenWRT设置

备份OpenWRT设置,在出现问题时还原

http://192.168.0.1/cgi-bin/luci/admin/system/flashops

备份配置

备份配置文件,安全起见保存配置文件到百度盘之类的网盘。

恢复配置

在出现问题时,恢复配置

恢复出厂

由于使用的 openwrt 的固件安装包是基于 squashfs 格式的,因此支持恢复到出厂设置。

当出现严重问题时,可以通过 恢复到出厂设置 + 恢复配置来快速的恢复正常使用。

6 - 设置OpenWRT的多wan支持

介绍在 OpenWRT 下多wan的设置

有两个宽带接入,一条是电信宽带,一条是移动宽带,两个光猫都设置为桥接模式,由路由器拨号。

现在准备用一个 openwrt 路由器,实现两个wan接口,同时接入两个宽带。

wan配置

在 “网络” -> “接口” 页面上,删除现有的wan(可能还有wan6)。

重新创建两个 wan 接口:

  • 名称设置为 wan10086 / wan10000,后面用这两个wan口分别接移动宽带和电信宽带。
  • 防火墙设置一定要设置为 wan。
  • wan10000 的网关跃点设置为 20,wan10086 的网关跃点设置为 22 (跃点越低优先级越高)

设置负载均衡

接口设置

在 “网络” -> “负载均衡” -> “接口” 页面,先删除所有的现有规则(默认为空,如果有就删掉)。

再新建两个规则,注意规则名称必须和上面的 wan 接口的名称保持一致,否则会无法使用:

  • wan10000
  • wan10086

成员设置

打开 “网络” -> “负载均衡” -> “成员” 页面,删除现有成员,新建两个成员:

  • WAN_M1_10000: 接口选择 M10000, 跃点1,权重1
  • WAN_M1_10086: 接口选择 M10086, 跃点1,权重1

策略设置

在 “网络” -> “负载均衡” -> “策略” 页面,新建两个策略:

  • P10000: 使用成员 WAN_M1_10000,备用成员选择 “默认(使用主路由表)”
  • P10086: 使用成员 WAN_M1_10086,备用成员选择 “默认(使用主路由表)”

修改已有的 lalanced 策略,将成员修改为 WAN_M1_10000 + WAN_M1_10086。

规则设置

在 “网络” -> “负载均衡” -> “规则” 页面,默认就有两个规则,确认分配的策略都被设置为 lalanced 。

补充一些特殊规则,主要是为了让两个房子之间的网络访问只走电信网络,不走移动网络:

  • 99_SKYSERVERS: 目标地址 192.168.99.0/24,分配的策略为p10000
  • 100_SKYSERVERS: 目标地址 192.168.100.0/24,分配的策略为p10000
  • 0_SKYSERVERS: 目标地址 192.168.0.0/24,分配的策略为p10000
  • ZEROTIER: 目标地址 192.168.192.0/24,分配的策略为p10000

验证

在 “状态” -> “负载均衡” -> “接口” 页面,如果两个 mwan 接口都显示在线(绿色),则表明设置成功。

打开 10000.gd.cn 页面进行测速,也可以验证是否成功。

https://10000.gd.cn/#/speed

参考资料

7 - 检查是否公网IP

检查 wan ip,如果不是公网ip,则重新拨号,确保公网ip可用

背景

在某处的宽带网络中,wan ip 有时不是公网ip,而是内网ip(100开头的号段),导致无法通过公网/DDNS访问。

因此,需要检查 wan ip,如果不是公网ip,则重新拨号。按照经验,一般拨号3-5次就大概率能获取到公网ip。

脚本实现

ssh 登录 openwrt 路由器,添加以下脚本:

vi /usr/bin/check_wan_ip.sh

内容为:

#!/bin/sh

# 日志文件路径
LOGFILE="/var/log/check_wan_ip.log"
# 日志大小上限(字节,10MB)
MAXSIZE=$((10 * 1024 * 1024))

# 检查日志文件大小,超过则轮转
if [ -f "$LOGFILE" ]; then
    SIZE=$(stat -c%s "$LOGFILE")
    if [ "$SIZE" -ge "$MAXSIZE" ]; then
        mv "$LOGFILE" "$LOGFILE.1"
        echo "$(date '+%F %T') Log rotated, old log moved to $LOGFILE.1" > "$LOGFILE"
    fi
fi

# 开机宽限期(秒)
BOOT_GRACE=120

# 获取当前 WAN 接口的 IPv4 地址
IP=$(ifstatus wan | grep '"address"' | head -n1 | awk -F'"' '{print $4}')

# 定义日志函数(写入文件)
log() {
    echo "$(date '+%F %T') $1" >> "$LOGFILE"
}

# 定义重拨函数
redial() {
    log "Redialing wan..."
    ifdown wan && sleep 5 && ifup wan
}

# 如果没取到 IP,检查启动时间
if [ -z "$IP" ]; then
    UPTIME=$(cut -d. -f1 /proc/uptime)
    if [ "$UPTIME" -lt "$BOOT_GRACE" ]; then
        log "No IP yet, but system just booted ($UPTIME s), skipping check."
        exit 0
    else
        log "No IP found on wan after $UPTIME s, redialing..."
        redial
        exit 0
    fi
fi

# 判断是否为私网/CGNAT
is_private_ip() {
    case $1 in
        10.*) return 0 ;;                                      # 10.0.0.0/8
        192.168.*) return 0 ;;                                 # 192.168.0.0/16
        172.1[6-9].*|172.2[0-9].*|172.3[0-1].*) return 0 ;;    # 172.16.0.0/12
        100.6[4-9].*|100.7[0-9].*|100.8[0-9].*|100.9[0-5].*) return 0 ;; # 100.64.0.0/10
    esac
    return 1
}

if is_private_ip "$IP"; then
    log "Got private/CGNAT IP ($IP) on wan"
    redial
else
    log "Got public IP ($IP) on wan, OK."
fi

增加执行权限:

chmod +x /usr/bin/check_wan_ip.sh

定期检查

设置每分钟检查一次:

crontab -e

添加以下内容:

*/1 * * * * /usr/bin/check_wan_ip.sh

保存并退出。确保 cron 服务已启用并运行:

/etc/init.d/cron enable
/etc/init.d/cron start

检查日志内容:

tail -f /var/log/check_wan_ip.log

如果获取到的是公网ip,会看到类似如下的内容:

2025-10-31 21:12:00 Got public IP (116.21.255.172) on wan, OK.
2025-10-31 21:13:00 Got public IP (116.21.255.172) on wan, OK.
2025-10-31 21:14:00 Got public IP (116.21.255.172) on wan, OK.

如果获取到的是私网ip,则会多次尝试拨号,直到获取到公网ip:

2025-10-31 21:27:00 Got private/CGNAT IP (100.95.147.166) on wan
2025-10-31 21:27:00 Redialing wan...
2025-10-31 21:28:00 Got private/CGNAT IP (100.95.155.241) on wan
2025-10-31 21:28:00 Redialing wan...
2025-10-31 21:29:00 Got private/CGNAT IP (100.95.143.37) on wan
2025-10-31 21:29:00 Redialing wan...
2025-10-31 21:30:00 Got private/CGNAT IP (100.95.143.37) on wan
2025-10-31 21:30:00 Redialing wan...
2025-10-31 21:31:00 Got public IP (49.84.144.173) on wan, OK.
2025-10-31 21:32:00 Got public IP (49.84.144.173) on wan, OK.