华硕网络产品技术交流平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

查看: 86391|回复: 44

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

[复制链接]

14

主题

834

回帖

2万

积分

特聘会员

Rank: 2

积分
21713
发表于 2017-5-25 19:30:29 | 显示全部楼层 |阅读模式
本帖最后由 Jack 于 2020-5-1 14:59 编辑

下方内容已经过时故不再维护,若有需求请使用其他代替方案。

微信扫一扫,阅读更方便^_^

14

主题

834

回帖

2万

积分

特聘会员

Rank: 2

积分
21713
 楼主| 发表于 2017-5-25 19:32:01 | 显示全部楼层
本帖最后由 Jack 于 2017-6-5 17:39 编辑

本教程重在寻找过程,如果你在意最终结果,请直接看本文最后一段脚本。

在几天前,我看到了这篇文章《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://winhelp2002.mvps.org/hosts.txt
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://winhelp2002.mvps.org/hosts.txt" "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://winhelp2002.mvps.org/hosts.txt" "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://winhelp2002.mvps.org/hosts.txt" "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://winhelp2002.mvps.org/hosts.txt" "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 Router(将脚本运行在华硕路由器上 英文)
[10] 与 @Jack- 讨论开机脚本的问题
[11] 上海电信4K盒子+华硕路由器原厂固件/R7000实现拨号


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

14

主题

834

回帖

2万

积分

特聘会员

Rank: 2

积分
21713
 楼主| 发表于 2017-5-25 22:50:50 | 显示全部楼层
本帖最后由 Jack 于 2017-5-26 07:43 编辑

警告信息

此教程可能会被一些坏人利用,使用华硕、Asuswrt-Merlin 路由器的人请小心!
假设有一个不怎么喜欢我的朋友,他看到这篇教程,来到我家做客,趁我不注意将一个含有恶意脚本的 U 盘插入我的路由器,然后路由器会在 U 盘插入后开始运行这个脚本,而根本不会像 SSH 那样登录后才能运行。
请保护好你的路由器,对你的损失,我概不负责。

不过,我提供以下几点预防措施:
第一、买一只狗,在网上学习训狗教程,训练狗狗嗅探 U 盘。第二、买一串冰糖葫芦,吃完后留下签子,用签子插入路由器 USB 接口中,用力去戳,直到路由器的 USB 接口报废。
第三、重新装修你的房子,挖一个壁橱,把路由器通电后放进去,用砖和水泥盖上。
第四、找来一把锤子,用力砸你的路由器,然后把你砸碎的路由器丢入可回收垃圾箱,再花 100 元买一个没有 USB 接口的路由器。

如果你还有其他好办法,请告诉我:)

1

主题

9

回帖

41

积分

新手上路

Rank: 1

积分
41
发表于 2017-5-27 15:58:28 | 显示全部楼层
Jack 发表于 2017-5-25 19:32
本教程重在寻找过程,如果你在意最终结果,请直接看本文最后一段脚本。

在几天前,我看到了这篇文章《ac68 ...

楼主你好,按照你的方法,
#!/bin/sh

i=0

while [ $i -le 30 ]; do

      success_start_service=`nvram get success_start_service`

      if [ "$success_start_service" == "1" ]; then

              break

      fi

      i=$(($i+1))

      echo "autorun APP: wait $i seconds...";

      sleep 1
0
done

arp -s 192.168.1.88 2E:35:8F:00:13:2F

这个保存在U盘的asusware.arm ,且命名为 .asusrouter
U盘是USB3.0 的16G金士顿U盘,但是重启路由未能成功执行 arp -s 这条语句,手动 sh .asusrouter 是能成功 执行了 ARP 命令的。。困惑中!!

0

主题

5

回帖

46

积分

新手上路

Rank: 1

积分
46
发表于 2017-6-6 17:15:03 | 显示全部楼层

回帖奖励 +1 路由币

大神,你做好文件我们下载,电脑不会保存什末格式的?

16

主题

3040

回帖

7720

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
7720

RT-AC68URT-AC86UGT-AC5300

发表于 2017-5-25 21:40:55 | 显示全部楼层
感谢分享
回复

使用道具 举报

1

主题

9

回帖

41

积分

新手上路

Rank: 1

积分
41
发表于 2017-5-25 21:43:41 | 显示全部楼层

回帖奖励 +1 路由币

关键内容在哪呢?

15

主题

80

回帖

794

积分

高级会员

Rank: 4

积分
794

RT-AC88U

发表于 2017-5-26 01:40:01 | 显示全部楼层

回帖奖励 +1 路由币

希望看到关键的内容 向楼主致敬

561

主题

2018

回帖

7554

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
7554

RT-AC88U

发表于 2017-5-26 08:54:39 | 显示全部楼层

回帖奖励 +1 路由币

看起來很不錯。

629

主题

6181

回帖

1万

积分

管理员

正品行货

Rank: 9Rank: 9Rank: 9

积分
16829

RT-AC88URT-AX68U

发表于 2017-5-26 09:46:02 | 显示全部楼层

回帖奖励 +1 路由币

文章很棒!
回复

使用道具 举报

0

主题

16

回帖

64

积分

注册会员

Rank: 2

积分
64
发表于 2017-5-26 11:16:28 | 显示全部楼层
谢谢分享  慢慢研究消化
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

快速回复 返回列表 搜索 官方QQ群
×

秒后自动关闭

小黑屋|手机版|Archiver|华硕网络产品技术交流平台 ( 苏ICP备16010857号-1 )苏公网安备 32050502000499号

GMT+8, 2024-4-23 19:20 , Processed in 0.041352 second(s), 35 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表