xray 透明代理

前排声明,下面的内容是在山上捡到的u盘里面的一段文字。

本篇中介绍的透明路由更偏向隐藏自身,以及连接国内网站的极致速度,访问国外网站性能稍差。主要访问国外网站的用户请选择其他方式。

#前言

今天看了一篇关于 ip 转发的讨论,又想搞透明路由了。几年前升级宽带的时候,买了一台网件的路由器,刷过一些第三方固件,在路由器上安装过翻墙软件,但后来放弃了。因为这会给所有访问增加延迟:在路由器上安装翻墙软件,分流的任务大都交给翻墙软件,国内直连的网站也多了一些步骤,延迟会增加几毫秒到几十毫秒。玩游戏或者刷视频时,难以接受。今天用两个路由器加一个树莓派搭一个复杂点的路由系统,看看效果如何。其实只需要两台路由器就可以了,但是我只有一台性能还过得去的路由器,另一台连第三方固件都没有,所以加上一个树莓派做网关。

将 xray 运行在次级路由的好处是:

  1. 主路由不受影响,延迟低,访问国内互联网时,直接。
  2. 隐藏 xray,内网设备对外网来说不可见,很难从外部探测到主路由器下的设备运行什么软件。
  3. 连接翻墙路由器直接访问大互联网,不需要手动设置网关,无感。

本文参考了 v2ray 新白话文指南 透明代理(TPROXY),以及 xray 透明代理(TProxy)配置教程

#所需设备

一台主路由器 R1。

一台翻墙路由器 R2。

一台树莓派 P,可以是任何运行 linux 的设备,推荐使用 Debian 系。

在未执行完所有必须命令前,你可能无法通过路由器 R2 上网,请不要惊慌。

#路由器设置

路由器 R1 连接 ISP,我是 pppoe 拨号上网,LAN 口地址 10.0.0.1,子网掩码 255.255.255.0,网关地址 10.0.0.1,开启 dhcp ,dhcp 分配的地址从 10.0.0.100 开始。

路由器 R2 连接路由器 R1,WAN 口地址设置为 10.0.0.5, LAN 口地址192.168.1.7,开启 dhcp,网关设置为树莓派 P 的地址 10.0.0.3

两个路由器可以设置固定的信道,避免自己家的路由器互相冲突。R1 的 LAN 口,R2的 WAN 口,LAN 口,以及树莓派的 ip 地址可以使用任何自己喜欢的地址,但是请注意不要冲突,并修改路由规则中相应的地址。

#树莓派设置

树莓派 P 连接到路由器 R1 上,设置静态 ip 地址 10.0.0.3,网关以及 dns 服务器均是路由器 R1 。

#树莓派设置静态 ip

开启树莓派的 dhcp client 服务,并设置开机启动。 dhcp client daemon,dhcp 客户端守护进程,简写 dhcpcd 。

sudo systemctl enable dhcpcd --now

修改 dhcp client 的配置文件

sudo nano /etc/dhcpcd.conf

注意根据自己的需求设置静态 ip 地址,不要造成 ip 冲突。

interface eth0
static ip_address=10.0.0.3
static routers=10.0.0.1
static domain_name_servers=10.0.0.1

保存后记得重启

sudo reboot

同时可以选择关闭树莓派的无线网卡 wlan0,这一步不是必须的

sudo ifconfig wlan0 down
#树莓派 xray 配置

为了更好的分流,先替换 xray 的路由规则: geoip.datgeosite.dat

xray 默认的 路由规则在 /usr/local/share/xray/,建议将下列更新路由规则的命令保存成本地,并时常更新,使用最新的规则。

sudo wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat -O /usr/local/share/xray/geoip.dat

sudo wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat -O /usr/local/share/xray/geosite.dat

下面的配置来自上面提到的参考文章,带有一定的 DNS 分发处理,屏蔽广告,大陆网站分流等功能,但是需要替换路由规则,没有替换过路由规则可能导致 xray 因配置问题而运行失败。

{
  "log": {
    "loglevel": "warning",
    "error": "/var/log/xray/error.log",
    "access": "/var/log/xray/access.log"
  },
  "inbounds": [
    {
      "tag": "all-in",
      "port": 35791,
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp",
        "followRedirect": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      },
      "streamSettings": {
        "sockopt": {
          "tproxy": "tproxy"
        }
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {
        "domainStrategy": "UseIPv4"
      },
      "streamSettings": {
        "sockopt": {
          "mark": 2
        }
      }
    },
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "usla.acytoo.com",
            "port": 57913,
            "users": [
              {
                "id": "a808524e-80fc-482f-8c18-b0e0a0026a09",
                "flow": "xtls-rprx-splice",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "xtls",
        "sockopt": {
          "mark": 2
        }
      }
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {
        "response": {
          "type": "http"
        }
      }
    },
    {
      "tag": "dns-out",
      "protocol": "dns",
      "settings": {
        "address": "8.8.8.8"
      },
      "proxySettings": {
        "tag": "proxy"
      },
      "streamSettings": {
        "sockopt": {
          "mark": 2
        }
      }
    }
  ],
  "dns": {
    "hosts": {
      "usla.acytoo.com": "34.94.134.193"
    },
    "servers": [
      {
        "address": "119.29.29.29",
        "port": 53,
        "domains": [
          "geosite:cn"
        ],
        "expectIPs": [
          "geoip:cn"
        ]
      },
      {
        "address": "223.5.5.5",
        "port": 53,
        "domains": [
          "geosite:cn"
        ],
        "expectIPs": [
          "geoip:cn"
        ]
      },
      "8.8.8.8",
      "1.1.1.1",
      "https+local://doh.dns.sb/dns-query"
    ]
  },
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "all-in"
        ],
        "port": 53,
        "outboundTag": "dns-out"
      },
      {
        "type": "field",
        "ip": [
          "8.8.8.8",
          "1.1.1.1"
        ],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "domain": [
          "geosite:category-ads-all"
        ],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "domain": [
          "geosite:geolocation-!cn"
        ],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "ip": [
          "geoip:telegram"
        ],
        "outboundTag": "proxy"
      }
    ]
  }
}
#树莓派路由配置

我本地端口用的是35791,如果你用不同的本地端口,记得修改,包括 iptables 里面的转发,以及 xray 的配置。

iptables -t mangle -N XRAY
iptables -t mangle -A XRAY -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A XRAY -d 100.64.0.0/10 -j RETURN
iptables -t mangle -A XRAY -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A XRAY -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A XRAY -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A XRAY -d 192.0.0.0/24 -j RETURN
iptables -t mangle -A XRAY -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A XRAY -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A XRAY -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A XRAY -d 192.168.0.0/16 -p tcp ! --dport 53 -j RETURN
iptables -t mangle -A XRAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A XRAY -p tcp -j TPROXY --on-port 35791 --tproxy-mark 1
iptables -t mangle -A XRAY -p udp -j TPROXY --on-port 35791 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j XRAY

iptables -t mangle -N XRAY_SELF
iptables -t mangle -A XRAY_SELF -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A XRAY_SELF -d 100.64.0.0/10 -j RETURN
iptables -t mangle -A XRAY_SELF -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A XRAY_SELF -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A XRAY_SELF -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A XRAY_SELF -d 192.0.0.0/24 -j RETURN
iptables -t mangle -A XRAY_SELF -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A XRAY_SELF -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A XRAY_SELF -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A XRAY_SELF -d 192.168.0.0/16 -p tcp ! --dport 53 -j RETURN
iptables -t mangle -A XRAY_SELF -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A XRAY_SELF -m mark --mark 2 -j RETURN
iptables -t mangle -A XRAY_SELF -p tcp -j MARK --set-mark 1
iptables -t mangle -A XRAY_SELF -p udp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j XRAY_SELF
ip route add local default dev lo table 100
ip rule add fwmark 1 table 100

#测试及保存

经过上面的步骤,即

  • 配置路由器,树莓派 IP,设置翻墙路由器的网关为树莓派。
  • 配置运行在树莓派上的 xray。
  • 配置树莓派的路由表。

我们的目标路由器 R2 已配置完毕。使用另一台设备,连接路由器 R2,不需要在设备上进行任何设置,就已经可以访问互联网了。

除了检查是否能访问互联网,还要看看 ssh 到树莓派,路由器的连接有没有断,是否互相可达。

得到想要的结果,那么可以进行下一步。如果无法访问,那么有可能是路由规则出错了,请检查自己的 ip 设置。遇到问题,请重启相关设备。

接下来我们将设置 iptables 开机设置,这是一个较为危险的步骤,如果配置中出现了环,除了造成路由拥塞外,更可能的是无法连接树莓派或者路由器,那时可能要重装系统了。

有的文章说用 iptables-persistent,我试了试,真好用啊,以前都是写 systemd 开机执行脚本,现在有别的软件自动做了。

sudo apt install iptables-persistent

sudo netfilter-persistent save

然后修改 /lib/systemd/system/netfilter-persistent.service

sudo nano /lib/systemd/system/netfilter-persistent.service

在 ExecStart 与ExecStop 后面各加上两条指令。修改完成的文件长这个样子。

[Unit]
Description=netfilter persistent configuration
DefaultDependencies=no
Wants=network-pre.target systemd-modules-load.service local-fs.target
Before=network-pre.target shutdown.target
After=systemd-modules-load.service local-fs.target
Conflicts=shutdown.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/netfilter-persistent start ; ip route add local default dev lo table 100 ; ip rule add fwmark 1 table 100
ExecStop=/usr/sbin/netfilter-persistent stop ; ip route del local default dev lo table 100 ; ip rule del table 100

[Install]
WantedBy=multi-user.target

#设置完毕

所有需要的操作都已经完成,这时断电重启,路由器 R2 依旧可以跨越网络长城。

#树莓派是否开启 ip 转发

很多配置都会叫你打开 ip 转发,其实不必。

详情请看 开启 ip 转发会严重降低 xray splice 性能

这是因为我们配置了 xray 为转发工具。xray 开启时,可以正常上网;当 xray 关闭 或路由表未配置,且 ip 转发关闭时,通过翻墙路由无法连接任何网站,因为你的请求没发出去。

不建议大家开启 ip 转发,但是如果你想开启,方法如下。

su -

echo 1 > /proc/sys/net/ipv4/ip_forward

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

sysctl -p /etc/sysctl.conf

exit

echo 命令后> 表示将文件替换成 echo 的内容,>> 表示在文件末尾添加 echo 的内容。在 /etc/sysctl.conf 文件中,本来就有关于 ip 转发的命令,但是被注释掉了。同一文件中,如果有相同的配置题条目,那么后面的覆盖前面的。所以执行上面的命令时,你不必担心以前设置过类似的内容而导致配置失败。

开启 ip 转发后,即使 xray 进程以外终止,依旧可以通过 R2 路由器访问国内的互联网。

如果你后悔开启 ip 转发,下面的命令可以关闭它。

su -

echo 0 > /proc/sys/net/ipv4/ip_forward

echo "net.ipv4.ip_forward=0" >> /etc/sysctl.conf

sysctl -p /etc/sysctl.conf

exit