v2fly / v2ray-step-by-step

This repo is a fork of ToutyRater/v2ray-guide, we aim to provide a new step-by-step guide of v2ray
https://guide.v2fly.org
Creative Commons Attribution 4.0 International
755 stars 427 forks source link

[bug] 透明代理无法访问内网地址 #255

Closed Icarusradio closed 2 years ago

Icarusradio commented 2 years ago

与 bug 有关的页面 / related page

tproxy.md

bug 描述 / description of the bug

学校内网的网段是 10.0.0.0/8,自己路由器的网段是 192.168.1.0/24,在按照教程配置好透明代理后,发现内网地址访问均超时。 简易网络拓扑图:

                             | 10.19.108.152
                        +----+---+
                        | Router |
                        +----+---+
                             | 192.168.1.1
     ------------------------+-----------------------+
     | 192.168.1.103         | 192.168.1.100         | 192.168.1.105
+----+----+            +----------+            +-----+----+            ......
| Gateway |            | Device 1 |            | Device 2 |
+---------+            +----------+            +----------+

复现步骤 / how we can reproduce

V2Ray 配置文件 config.json,基本和教程给的一致

{
  "log": {
    "access": "/var/log/v2ray/access.log",
    "error": "/var/log/v2ray/error.log",
    "loglevel": "warning"
  },
  "dns": {
    "servers": [
      "10.15.44.11",       // 学校内网 DNS 服务器
      {
        "address": "1.1.1.1",
        "domains": [
          "geosite:geolocation-!cn"
        ]
      }
    ],
    "queryStrategy": "UseIPv4",
    "tag": "dns_inbound"
  },
  "routing": {
    "domainStrategy": "IPOnDemand",
    "domainMatcher": "mph",
    "rules": [
      {
        "type": "field",
        "protocol": ["bittorrent"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "port": 53,
        "network": "udp",
        "inboundTag": ["transparent"],
        "outboundTag": "dns-out"
      },
      {
        "type": "field",
        "port": 123,
        "network": "udp",
        "inboundTag": ["transparent"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["1.1.1.1"],
        "port": 53,
        "inboundTag": ["dns_inbound"],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "domain": [
          "domain:xxx.edu.cn",               // 学校域名
          "geosite:cn"
        ],
        "network": "tcp,udp",
        "protocol": ["http", "tls"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:cn", "geoip:private"],
        "network": "tcp,udp",
        "protocol": ["http", "tls"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "protocol": ["http", "tls"],
        "outboundTag": "proxy"
      }
    ]
  },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 1080,
      "protocol": "socks",
      "settings": {
        "udp": true
      },
      "tag": "proxy",
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      }
    },
    {
      "port": 12345,
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp",
        "followRedirect": true
      },
      "streamSettings": {
        "sockopt": {
          "tproxy": "tproxy",
          "mark":255
        }
      },
      "tag": "transparent",
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {
        "domainStrategy": "UseIPv4"
      },
      "tag": "direct",
      "streamSettings": {
        "sockopt": {
          "mark": 255
        }
      }
    },
    {
      "protocol": "dns",
      "tag": "dns-out",
      "streamSettings": {
        "sockopt": {
          "mark": 255
        }
      }
    },
    {
      "protocol": "vmess",
      "settings": {},  // VMess 配置略去
      "tag": "proxy",
      "streamSettings": {
        "sockopt": {
          "mark": 255
        }
      }
    }
  ]
}

iptables 配置指令(基本和教程一样,部分地方有改动):

# 设置策略路由
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
iptables -t mangle -A V2RAY -d 127.0.0.1/32 -j RETURN
iptables -t mangle -A V2RAY -d 10.0.0.0/8 -j RETURN # 这里改成内网地址了
iptables -t mangle -A V2RAY -d 255.255.255.255/32 -j RETURN 
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p tcp -j RETURN # 直连局域网,避免 V2Ray 无法启动时无法连网关的 SSH,如果你配置的是其他网段(如 10.x.x.x 等),则修改成自己的
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS)
iptables -t mangle -A V2RAY -j RETURN -m mark --mark 0xff    # 直连 SO_MARK 为 0xff 的流量(0xff 是 16 进制数,数值上等同与上面V2Ray 配置的 255),此规则目的是解决v2ray占用大量CPU(https://github.com/v2ray/v2ray-core/issues/2621)
iptables -t mangle -A V2RAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 # 给 UDP 打标记 1,转发至 12345 端口
iptables -t mangle -A V2RAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 # 给 TCP 打标记 1,转发至 12345 端口
iptables -t mangle -A PREROUTING -j V2RAY # 应用规则

# 没有对网关本机进行代理

# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升
iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT

后续尝试了配置网关本机代理,还是无法连接内网。 日志文件 access.log

2021/10/12 02:16:52 192.168.1.105:2018 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:16:52 192.168.1.105:47988 accepted tcp:109.244.23.123:443 [direct]
2021/10/12 02:16:52 192.168.1.105:42586 accepted tcp:223.166.152.106:8080 [direct]
2021/10/12 02:16:52 192.168.1.105:6428 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:16:53 192.168.1.105:62326 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:16:53 192.168.1.105:49204 accepted tcp:175.27.0.201:80 [direct]
2021/10/12 02:16:53 192.168.1.105:27248 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:16:53 192.168.1.105:26747 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:16:54 192.168.1.105:40055 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:16:54 192.168.1.105:45876 accepted tcp:42.81.172.207:80 [direct]
2021/10/12 02:16:54 192.168.1.105:45190 accepted tcp:175.27.0.15:80 [direct]
2021/10/12 02:16:54 192.168.1.105:14377 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:16:55 192.168.1.105:37282 accepted tcp:109.244.23.180:55260 [direct]
2021/10/12 02:16:56 192.168.1.105:40252 accepted tcp:203.208.40.98:80 [direct]
2021/10/12 02:16:58 192.168.1.105:39992 accepted tcp:36.155.208.76:80 [direct]
2021/10/12 02:16:58 192.168.1.105:39994 accepted tcp:36.155.208.76:80 [direct]
2021/10/12 02:16:58 192.168.1.105:48152 accepted tcp:121.51.52.82:443 [direct]
2021/10/12 02:16:58 192.168.1.105:45216 accepted tcp:216.58.200.46:443 [proxy1]
2021/10/12 02:16:58 192.168.1.105:37358 accepted tcp:142.251.43.13:443 [proxy1]
2021/10/12 02:16:59 192.168.1.105:49002 accepted tcp:203.208.43.98:80 [proxy1]
2021/10/12 02:16:59 192.168.1.105:42950 accepted tcp:203.208.43.98:443 [proxy1]
2021/10/12 02:17:00 192.168.1.105:10489 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:01 192.168.1.105:41562 accepted tcp:142.250.101.188:5228 [proxy1]
2021/10/12 02:17:02 192.168.1.105:38073 accepted udp:216.58.200.46:443 [direct]
2021/10/12 02:17:05 192.168.1.105:27604 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:05 192.168.1.105:20796 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:05 192.168.1.105:15781 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:06 192.168.1.105:39512 accepted tcp:172.217.14.74:443 [proxy1]
2021/10/12 02:17:06 192.168.1.105:39800 accepted tcp:142.250.72.174:443 [proxy1]
2021/10/12 02:17:06 192.168.1.105:49016 accepted tcp:203.208.43.98:80 [proxy1]
2021/10/12 02:17:06 192.168.1.105:42968 accepted tcp:203.208.43.98:443 [proxy1]
2021/10/12 02:17:35 192.168.1.105:21623 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:36 192.168.1.105:24450 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:36 192.168.1.105:49454 accepted tcp:142.250.188.227:443 [proxy1]
2021/10/12 02:17:36 192.168.1.105:49854 accepted tcp:142.250.188.4:443 [proxy1]
2021/10/12 02:17:36 192.168.1.105:49856 accepted tcp:142.250.188.4:443 [proxy1]
2021/10/12 02:17:37 192.168.1.105:15730 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:37 192.168.1.105:41806 accepted tcp:142.250.72.144:80 [proxy1]
2021/10/12 02:17:38 192.168.1.105:42745 accepted udp:142.250.188.227:443 [direct]
2021/10/12 02:17:40 192.168.1.105:29479 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:40 192.168.1.105:42348 accepted tcp:39.156.167.33:80 [direct]
2021/10/12 02:17:46 192.168.1.100:48730 accepted tcp:203.208.50.98:80 [proxy1]
2021/10/12 02:17:46 192.168.1.100:40698 accepted tcp:203.208.50.98:443 [proxy1]
2021/10/12 02:17:46 192.168.1.100:53569 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:48 192.168.1.100:32939 accepted udp:192.168.1.103:53 [dns-out]
2021/10/12 02:17:48 192.168.1.100:45782 accepted tcp:142.250.72.131:80 [direct]

开启 debug 模式的 error.log 较长,截取了与内网相关的

2021/10/12 02:17:05 [Debug] app/dns: domain www.xxx.edu.cn will use DNS in order: [UDP:10.15.44.11:53 UDP:1.1.1.1:53]
2021/10/12 02:17:05 [Debug] app/dns: UDP:10.15.44.11:53 querying DNS for: www.xxx.edu.cn.
2021/10/12 02:17:05 [Debug] transport/internet/udp: dispatch request to: udp:10.15.44.11:53
2021/10/12 02:17:05 [Info] transport/internet/udp: establishing new connection for udp:10.15.44.11:53
2021/10/12 02:17:05 [Info] app/dispatcher: default route for udp:10.15.44.11:53
2021/10/12 02:17:05 [Info] proxy/freedom: opening connection to udp:10.15.44.11:53
2021/10/12 02:17:05 [Info] app/dns: UDP:10.15.44.11:53 got answer: www.xxx.edu.cn. TypeA -> [10.15.45.164] 2.547619ms
2021/10/12 02:17:05 [Debug] app/dns: UDP:10.15.44.11:53 updating IP records for domain:www.xxx.edu.cn.

可以看到,access.log 内并没有 DNS 查询到的 10.15.45.164 访问记录。直接访问内网 IP 也无法链接。

JusTT commented 2 years ago

要不然就是freedom去掉mark 255标记,dns出口也去掉mark 255标记,vmess也去掉mark 255;要不然就保留教程里的本机流出流量的有关mark处理的规则。

Icarusradio commented 2 years ago

要不然就是freedom去掉mark 255标记,dns出口也去掉mark 255标记,vmess也去掉mark 255;要不然就保留教程里的本机流出流量的有关mark处理的规则。

您好,第一段我大概理解意思,就是去掉每个 outbound 里的 sockopt 内的 mark:255。第二段我没有太理解,能不能再解释一下呢?我觉得我的配置应该是按照教程里做的。

JusTT commented 2 years ago

要不然就是freedom去掉mark 255标记,dns出口也去掉mark 255标记,vmess也去掉mark 255;要不然就保留教程里的本机流出流量的有关mark处理的规则。

您好,第一段我大概理解意思,就是去掉每个 outbound 里的 sockopt 内的 mark:255。第二段我没有太理解,能不能再解释一下呢?我觉得我的配置应该是按照教程里做的。

我建议你保留教程里的所有iptables 的规则,理解了之后再去做出合适的修改,你现在对加了标记的数据包在本机的流出方向上没做任何处理,这些加了mark的包出不去。 至少也要保留OUTPUT方向上有iptables -t mangle -A V2RAY_MASK -j RETURN -m mark --mark 0xff 这个规则

Icarusradio commented 2 years ago

要不然就是freedom去掉mark 255标记,dns出口也去掉mark 255标记,vmess也去掉mark 255;要不然就保留教程里的本机流出流量的有关mark处理的规则。

您好,第一段我大概理解意思,就是去掉每个 outbound 里的 sockopt 内的 mark:255。第二段我没有太理解,能不能再解释一下呢?我觉得我的配置应该是按照教程里做的。

我建议你保留教程里的所有iptables 的规则,理解了之后再去做出合适的修改,你现在对加了标记的数据包在本机的流出方向上没做任何处理,这些加了mark的包出不去。 至少也要保留OUTPUT方向上有iptables -t mangle -A V2RAY_MASK -j RETURN -m mark --mark 0xff 这个规则

按照教程完整走了一遍,发现问题所在了。我对教程的这句进行了修改

iptables -t mangle -A V2RAY -d 224.0.0.0/4 -j RETURN

这里我把 224.0.0.0/4 改成了 10.0.0.0/8 导致没法访问内网。

问题解决了,但是我很好奇这条命令的作用是什么呢?