v2ray介绍

参考这两篇

第二篇适合小白,从未接触过v2ray,第一篇适合玩会一点v2ray, 想了解更多。

自己的文章记录自己实践过程,主要内容:

  • 下载安装及基本配置
  • 路由功能区别内外流量
  • DNS按需解析
  • 兼容酸酸乳
  • websocket
  • 流量统计

下载安装

1
2
wget https://install.direct/go.sh
sudo bash go.sh

或者直接去https://github.com/v2ray/v2ray-core/releases 下载
(直接下载的,要把v2ray及v2ctl增加执行权限,不然会出现permission denied)

两种方式差不多,脚本的方式把v2ray安装成服务。配置文件在/etc/v2ray目录下

测试配置文件是否有效:
v2ray -test -config /etc/v2ray/config.json

启动:
sudo systemctl start v2ray

其中uuid是自动生成,可以用命令uuidgen生成

基本的配置

服务器与客户端都是同一套软件,只是应用的配置不同

服务端的最小化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"inbounds": [
{
"port": 1234,
"protocol": "vmess",
"settings":
{
"clients": [
{
"id": "7d66acdb-5491-4d0e-a894-024bdcbd8e28",
"level": 1,
"alterId": 64
}]
}
}],
"outbounds": [
{
"protocol": "freedom",
"settings":
{}
}]
}

客户端的最小化配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"inbounds": [
{
"port": 1087,
"protocol": "socks"
}],
"outbounds": [
{
"protocol": "vmess",
"settings":
{
"vnext": [
{
"address": "serverip",
"port": 1234,
"users": [
{
"id": "7d66acdb-5491-4d0e-a894-024bdcbd8e28",
"alterId": 64
}]
}]
}
}]
}

解释

这只是一个最小的化的配置,帮助理解这其中的通讯过程。

  • 每个节点(客户端,或者服务端)都最小有一个inbound和一个outbound
  • 数据流量从inbound进,从outbound出,配置中指定了inbound和outbound的进出协议。
  • vmess是v2ray自定义的协议,freedom是什么都不干,直接交付的协议,socks就是普通的socks代理协议
  • 浏览器–(socks)–>v2ray客户端的inbound—->v2ray客户端的outbound–(vmess)–>v2ary服务端的inbound–>v2ary服务端的outbound–(freedom)–>目标站点
  • v2ray客户端要与v2ary服务端达成协议,需要统一id及端口,id是由uuid生成的。
  • 如果配置中出现未知错误,可以把日志打开
    1
    2
    3
    4
    5
    6
    "log":
    {
    "access": "log/access.log",
    "error": "log/error.log",
    "loglevel": "info"
    }

协议列表

  • Blackhole 它会阻碍所有数据的出站,配合路由(Routing)一起使用,可以达到禁止访问某些网站的效果
  • Dokodemo-door (任意门)是一个入站数据协议,它可以监听一个本地端口,并把所有进入此端口的数据发送至指定服务器的一个端口,从而达到端口映射的效果。
  • Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。
  • HTTP 是一个入站数据协议,兼容 HTTP 1.x 代理。
  • MTProto 是一个 Telegram 专用的代理协议
  • Shadowsocks 包含入站和出站两部分,兼容大部分其它版本的实现
  • Socks 标准 Socks 协议实现,兼容 Socks 4、Socks 4a 和 Socks 5
  • VMess 是一个加密传输协议,依赖于系统时间

路由功能

上面只是一个简单的加密代理功能,在它的基础之上再增加配置,可以增加更多实用的功能。
考虑到场景:

  • 浏览器在代理的时候,不希望把本地的地址如192.168.2.x的请求也转发到远程服务器。
  • 浏览器在代理的时候,不希望把国内的域名站点的请求转发到远程服务器。

在这里就需要根据ip/域名,把不同的流量转发到不同的出口。v2ray就提供这样的功能。
(其它的代理软件一般是用pac方式)

要根据ip/域名转发,首先要解析出当前流量的ip/域名。
需要在inbounds中开启sniffing嗅探。

1
2
3
4
5
6
7
8
9
10
11
"inbounds": [
{
"port": 1085,
"listen": "127.0.0.1",
"protocol": "socks",
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
],

在outbounds中再增加几个出口,添加标签,供路由选择。

1
2
3
4
5
6
7
8
9
10
11
12
{
"protocol": "freedom",
"settings":
{},
"tag": "direct"
},
{
"protocol": "blackhole",
"settings":
{},
"tag": "blocked"
}

增加路由配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"routing":
{
"domainStrategy": "IPOnDemand",
"rules": [
{
"type": "field",
"ip": ["geoip:private", "geoip:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:category-ads"],
"outboundTag": "blocked"
}]
},

上面配置的含义是
* ip在geoip:private(私有网段)及geoip:cn(中国网段),进行直联。

  • 域名在geosite:cn(国内常用域名),进行直联
  • 域名在geosite:category-ads(常见的广告域名),进行拦截
  • 没有匹配到的域名与ip,就默认走outbounds中的第一项,就是vmess协议。

这样就实现国内外流量的分流。可以认为是白名单走国内。其它走代理。

这里只对客户端进行配置。

domainStrategy 域名解析策略

目前只有三个可以取的值。”AsIs” | “IPIfNonMatch” | “IPOnDemand”

  • “AsIs”: 只使用域名进行路由选择。默认值。
  • “IPIfNonMatch”: 当域名没有匹配任何规则时,将域名解析成 IP(A 记录或 AAAA 记录)再次进行匹配;
    • 当一个域名有多个 A 记录时,会尝试匹配所有的 A 记录,直到其中一个与某个规则匹配为止;
    • 解析后的 IP 仅在路由选择时起作用,转发的数据包中依然使用原始域名;
  • “IPOnDemand”: 当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配;

关于DNS的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"dns":{
"servers":[
{
"address":"114.114.114.114",
"port":53,
"domains":[
"geosite:cn"
]
},
"1.1.1.1",
"8.8.8.8",
"localhost"
]
}

这里的配置是让geosite:cn中的域名,使用114进行解析。别的域名使用1.1.1.1进行解析。
因为1.1.1.1所属ip不在cn中,根据路由规则,直接使用默认代理。相关的dns解析会到远程服务器上。

验证工具 curl

socks5h会使用代理服务器的dns,而socks5会使用本地的dns。会存在被污染的可能。

1
curl -x socks5h://127.0.0.1:1087 www.google.com

如何验证上面的dns是按相应的规则进行解析

首先把服务端及客户端log的级别打开到debug。
如果是国内域名,可能会出现如下日志。
[Debug] v2ray.com/core/app/dns: querying DNS for: xx.example.com.
[Debug] v2ray.com/core/transport/internet/udp: dispatch request to: udp:114.114.114.114:53
如果是国外域名,客户端可能出现如下日志。
[Debug] v2ray.com/core/app/dns: updating IP records for domain:xx.example.com
服务端:accepted udp:1.1.1.1:53

兼容酸酸乳

把默认的outbound替换下协议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"protocol": "shadowsocks",
"settings": {
"servers": [
{
"address": "server.com",
"method": "chacha20",
"ota": false,
"password": "password",
"port": 1234
}
]
}
},

以网关方式做透明代理

  • 风关机开启ip转发,编辑/etc/sysctl.conf添加一行net.ipv4.ip_forward1。再执行sysctl -p使之生校。
  • 让局域网的机器的网关ip指向网关机
  • 网关机配置好 v2ray
  • 添加v2ray配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    {
    "routing": {...},
    "inbounds": [
    {
    ...
    },
    {
    "port": 12345, //开放的端口号
    "protocol": "dokodemo-door",
    "settings": {
    "network": "tcp,udp",
    "followRedirect": true // 这里要为 true 才能接受来自 iptables 的流量
    },
    "sniffing": {
    "enabled": true,
    "destOverride": ["http", "tls"]
    }
    }
    ],
    "outbounds": [
    {
    ...
    "streamSettings": {
    ...
    "sockopt": {
    "mark": 255 //这里是 SO_MARK,用于 iptables 识别,每个 outbound 都要配置;255可以改成其他数值,但要与下面的 iptables 规则对应;如果有多个 outbound,最好奖所有 outbound 的 SO_MARK 都设置成一样的数值
    }
    }
    }
    ...
    ]
    }
  • 设定tcp透明代理的iptables规则

    1
    2
    3
    4
    5
    6
    iptables -t nat -N V2RAY # 新建一个名为 V2RAY 的链
    iptables -t nat -A V2RAY -d 192.168.0.0/16 -j RETURN # 直连 192.168.0.0/16
    iptables -t nat -A V2RAY -p tcp -j RETURN -m mark --mark 0xff # 直连 SO_MARK 为 0xff 的流量(0xff 是 16 进制数,数值上等同与上面配置的 255),此规则目的是避免代理本机(网关)流量出现回环问题
    iptables -t nat -A V2RAY -p tcp -j REDIRECT --to-ports 12345 # 其余流量转发到 12345 端口(即 V2Ray)
    iptables -t nat -A PREROUTING -p tcp -j V2RAY # 对局域网其他设备进行透明代理
    iptables -t nat -A OUTPUT -p tcp -j V2RAY # 对本机进行透明代理
  • 设定udp透明代理的iptables规则

    1
    2
    3
    4
    5
    6
    ip rule add fwmark 1 table 100
    ip route add local 0.0.0.0/0 dev lo table 100
    iptables -t mangle -N V2RAY_MASK
    iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -j RETURN
    iptables -t mangle -A V2RAY_MASK -p udp -j TPROXY --on-port 12345 --tproxy-mark 1
    iptables -t mangle -A PREROUTING -p udp -j V2RAY_MASK

注意事项且

上面的设置,如果访问国外的网站,依旧会使用系统的dns进行查询。可能有些网站会补污染。所以需要自己在客户端使用指定dns。这一步也可以由dhcp服务器来处理。

websocket方式

流量统计

grpc来获取

附录配置

这是用脚本安装后,服务器默认配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
"inbounds": [{
"port": 14321,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "7d66acdb-5491-4d0e-a894-024bdcbd8e28",
"level": 1,
"alterId": 64
}
]
}
}],
"outbounds": [{
"protocol": "freedom",
"settings": {}
},{
"protocol": "blackhole",
"settings": {},
"tag": "blocked"
}],
"routing": {
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "blocked"
}
]
}
}

客户端的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"inbounds": [
{
"port": 1080,
"protocol": "socks",
"sniffing":
{
"enabled": true,
"destOverride": ["http", "tls"]
},
"settings":
{
"auth": "noauth"
}
}],
"outbounds": [
{
"protocol": "vmess",
"settings":
{
"vnext": [
{
"address": "serveraddr.com",
"port": 16823,
"users": [
{
"id": "b831381d-6324-4d53-ad4f-8cda48b30811",
"alterId": 64
}]
}]
}
}]
}