使用 V2Ray 进行内网穿透的简易方法


一、前言

之前我写了一篇文章介绍了如何使用 autossh 进行内网穿透。

使用 autossh 进行快速内网穿透

而前不久,知名的网络工具集 V2Ray(Project V)推出了内网穿透(反向代理)功能。

V2Ray 可使用 VMess 协议进行内网穿透。

与 SSH 协议相比,VMess 协议(普通的 TCP 模式)在建立连接时除了 TCP 三次握手之外无需其他握手流程,这使得它在恶劣的网络环境下也能获得较为稳定的连接。

还有,V2Ray 可以支持 UDP 的内网穿透!

鉴于目前网上相关的教程都比较复杂,所以我在配置完成之后特地整理了一下相关的配置然后给大家分享,方便新手入门。如有错误请及时提出,谢谢!

说明
• V2Ray 配置内网穿透的难点在于:如何将属于内网穿透的流量从 VMess 流量中剥离开来。
• 简单来说,V2Ray 中使用了一个域名来标记属于内网穿透的流量。通过抓取该域名并设置相应的路由规则,即可实现内网穿透流量以及普通代理流量的正确转发。


二、操作环境

  • 服务器操作系统:CentOS 7.6.1810
  • 客户端操作系统:CentOS 7.6.1810
  • 服务器 V2Ray 版本:4.10.0
  • 客户端 V2Ray 版本:4.10.0

下面只介绍 V2Ray 配置文件中与内网穿透有关那部分的格式。关于如何安装及使用 V2Ray,可以参考我之前写的一篇文章,这里不再赘述。

在 CentOS 7 上部署 VMess + TLS + WebSocket 代理服务器


三、配置文件格式

说明
• 配置文件必须遵循 json 格式标准,否则 V2Ray 服务将无法启动。
• 在启动 V2Ray 之前,可通过执行 v2ray -test -config <配置文件路径> 命令来检测配置文件是否正确。

3.1 服务器

{
    "inbounds": [
        {
            "tag": "<VMess 服务名称>",
            "port": <VMess 服务器监听的端口>,
            "protocol": "vmess",
            "settings": {
                "clients": [
                    {
                        "id": "<UUID>",
                        "alterId": 64,
                        "level": 0
                    }
                ]
            }
        },

        {
            "tag": "<内网穿透服务名称 1>",
            "listen":"<远程服务器监听的 IP>",
            "port": <远程服务器监听的端口>,
            "protocol": "dokodemo-door",
            "settings": {
                "address": "<本地服务的 IP>",
                "port": <本地服务的端口>,
                "network": "tcp|udp"
            }
        },

        {
            "tag": "<内网穿透服务名称 2>",
            "listen":"<远程服务器监听的 IP>",
            "port": <远程服务器监听的端口>,
            "protocol": "dokodemo-door",
            "settings": {
                "address": "<本地服务的 IP>",
                "port": <本地服务的端口>,
                "network": "tcp|udp"
            }
        },

        ...

    ],

    "reverse": {
        "portals": [
            {
                "tag": "REVERSE-SERVICE",
                "domain": "v2ray-reverse-proxy"
            }
        ]
    },

    "routing": {
        "strategy": "rules",
        "settings": {
            "domainStrategy": "IPIfNonMatch",
            "rules": [
                {
                    "type": "field",
                    "inboundTag": ["<内网穿透服务名称 1>", "<内网穿透服务名称 2>",...],
                    "outboundTag": "REVERSE-SERVICE"
                },

                {
                    "type": "field",
                    "inboundTag": ["<VMess 服务名称>"],
                    "domain": ["v2ray-reverse-proxy"],
                    "outboundTag": "REVERSE-SERVICE"
                }
            ]
        }
    }
}

3.2 客户端

{
    "outbounds": [
        {
            "tag": "<VMess 服务名称>",
            "protocol": "vmess",
            "settings": {
                "vnext": [
                    {
                        "address": "<VMess 服务器的域名/IP>",
                        "port": <VMess 服务器监听的端口>,
                        "users": [
                            {
                                "id": "<UUID>",
                                "alterId": 64
                            }
                        ]
                    }
                ]
            }
        },

        {
            "tag": "OUTPUT",
            "protocol": "freedom",
            "settings": {}
        }
    ],

    "reverse": {
        "bridges": [
            {
                "tag": "REVERSE-SERVICE",
                "domain": "v2ray-reverse-proxy"
            }
        ]
    },

    "routing": {
        "strategy": "rules",
        "settings": {
            "domainStrategy": "IPIfNonMatch",
            "rules": [
                {
                    "type": "field",
                    "inboundTag": ["REVERSE-SERVICE"],
                    "domain": ["v2ray-reverse-proxy"],
                    "outboundTag": "<VMess 服务名称>"
                },

                {
                    "type": "field",
                    "inboundTag": ["REVERSE-SERVICE"],
                    "outboundTag": "OUTPUT"
                }
            ]
        }
    }
}

四、举例说明

把本地的 22 端口映射到远程服务器的 2222 端口;把本地的 80 端口映射到远程服务器的 80 端口;把本地的 443 端口映射到远程服务器的 443 端口。映射到远程服务器上的端口必须被远程服务器上的所有网络接口监听。

远程服务器 VMess 服务监听的端口为 8443,IP 地址为 10.0.0.1,连接所用的 UUID 为 15bf61ad-e7f3-49a9-b5f7-f3371e502cb6

4.1 服务器配置文件

{
    "inbounds": [
        {
            "tag": "VMESS-SERVICE",
            "port": 8443,
            "protocol": "vmess",
            "settings": {
                "clients": [
                    {
                        "id": "15bf61ad-e7f3-49a9-b5f7-f3371e502cb6",
                        "alterId": 64,
                        "level": 0
                    }
                ]
            }
        },

        {
            "tag": "SSH",
            "listen":"0.0.0.0",
            "port": 2222,
            "protocol": "dokodemo-door",
            "settings": {
                "address": "127.0.0.1",
                "port": 22,
                "network": "tcp"
            }
        },

        {
            "tag": "HTTP",
            "listen":"0.0.0.0",
            "port": 80,
            "protocol": "dokodemo-door",
            "settings": {
                "address": "127.0.0.1",
                "port": 80,
                "network": "tcp"
            }
        },

        {
            "tag": "HTTPS",
            "listen":"0.0.0.0",
            "port": 443,
            "protocol": "dokodemo-door",
            "settings": {
                "address": "127.0.0.1",
                "port": 443,
                "network": "tcp"
            }
        }
    ],

    "reverse": {
        "portals": [
            {
                "tag": "REVERSE-SERVICE",
                "domain": "v2ray-reverse-proxy"
            }
        ]
    },

    "routing": {
        "strategy": "rules",
        "settings": {
            "domainStrategy": "IPIfNonMatch",
            "rules": [
                {
                    "type": "field",
                    "inboundTag": ["SSH", "HTTP", "HTTPS"],
                    "outboundTag": "REVERSE-SERVICE"
                },

                {
                    "type": "field",
                    "inboundTag": ["VMESS-SERVICE"],
                    "domain": ["v2ray-reverse-proxy"],
                    "outboundTag": "REVERSE-SERVICE"
                }
            ]
        }
    }
}

4.2 客户端配置文件

{
    "outbounds": [
        {
            "tag": "VMESS-SERVICE",
            "protocol": "vmess",
            "settings": {
                "vnext": [
                    {
                        "address": "10.0.0.1",
                        "port": 8443,
                        "users": [
                            {
                                "id": "15bf61ad-e7f3-49a9-b5f7-f3371e502cb6",
                                "alterId": 64
                            }
                        ]
                    }
                ]
            }
        },

        {
            "tag": "OUTPUT",
            "protocol": "freedom",
            "settings": {}
        }
    ],

    "reverse": {
        "bridges": [
            {
                "tag": "REVERSE-SERVICE",
                "domain": "v2ray-reverse-proxy"
            }
        ]
    },

    "routing": {
        "strategy": "rules",
        "settings": {
            "domainStrategy": "IPIfNonMatch",
            "rules": [
                {
                    "type": "field",
                    "inboundTag": ["REVERSE-SERVICE"],
                    "domain": ["v2ray-reverse-proxy"],
                    "outboundTag": "VMESS-SERVICE"
                },

                {
                    "type": "field",
                    "inboundTag": ["REVERSE-SERVICE"],
                    "outboundTag": "OUTPUT"
                }
            ]
        }
    }
}

五、参考文献

  1. 反向代理 · Project V 官方网站
  2. 反向代理/内网穿透 · V2Ray 配置指南 | V2Ray 白话文教程
  3. 反向代理/内网穿透 2 · V2Ray 配置指南 | V2Ray 白话文教程

发表评论