v2ray多实例

v2ray多实例

之前买的代理服务,使用的是v2ray客户端(windows是v2rayN, linux是qv2ray, android的是v2rayNG)。有个问题, 服务商提供的是v2ray订阅链接。几乎是每天都需要手动更新一下订阅,通过订阅来生成新的服务器连接配置。

就想自己租一台外网vps, 搭一台自己的v2ray服务器自用。

v2ray服务端单实例

根据文档的说法,v2ray不区分服务端和客户端(几个客户端都是基于v2ray-core这个项目开发的),只是配置文件不相同。

先在服务器上安装v2ray。可以去github上下载对应版本的v2ray编译包。也可以github找fhs-install-v2ray这个项目(好像是),使用脚本自动安装,并提供了systemd服务。

搬v2ray官网服务端配置,自己设个uuid

{
    "inbounds": [
        {
            "port": 10086, // 服务器监听端口
            "protocol": "vmess",
            "settings": {
                "clients": [
                    {
                        "id": "b831381d-6324-4d53-ad4f-8cda48b30811"
                    }
                ]
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "freedom"
        }
    ]
}

然后在自己的各个v2ray客户端上增加一个vmess服务器配置(windows/linux/android客户端都有ui界面)。

试了下,没问题, 带宽也挺足。

一天多之后,外网vps服务器ip被封了。不是简单的封端口,而是整个ip都被封掉了。国内ping不通vps的ip地址。

网上听他们说可能会封几天到半年不等,而且vmess协议能被识别,一段时间内流量过大超过某个阈值就会被封ip或封端口。

从这个角度考虑, 是不是可以在v2ray服务端多开v2ray实例到多个端口,国内加一台中转v2ray, 连接到这些vps的v2ray实例上,我实际使用的v2ray客户端(在linux/windows上)连接的是这台国内的中转v2ray。中转v2ray上应该是会自动负载均衡的,分担到每个端口上的流量就不会太大(我比较担心gfw是按ip统计流量阈值的,那这么做就没有意义)。

OK,有思路就试一下。

v2ray多实例

大体不变,只是原来启动的是v2ray.service.现在通过脚本,循环启动多个v2ray@<port_i>.service。

看下最后有哪些文件:

  • systemd/v2ray@.service (从/etc/systemd/system/下复制出来的,脚本中会略有改动)
  • systemd/v2ray@.service.d/10-donot_touch_single_conf.conf_bak (从/etc/systemd/system/下复制出来的,后缀改为_bak注释掉了,可以不要)
  • template.json (v2ray服务端配置模板)
  • conf.d目录(里面的json文件是使用v2ray_server脚本,根据template.json自动生成的)
  • v2ray_server脚本
[root@localhost local]# tree v2ray_server/
v2ray_server/
├── conf.d
├── systemd
│   ├── v2ray@.service
│   └── v2ray@.service.d
│       └── 10-donot_touch_single_conf.conf_bak
├── template.json
└── v2ray_server

systemd/v2ray@.service如下

[root@localhost local]# cat v2ray_server/systemd/v2ray@.service
[Unit]
Description=V2Ray Service
Documentation=https://www.v2fly.org/
After=network.target nss-lookup.target

[Service]
User=nobody
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ExecStart=/usr/local/bin/v2ray run -config /usr/local/v2ray_server/conf.d/%i.json
#Restart=on-failure
RestartPreventExitStatus=23
#edited by jingmin
Restart=5min
LimitCORE=infinity
LimitNOFILE=102400
LimitNPROC=102400


[Install]
WantedBy=multi-user.target

template.json

[root@localhost local]# cat v2ray_server/template.json 
{
    "inbounds": [
        {
            //"port": 10086,
            "protocol": "vmess",
            "settings": {
                "clients": [
                    {
                        "id": "4bc74eef-0889-4b6b-86ce-3d5e24a62db4"
                    }
                ]
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "freedom"
        }
    ]
}

v2ray_server脚本

[root@localhost local]# cat v2ray_server/v2ray_server 
#!/bin/bash

### BEGIN INIT INFO
# Provides:          v2ray_server
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO



PORT_START=10000
PORT_END=10200
PORT_STEP=7

#使用说明,用来提示输入参数usage() {
    echo "Usage: sh 执行脚本.sh [start|stop|restart|status]"
    exit 1
}
 


#启动方法start(){
    init
    echo -------- Starting v2ray_server --------
    
    #for i in {10000..11000..7}
    for ((i=$PORT_START;i<=$PORT_END;i+=$PORT_STEP))
    do
        systemctl start v2ray@$i.service
    done
    echo --------v2ray_server is Running --------------

}
 
#停止方法stop(){
    echo -------- Stopping v2ray_server --------

    #for i in {10000..11000..7}
    for ((i=$PORT_START;i<=$PORT_END;i+=$PORT_STEP))
    do
        systemctl stop v2ray@$i.service
    done
    echo ------------Stop v2ray_server ------------
 
}
 
#输出运行状态status(){
  echo -----------null ------------
}
 
#重启restart(){
  stop
  start
}



init(){

    #BASE_DIR=`dirname $0`
    BASE_DIR=$(dirname $(readlink -f $0))
    echo "cd $BASE_DIR"
    cd $BASE_DIR
    
    rm -rf ./conf.d/*

    #for i in {10000..11000..7}
    for ((i=$PORT_START;i<=$PORT_END;i+=$PORT_STEP))
    do
        #echo "welcome port $i"
        cp ./template.json ./conf.d/$i.json
        sed -i "/\/\/\"port\"\: 10086,/i \              \"port\"\:$i," ./conf.d/$i.json
    done

    #对path做转换,实现自动转义/字符    #https://juejin.cn/post/6887526056380039182
    #https://blog.51cto.com/xuke1668/868683
    BASE_DIR_ESCAPE=${BASE_DIR//\//\\\/}
    echo $BASE_DIR_ESCAPE
    sed -i "s/ExecStart=.*/ExecStart=\/usr\/local\/bin\/v2ray run -config ${BASE_DIR_ESCAPE}\/conf.d\/%i.json/g" ./systemd/v2ray@.service
    rm -rf /etc/systemd/system/v2ray*
    cp -rf ./systemd/v2ray* /etc/systemd/system/
    systemctl daemon-reload
}
 
#根据输入参数,选择执行对应方法,不输入则执行使用说明case "$1" in
  "start")
    start
    ;;
  "stop")
    stop
    ;;
  "status")
    status
    ;;
  "restart")
    restart
    ;;
  "init")
    init
    ;;
   *)
    usage
    ;;
esac
exit 0

v2ray国内中转

国内中转v2ray服务端。可以租一台国内的vps.

我的话是没有再买vps了。 家里用的电信宽带。打人工客服,要求分配公网IPv4。 买一个便宜点的域名。DnsPod动态域名绑定。github找脚本定时访问DnsPod的API更新自己家的IP-domain绑定。 电信光猫路由器找管理员帐号,设置端口映射或者DMZ主机,暴露家庭内网服务。 或者直接上软路由,光猫路由器改桥接(打电信人工客服),光猫只负责PPPoE拨号。(我这边是直接用了软路由方案,v2ray国内中转直接放到了软路由上) 基本上就可以当作vps来用了,而且带宽足够。

看一下有哪些文件:

[root@localhost local]# tree v2ray_client/
v2ray_client/
├── systemd
│   ├── v2ray.service
│   ├── v2ray.service.d
│       └── 10-donot_touch_single_conf.conf
├── template.json
└── v2ray_client
  • systemd目录下的服务文件,是及直接从/etc/systemd/system/目录下拷出来的,我记得没有改动
  • template.json 是v2ray客户端配置文件模板
  • v2ray_client脚本

template.json文件内容如下:

[root@localhost local]# cat v2ray_client/template.json 
{
    "inbounds": [
        {
            "tag":"transparent",
            "port": 12345,
            "protocol": "dokodemo-door",
            "settings": {
                "network": "tcp,udp",
                "followRedirect": true
            },
            "sniffing": {
                "enabled": true,
                "destOverride": [
                    "http",
                    "tls"
                ]
            },
            "streamSettings": {
                "sockopt": {
                    "tproxy": "tproxy", // 透明代理使用 TPROXY 方式                    "mark":255
                }
            }
        },
        {
            "listen": "127.0.0.1",
            "port": 15490,
            "protocol": "dokodemo-door",
            "settings": {
                "address": "127.0.0.1"
            },
            "sniffing": {
            },
            "tag": "QV2RAY_API_INBOUND"
        },
        {
            "listen": "0.0.0.0",
            "port": 8889,
            "protocol": "http",
            "settings": {
                "allowTransparent": true,
                "timeout": 300
            },
            "sniffing": {
            },
            "tag": "http_IN"
        },
        {
            "listen": "0.0.0.0",
            "port": 1089,
            "protocol": "socks",
            "settings": {
                "auth": "noauth",
                //"ip": "127.0.0.1",
                "udp": true
            },
            "sniffing": {
            },
            "tag": "socks_IN"
        }
    ],
    "log": {
        "loglevel": "warning",
        "access": "/tmp/v2ray_access.log",
        "error": "/tmp/v2ray_error.log"
    },
    "outbounds": [
        {
            "protocol": "vmess",
            "sendThrough": "0.0.0.0",
            "settings": {
                "vnext": [
                    //insert vnext here
                    //{
                    //    "address": "104.245.99.207",
                    //    "port": 18087,
                    //    "users": [
                    //        {
                    //            "id": "4bc74eef-0889-4b6b-86ce-3d5e24a62db4",
                    //            "security": "aes-128-gcm"
                    //        }
                    //    ]
                    //}
                ]
            },
            "streamSettings": {
                "sockopt": {
                    "mark": 255
                },
                "tlsSettings": {
                    "disableSystemRoot": false
                },
                "xtlsSettings": {
                    "disableSystemRoot": false
                }
            },
            "tag": "proxy"
        },
        {
            "protocol": "freedom",
            "sendThrough": "0.0.0.0",
            "settings": {
                //"domainStrategy": "AsIs",
                "domainStrategy": "UseIP",
                "redirect": ":0"
            },
            "streamSettings": {
                "sockopt": {
                    "mark": 255
                }
            },
            "tag": "direct"
        },
        {
            "protocol": "blackhole",
            "sendThrough": "0.0.0.0",
            "settings": {
                "response": {
                    //"type": "none"
                    "type": "http"
                }
            },
            "streamSettings": {
            },
            "tag": "block"
        },
        {
            "tag": "dns-out",
            "protocol": "dns",
            "streamSettings": {
                "sockopt": {
                    "mark": 255
                }
            }  
        }
    ],
    "dns": {
        "hosts": {
            "ole12138.top": "192.168.1.7"
        },
        "servers": [
            {
                "address": "223.5.5.5", //中国大陆域名使用阿里的 DNS
                "port": 53,
                "domains": [
                    "geosite:cn",
                    "ntp.org",   // NTP 服务器                    "justmysocks5.net", // 此处改为你 VPS 的域名                    "v4.myip.la", // ddns wan ip查询                    "bing.com"
                ]
            },
            {
                "address": "114.114.114.114", //中国大陆域名使用 114  DNS (备用)
                "port": 53,
                "domains": [
                    "geosite:cn",
                    "ntp.org",   // NTP 服务器                    "justmysocks5.net", // 此处改为你 VPS 的域名                    "v4.myip.la" // ddns wan ip查询                ]
            },
            {
                "address": "8.8.8.8", //非中国大陆域名使用 Google  DNS
                "port": 53,
                "domains": [
                    "geosite:geolocation-!cn"
                ]
            },
            {
                "address": "1.1.1.1", //非中国大陆域名使用 Cloudflare  DNS
                //"port": 53,
                "domains": [
                    "geosite:geolocation-!cn"
                ]
            }
        ]
    },
    "policy": {
        "system": {
            "statsInboundDownlink": true,
            "statsInboundUplink": true,
            "statsOutboundDownlink": true,
            "statsOutboundUplink": true
        }
    },
    "routing": {
        "domainStrategy": "IPOnDemand",
        "rules": [
            { // 劫持 53 端口 UDP 流量,使用 V2Ray  DNS
                "type": "field",
                "inboundTag": [
                    "transparent"
                ],
                "port": 53,
                "network": "udp",
                "outboundTag": "dns-out" 
            },    
            { // 直连 123 端口 UDP 流量(NTP 协议)                "type": "field",
                "inboundTag": [
                    "transparent"
                ],
                "port": 123,
                "network": "udp",
                "outboundTag": "direct" 
            },    
            {
                "type": "field", 
                "ip": [ 
                    // 设置 DNS 配置中的国内 DNS 服务器地址直连,以达到 DNS 分流目的                    "223.5.5.5",
                    "114.114.114.114"
                ],
                "outboundTag": "direct"
            },
            {
                "type": "field",
                "ip": [ 
                    // 设置 DNS 配置中的国外 DNS 服务器地址走代理,以达到 DNS 分流目的                    "8.8.8.8",
                    "1.1.1.1"
                ],
                "outboundTag": "proxy" // 改为你自己代理的出站 tag
            },
            //{ // 广告拦截            //    "type": "field", 
            //    "domain": [
            //        "geosite:category-ads-all",
            //        "geosite:category-porn"
            //    ],
            //    "outboundTag": "block"
            //},
            { // BT 流量直连                "type": "field",
                "protocol":["bittorrent"], 
                "outboundTag": "direct"
            },
            { // 直连中国大陆主流网站 ip  保留 ip
                "type": "field", 
                "ip": [
                    "geoip:private",
                    "geoip:cn"
                ],
                "outboundTag": "direct"
            },
            { // 直连中国大陆主流网站域名                "type": "field", 
                "domain": [
                    "geosite:cn",
                    "v4.myip.la", // ddns wan ip查询网址                    "ole12138.top", // ddns 关联的域名                    "domain:bing.com"
                ],
                "outboundTag": "direct"
            }
        ]
    },
    "stats": {
    }
}

其后有一部分是透明代理的配置,需要iptables的配合。emmm,这一块不影响,懒得鉴别出来删掉了,不影响。

v2ray_client脚本内容:

[root@localhost local]# cat v2ray_client/v2ray_client 
#!/bin/bash

### BEGIN INIT INFO
# Provides:          v2ray_client
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO


PORT_START=10000
PORT_END=11000
PORT_STEP=7

#使用说明,用来提示输入参数usage() {
    echo "Usage: sh 执行脚本.sh [start|stop|restart|status]"
    exit 1
}
 


#启动方法start(){
    init
    echo -------- Starting v2ray_server --------
    systemctl start v2ray.service
    echo --------v2ray_server is Running --------------

}
 
#停止方法stop(){
    echo -------- Stopping v2ray_server --------
    systemctl stop v2ray.service
    echo ------------Stop v2ray_server ------------
 
}
 
#输出运行状态status(){
  echo -----------null ------------
}
 
#重启restart(){
  stop
  start
}



init(){

    #BASE_DIR=`dirname $0`
    BASE_DIR=$(dirname $(readlink -f $0))
    echo "cd $BASE_DIR"
    cd $BASE_DIR
    
    cp -rf ./template.json ./tmp.json

    #for i in {10000..11000..7}
    for ((i=$PORT_START;i<=$PORT_END;i+=$PORT_STEP))
    do
        #echo "welcome port $i"
        sed -i "/\/\/insert vnext here/i \                   {" tmp.json
        #sed -i "/\/\/insert vnext here/i \                       \"address\"\: \"195.58.48.131\"," tmp.json
        sed -i "/\/\/insert vnext here/i \                       \"address\"\: \"98.142.140.53\"," tmp.json
        sed -i "/\/\/insert vnext here/i \                       \"port\"\: $i," tmp.json
        sed -i "/\/\/insert vnext here/i \                       \"users\"\: [" tmp.json
        sed -i "/\/\/insert vnext here/i \                           {" tmp.json
        sed -i "/\/\/insert vnext here/i \                           \"id\"\: \"4bc74eef-0889-4b6b-86ce-3d5e24a62db4\"" tmp.json
        sed -i "/\/\/insert vnext here/i \                           }" tmp.json
        sed -i "/\/\/insert vnext here/i \                       ]" tmp.json
        sed -i "/\/\/insert vnext here/i \                   }" tmp.json
        if (( $i+$PORT_STEP <= $PORT_END )) ; then
            sed -i "/\/\/insert vnext here/i \                   ," tmp.json
        fi
    done

    rm -rf /etc/systemd/system/v2ray.service
    cp -rf ./systemd/v2ray.service /etc/systemd/system/v2ray.service
    cp -rf ./tmp.json /usr/local/etc/v2ray/config.json
    systemctl daemon-reload
}
 
#根据输入参数,选择执行对应方法,不输入则执行使用说明case "$1" in
  "start")
    start
    ;;
  "stop")
    stop
    ;;
  "status")
    status
    ;;
  "restart")
    restart
    ;;
  "init")
    init
    ;;
   *)
    usage
    ;;
esac
exit 0

评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注