华硕路由器官方固件开机自动运行脚本方法

本教程重在寻找过程,如果你在意最终结果,请直接看本文最后一段脚本。
  
在几天前,我看到了这篇文章《ac68等arm迅雷、aria2安装小白教程及官固自启动插件教程》[1],标题中的 “官固自启动” 让我非常感兴趣,通过这篇文章我了解到:华硕路由器的 Download Master(下载大师)功能保存在 U 盘上,而华硕官方固件(或 Asuswrt-Merlin)可以运行 U 盘上的脚本,我们也可以将自己的脚本放在 U 盘上实现开机自动运行。
具体是如何实现的?
我向 52asus 的一位管理者 Master 寻求帮助,收到了如下回复

你尝试一下将任意脚本放到/opt/etc/init.d/ 中,并且以 S 开头

相对于 U 盘,是放到了 asusware.arm/etc/init.d/ 目录下
他建议我参考这篇文章《RT-AC66UB1 开机自动执行脚本》[2],这篇文章初期对我的帮助价值非常大,很贴近最终答案,不过由于后面有更好地解决方法,这篇文章不会被用于本教程。
  
于是,我就想到,我之前在 Asuswrt-Merlin 固件时用到的屏蔽广告脚本《AdBlocking with combined hosts file》[3] 能否在我当前官方固件上运行?这个脚本主要是基于修改 hosts 文件实现,官方固件也可以修改 hosts,但是每次开机后 hosts 文件都会被刷新重置 [4],所有保存的信息会被清空。那么我能否利用上方发现的自启动脚本方法,在每次开机清空后再重新写入新的信息到 hosts 文件?答案是可行的。
  
仔细分析《AdBlocking with combined hosts file》文章,我看到了屏蔽广告的 hosts 来源,分别是:
(此处有一个链接无法发出)
http://someonewhocares.org/hosts/zero/hosts
http://pgl.yoyo.org/adservers/se ... &mimetype=plaintext
不过原文中的命令不适用于我,我首先需要做的是:找一个命令把这些链接中的内容写入到路由器的 hosts 中。
  
经过了一番寻找,我找到了这两篇文章《分享一个OpenWRT路由器的自动更新hosts方法,无需脚本》[5] 和《路由器自动修改hosts脚本》[6],这两篇文章都是国人写的,里面命令对我十分有用。
借助《wget 指令用法與教學》[7] 对命令进行了简单的修改,我得到了可以用于路由器更新 hosts 的命令:

  1. wget -q "http://someonewhocares.org/hosts/zero/hosts" "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" -O /etc/hosts

复制代码

并且将其制作为脚本:

  1. #!/bin/sh
  2. wget -q  "http://someonewhocares.org/hosts/zero/hosts" "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" -O /etc/hosts

复制代码

命令运行成功,在路由器中 ping 相应网址也得到了正确反馈,但我很快发现,为何我的电脑仍能看到广告?我在电脑中 ping 这些网站发现并没有被屏蔽。于是我开始找原因,在上面那些包含命令的文章中,我注意到了几个关键的命令 service restart_dnsmasq 和 /etc/init.d/dnsmasq restart 这些命令都是用来重启 dnsmasq 的,似乎必须重启后才能对客户端生效,前一个命令重启后会导致 hosts 如同开机般被清空,后者则不适用于华硕路由器。我又重新开始寻找新的命令。
  
在和《RT-AC66UB1 开机自动执行脚本》作者 右手边 交流中,他为我提供了一个新的命令,并发布了一篇教程《如何更改华硕路由器的 hosts》[8],这个新的命令完美地解决了 hosts 修改后不能生效的问题:

  1. killall -SIGHUP dnsmasq

复制代码

既然有了这个命令,那么就把它加入脚本

  1. #!/bin/sh
  2. wget -q "http://someonewhocares.org/hosts/zero/hosts" "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" -O /etc/hosts
  3. sleep 30
  4. killall -SIGHUP dnsmasq

复制代码

实践证明脚本完美运行。既然可以运行,那么让我来将其改造为开机启动。在本文开头提到的开机启动方法固然可以,但是过于复杂,因为需要基于各种库,如果用不到 Download Master,那些库就没有必要,毕竟那么多的库会拖慢开机时间。
  
因此我开始寻找一个更好地方法,在寻找中我看到了一个新的文章《Hacking Functionality into ASUSWRT Routers》[9] 其中这样写道:

When a USB storage device is inserted into the router’s USB port, the rc system daemon mounts the partition and checks for the existence of an asusware/.asusrouter script on the mount point. If it exists, the asusware folder is then symlinked to /tmp/opt (and also /opt) and the script is executed. Since this is all open source, you can find the relevant code in the mount_partition function in release/src/router/rc/usb.c.

大意为:

当 U 盘插入路由器后,rc 系统守护进程将挂载 U 盘,并检查 U 盘 asusware 文件夹下是否存在名为 .asusrouter 的脚本文件,如果存在将会把 asusware 文件夹链接为 /tmp/opt(和 /opt),并且运行脚本。因为是开源固件,可以在源代码 release/src/router/rc/usb.c 的 mount_partition 函数中找到相关信息。

大家明白了吗?这就是为什么之前脚本要放在 asusware.arm/etc/init.d/ 里面,因为 opt/etc/init.d/ 是启动目录,开机后会运行 /init.d/ 目录下所有的脚本。但是会首先运行 asusware.arm/.asusrouter 这个脚本。  

.asusrouter 这个脚本后来了解到主要是用来启动各种库的命令 [10],而我不需要 Download Master 也用不到这些库,直接清空 .asusrouter 文件,将自己的脚本写进去即可。《Hacking Functionality into ASUSWRT Routers》文章中也写道:

Put the commands you wish to execute in asusware/.asusrouter on your USB storage device. Like any shell script, make sure it has #!/bin/sh as its first line and that the file uses UNIX line endings. The filesystem can be anything supported by the kernel – ext2, ext3 or fat. If you are using a filesystem that implements Linux permissions (such as ext2 or ext3), be sure to set the script as executable.

大意为:

将你的命令保存到 U盘 asusware 目录下的 .asusrouter 文件中,和任何 shell 脚本一样,确保脚本第一行内容为 #!/bin/sh,并且以 UNIX 作为换行符,内核支持 ext2、ext3 或 fat 格式的 U 盘,如果使用 Linux 的 ext2 或 ext3 文件系统,请确保脚本拥有执行权限。

他写的这篇文章文件夹目录是不完全正确的,因为 ARM CPU 的路由器文件夹目录是 asusware.arm,一共有四种对应不同架构 CPU 的目录,分别是:asusware、asusware.arm、asusware.big 和 asusware.mipsbig,要确定你的路由器是哪种请在 telnet 下输入命令 [11]

  1. nvram get apps_install_folder

复制代码

接下来需要注意的是 U 盘不一定是  ext2、ext3 或 fat 格式,经过我的测试 NTFS 和 FAT32 也可以。最重要的是 FAT、FAT32 和 NTFS 这三种格式不需要修改权限,因此我推荐使用这三种格式。
  
继续看《Hacking Functionality into ASUSWRT Routers》文章:

One caveat when running network programs (like DHCP forwarder or mDNS repeater) is that you need to wait until everything has been initialized. ASUS does that by polling the success_start_service NVRAM variable with this bash snippet:
  1. i=0
  2. while [ $i -le 20 ]; do
  3.       success_start_service=`nvram get success_start_service`
  4.       if [ "$success_start_service" == "1" ]; then
  5.               break
  6.       fi
  7.       i=$(($i+1))
  8.       echo "autorun APP: wait $i seconds...";
  9.       sleep 1
  10. done
复制代码

大意为

运行和网络有关的脚本,需要等待路由器所有程序初始化完成。因此华硕使用如下命令保证这一点。
这段命令大意是:不断查询程序是否初始化完成,如果没有完成就等待,如果完成了就运行接下来的命令。由于 hosts 是和网络有关的脚本,因此我必须等待所有程序初始化完成。


所以,最终的开机修改 hosts 脚本为:

  1. #!/bin/sh
  2. i=0
  3. while [ $i -le 20 ]; do
  4.       success_start_service=`nvram get success_start_service`
  5.       if [ "$success_start_service" == "1" ]; then
  6.               break
  7.       fi
  8.       i=$(($i+1))
  9.       echo "autorun APP: wait $i seconds...";
  10.       sleep 1
  11. done
  12. wget -q  "http://someonewhocares.org/hosts/zero/hosts" "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" -O /etc/hosts
  13. sleep 30
  14. killall -SIGHUP dnsmasq

复制代码

将这段脚本保存为 .asusrouter 文件,然后放到 U 盘的 asusware 或者 asusware.arm 或者 asusware.big 或者 asusware.mipsbig 文件夹中,我的路由器则是放到 asusware.arm 目录中。 
好了,这就可以开机运行了

对于你,你也可以将任何 shell 脚本写在 .asusrouter 里面(以 UNIX 作为换行符),并且保存在 U 盘上 asusware 或者 asusware.arm 或者 asusware.big 或者 asusware.mipsbig 文件夹中,具体是哪一个文件夹,上方有查询方法。
我建议 .asusrouter 里面应该至少包含以下内容:

  1. #!/bin/sh
  2. i=0
  3. while [ $i -le 20 ]; do
  4.       success_start_service=`nvram get success_start_service`
  5.       if [ "$success_start_service" == "1" ]; then
  6.               break
  7.       fi
  8.       i=$(($i+1))
  9.       echo "autorun APP: wait $i seconds...";
  10.       sleep 1
  11. done
  12. #从下方开始你的脚本

复制代码

如果你有多个脚本,我建议将多个脚本独立保存为随意文件名,然后放入 asusware 或者 asusware.arm 或者 asusware.big 或者 asusware.mipsbig 文件夹中,在 .asusrouter 里面直接写一段代码引导到你的脚本,例如我有名为 test1、test2 和 test3 脚本保存在 U 盘的 asusware.arm 里面,我想要他们几乎同时启动,我需要这样写:

  1. #!/bin/sh
  2. i=0
  3. while [ $i -le 20 ]; do
  4.       success_start_service=`nvram get success_start_service`
  5.       if [ "$success_start_service" == "1" ]; then
  6.               break
  7.       fi
  8.       i=$(($i+1))
  9.       echo "autorun APP: wait $i seconds...";
  10.       sleep 1
  11. done
  12. /opt/test1
  13. sleep 1
  14. /opt/test2
  15. sleep 1
  16. /opt/test3

复制代码

如果你不需要同时运行这些脚本,而是上一个脚本运行结束、再运行下一个,你只要将 test1 写在启动命令里面,然后编辑 test1 文件,在最后一行加入 /opt/test2 启动 test2,test2 脚本最后一行加入 /opt/test3 启动 test3,如同多米诺骨牌一样。


特别感谢:
来自 koolshare 的 konglang_616,来自 52asus 的 Master 和 右手边

参考资料:
[1] ac68等arm迅雷、aria2安装小白教程及官固自启动插件教程
[2] RT-AC66UB1 开机自动执行脚本
[3] AdBlocking with combined hosts file(利用 hosts 文件过滤广告 英文)
[4] 請問RT-N16以及N66U的hosts修改
[5] 分享一个OpenWRT路由器的自动更新hosts方法,无需脚本
[6] 路由器自动修改hosts脚本
[7] wget 指令用法與教學
[8] 如何更改华硕路由器的 hosts
[9] Hacking Functionality into ASUSWRT Routers(将脚本运行在华硕路由器上 英文)
[10] 与 @Jack- 讨论开机脚本的问题
[11] 上海电信4K盒子+华硕路由器原厂固件/R7000实现拨号

其他资料:
[12] Asuswrt-Merlin 開機時未執行 init.d 腳本的問題
[13] User scripts · RMerl/asuswrt-merlin Wiki(用户脚本 梅林百科 英文)
[14] ASUSWRT原廠固件安裝 entware

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 你可以使用Python来写一个脚本来获取华为路由器接口IP地址。你可以使用urllib模块来实现这一功能,并使用正则表达式来提取IP地址。你还可以使用requests模块来访问指定的URL,获取该网页的源代码,并解析出IP地址。 ### 回答2: 要编写一个自动获取华为路由器接口IP地址的Python脚本,首先需要使用Python的网络编程库来与路由器进行通信。以下是一个可能的实现思路: 1. 导入必要的Python库,如paramiko(用于SSH连接)、re(用于正则表达式匹配)和time(用于延时等待)。 2. 创建一个SSH连接路由器的函数。在函数中使用paramiko库来建立SSH连接,并使用用户名和密码进行身份验证。 3. 在SSH连接中执行命令来获取路由器的接口信息。使用paramiko库中的`exec_command()`函数来执行命令,并使用`recv()`函数来获取命令输出。 4. 使用正则表达式匹配从路由器接口信息中提取IP地址。可以使用re库中的`findall()`函数来匹配IP地址的模式,并将匹配到的IP地址保存在一个列表中。 5. 返回IP地址列表。 以下是一个简单的示例代码: ```python import paramiko import re import time def get_router_ip(username, password): router_ip_list = [] # SSH连接路由器 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('router_ip', username=username, password=password) # 执行命令获取接口信息 stdin, stdout, stderr = ssh.exec_command('display ip interface brief') time.sleep(1) # 等待命令执行完成 # 获取命令输出并使用正则表达式匹配IP地址 output = stdout.read().decode('utf-8') ip_addresses = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', output) # 将匹配到的IP地址添加到列表中 for ip_address in ip_addresses: router_ip_list.append(ip_address) # 关闭SSH连接 ssh.close() return router_ip_list # 调用函数并打印结果 username = 'your_username' password = 'your_password' router_ip_list = get_router_ip(username, password) print(router_ip_list) ``` 请注意,此示例仅提供了基本的框架和思路,实际操作中需根据华为路由器的具体配置和命令进行调整。同时,需要替换掉代码中的'router_ip'、'your_username'和'your_password'为实际的路由器IP地址、用户名和密码。 ### 回答3: 要编写一个自动获取华为路由器接口IP地址的Python脚本,你可以使用telnetlib库来远程连接路由器并发送命令。以下是一个示例脚本: ```python import telnetlib host = "路由器IP地址" username = "路由器用户名" password = "路由器密码" # 连接到路由器 tn = telnetlib.Telnet(host) # 输入用户名 tn.read_until(b"Username: ") tn.write(username.encode('ascii') + b"\n") # 输入密码 tn.read_until(b"Password: ") tn.write(password.encode('ascii') + b"\n") # 登录成功后发送命令 tn.write(b"interface brief\n") tn.write(b"display ip interface brief\n") tn.write(b"quit\n") # 读取路由器返回的结果 output = tn.read_all().decode('ascii') # 解析结果,获取接口IP地址 lines = output.split("\n") for line in lines: words = line.split() if len(words) >= 4 and words[0].startswith("GigabitEthernet"): interface = words[0] ip_address = words[1] print("接口名:", interface, " IP地址:", ip_address) # 关闭连接 tn.close() ``` 在上述脚本中,需要将`host`变量替换为你的华为路由器的IP地址,`username`和`password`变量替换为你的登录凭据。脚本首先通过telnet连接到路由器,然后输入用户名和密码进行登录。之后发送命令`interface brief`和`display ip interface brief`来获取接口IP地址的信息,并解析返回的结果,输出接口名和IP地址。最后关闭telnet连接。 请注意,使用telnet进行远程连接存在安全风险。为了更安全地获取接口IP地址,推荐使用SSH协议,可以使用`paramiko`库来进行SSH连接和命令发送。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值