最开始用ngrok,难用。然后准备搞frp,结果一直没时间咕咕咕,现在v2有了反向代理功能,终于可以研究一下了。

为什么需要反向代理和内网穿透,这里不多说了,反正点进来看的都是有这需求的。

这里只说感想:v2ray的反向代理配合路由真的可以玩出很多骚操作!

为方便理解和统一称呼,我们把没有公网IP的主机,即欲访问的内网服务器称为bridge;把具有公网IP的主机,即外网直接访问的服务器称为portal;所有的外网设备都称为client

v2ray反向代理的大致工作原理如下:

  • 在 bridge 和 portal 中配置各一个V2Ray。
  • bridge 会向 portal 主动建立连接,此连接的目标地址可以自行设定。portal 会收到两种连接,一是由 bridge 发来的连接,二是公网用户发来的连接。portal 会自动将两类连接合并。于是 bridge 就可以收到公网流量了。
  • bridge 在收到公网流量之后,会将其原封不动地发给主机 A 中的网页服务器。当然,这一步需要路由的协作。

因此,bridge 需要两个 outbound ,portal 需要两个inbound ,它们都需要配置相应的路由。

ps:本文省略了部分基础内容,详情请参考:V2Ray完全配置指南/反向代理配置章节,或直接查看官方文档

pss:本文中所有实例都是实验通过的,如有其他思路欢迎在评论里面讨论。

本文更新2020年2月22日

目录

基础反向代理

用到反向代理最常见的场景就是想要在外面访问家中的NAS,此时家中的NAS即为bridge。

在本场景中,client 不需要安装 v2ray 客户端,直接通过浏览器进行访问。

bridge的配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "bridges": [
      {
        "tag": "bridge",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "outbounds": [
    {
      "tag": "bridgeout",
      "protocol": "freedom",
      "settings": {
        "redirect": "127.0.0.1:80"  // 将所有流量转发到网页服务器
      }
    },
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "portal的IP地址",
            "port": 4096,
            "users": [
              {
                "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "tag": "interconn"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "domain": [
          "full:test.ailitonia.com"
        ],
        "outboundTag": "interconn"
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "outboundTag": "bridgeout"
      }
    ]
  }
}

 

portal的配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "portals": [
      {
        "tag": "portal",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "inbounds": [
    {
      "tag": "portalin",
      "port": 80,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",  // 将所有流量转发到网页服务器,与bridge上redirect配置相同,或任选其一配置
        "port": 80,
        "network": "tcp"
      }
    },
    {
      "port": 4096,
      "tag": "interconn",
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
            "alterId": 64
          }
        ]
      }
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "portalin"
        ],
        "outboundTag": "portal"
      },
      {
        "type": "field",
        "inboundTag": [
          "interconn"
        ],
        "outboundTag": "portal"
      }
    ]
  }
}

 

client 无需配置。

配置好 bridge 和 portal 的 V2Ray 后,先后运行 bridge 和 portal 的 V2Ray,访问 portal 的 IP 或域名,这时就能内网穿透访问内网服务器了。

注意在本场景下,brigde 配置中 outbounds 的 redirect 和 portal 配置中 inbounds 的转发端口要配置相同,或者就不配置 bridge 的。

返回目录

全局反向代理(反向翻墙代理)

这个场景适用于:想要从国外翻回国内,但国内VPS贼贵,于是家中路由器上搭建;可以利用反向代理在校外访问校园网的资源;在以上等等场景之外,同样能访问家中内网里的NAS等设备。

在本场景中,client 等效于在 bridge 网络中。

在本场景中,client 需要安装 v2ray 客户端并进行相应的配置。

bridge配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "bridges": [
      {
        "tag": "bridge",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "outbounds": [
    {
      "tag": "bridgeout",
      "protocol": "freedom"
    },
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "portal的IP地址",
            "port": 4096,
            "users": [
              {
                "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "tag": "interconn"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "domain": [
          "full:test.ailitonia.com"
        ],
        "outboundTag": "interconn"
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "outboundTag": "bridgeout"
      }
    ]
  }
}

 

portal的配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "portals": [
      {
        "tag": "portal",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "inbounds": [
    {
      "tag": "portalin",
      "port": 5001,
      "protocol": "vmess",  // 用于client连接
      "settings": {
        "clients": [
          {
            "id": "89682891-3d57-4cef-abbb-fbac5937ba29",
            "alterId": 64
          }
        ]
      }
    },
    {
      "port": 4096,
      "tag": "interconn",
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
            "alterId": 64
          }
        ]
      }
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "portalin"
        ],
        "outboundTag": "portal"
      },
      {
        "type": "field",
        "inboundTag": [
          "interconn"
        ],
        "outboundTag": "portal"
      }
    ]
  }
}

 

client配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "port": 1080,
      "listen": "127.0.0.1",
      "protocol": "socks"
    }
  ],
  "outbounds": [
    {
      "protocol": "vmess",  // 对应portal中tag为portalin的inbound
      "settings": {
        "vnext": [
          {
            "address": "portal的IP",
            "port": 5001,
            "users": [
              {
                "id": "89682891-3d57-4cef-abbb-fbac5937ba29",
                "alterId": 64
              }
            ]
          }
        ]
      }
    }
  ]
}

 

配置好 bridge、portal 和 client 的 v2ray 后,先后运行 bridge 和 portal 的 v2ray,再在 client 上运行v2ray即可。

本场景与第一个场景相比,主要区别有两个:

  1. bridge 和 portal 均没有配置端口转发
  2. portal 中原来的 dokodemo-door 协议变成了 vmess
  3. client 需要运行 v2ray 客户端,配置方法等同于连接到一个正常的 vmess 服务器

在第一个场景中,由于 portal 中的对于 client 的入站协议是 dokodemo-door,这时 v2ray 会将收到的流量原封不动地转发,因此相当于一个端口映射,我们通过指定端口的方式,将内网服务器的端口通过反向代理的方式暴露给外网。

而在本场景中,portal 对于 client 的入站协议变成了 vmess,因此 client 也需要配置 v2ray客户端;同时由于以上原因,portal 将不是一个单纯的“端口转发机”,而是成为了一个v2ray梯子,只不过这个梯子的出口是你自家的内网而已;同时内网设备将不会直接暴露于公网中,而需要通过连接 v2ray 客户端后才能访问。

在本场景的实际使用中,在 client 看来,portal 和 bridge 就像成为了一个整体,通过 v2ray 客户端连接后访问任何网站就如同是从 bridge 上访问的一样,就如同置身于家中的内网环境中。此时如要访问家中的设备,直接在浏览器中访问192.168.1.x这样的内网地址就行了(家中NAS设备记得配置静态地址,不然你懂的……)。

返回目录

分流反向代理

以上两个场景基本就是绝大部分的使用场景了,但如果有些奇怪的需求,比如:我想在 client 上配置 v2ray 后,既能同时访问家中的内网设备,又能同时利用海外的服务器翻墙呢?

你们先把头伸过来,我给你们上个祝福.webp

先解释一下为什么会有这种需求。对于身在海外的人来说,翻回国内和访问国内内网设备的需求是同向的,因此直接适用场景二即可;但对于身在国内的人来说,需要同时翻出去和访问国内内网设备(以及身在海外要翻回国内同时还要访问海外内网设备的),这两个需求的方向是不同的,因此直接使用场景二中的方法就不靠谱了。

因此,我们需要使用一点小手段,来分流我们的流量,这个方法就是:路由。当然,在这里只是提出一种思路,和一个例子,通过这种方法甚至还能实现身在国内能同时同时翻出去和访问国内内网设备并能访问海外内网设备(真有这么闲到蛋疼的人吗)

前面开篇就说到,利用路由可以在反向代理上能玩出很多骚操作,这个方法的重点在于如何区分我们想要进行反向代理的流量和爬梯子的流量。

那如何区分呢?答案是:端口。通过配置 portal 和 client 的路由配置,我们可以做到正常翻墙的同时,用特定端口访问我们自己的内网设备!(考验各位记忆力的时候到了!)

首先假设自己是个有钱人,家里面有NAS、有服务器、有智能家具、有一堆可以联网的设备,我们想要从外网访问它们。假设你有个刷了 openwrt 的路由器并且把 v2ray 装好了,现在这个路由器就是 bridge 了。

bridge配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "bridges": [
      {
        "tag": "bridge",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "outbounds": [
    {
      "tag": "bridgeout1",  // 内网设备1
      "protocol": "freedom",
      "settings": {
        "redirect": "127.0.0.1:21"  // 内网设备1的内网地址与端口
      }
    },
    {
      "tag": "bridgeout2",  // 内网设备2
      "protocol": "freedom",
      "settings": {
        "redirect": "192.168.1.110:22"  // 内网设备2的内网地址与端口
      }
    },
    {
      "tag": "bridgeout3",  // 内网设备3
      "protocol": "freedom",
      "settings": {
        "redirect": "192.168.1.120:80"  // 内网设备3的内网地址与端口
      }
    },
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "portal的IP地址",
            "port": 4096,
            "users": [
              {
                "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "tag": "interconn"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "domain": [
          "full:test.ailitonia.com"
        ],
        "outboundTag": "interconn"
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "port": "5001",  // 为内网设备1分配访问端口,须在portal分配的端口范围中
        "outboundTag": "bridgeout1"  // 对应内网设备1
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "port": "5002",  // 为内网设备2分配访问端口,须在portal分配的端口范围中
        "outboundTag": "bridgeout2"  // 对应内网设备2
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "port": "5003",  // 为内网设备3分配访问端口,须在portal分配的端口范围中
        "outboundTag": "bridgeout3"  //对应内网设备3
      }
    ]
  }
}

 

portal配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "portals": [
      {
        "tag": "portal",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "inbounds": [
    {
      "tag": "portalin",  // 与client连接
      "port": 5001,
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "89682891-3d57-4cef-abbb-fbac5937ba29",
            "alterId": 64
          }
        ]
      }
    },
    {
      "port": 4096,
      "tag": "interconn",  // 与bridge连接
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
            "alterId": 64
          }
        ]
      }
    }
  ],
  "outbounds": [
    {
      "tag": "crossfire",  // 正常流量出口
      "protocol": "freedom"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "portalin"
        ],
        "ip": "111.111.111.111",  // 指定一个用来进行内网穿透的ip
        "port": "5001-5100",  // 指定一个进行内网穿透的端口范围
        "outboundTag": "portal"  // 对应内网穿透连接
      },
      {
        "type": "field",
        "inboundTag": [
          "interconn"
        ],
        "outboundTag": "portal"  // 对应bridge连接
      },
      {
        "type": "field",
        "inboundTag": [
          "portalin"
        ],
        "outboundTag": "crossfire"  //对应翻墙连接
      }
    ]
  }
}

 

client的配置与第二个场景中的相同:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "port": 1080,
      "listen": "127.0.0.1",
      "protocol": "socks"
    }
  ],
  "outbounds": [
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "portal的IP",
            "port": 5001,
            "users": [
              {
                "id": "89682891-3d57-4cef-abbb-fbac5937ba29",
                "alterId": 64
              }
            ]
          }
        ]
      }
    }
  ]
}

 

配置好 bridge、portal 和 client 的 v2ray 后,先后运行 bridge 和 portal 的 v2ray,再在 client 上运行v2ray即可。

此时 client 可以正常翻墙,portal 即为梯子。如果想要访问内网设备,在浏览器中输入 portal 配置中的指定的ip,加上 bridge 为内网设备分配的端口号即可。如在本例中,如果我想要访问家中内网设备3,只需要连接上 v2ray 后直接访问 111.111.111.111:5003 就行了。

在本例中,我们使用路由配置将家中的内网ip映射到一个(xjb写的)ip上,同时将内网设备的不同端口也映射到了这个(xjb写的)ip的不同端口上。

在本场景中,内网设备同样不会直接暴露于公网中,需要通过连接 v2ray 客户端后才能访问。而与场景二的不同在于,场景二中连接 v2ray 客户端后相当于处于家中内网环境,访问内网设备是通过直接访问内网ip进行的;而本例在连接 v2ray 客户端后是处于翻墙后的状态,访问内网设备需要通过访问特定的(那个xjb写的)ip以及为内网设备分配的端口进行。

这个xjb写的ip地址其实不写也是可以的,但这样的话像本例中访问任意ip的5001-5100端口都会被转发到内网去了……不过为了方便好记,这个(xjb写的)ip当然是越简单越好,不过意外事故还是有可能的,比如政府网上办事/公司/学校给的一些ip地址刚好和你用的撞车(怎么可能),这时改改就行了,反正就改几个数字耗不了多少时间远程登陆费的是时间)。端口号也按个人喜好分配,也是方便记忆的最好。这个端口号和 v2ray 客户端连接的端口也没有关系,一样也是可以的。

还有一点就是映射端口时,和上一个场景一样,家中设备要记得配置静态地址,不然的话后果自己体会。当然这个方法配置起来比较麻烦,毕竟需要把家中每个设备都单独配置 outbound,不过这个方法用起来是最舒服的,值得用点时间去写配置文件。

而且本例中 client 的配置,就是个白板配置,完全可以再加点国内直连啊,广告过滤啊什么的,多的就不在这里详说了……

返回目录

基础反向代理·改

看了上面这个实例,估计有的人又有新想法了。

我给你的祝福还没有上够吗.png

基础的反向代理一个ip就对应一个设备,利用率太低了。既然上面可以使用路由配置实现类似端口映射的效果,那能不能直接在最简单的反向代理中实现呢,毕竟不是随时随地用到的所有设备上都装了 v2ray 吧,能在任何设备上直接访问不是更方便吗嘛?

答案当然是不可以啦!因为 portal 的入站协议是 dokodemo-door,是必须要指定一个转发的端口的,因此是不能只通过一个 inbound 就搞定多个端口的转发的。

所以在这个场景中的配置其实和路由完全没有一点关系,只需要给每一个内网设备都配置一个 inbound 就行了(其实就是第一个例子在portal上多加了几个inbound而已,没什么改动)(和上面那个例子中每个设备都配置一个 outbound 一样都极不优雅)

(为什么把这段放在这个位置?我也是写到这才想起来还有这茬的)

bridge配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "bridges": [
      {
        "tag": "bridge",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "outbounds": [
    {
      "tag": "bridgeout",
      "protocol": "freedom"
    },
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "portal的IP地址",
            "port": 4096,
            "users": [
              {
                "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "tag": "interconn"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "domain": [
          "full:test.ailitonia.com"
        ],
        "outboundTag": "interconn"
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "outboundTag": "bridgeout"
      }
    ]
  }
}

 

portal配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "portals": [
      {
        "tag": "portal",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "inbounds": [
    {
      "tag": "device1",  // 内网设备1
      "port": 5001,  // 访问端口
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",  // 内网ip
        "port": 80,  // 设备开放端口
        "network": "tcp"
      }
    },
    {
      "tag": "device2",  // 内网设备2
      "port": 5002,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "192.168.1.100",
        "port": 80,
        "network": "tcp"
      }
    },
    {
      "tag": "device3",  // 内网设备3
      "port": 5003,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "192.168.1.200",
        "port": 21,
        "network": "tcp"
      }
    },
    {
      "port": 4096,
      "tag": "interconn",
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
            "alterId": 64
          }
        ]
      }
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [  // 前面所有inbound的tag都要写
          "device1",
          "device2",
          "device3"
        ],
        "outboundTag": "portal"
      },
      {
        "type": "field",
        "inboundTag": [
          "interconn"
        ],
        "outboundTag": "portal"
      }
    ]
  }
}

 

client 无需配置。

配置好 bridge 和 portal 的 V2Ray 后,先后运行 bridge 和 portal 的 V2Ray,访问 portal 的 IP 或域名+端口号,这时就能内网穿透访问内网设备了。

返回目录

基础反向代理·二改

在面对多个内网设备的情况下,如何优雅简单地写配置文件并简单优雅地访问一直是个问题,因为有多个设备的话想要分别访问就不可避免的要为其挨个单独设置一个 inbound 或 outbound。况且使用端口号来访问对应设备对记忆起来也是个说大不大说小不小的麻烦。虽说本文第二例的配置就挺简单的,但毕竟作为梯子才是v2ray的主业,内网穿透只是兼职而已。所以想要翻墙同时内网穿透,跟简单优雅的配置仿佛就是鱼与熊掌不可兼得的难题。

在认识到这个现状之后,我突然醒悟了:复杂的配置是为了简单优雅的使用而服务的口牙。只要用起来方便,配置复杂点又有什么关系呢(这是邪道好孩子不要学)。

v2ray的路由配置目前毕竟只能实现一些简单的功能,前面的使用特定ip访问也是一种取巧的方法。在本例中将展示使用 nginx 配合 v2ray 实现的反向代理。

使用建议:最好有个自己的域名。

首先准备工作:先把 nginx 装上:Nginx安装与配置

注意:本例使用的web服务器启用了SSL,并且由于使用了nginx转发,请注意bridge和portal端口不同

装好 nginx 后随便上传个模板主页充当门面。

接下来先开始配置 v2ray。

bridge配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "bridges": [
      {
        "tag": "bridge",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "outbounds": [
    {
      "tag": "bridgeout",
      "protocol": "freedom"
    },
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "portal的域名",
            "port": 443,
            "users": [
              {
                "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
                "alterId": 64
              }
            ]
          }
        ]
      },
	  "streamSettings": {
        "network": "ws",  //为了使用nginx反代这里需要使用ws
        "security": "tls",
        "tlsSettings": {
          "allowInsecure": false
        },
        "wsSettings": {
          "path": "/interconnpath"
        }
      },
      "tag": "interconn"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "domain": [
          "full:test.ailitonia.com"
        ],
        "outboundTag": "interconn"
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "outboundTag": "bridgeout"
      }
    ]
  }
}

 

portal配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "portals": [
      {
        "tag": "portal",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "inbounds": [
    {
      "tag": "device1",
      "port": 5001,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "127.0.0.1",
        "port": 80,
        "network": "tcp"
      }
    },
    {
      "tag": "device2",
      "port": 5002,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "192.168.1.100",
        "port": 80,
        "network": "tcp"
      }
    },
    {
      "tag": "device3",
      "port": 5003,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "192.168.1.200",
        "port": 21,
        "network": "tcp"
      }
    },
    {
      "port": 4096,
      "tag": "interconn",
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "134b53ca-b0cc-44a7-a28f-4214842c2fd6",
            "alterId": 64
          }
        ]
      },
      "streamSettings": {
        "network": "ws",  //为了使用nginx反代这里需要使用ws
        "wsSettings": {
          "path": "/interconnpath"
        }
      }
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "device1",
          "device2",
          "device3"
        ],
        "outboundTag": "portal"
      },
      {
        "type": "field",
        "inboundTag": [
          "interconn"
        ],
        "outboundTag": "portal"
      }
    ]
  }
}

 

nginx配置:

upstream nas {
  server 127.0.0.1:5001;
}
upstream htpc {
  server 127.0.0.1:5002;
}
upstream ssh {
  server 127.0.0.1:5003;
}
server {
...
    location /interconnpath {
        proxy_redirect off;
        proxy_pass http://127.0.0.1:4096;  #WebSocket监听端口
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
    }
    location /nas/ {
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://nas;
    }
    location /htpc/ {
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://htpc;
    }
    location /ssh/ {
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://ssh;
    }
...
}

 

返回目录

反向代理的底层传输配置

有的人可能看到这里还在纠结为什么 v2ray 的反向代理在 bridge 和 portal 之间需要两条连接,现在就先别纠结了,因为实际上这里虽然有两个连接,但在实际的通信中这两条连接实际上是只通过一条连接,也就是上面例子中 tag 为 interconn 的那对出/入站协议进行的。

换句话说,我们可以为反向代理的连接配置底层传输方式,甚至还可以用其他的协议比如shadowsocks来传输反向代理的流量

对于有极端强迫症的人以及有特殊需求的人来说,这是个还算有价值的方案。

真有这样的人?

这里依然以上面第三个实例为基础,但本例中,我们在 bridge 和 portal 之间使用 shadowsocks 协议和 QUIC 传输方式;在 client 和 portal 之间使用 vmess 协议和 WebSocket 传输方式,并且 client 和 portal 之间的连接使用CDN进行中转。使用tls和CDN时需要提前准备一个域名并解析到 portal 上。

ps:所有的协议和底层传输都是可以改的,不是只有这种组合,这个例子(无法形容的奇葩组合方式)只是用于展示本方案可能性,并不是一个好的配置组合(好孩子千万不要直接照抄哦)

pss:如果之前对这方面没有了解,建议先看看V2Ray完全配置指南/WebSocket+TLS+Web部分

bridge配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "bridges": [
      {
        "tag": "bridge",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "outbounds": [
    {
      "tag": "bridgeout1",
      "protocol": "freedom",
      "settings": {
        "redirect": "127.0.0.1:21"
      }
    },
    {
      "tag": "bridgeout2",
      "protocol": "freedom",
      "settings": {
        "redirect": "192.168.1.110:22"
      }
    },
    {
      "tag": "bridgeout3",
      "protocol": "freedom",
      "settings": {
        "redirect": "192.168.1.120:80"
      }
    },
    {
      "protocol": "shadowsocks",
      "settings": {
        "servers": [
          {
            "address": "portal的ip",
            "port": 4096,
            "method": "aes-128-cfb",
            "password": "87654321"
          }
        ]
      },
      "streamSettings": {  // 底层传输配置,使用quic
        "network": "quic",
        "quicSettings": {
          "security": "aes-128-gcm",
          "key": "",
          "header": {
            "type": "utp"
          }
        }
      },
      "tag": "interconn"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "domain": [
          "full:test.ailitonia.com"
        ],
        "outboundTag": "interconn"
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "port": "5001",
        "outboundTag": "bridgeout1"
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "port": "5002",
        "outboundTag": "bridgeout2"
      },
      {
        "type": "field",
        "inboundTag": [
          "bridge"
        ],
        "port": "5003",
        "outboundTag": "bridgeout3"
      }
    ]
  }
}

 

portal配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "reverse": {
    "portals": [
      {
        "tag": "portal",
        "domain": "test.ailitonia.com"
      }
    ]
  },
  "inbounds": [
    {
      "tag": "portalin",
      "port": 5001,  // 注意在web服务器上配置转发
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "89682891-3d57-4cef-abbb-fbac5937ba29",
            "alterId": 64
          }
        ]
      },
      "streamSettings": {  // 底层传输配置,client配置应与其相同
        "network": "ws",
        "wsSettings": {
          "path": "/portalin",
          "headers": {
            "Host": "ailitonia.com"
          }
        }
      }
    },
    {
      "port": 4096,
      "tag": "interconn",
      "protocol": "shadowsocks",
      "settings": {
        "method": "aes-128-cfb",
        "password": "87654321"
      },
      "streamSettings": {  // 底层传输配置,应与bridge配置相同
        "network": "quic",
        "quicSettings": {
          "security": "aes-128-gcm",
          "key": "",
          "header": {
            "type": "utp"
          }
        }
      }
    }
  ],
  "outbounds": [
    {
      "tag": "crossfire",
      "protocol": "freedom"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "portalin"
        ],
        "ip": "111.111.111.111",
        "port": "5001-5100",
        "outboundTag": "portal"
      },
      {
        "type": "field",
        "inboundTag": [
          "interconn"
        ],
        "outboundTag": "portal"
      },
      {
        "type": "field",
        "inboundTag": [
          "portalin"
        ],
        "outboundTag": "crossfire"
      }
    ]
  }
}

 

使用CDN时应当配置web服务器(如Nginx、Caddy)分流。

使用QUIC时记得服务器防火墙放行udp

client配置:

{
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "port": 1080,
      "listen": "127.0.0.1",
      "protocol": "socks"
    }
  ],
  "outbounds": [
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "portal的域名",
            "port": 443,
            "users": [
              {
                "id": "89682891-3d57-4cef-abbb-fbac5937ba29",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "allowInsecure": false
        },
        "wsSettings": {
          "path": "/portalin",
          "headers": {
            "Host": "ailitonia.com"
          }
        }
      }
    }
  ]
}

 

配置好 bridge、portal 和 client 的 v2ray 后,先后运行 bridge 和 portal 的 v2ray,再在 client 上运行v2ray即可。

访问方式与“分流反向代理”中相同。

返回目录

反向代理的负载均衡

v2ray在V4.4的时候不声不响地放出了路由中负载均衡的配置,相比于之前在同一个 outbound 的 vnext 写入多个服务器的配置方式,在路由中配置负载均衡不仅不需要各服务器的协议与底层传输方式配置相同,还能配合其他路由设置实现更加灵活的分流。虽然目前的负载均衡器似乎只有简单的随机策略,但已经足够我们使用了。

依旧是本文的第三个实例中,这回我们有了十多台服务器,我们要在这十多台服务器上配置负载均衡,同时还要能保证在负载均衡后不仅翻墙要正常,而且反向代理的内网设备也要能正常访问

负载均衡的配置只涉及到 bridge 和 client,而 portal 的配置与第三个例子中的没有区别,只是需要在很多服务器上都配置一遍而已。

bridge配置:

就是个多个负载均衡的配置啦

等我有空再写(咕咕咕)

 

返回目录

 


2018.12.28  初版

2019.1.3  增加:分流反向代理

2019.1.4  增加:反向代理的底层传输配置

2020.2.22 update 修改了部分描述


本文被阅读了:160,365次

作者头像
关于  Ailitonia

正因站在了巨人的肩膀上,才越发觉得自己渺小。不求成为巨人,但求与其同行。 把自己所见所闻,记录下来。

→查看所有由Ailitonia发布的文章