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

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

查看: 24182|回复: 13

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

[复制链接]

2

主题

6

回帖

68

积分

注册会员

Rank: 2

积分
68
发表于 2021-2-2 23:19:49 | 显示全部楼层 |阅读模式
华硕路由器开机自动运行自定义脚本实现hosts即时生效的方法之123
2021年2月2日

一、需求

随着家庭网络内的联网设备越来越多,如电视、播放机、文件服务器、打印机、笔记本、手机等等,直接用IP地址的方式来管理这些设备越来越困难,费时费力。自己可以建一个hosts文件,为每一台设备取一个名字,并分配一个固定的IP地址。
示例如下。
hosts文件:
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
192.168.*.250   DL              #PRE             #PC机(DL)
192.168.*.251   R478          #PRE             #TL-R478+路由器  校园网
192.168.*.252  R300           #PRE             #MW300R路由器
192.168.*.253   4K              #PRE             #PC机(4K)
192.168.*.230  TV              #PRE             #电视
192.168.*.231  Z9F             #PRE             #音响
192.168.*.232  BD              #PRE             #播放机
192.168.*.1  AC5300        #PRE             #主路由器
192.168.*.2  H3C              #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/ S50hosts
S50hosts脚本如下:
#!/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.conf
cp  /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=1
nvram set jffs2_exec=”sh /jffs/init.sh”
以上命令指定路由器启动时,自动运行 /jffs/init.sh脚本。

nvram show|grepjffs2_  命令查看JFFS分区启动自动执行脚本的设置如下:
jffs2_enable=1
jffs2_exec=sh/jffs/init.sh
jffs2_format=0
jffs2_on=1
jffs2_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=“”指定脚本执行这一机制目前还有效。

-完-

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

561

主题

2018

回帖

7554

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
7554

RT-AC88U

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

561

主题

2018

回帖

7554

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
7554

RT-AC88U

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

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

2

主题

6

回帖

68

积分

注册会员

Rank: 2

积分
68
 楼主| 发表于 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被冲掉后就可以恢复。

2

主题

6

回帖

68

积分

注册会员

Rank: 2

积分
68
 楼主| 发表于 2021-2-3 12:51:41 | 显示全部楼层
iphone8 发表于 2021-2-3 09:19
另外,如果仅想顺利管控不同设备,指定固定 IP,同时又担心重启路由器之后再导入hosts的话。

你可以路由器 ...

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

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

561

主题

2018

回帖

7554

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
7554

RT-AC88U

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

嗯嗯,好做法。

561

主题

2018

回帖

7554

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
7554

RT-AC88U

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

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

0

主题

3

回帖

21

积分

新手上路

Rank: 1

积分
21
发表于 2023-5-17 22:07:43 | 显示全部楼层
目前这个 script_usbmount 也没有了, 没找到这个脚本

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

0

主题

3

回帖

22

积分

新手上路

Rank: 1

积分
22
发表于 2023-6-3 12:30:34 | 显示全部楼层
了迎林 发表于 2023-5-17 22:07
目前这个 script_usbmount 也没有了, 没找到这个脚本

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

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

0

主题

5

回帖

16

积分

新手上路

Rank: 1

积分
16
发表于 2023-7-25 21:45:41 | 显示全部楼层
大佬,似乎失效了,今年更新的官方固件386.5xxxx重启后无效,RT-AC86U最后一个可用版本是48260
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

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

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

秒后自动关闭

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

GMT+8, 2024-4-28 21:49 , Processed in 0.043585 second(s), 33 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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