Skip to content

Instantly share code, notes, and snippets.

@wd
Last active August 19, 2023 22:23
Show Gist options
  • Save wd/e0bc83b33ce63506a9bdbc3b81658c52 to your computer and use it in GitHub Desktop.
Save wd/e0bc83b33ce63506a9bdbc3b81658c52 to your computer and use it in GitHub Desktop.
路由器梅林固件上面使用 v2ray 的方案
{
"log": {
"loglevel": "none"
},
"inbound": {
"port": 23456,
"listen": "127.0.0.1",
"protocol": "socks",
"settings": {
"udp": true
}
},
"inboundDetour":
[{
"port": 3333,
"listen": "0.0.0.0",
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
}
}],
"outbound": {
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "这里输入你的服务器信息",
"port": 443,
"users": [
{
"id": "这里输入你的id,其他配置根据你需要配置",
"alterId": 64,
"security": "auto"
}
]
}
]
},
"streamSettings":
{
"network": "tcp",
"security": "tls",
"tlsSettings": { "allowInsecure": true }
}
},
"policy": {
"levels": {
"0": {"uplinkOnly": 0}
}
}
}
#!/bin/sh
CUR_VER=""
NEW_VER=""
ARCH=""
VDIS="arm"
ZIPFILE="/tmp/v2ray/v2ray.zip"
V2RAY_DIR="/jffs/v2ray"
CMD_INSTALL=""
CMD_UPDATE=""
SOFTWARE_UPDATED=0
#######color code########
RED="31m"
GREEN="32m"
YELLOW="33m"
BLUE="36m"
sysArch(){
ARCH=$(uname -m)
if [[ "$ARCH" == "i686" ]] || [[ "$ARCH" == "i386" ]]; then
VDIS="32"
elif [[ "$ARCH" == *"armv7"* ]] || [[ "$ARCH" == "armv6l" ]]; then
VDIS="arm"
elif [[ "$ARCH" == *"armv8"* ]] || [[ "$ARCH" == "aarch64" ]]; then
VDIS="arm64"
elif [[ "$ARCH" == *"mips64le"* ]]; then
VDIS="mips64le"
elif [[ "$ARCH" == *"mips64"* ]]; then
VDIS="mips64"
elif [[ "$ARCH" == *"mipsle"* ]]; then
VDIS="mipsle"
elif [[ "$ARCH" == *"mips"* ]]; then
VDIS="mips"
elif [[ "$ARCH" == *"s390x"* ]]; then
VDIS="s390x"
fi
return 0
}
colorEcho(){
COLOR=$1
echo -e "\033[${COLOR}${@:2}\033[0m"
}
downloadV2Ray(){
rm -rf /tmp/v2ray
mkdir -p /tmp/v2ray
colorEcho ${BLUE} "Downloading V2Ray."
DOWNLOAD_LINK="https://github.com/v2ray/v2ray-core/releases/download/${NEW_VER}/v2ray-linux-${VDIS}.zip"
curl -L -H "Cache-Control: no-cache" -o ${ZIPFILE} ${DOWNLOAD_LINK}
if [ $? != 0 ];then
colorEcho ${RED} "Failed to download! Please check your network or try again."
exit 1
fi
return 0
}
installSoftware(){
COMPONENT=$1
if [[ -n `command -v $COMPONENT` ]]; then
return 0
fi
getPMT
if [[ $? -eq 1 ]]; then
colorEcho $YELLOW "The system package manager tool isn't APT or YUM, please install ${COMPONENT} manually."
exit
fi
colorEcho $GREEN "Installing $COMPONENT"
if [[ $SOFTWARE_UPDATED -eq 0 ]]; then
colorEcho ${BLUE} "Updating software repo"
$CMD_UPDATE
SOFTWARE_UPDATED=1
fi
colorEcho ${BLUE} "Installing ${COMPONENT}"
$CMD_INSTALL $COMPONENT
if [[ $? -ne 0 ]]; then
colorEcho ${RED} "Install ${COMPONENT} fail, please install it manually."
exit
fi
return 0
}
extract(){
colorEcho ${BLUE}"Extracting V2Ray package to /tmp/v2ray."
mkdir -p /tmp/v2ray
unzip $1 -d "/tmp/v2ray/"
if [[ $? -ne 0 ]]; then
colorEcho ${RED} "Extracting V2Ray faile!"
exit
fi
return 0
}
# 1: new V2Ray. 0: no
getVersion(){
CUR_VER=`$V2RAY_DIR/v2ray -version 2>/dev/null | head -n 1 | cut -d " " -f2`
TAG_URL="https://api.github.com/repos/v2ray/v2ray-core/releases/latest"
NEW_VER=`curl ${PROXY} -s ${TAG_URL} --connect-timeout 10| grep 'tag_name' | cut -d\" -f4`
if [[ $? -ne 0 ]] || [[ $NEW_VER == "" ]]; then
colorEcho ${RED} "Network error! Please check your network or try again."
exit
elif [[ "$NEW_VER" != "$CUR_VER" ]];then
return 1
fi
return 0
}
copyFile() {
NAME=$1
MANDATE=$2
ERROR=`cp "/tmp/v2ray/v2ray-${NEW_VER}-linux-${VDIS}/${NAME}" "$V2RAY_DIR/${NAME}"`
if [[ $? -ne 0 ]]; then
colorEcho ${YELLOW} "${ERROR}"
if [ "$MANDATE" = true ]; then
exit
fi
fi
}
installV2Ray(){
# Install V2Ray binary to $V2RAY_DIR
mkdir -p $V2RAY_DIR
copyFile v2ray true
makeExecutable v2ray
copyFile v2ctl false
makeExecutable v2ctl
copyFile geoip.dat false
copyFile geosite.dat false
return 0
}
makeExecutable() {
chmod +x "$V2RAY_DIR/$1"
}
updateWatchDog() {
colorEcho ${GREEN} "Update v2ray_watchdog.sh"
echo "IyEvYmluL3NoCgp2MnJheT0nL2pmZnMvdjJyYXkvdjJyYXknCgppc192MnJheV9hbGl2ZSgpIHsKICAgIHYycmF5X2NvdW50PWBwcyAtdyB8Z3JlcCAnL2pmZnMvdjJyYXkvdjJyYXknfGdyZXAgLXYgZ3JlcHxncmVwIC12IHdhdGNoZG9nfHdjIC1sYAogICAgaWYgWyAiJHYycmF5X2NvdW50IiAtZXEgMSBdO3RoZW4KICAgICAgICByZXR1cm4gMCAgIyB3b3JrIG9rCiAgICBlbHNlCiAgICAgICAgcmV0dXJuIDEKICAgIGZpCn0KCnJlc3RhcnRfdjJyYXkoKSB7CiAgICBraWxsYWxsIHYycmF5ID4vZGV2L251bGwgMj4mMQogICAgJHYycmF5ICYKICAgIGVjaG8gJCQgPiAvdG1wL3YycmF5LnBpZAp9CgpzdG9wX3NzKCkgewogICAga2lsbGFsbCBzcy1sb2NhbCA+L2Rldi9udWxsIDI+JjEKICAgIGtpbGxhbGwgc3MtcmVkaXIgPi9kZXYvbnVsbCAyPiYxCn0KCm1haW4oKXsKICAgIGlzX3YycmF5X2FsaXZlCiAgICBpZiBbICIkPyIgLW5lIDAgXTt0aGVuCiAgICAgICAgc3RvcF9zcwogICAgICAgIHJlc3RhcnRfdjJyYXkKICAgICAgICBlY2hvICJ2MnJheSByZXN0YXJ0IGF0ICIkKGRhdGUpID4+IC90bXAvdjJyYXkubG9nCiAgICBmaQp9CgptYWluCg==" > /tmp/dog.in
base64 -d /tmp/dog.in > "$V2RAY_DIR/v2ray_watchdog.sh"
rm /tmp/dog.in
}
main() {
# dowload via network and extract
updateWatchDog
getVersion
if [[ $? == 0 ]]; then
colorEcho ${GREEN} "Lastest version ${NEW_VER} is already installed."
exit
else
colorEcho ${BLUE} "Installing V2Ray ${NEW_VER} on ${ARCH}"
downloadV2Ray
extract ${ZIPFILE}
fi
installV2Ray
colorEcho ${GREEN} "V2Ray ${NEW_VER} is installed."
rm -rf /tmp/v2ray
return 0
}
main
# 修改 /jffs/scripts/nat-start 和 /jffs/scripts/wan-start 都增加一行 cron 的配置,定时跑 watchdog 检查服务
# 注意:下面的 admin 需要改成你自己的用户名
grep -q 'v2ray_watchdog.sh' /var/spool/cron/crontabs/admin || echo "*/5 * * * * /bin/sh /jffs/v2ray/v2ray_watchdog.sh" >> /var/spool/cron/crontabs/admin
#!/bin/sh
v2ray='/jffs/v2ray/v2ray' # v2ray 的所有文件放到 /jffs/v2ray 下面
is_v2ray_alive() {
v2ray_count=`ps -w |grep '/jffs/v2ray/v2ray'|grep -v grep|grep -v watchdog|wc -l`
if [ "$v2ray_count" -eq 1 ];then
return 0 # work ok
else
return 1
fi
}
restart_v2ray() {
killall v2ray >/dev/null 2>&1
$v2ray &
echo $$ > /tmp/v2ray.pid
}
stop_ss() {
killall ss-local >/dev/null 2>&1
killall ss-redir >/dev/null 2>&1
}
main(){
is_v2ray_alive #判断 v2ray 是不是还活着
if [ "$?" -ne 0 ];then
stop_ss # 停止 ss 相关进程,因为我们会用 v2ray 代替他
restart_v2ray # 启动 v2ray
echo "v2ray restart at "$(date) >> /tmp/v2ray.log
fi
}
main
@wd
Copy link
Author

wd commented Feb 10, 2018

建议 kooshare ss 插件版本在 3.8.6 以上的,使用 https://gist.github.com/wd/1445e3fcf0c9bc535a6e70d2de1d1624 方案。相对简单一点。

这个方法整体的思路是,在后台配置使用 ss 的方案,然后我们把 ss 这些进程提供的功能用 v2ray 替代。这样无缝替换掉 ss。所以上面的 23456 端口和 3333 端口都必须和 ss 原有的对应,如果用的方案和我的不一样,那可以自己调整一下。

注意:

  1. 因为路由器上面内存有限,所以需要调整 alterId 为比较小的数值,这个值不同路由器会不一样,我这里使用的是 r6300v2,使用 10 没问题。alterId 调整需要服务器端一起调整,所以如果你的服务器端服务不是你自己搭建的不能修改的话,那么得有心理准备,可能跑不起来。
  2. 上面的文件,都必须要求是 utf8 no bom unix 格式的。可以通过点击文件右边的 raw 按钮,得到文件的 url,然后在路由器上面执行 wget url 获取文件。如果你用的是 windows,或者看不懂我说的是什么,那最好在路由器上面直接执行下面的语句。这个步骤,代替了下面的 1-3 步骤。这个脚本修改自 v2ray 官方的那个,修改了一下目录。这个脚本可以多次执行,以后升级的时候可以直接执行这个脚本完成。
# wget https://gist.githubusercontent.com/wd/e0bc83b33ce63506a9bdbc3b81658c52/raw/4820a3d2886edef48997aa314db249cfce27a321/go_arm.sh
# chmod +x go_arm.sh
# ./go_arm.sh

注意:如果执行了上面的操作,那就继续执行下面的 4 就可以,跳过 1,2,3。

注意:下面命令只复制 # 后面的,# 不需要复制。

  1. 下载 v2ray arm 版本,arm 版本有两个,一个是 arm,一个是 arm64 。我的是 armv7 的,使用 arm 版本。
# uname -a
Linux wd 2.6.36.4brcmarm #40 SMP PREEMPT Mon Jul 17 13:47:41 CST 2017 armv7l ASUSWRT-Merlin
  1. 下载之后,解压,放到 /jffs/v2ray/ 目录里面。把上面提到的 config.jsonv2ray_watchdog.sh 也放进去。
# ls /jffs/v2ray/
config.json        geoip.dat          geosite.dat        v2ctl*             v2ctl.sig          v2ray*             v2ray.sig          v2ray_watchdog.sh*
  1. 给程序增加可执行权限。
# chmod +x /jffs/v2ray/v2ray
# chmod +x /jffs/v2ray/v2ctl
# chmod +x /jffs/v2ray/v2ray_watchdog.sh

有些人使用 windows 会传上去不符合要求的格式的文件,执行下面的命令可以修复。

# dos2unix /jffs/v2ray/v2ray_watchdog.sh
# dos2unix  /jffs/v2ray/config.json
  1. 先在路由器后台把 ss 相关的配置都关闭。就是那个「科学上网开关」处于关闭状态。然后手动运行一下 /jffs/v2ray/v2ray_watchdog.sh 看看是不是不报错,如果有报错,那需要先解决错误。
  2. 在梅林后台,打开 ss 开关,任意配置一个节点,选 gfwlist 模式(其他模式应该也可以支持,没有深入测试过,建议可以先用这个模式测试可以用之后,再调整其他模式),节点 ip 和用户信息什么的全部都可以随便写(注意要关闭 obfs),国外 dns 配置为 chinadns1(如果配置为其他的,需要调整对应 watchdog 脚本,因为不同方案可能使用的 dns 查询方案不一样,端口可能会不一样,我只测试了这个方案)
  3. 点击保存应用,然后 merlin 会启动 ss 相关的程序。这个时候后台会显示国外连接是失败的。不过没关系。
  4. 手动执行一下 v2ray_watchdog.sh
# /jffs/v2ray/v2ray_watchdog.sh
...... 这里会有一些输出
  1. 等 merlin 国外的下一个检查时间,一般几分钟内,国外连接会显示 ok。那么这个时候基本就是可行的了。下面是如何让 v2ray 自动启动。
  2. 修改 /jffs/scripts/nat-start/jffs/scripts/wan-start 增加一行,里面的 */5 是 5 分钟执行一次检查,如果你有需要更快,可以改成比如 */1 表示一分钟检查一次。另外,注意修改里面的 admin 为你自己的用户名,一共两个地方需要改。
grep -q 'v2ray_watchdog.sh' /var/spool/cron/crontabs/admin || echo "*/5 * * * * /bin/sh /jffs/v2ray/v2ray_watchdog.sh" >> /var/spool/cron/crontabs/admin
  1. 重启一下路由器。等路由器启动之后,可以看看 v2ray 进程是不是启动了。
  2. 如果你的 v2ray 服务器是通过域名访问的,请注意看下面 FAQ 里面的 2 。

************************************************ FAQ *********************************

  1. 如何判断 v2ray 是不是启动了?
    看到这个输出就表示启动了。
# ps |grep v2ray
 1598 admin     780m S    /jffs/v2ray/v2ray
  1. v2ray 进程启动了,但是还是不能上网翻怎么回事?
    这个需要自己确定下自己的 outbound 配置是否可用。另外如果你的 outbound 用的是域名方式,那可能还需要在路由器后台的 Shadowsocks 设置 -> 黑白名单 -> 域名白名单 里面增加自己的域名。同时还可能需要增加 ntp 的域名。这是个先有鸡还是先有蛋的问题,v2ray 需要访问域名 -> 查询 dns -> merlin ss 原来的逻辑会走到 v2ray 的 socks 端口 这样就死循环了,导致无法翻墙。所以需要加白名单。
my.domain.com
pool.ntp.org
  1. 出现一会可以翻一会不能翻的情况怎么回事?
    看看 /tmp/v2ray.log 里面,是不是 v2ray 有崩溃重启的情况
# cat /tmp/v2ray.log
v2ray restart at Sun Feb 11 07:30:01 GMT 2018
v2ray restart at Sun Feb 11 07:35:01 GMT 2018
v2ray restart at Sun Feb 11 07:40:01 GMT 2018
v2ray restart at Sun Feb 11 07:45:01 GMT 2018

如果有,那么一般是内存问题。这个可以通过调整 config.json 输出更详细的 debug 信息看看。
我尝试了使用 swap 可以减少崩溃的情况。具体你可以搜索一下,但是对你不一定管用。

  1. 遇到内存问题怎么办?
    试试看调整 alterId 到小一点的值,我开始的时候使用 64,发现崩溃很严重,1 分钟就崩溃。后来改成了 10,就没问题了,这个值应该和路由器内存有关系,可以多调整几次找到适合自己的。要注意,这个值是需要和服务器端一起调整的,不能只调整客户端。

  2. 如何用回 ss ?
    如果不想用 v2ray 了,那可以修改 /jffs/v2ray/v2ray_watchdog.sh 在最后一行 main 前加一个 # 变成 #main,然后执行 killall v2ray ,之后就可以在 merlin 后台正常配置 ss 了。

  3. 如何检查 json 格式?
    可以访问 http://json.parser.online.fr/ ,把你自己的 json 贴进去。注意这里是不支持 json 里面的注释信息的,就是那些 // 后面的内容,需要删除才能在这里检查。

  4. 提示 Permission denied
    这个可能有几个情况
    a. 文件没有执行权限。执行 chmod +x 文件名可以解决。
    b. 磁盘空间不足。执行 df -h 看看,/jffs 分区和 /tmp 分区是不是还有空间。

  5. 如何使用 swap
    我是接了一个几个 G 的老 U 盘。接上去之后会自动挂载,我这设备是 /dev/sda1

# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                26.6M     26.6M         0 100% /
devtmpfs                124.8M         0    124.8M   0% /dev
tmpfs                   124.9M    908.0K    124.0M   1% /tmp
/dev/mtdblock5           88.8M     21.7M     67.0M  24% /jffs
/dev/sda1                 3.7G    284.1M      3.3G   8% /tmp/mnt/1.42.6-5644

/jffs/scripts/post-mount 里面,增加下面的内容,重启路由器启动的时候会自动建立一个 500M(有需要可以改下面的 500) 的 swap。

if [ -b /dev/sda1 ];then
    mkdir -p /tmp/opt
    mount -t ext4 -o rw,noatime /dev/sda1 /opt
    if [ -f /opt/swap ];then
        dd if=/dev/zero of=/opt/swap bs=1M count=500
        mkswap /opt/swap
    fi
    swapon /opt/swap
fi

启动之后,看看 swap 是不是启用了。最后那行应该只有中间一个是 0,表示启用成功。

# free -m
             total       used       free     shared    buffers     cached
Mem:        255716      72080     183636          0       1068      12476
-/+ buffers/cache:      58536     197180
Swap:       184316          0     184316
  1. v2ray 多节点启用负载均衡和灾备
    v2ray 的 vmess 协议,本身是支持多节点负载均衡的,但是没有故障转移功能。在其中一个节点挂掉的时候,不能自动转移到其他节点。可以用梅林自带的 haproxy 来解决这个问题。

注意:这个方案,我只测试了裸的 vmess 协议,没测试 websocket,tls 这些设置,这些可能是不行的,自己测试看吧。

在 Shadowsocks -> 负载均衡里面,启用负载均衡,配置一个端口,比如 1080,其他内容根据自己的需要设定,可以分配不同的权重什么的,也可以直接是相同权重,这些具体参考 haproxy 的逻辑吧。

添加之后,在 ss 那里选择不选择这个节点关系都不大。在你的 v2ray 的配置文件里面,outbound 部分要使用服务器 127.0.0.11080 端口。然后重启一下 v2ray 看看。

@wd
Copy link
Author

wd commented Feb 12, 2018

预留。

@wd
Copy link
Author

wd commented Mar 21, 2018

再单独说一下配置的修改,v2ray 的配置非常灵活,大家各自的情况都不一样。我尝试用简单的方法告诉你怎么做。

  1. 你先找一个可以图形配置的客户端,比如 Mac 的,ios 的等等,然后在上面配置一个你可以用的配置。然后把他的配置文件复制出来。
  2. 调整这个配置,把我这需要的配置加进去。json 对于数据的格式要求很严格,一个逗号都不能多。所以建议修改的时候,去 http://json.parser.online.fr/ ,这样修改之后如果有错误,他会立刻提示你。
  3. 调整方法如下,把 inbound 部分,替换成下面的。注意最后面的那个逗号,也需要有。
  "inbound": {
      "port": 23456,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "settings": {
        "udp": true
      }
    },
  "inboundDetour":
  [{
         "port": 3333,
         "listen": "0.0.0.0",
         "protocol": "dokodemo-door",
         "settings": {
             "network": "tcp,udp",
             "followRedirect": true
         }
  }],
  1. 其他部分不用动,看看是不是可以。如果还是不行,那就只能是自己研究下配置了。

@wd
Copy link
Author

wd commented Mar 23, 2018

如果要汇报问题,那么先准备好下面的内容:

  1. 执行命令 ps |grep v2ray 的输出。
  2. 执行命令 netstat -nlp |grep 'v2ray' 的输出。
  3. 执行命令 tail /tmp/v2ray.log 的输出。
  4. 执行命令 cat /jffs/scripts/nat-start |grep v2ray 的输出。
  5. 执行命令 cat /jffs/scripts/wan-start |grep v2ray 的输出。
  6. 执行命令 cat /var/spool/cron/crontabs/*|grep v2ray 的输出。
  7. 执行命令 ps |grep 23456 的输出。
  8. 路由器后台 Shadowsocks 里面 「账号设置」 「DNS设定」 「黑白名单」三个界面的截图。

@23202
Copy link

23202 commented Apr 4, 2018

感谢作者的辛苦劳动,如果能有现成安装包就好了。我通过ssh登录8500 后台后使用代替1-3那步,提示下载v2ray结果一直走下载,下了整整20分钟还是不行,不知道什么原因,不知道是不是我路由ssr没关闭的原因。

@imoldchen
Copy link

3.8.5版插件支持脚本了,可以做成v2ray脚本吗?这样可以省掉开机和定时运行监控脚本,维护升级也方便多了。

@wd
Copy link
Author

wd commented Apr 15, 2018

@imoldchen 做了一个新的方案 https://gist.github.com/wd/1445e3fcf0c9bc535a6e70d2de1d1624 有兴趣可以试试看。

@shichaochen
Copy link

Thanks!

@manchinhoo
Copy link

感谢!!!!!!!

@z16166
Copy link

z16166 commented Mar 21, 2020

这个arm版本为啥能跑起来的?我看梅林用的是uClibc。如果用普通的libc编译出来的二进制,应该跑不起来才对的呀。

我从V2ray的官网下载的linux arm版本的v2ray,一跑直接就是Illegal Instruction。只好自己编译了一个针对梅林的V2ray版本。

@wd
Copy link
Author

wd commented Mar 22, 2020

arm 似乎有 arm, armv7, arm64,我看 v2ray 提供了 arm 和 arm64 版本,是不是都试试看?我这跑没问题的,不用自己编译。
我的是 AC86u,uname -a 输出如下

Linux tux 4.1.27 #2 SMP PREEMPT Wed Jul 31 14:51:32 EDT 2019 aarch64 ASUSWRT-Merlin

v2ray -version 输出

V2Ray 4.22.1 (V2Fly, a community-driven edition of V2Ray.) Custom (go1.13.5 linux/arm64)
A unified platform for anti-censorship.

@cadexI9wUR7
Copy link

大佬可否做一个独立版的安装包啊?完全没理解为何你(似乎)连独立的插件控制页面都做出来了,为何还需要通过ss补丁的方式安装?
现在可否更新xray或者v2fly内核?另外你博客里说的奔溃了自动重启插件似乎被你删了?谢谢

@wd
Copy link
Author

wd commented Apr 25, 2023

不是已经有官方插件了吗?别用这个了吧。我好久不用 merlin 和 v2ray 了。

@cadexI9wUR7
Copy link

cadexI9wUR7 commented Apr 25, 2023

😅啊?!有官方的吗?我是想跑服务端的,梅林我只找到ssserver和fancyss。但是fancyss是客户端的。看了下你的代码,似乎是跑v2ray然后可以自定义config.json?所以可以当成服务器用?(所以你说的替换ss是指替换ss客户端啊?)

@wd
Copy link
Author

wd commented Apr 25, 2023

这个基于 kooshare 梅林固件的,你可以去看看他们有没有 v2ray 支持。我记得是有了的。

@cadexI9wUR7
Copy link

cadexI9wUR7 commented Apr 25, 2023

看过了,没有。。。或许是谁在论坛上发布的吧😅。。。就是没找到v2ray,xray之类的插件。整个github感觉你的最接近了。。。
https://github.com/koolshare/armsoft
https://github.com/orgs/koolshare/repositories

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment