/v2ray-core-ospf

A platform for building proxies to bypass network restrictions.

Primary LanguageGoMIT LicenseMIT

This is a modified V2Ray-core maintained by myself.

Updates from the upstream will be merged periodically.

It has several added features:

  • OSPFv2 support when act as an on-demand transparent proxy.
  • DNS-route capability.
  • Conn-track capability for routing decision.
  • HTTP health-check inbounds.

If you have any questions which are not related to features described above, please submit it to upstream project.

V2Ray

Project V

Project V is a set of network tools that helps you to build your own computer network. It secures your network connections and thus protects your privacy.

GitHub Test Badge codecov.io codebeat Codacy Badge Downloads

Related Links

为什么开发本项目

先叠个甲,本方案配置较为繁琐,有硬件要求,且深度涉及计算机网络原理,仅适用于有进阶网络知识的用户使用。

本项目旨在解决:使用透明代理进行网关科学的模式下,网关直接使用软路由带来的稳定性问题,以及性能问题。

如果你不在意:默认使用软路由作为你的家庭网关,且可以接受折腾软路由时造成全部网络中断/抖动的问题,则本文方案可能不适合你。

核心理念为:仅需要科学的流量会被转发至软路由处理,其余流量由主路由直接发出。 主路由使用常规硬路由以保证性能和稳定性。

因此,对于旁路由的性能要求降到了一个非常低的水平,同时,软路由的任何故障对于网络的影响也基本消除。

类似的,以“按需转发流量”作为核心理念的方案有:FakeDNS。 我也试用过相当长一段时间,但其存在几个我无法接受的问题:

  • FakeIP污染,例如:大陆白名单时,默认污染其他所有域名
  • 旁路由故障/修改配置重启时,FakeIP污染会持续一段时间无法立即清除
  • 需要手动在主路由上维护静态路由条目
  • 无法灵活应对Telegram这种不使用系统DNS的软件
  • 旁路由入侵网络拓扑,无法快速移除

相比之下,本方案具有以下优点:

  • 全真IP,不存在FakeIP污染,同时解决国内环境的DNS污染
  • 支持基于规则文件的IP路由规则,灵活应对Telegram类似的软件
  • 分流黑白名单模式可按喜好配置,无任何副作用
  • 默认支持 srcIP -> dstIP 作为pattern的Connection-track,路由决策无需Sniffing
  • 旁路由可插拔,生效路由条目由旁路由自动通告,无需维护静态路由条目,网络拓扑可自动容灾
  • 整体方案扩展能力强,可结合硬路由和软路由的各自特点,并充分利用优势

方案差异对比

特性 软路由 硬路由 本方案(按需旁路)
科学能力 强,取决于ROM 弱,配置复杂而且不灵活 强,包含所有V2Ray功能
性能 取决于硬件配置 强,直连性能等同于硬路由,科学性能取决于软路由配置
功耗 较低
NAT情况 取决于软件承诺 一般为FullClone 直连流量与硬路由无异,科学流量取决于V2Ray承诺
容灾 无,全部受影响 配置复杂 自动恢复拓扑,科学流量可降级为直连
稳定性 低,

前置要求

本项目中,V2Ray将被配置为旁路由透明代理使用,需要你事先掌握/具备以下条件:

理论知识

  • 理解什么是透明代理
  • 如何配置V2Ray以透明代理模式工作
  • 理解单臂路由(旁路由)的基本工作原理
  • 理解路由设备的工作原理,熟悉路由决策过程,理解路由表及防火墙基本原理
  • 熟悉nftables,具备基本的linux操作能力

硬件要求

  • 支持OSPFv2动态路由协议的主路由,且主路由需要支持策略路由(某些文章可能称为标记路由)。
  • 一台可运行V2Ray的Debian Linux作为旁路由

以下的使用说明中,采用的硬件配置为

主路由:MikroTik hAPac2 RBD52G-5HacD2HnD (RouterOS v6.49.14)

旁路由:Debian 11 Linux with 2-core 2GiB RAM (ESXi 7.0 on J4125)

推荐主路由使用ROS,旁路由使用Debian11及以上的linux系统。

使用说明

0x1: 网络拓扑配置

请参考如下拓扑,配置好主路由与旁路由。

核心诉求只有两点:

  • 主路由与旁路由最好和LAN设备隔离出一个网段(当然,同一个网段也行)
  • 主路由与旁路由IP固定(如果是同一个网段,请给旁路由固定IP)

[Network topology]

0x2: 旁路由配置

简单来说,旁路由配置主要有以下步骤:配置透明代理,配置OSPF相关参数/健康检查端口,配置IP masquerade等。

以下所有命令中 ${IFNAME} 均代表软路由和主路由连接的网卡名称,可以使用 ifconfig ip link 等命令查看。

使用时需要替换成你自己环境中的网卡名称。

配置透明代理

透明代理的配置教程 已经很多,我就不再赘述了,核心要求只有两个:

  • 只支持TPORXY模式的透明代理,请勿配置成REDIRECT模式。
  • 需要拦截UDP53的DNS查询请求,并转交给V2Ray内置DNS处理

另外,建议按照教程要求,修改v2ray的最大文件描述符限制, 避免在处理UDP流量时出现问题。

配置OSPF

此模块为本项目独立开发的部分,得益于V2Ray良好的模块化设计,最终以dnscircuit的模块形式嵌入了V2Ray中,需要在配置文件中写入指定配置方可开启。 不开启此模块时,该V2Ray与官方版本无异。

配置文件示例(节选),仅供格式参考。

实际配置请按自己实际情况填写

{
  // 最重要的部分
  // 用于DNS route的配置
  "dnsCircuit": {
    //(必填)DNS outbound 的Tag
    "dnsOutboundTag": "dns-out",
    //(必填)用于conn-track的inbound,目前只支持dokodemo-door协议的inbound。
    // 填写透明代理的inboundTag即可
    "inboundTags": [
      "transparent"
    ],
    //(必填)用于conn-track的outbound,DNS查询结果命中此outboundTag的流量都会被转发至旁路由。
    // 填写代理服务器的outboundTag即可
    "outboundTags": [
      "proxy"
    ],
    //(可选)固定通告某些IP段,目标IP在此范围内的流量都会被转发至旁路由。
    "persistentRoute": [
      "geoip:telegram", // 从规则文件中载入电报的服务器IP段,从而实现内网设备自动通过旁路由访问电报。
      "10.0.0.0/8" // 也可以直接以CIDR形式书写要转发至旁路的IP段,这块只是示例,请按自己实际情况填写。
    ],
    //(必填)OSPF设置
    // 需要填写软路由和主路由相连的网卡名称,以及软路由自己的IP和网段的掩码,以CIDR形式填写。
    "ospfSetting": {
      "ifName": "ens160", // 软路由上的网卡名称
      "address": "192.168.87.2/24" // 软路由自己的IP+子网掩码
    }
  },
  "routing": {
    // ... 省略
  },
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag":"transparent",
      "listen": "127.0.0.1",
      "port": 12345,
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp",
        "followRedirect": true
      },
      "sniffing": {
        "enabled": false, // 本方案无需开启嗅探
      },
      "streamSettings": {
        "sockopt": {
          "tproxy": "tproxy", // 透明代理必须使用 TPROXY 方式
          "mark":255
        }
      }
    }
    // ... 省略
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {
        "domainStrategy": "UseIPv4"
      },
      "streamSettings": {
        "sockopt": {
          "mark": 255
        }
      }
    },
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [{
          "address": "your.proxy.server",
          "port": 65535,
          "users": [
            {
              "id": "************************",
              "security": "auto"
            }
          ]
        }]
      },
      "streamSettings": {
        "sockopt": {
          "mark": 255
        }
      }
    },
    {
      "tag": "dns-out",
      "protocol": "dns",
      "streamSettings": {
        "sockopt": {
          "mark": 255
        }
      }
    }
    // ... 省略
  ],
  "dns": {
    // ... 省略
  }
}

配置IP masquerade

此配置的主要目的是,配合主路由上的策略路由规则,直接转发透明代理不处理的IP数据包(即,TCP/UDP协议以外的IP报文),避免形成路由环路。

直接按要求设置即可,主路由配置时会再提到这部分。

运行命令

# 在POSTROUTING上添加一个名为v2ray的链
nft add chain v2ray postrouting { type nat hook postrouting priority 0 \; }
# 向v2ray链中添加一条规则,从 ${IFNAME} 网卡发出的流量全部进行masquerade
nft add rule v2ray postrouting oif ${IFNAME} masquerade

收尾工作,配置持久化

将nftables的配置持久化,并做到开机自启动