pls translate 


Catalog

    选型
    实现
    实战测试

WireGuard Over VLESS——一个更稳定的三层隧道
October 31, 2021 • Read: 39780 • 越过长城

WireGuard 作为一个更现代、更先进的 VPN 实现，比起传统的 IPSec、OpenVPN 等，效率更高、搭建更便捷，且已经合并入 Linux 内核，安装使用更加方便，被越来越多地应用在跨境隧道的使用当中，例如国内和国外机器通过 WireGuard 打通隧道，变成伪 IPLC 专线，有了这一层 VPN 协议的包裹，在伪专线中跑各类 Socks、SS 等代理协议就会多了一层保护，不再是裸奔状态。

但是，WireGuard 使用 UDP 实现，本身并非为了规避审查而设计，与代理协议一样存在被识别、干扰、阻断的问题，而且 UDP 在晚高峰时段速度时高时低，稳定性堪忧。因此，十分有必要给 WireGuard 再套一个隧道。
选型

综合考虑 V2Ray 系列的协议，最终选择了 VLESS。因为目前主流的规避审查的方式是依赖 TLS 的密码学强度保证安全，传输上靠伪装成 HTTPS 流量混淆视听，所以 VMESS/VLESS 协议相对更好，而 VMESS 协议自身带了一次加密，和 WireGuard 自身的加密功能重复，浪费了性能，使用无加密的 VLESS 更为合适。

VLESS 还处在上升期，有更好的扩展性，无论之后混淆方案如何发展，都能在传输上做调整，即修改 streamSettings 即可，而无需改变隧道协议部分。
实现

    国内机器 A，公网 IP 1.3.5.7，分配内网 IP 10.10.0.1
    国外机器 B，公网 IP 2.4.6.8，分配内网 IP 10.10.20.1

VLESS 配置

简便起见，直接使用 VLESS TCP 模式。

在国外机器 B 上建立 VLESS 入站，在 2.4.6.8 的 52220 端口 上接收 VLESS TCP 流量。

    {
        "log": {
            "loglevel": "debug"
        },
        "dns": {
            "servers": [
                "1.1.1.1",
                "8.8.8.8",
                "8.8.4.4"
            ]
        },
        "inbounds": [
            {
                "listen": "0.0.0.0",
                "port": 52220,
                "protocol": "vless",
                "settings": {
                    "clients": [
                        {
                            "id": "c71c5890-56dd-4f32-bb99-3070ec2f20fa"
                        }
                    ],
                    "decryption": "none"
                },
                "streamSettings": {
                    "network": "tcp"
                }
            }
        ],
        "outbounds": [
            {
                "protocol": "freedom",
                "settings": {
                    "domainStrategy": "UseIP"
                },
                "tag": "free"
            }
        ],
        "routing": {
            "rules": []
        }
    }

在国内机器 A 上建立 VLESS 出站，入站使用 dokodemo-door 协议，添加一个 UDP 转发，监听 A 上的 10000 端口的 UDP 流量，将该流量通过 VLESS 出站，转发到 Server 端的 127.0.0.1:10000 上。

    {
        "log": {
            "loglevel": "debug"
        },
        "inbounds": [
            {
                "listen": "127.0.0.1",
                "port": 10000,
                "protocol": "dokodemo-door",
                "settings": {
                    "address": "127.0.0.1",
                    "port": 10000,
                    "network": "udp"
                },
                "tag": "wg"
            }
        ],
        "outbounds": [
            {
                "protocol": "freedom",
                "settings": {}
            },
            {
                "protocol": "vless",
                "settings": {
                    "vnext": [
                        {
                            "address": "2.4.6.8",
                            "port": 52220,
                            "users": [
                                {
                                    "id": "c71c5890-56dd-4f32-bb99-3070ec2f20fa",
                                    "encryption": "none"
                                }
                            ]
                        }
                    ]
                },
                "streamSettings": {
                    "network": "tcp"
                },
                "tag": "vless-tunnel"
            }
        ],
        "routing": {
            "rules": [
                {
                    "type": "field",
                    "inboundTag": [
                        "wg"
                    ],
                    "outboundTag": "vless-tunnel"
                }
            ]
        }
    }

至此，我们可以将流向国内机器 A 127.0.0.1:10000 的 UDP 流量，经由 VLESS 隧道，转发到国外机器 B 的 127.0.0.1:10000 上。
WireGuard 配置

在国内机器 A 上，添加一个 Interface，设置 Endpoint 为 127.0.0.1:10000，流入 VLESS 的入站。

    [Interface]
    Address = 10.10.0.1
    DNS = 1.1.1.1
    PrivateKey = 私钥
    ListenPort = 51820
    MTU = 1420

    [Peer]
    PublicKey = B 的公钥
    AllowedIPs = 10.10.20.1
    Endpoint = 127.0.0.1:10000
    PersistentKeepalive = 20

在国外机器 B 上，也添加 Interface，监听在 10000 端口，接收 VLESS 转发过来的流量。

    [Interface]
    Address = 10.10.20.1
    ListenPort = 10000
    PrivateKey = 私钥
    MTU = 1420

    [Peer]
    PublicKey = A 的公钥
    AllowedIPs = 10.10.0.1

配置完毕，启动两台机器上的 VLESS 和 WireGuard，即可联通。

如需修改传输方式，可修改入站出站的 streamSettings 配置，具体可参考 https://github.com/XTLS/Xray-examples，不再赘述。
实战测试

国内机器上海 CN2 NAT，国外机器 AWS HK EC2，在晚高峰时段测试。

    TCP 直连
        89.6 Mbit/s
        ping 32.3 ms

    WireGuard Only
        6.4 Mbit/s
        ping 35.1 ms

    WireGuard Over VLESS TCP
        70.3 Mbit/s
        ping 33.5 ms

    WireGuard Over VLESS TCP WS
        68.8 Mbit/s
        ping 37.3 ms

可以看出，加上 TCP 隧道后，可明显提升 WireGuard 原生 UDP 被干扰的状态，ping 值变化不明显，推测 UDP 打洞连接是成功的，对 ping 的影响较小。
v2ray
vpn
wireguard
Tipping QR Code

谈谈怎样正确认识事物

构筑局部优势——浅谈应用安全「全局视野」建设
Leave a Comment

DO NOT Send me reply emails

15 Comments

    Han Han
    Reply
    November 3, 2021

    表哥太强了
    dodo dodo
    Reply
    November 9, 2021

    还可以更加优雅，因为 tls 和 wireguard 都有加密。考虑使用 GRE OVER GUE 效率更高。
        40huo 40huo
        Reply
        November 11, 2021

        @dodovless 不加 tls 可以避免双层加密的问题，不用 gre 是因为想用 wireguard 来着
    huazai huazai
    Reply
    November 12, 2021

    这个思路确实不错，wg 的性能比其他 VPN 确实还是强不少。
    Tom Tom
    Reply
    January 14, 2022

    没有测试，可以考虑在国内 nat 的 inbound "listen": "127.0.0.1", 这里监听 0.0.0.0 吗？这样就直接本机拨 nat 机器的 wireguard，出口就走国外 B 了？
    sir sir
    Reply
    January 20, 2022

    老兄，按照你这个代码提示无法出站～
    OwO OwO
    Reply
    January 29, 2022

    请问下表哥，用 wiregurard 中间的中继隧道应该怎么做？用 gost 吗？
    Wayne Wayne
    Reply
    July 20, 2022

    请问你是怎么测速的呀？ 两个不同网段的 IP 为啥搞得不一样呢？
    fscarmen fscarmen
    Reply
    September 1, 2022

    表哥厉害，收藏了
    低智兔友 低智兔友
    Reply
    June 10, 2023

    这样搭建的话，VLESS 的协议头会暴露在外（
    参见 https://xtls.github.io/development/protocols/vless.html#request-response），理论上会产生可供审查者识别的特征。如果机器性能不太差的话，还是套一层 TLS 比较好。
        40huo 40huo
        Reply
        August 5, 2023

        @低智兔友是的，文中也说到了，可以通过添加 streamSettings 增加传输层的混淆，具体要看墙的封禁策略的变化。
        yy yy
        Reply
        3 Months Ago

        @40huo 没有看明白 wg 的怎么配置的
    小蛤蟆 小蛤蟆
    Reply
    11 Months Ago

    这样做的话，国内 IP 流量一旦大起来，可能就被墙封海外了的吧？所有海外 IP 都没办法访问。
    ow ow
    Reply
    10 Months Ago

    如 wireguard 官方介绍所提到，https://www.wireguard.com/protocol/，wireguard 会随机填充数据包使其包长变为 16 的倍数，“zero padding in order to make the length a multiple of 16”。而 vless 目前的流控或填充大多针对 tls，wireguard 一类的加密会直接通过 tls 传输，导致包长特征会非常明显。私以为需要想办法额外追加随机填充
    你好 你好
    Reply
    8 Months Ago

    没懂，直接 bless ws tls 不就行了 wireguard 的作用是？

Copyright © 2024 40huo's - 知至知终

粤ICP备15113345号 • Powered by Typecho • Theme Mirages