ydtan 发表于 2021-2-2 23:19:49

华硕路由器开机自动运行自定义脚本,实现hosts即时生效

华硕路由器开机自动运行自定义脚本实现hosts即时生效的方法之1232021年2月2日
一、需求
随着家庭网络内的联网设备越来越多,如电视、播放机、文件服务器、打印机、笔记本、手机等等,直接用IP地址的方式来管理这些设备越来越困难,费时费力。自己可以建一个hosts文件,为每一台设备取一个名字,并分配一个固定的IP地址。示例如下。hosts文件:127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopback192.168.*.250   DL            #PRE             #PC机(DL)192.168.*.251   R478          #PRE             #TL-R478+路由器校园网192.168.*.252R300         #PRE             #MW300R路由器192.168.*.253   4K            #PRE             #PC机(4K)192.168.*.230TV            #PRE             #电视192.168.*.231Z9F             #PRE             #音响192.168.*.232BD            #PRE             #播放机192.168.*.1AC5300      #PRE             #主路由器192.168.*.2H3C            #PRE             #交换机192.168.0.1   EPON         #PRE             #电信光猫……
hosts文件,你可以存到本机里面,如C:\Windows\System32\drivers\etc目录下。这样做有两个问题。一是Android手机是不允许写入hosts文件的。二是在数十台设备维护hosts的数十个版本是不可行的。一个办法是把hosts文件写到路由器里面。如/tmp/etc/hosts但是!但是!但是!重要的事情说三边,华硕路由器在重新启动后,任何对hosts文件的更改都会被清除,重置为路由器系统默认的hosts文件。
能否把hosts文件存到路由器挂载的U盘中,如/tmp/mnt/sda1/asusware.arm/etc/init.d目录下,等路由器启动后自动将/tmp/mnt/sda1/asusware.arm/etc/init.d/hosts复制到/tmp/etc/hosts,实现hosts文件的更新呢?并让hosts文件生效呢?
答案至少有三种。试验表明,现在能用的是第三种。请看下文!
二、以Sxxhosts命名的脚本实现启动时自动执行(1)编写一个脚本:S50hosts,文件名以大写S开头+xx两位数字+任意名字。(2)将脚本放到/opt/etc/init.d/ S50hostsS50hosts脚本如下:#!/bin/sh#确保脚本第一行内容为#!/bin/sh,并且以 UNIX 作为换行符#等待路由器所有程序初始化完成,不断查询程序是否初始化完成i=0   while [ $i -le 20 ]; 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   done#复制自己定义的hosts文件到/etc目录下cp/opt/etc/init.d/hosts /tmp/etc/hosts
#复制域名解析配置文件resolv.conf到/tmp及/tmp/etc目录下cp/opt/etc/init.d/resolv.conf/tmp/etc/resolv.confcp/opt/etc/init.d/resolv.conf /tmp/resolv.conf
#复制dnamasq配置文件dnsmasq.conf到/tmp/etc目录下cp/opt/etc/init.d/dnsmasq.conf/tmp/etc/dnsmasq.conf
#复制dnamasq配置文件dnsmasq.conf到/tmp目录下cp /opt/etc/init.d/resolv.dnsmasq/tmp/resolv.dnsmasq
sleep 20#非常重要:重启 dnsmasq,并使hosts文件生效#dnsmasq是华硕路由器自带的一个轻量DNS解析服务,首先查询/etc/hosts文件,#查不到的话,查询上有DNS服务器,如中国电信成都的DNS服务器:61.139.2.69# service restart_dnsmasq执行后会导致 hosts 同开机一样被清空#正确的操作方式如下killall -SIGHUP dnsmasq
特别提示:(1)手动执行脚本 ./S50hots,dnsmasq 重启成功,自定义hosts生效。(2)重新启动路由器,S50hots脚本并未自动执行。
目标没有达成!可能原因是华硕路由器的新版本固件不再支持这种脚本自动执行方法。为了实现我们的目标:开机自动执行S50hosts这个脚本,需要找另外的新方法。
三、jffs2_exec=””指定脚本执行华硕路由器JFFS分区是路由器闪存的可写部分,是放置脚本文件的好地方,因为此分区在路由器重新启动后不会被擦除,继续有效。放在此分区的脚本将在启动时先于USB磁盘被加载,对于要在路由器关机后不丢失脚本的需求,可以使用路由器JFFS分区。JFFS分区原本用于存储路由器的所有配置信息,使用nvram show命令可以查看所有配置参数。
华硕路由器开机时,有一个脚本自动运行的钩子:nvram set jffs2_on=1nvram set jffs2_exec=”sh /jffs/init.sh”以上命令指定路由器启动时,自动运行 /jffs/init.sh脚本。
nvram show|grepjffs2_命令查看JFFS分区启动自动执行脚本的设置如下:jffs2_enable=1jffs2_exec=sh/jffs/init.shjffs2_format=0jffs2_on=1jffs2_size=66060288
init.sh脚本文件#!/bin/sh## init.sh - custom script executed at boot(during start of jffs)## Note:#   1) NVRAM variable "jffs2_exec" must point to this script#      nvram set jffs2_exec="sh /jffs/init.sh"#   2) The calling code waits for this script to terminate,#      so in order to not stall the boot process, we quickly#      move to the background# the calling code waits for the script toterminate (different from script_usbmount),# so as the script waits for routerservices to finish start-up# (polling success_start_service NVRAMvariable),# the script should move to background in apseudo-daemon way.
maxwait=300#设置调用/opt/etc/init.d/S50hosts脚本的变量S50hosts='/opt/etc/init.d/S50hosts'umask 022## move to background in a subshell#(   cd /    #ignore SIGHUP   trap '' SIGHUP    #redirect STDIN, STDOUT, STDERR   exec 0< '/dev/null'   exec 1> '/dev/null'   exec 2> '/dev/null'    #    #wait till all the system services are started    #by polling "success_start_service" NVRAM variable    #   i=0   while [ "$i" -le "$maxwait" ]   do       success_start_service="$( nvram get 'success_start_service' )"       if [ "$success_start_service" == '1' ]       then         break       fi       sleep 10       i=$(( $i + 10 ))   done   if [ "$i" -gt "$maxwait" ]   then      # timeout       logger 'init.sh script: timout waiting for"success_start_service"'       exit 1   fi    #    #wait a little longer to allow ntp client to get correct time    #   sleep 60   logger 'init.sh executing'    #append custom hosts file to hosts   if [ -x "$S50hosts" ]then#调用S50hosts脚本       eval "$S50hosts"   fi    #add other stuff you want to do...   echo "S50hosts done!">>/jffs/init.log   exit 0)&exit 0
特别提醒:(1)    手动执行/jffs/init.sh,S50hosts脚本成功执行,hosts生效。(2)    遗憾的是,华硕路由器重新启动时,/jffs/init.sh并未自动执行。这意味着用jffs2_exec=”sh /jffs/init.sh”这一钩子自动执行脚本的努力化为泡影!也就是说华硕路由器不在支持这一机制。
为了实现我们的目标:开机自动执行S50hosts这个脚本,需要再度寻找新的方法!
四、script_usbmount=“”指定脚本执行
除上述jffs2_exec=”sh /jffs/init.sh” 这一钩子之外,华硕路由器理论上还有可用的钩子:挂载USB和卸载USB设备时的钩子,分别是script_usbmount,script_usbumount。
使用nvram set script_usbmount=”sh /jffs/init.sh”命令设置USB挂载时执行的脚本/jffs/init.sh。
*重启路由器!
幸运的是/jffs/init.sh得以自动运行。
其效果是:存在U盘上的S50hosts脚本得以执行,并且hosts即时生效。
五、小结华硕路由器启动时自动执行脚本的机制至少有:(1)以Sxxhosts命名的脚本实现启动时自动执行;(2)jffs2_exec=””指定脚本执行;(3)script_usbmount=“”指定脚本执行
随着时间的推移,前两种机制已经作废!幸运的是script_usbmount=“”指定脚本执行这一机制目前还有效。
-完-

iphone8 发表于 2021-2-3 08:33:07

这个厉害了,必须给个赞:victory:
需要注意的是做好hosts备份,路由器一旦重启之后需要重新导入设定。

iphone8 发表于 2021-2-3 09:19:35

另外,如果仅想顺利管控不同设备,指定固定 IP,同时又担心重启路由器之后再导入hosts的话。

你可以路由器路由器的管理页面。内部网络(LAN)-DHCP 服务器页面,再瘦点指定 IP 的 DHCP 列表下设置就可以指定不同设备固定 IP,此时路由器重启就不用担心从新导入问题。

ydtan 发表于 2021-2-3 12:43:52

iphone8 发表于 2021-2-3 08:33
这个厉害了,必须给个赞
需要注意的是做好hosts备份,路由器一旦重启之后需要重新导入设定。
...

把hosts文件存到路由器挂载的U盘中,如
/tmp/mnt/sda1/asusware.arm/etc/init.d目录下,等路由器启动后自动将
/tmp/mnt/sda1/asusware.arm/etc/init.d/hosts复制到/tmp/etc/hosts,

这样做的话,自定义hosts被冲掉后就可以恢复。

ydtan 发表于 2021-2-3 12:51:41

iphone8 发表于 2021-2-3 09:19
另外,如果仅想顺利管控不同设备,指定固定 IP,同时又担心重启路由器之后再导入hosts的话。

你可以路由器 ...

这样做也不错。
不过,需要与设备的MAC地址绑定。
还有一个局限,我的家庭网是多路由器系统,
设备挂在不同子网下,如何绑定MAC了?

本文的目标是,家庭网内所有设备都可以查询这“一个hosts”文件。

iphone8 发表于 2021-2-3 13:53:41

ydtan 发表于 2021-2-3 12:43
把hosts文件存到路由器挂载的U盘中,如
/tmp/mnt/sda1/asusware.arm/etc/init.d目录下,等路由器启动后自 ...

嗯嗯,好做法。

iphone8 发表于 2021-2-3 14:01:42

ydtan 发表于 2021-2-3 12:51
这样做也不错。
不过,需要与设备的MAC地址绑定。
还有一个局限,我的家庭网是多路由器系统,


你只要在主路由器中设置指定次路由器对应固定IP就应该可以。譬如:192.168.*.252R300         #PRE             #MW300R路由器,这次MW300R 连接到主路由器下会,网络地图-用户数页面就会显示对应的MAC与IP

了迎林 发表于 2023-5-17 22:07:43

目前这个 script_usbmount 也没有了, 没找到这个脚本

/tmp/home/root# nvram show | grep scrip
script_usbhotplug=

猫名顶替 发表于 2023-6-3 12:30:34

了迎林 发表于 2023-5-17 22:07
目前这个 script_usbmount 也没有了, 没找到这个脚本

/tmp/home/root# nvram show | grep scrip


能用的,我弄成功了。梅林386.7_2

laysss 发表于 2023-7-25 21:45:41

大佬,似乎失效了,今年更新的官方固件386.5xxxx重启后无效,RT-AC86U最后一个可用版本是48260
页: [1] 2
查看完整版本: 华硕路由器开机自动运行自定义脚本,实现hosts即时生效