K 的博客

记录精彩的程序人生 开始使用

梅林固件装 Opkg

1 装之前需要打开 JFFS partition、打开 SSH

系统管理 > 系统设置
| Enable SSH | 是 |
| Enable JFFS custom scripts and configs | 是 |

2ssh 登录路由器

登录路由器后 用命令安装配置

#创建目录 与文件
cd /jffs
mkdir /jffs/opt
ln -nsf /jffs/opt /tmp/opt


#编辑启动脚本
vi /jffs/scripts/post-mount
	#!/bin/sh
	ln -nsf /jffs/opt /tmp/opt
chmod a+rx /jffs/scripts/post-mount


#下载安装脚本 并运行安装
wget http://qnapware.zyxmon.org/binaries-armv7/installer/entware_install_arm.sh
 sh ./entware_install_arm.sh

#好了现在就可以用 命令安装了
opkg update
opkg install xxxx

OK 完成,这样路由器就安装好了 软件包管理器

编辑 /jffs/opt/etc/opkg.conf
src/gz entware http://bin.entware.net/armv7sf-k2.6
src/gz entware http://pkg.entware.net/binaries/armv7
替换源可以用这 2 个。或者直接用这里面的 安装脚本进行安装
wget -O - http://bin.entware.net/armv7sf-k3.2/installer/generic.sh | sh

路由器配置

  • 华硕 AC-86U
  • 刷入梅林固件
  • 启用 SSH / 安装 ShellinaBox 插件(Web SSH 插件)
  • SSH 用户名密码和登陆路由器后台的帐号密码一致

Hosts 设置

一、在 **/jffs/ **目录下创建一个名为 dnsmasq.conf.add 的文件,内容为 addn-hosts=/jffs/configs/hosts 并且保存

vi /jffs/dnsmasq.conf.add

二、进入该目录下的 configs 文件夹(/jffs/configs),创建一个名为 hosts 的文件,并且在该文件中设置自定义域名解析,并且保存。

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

转载 wenzhp1975 发布于 2019-06-14 09:53:09 阅读数 885 收藏

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

在几天前,我看到了这篇文章《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