一、简介
在过去相当长一段时间内,稳定的科学上网方法为使用国外部署shadowsocks+本地部署clash等技术实现本地socks代理,适用于浏览器等终端挂载使用。而对于操作系统,则可以通过设置系统全局代理或者设置终端http_proxy https_proxy socks_proxy all_proxy等参数也可以实现terminal终端等的使用,但是该方法受限于应用程序的支持程度不同导致现无法使用的情况。
无疑使我们想到了使用VPN的方式。其实早先,可以使用VPN协议直达国外网络,但是GFW对于VPN协议的识别和拦截程度相当严格,最终无法使用。近期,通过对Xray的研究,发现其对于iptables-tproxy的支持,可以实现透明代理。在局域网,可以通过设置网关为配置了iptables-tproxy的xray服务器。通过测试,也实现了从公网访问wg服务器,且wg服务器通过设置默认网关为Xray服务器,策略路由控制其udp 51820流量走默认网关,实现VPN科学上网。
拓扑图如下
二、部署xray client systemd服务
2.1 下载文件
wget http://vip.123pan.cn/1815238395/download/xray/Xray-core%20v1.8.8/Xray-linux-64.zip
cp xray /usr/local/bin/
mkdir -p /usr/local/share/xray
wget --no-check-certificate -O /usr/local/share/xray/ http://vip.123pan.cn/1815238395/download/xray/rules/20240228/geoip.dat
wget --no-check-certificate -O /usr/local/share/xray/ http://vip.123pan.cn/1815238395/download/xray/rules/20240228/geosite.dat
2.2 配置服务
mkdir -p /etc/systemd/system/xray.service.d
cat <<'EOF'>10-donot_touch_single_conf.conf
# In case you have a good reason to do so, duplicate this file in the same directory and make your customizes there.
# Or all changes you made will be lost! # Refer: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
[Service]
ExecStart=
ExecStart=/usr/local/bin/xray run -config /usr/local/etc/xray/config.json
mkdir -p /etc/systemd/system/xray@.service.d/
cat <<'EOF'>10-donot_touch_single_conf.conf
# In case you have a good reason to do so, duplicate this file in the same directory and make your customizes there.
# Or all changes you made will be lost! # Refer: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
[Service]
ExecStart=
ExecStart=/usr/local/bin/xray run -config /usr/local/etc/xray/%i.json
cat <<'EOF'>/etc/systemd/system/xray.service
[Unit]
Description=Xray Service
Documentation=https://github.com/xtls
After=network.target nss-lookup.target
[Service]
User=nobody
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ExecStart=/usr/local/bin/xray run -config /usr/local/etc/xray/config.json
Restart=on-failure
RestartPreventExitStatus=23
LimitNPROC=10000
LimitNOFILE=1000000
[Install]
WantedBy=multi-user.target
EOF
cat <<'EOF'>/etc/systemd/system/xray@.service
[Unit]
Description=Xray Service
Documentation=https://github.com/xtls
After=network.target nss-lookup.target
[Service]
User=nobody
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ExecStart=/usr/local/bin/xray run -config /usr/local/etc/xray/%i.json
Restart=on-failure
RestartPreventExitStatus=23
LimitNPROC=10000
LimitNOFILE=1000000
[Install]
WantedBy=multi-user.target
chmod 644 /etc/systemd/system/xray.service /etc/systemd/system/xray@.service
2.3 配置xray client.json
cat <<'EOF'>/usr/local/etc/xray/config.json
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "all-in",
"port": 12345,
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"]
},
"streamSettings": {
"sockopt": {
"tproxy": "tproxy"
}
}
},
{
"port": 10808,
"protocol": "socks",
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"]
},
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
//此为默认outbound,路由(routing)模块若未匹配到任何规则,则默认走此 proxy 出口,如果你希望直连国内优先请将下面 direct 出口放到 outbound 第一,看不懂可忽略
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "1111", //改为你自己的域名,直接填写ipv4或ipv6地址也可以
"port": 443,
"users": [
{
"id": "1111", //填写uuid,可通过在终端中输入 xray uuid 生成;此处也支持任意字符串(https://xtls.github.io/config/inbounds/vless.html#clientobject)
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"sockopt": {
"mark": 255
},
"network": "tcp",
"security": "tls", //注意使用 xtls-rprx-vision 流控此处需为 tls
"tlsSettings": {
//注意使用 xtls-rprx-vision 流控此处需为 tlsSettings
"allowInsecure": false,
"serverName": "111", //改为你自己的域名
"fingerprint": "chrome" //此设置建议先看下Release, https://github.com/XTLS/Xray-core/releases/tag/v1.7.3
}
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIP"
},
"streamSettings": {
"sockopt": {
"mark": 255
}
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {
"response": {
"type": "http"
}
}
},
{
"tag": "dns-out",
"protocol": "dns",
"streamSettings": {
"sockopt": {
"mark": 255
}
}
}
],
"dns": {
"hosts": {
"domain:googleapis.cn": "googleapis.com",
"dns.google": "8.8.8.8",
"111": "111" //如果 outbound 的 proxy 里 address 填的域名:希望代理走ipv4,这里 VPS IP 填VPS的ipv4, 希望代理走ipv6,这里VPS IP 填VPS的ipv6;outbound 的 proxy 里 address 填的 IP,这行不用写。
},
"servers": [
"https://1.1.1.1/dns-query",
{
"address": "119.29.29.29",
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
"https://dns.google/dns-query",
"223.5.5.5",
"localhost"
]
},
"routing": {
"domainMatcher": "mph",
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
{
"type": "field",
"inboundTag": ["all-in"],
"port": 123,
"network": "udp",
"outboundTag": "direct"
},
{
"type": "field",
"inboundTag": ["all-in"],
"port": 53,
"network": "udp",
"outboundTag": "dns-out"
},
{
"type": "field",
"ip": ["119.29.29.29", "223.5.5.5"],
"outboundTag": "direct"
},
{
"type": "field",
"protocol": ["bittorrent"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:private", "geoip:cn"], //此处可加入 VPS IP 避免 ssh 时被代理
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["1.1.1.1", "8.8.8.8"],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [
"geosite:geolocation-!cn",
"domain:googleapis.cn",
"dns.google"
],
"outboundTag": "proxy"
}
]
}
}
EOF
2.4 启动服务
systemctl enable xray
systemctl restart xray
2.5 设置支持流量转发到xray
#!/bin/bash
# 路由
ip rule delete fwmark 1 table 100
ip rule add fwmark 1 table 100
ip route flush table 100
ip route add local default dev lo table 100
ip route list table 100
# 代理局域网设备 v4
iptables -t mangle -N XRAY
iptables -t mangle -F XRAY
iptables -t mangle -A XRAY -p udp --dport 51820 -j RETURN
iptables -t mangle -A XRAY -p udp --sport 51820 -j RETURN
iptables -t mangle -A XRAY -d 127.0.0.1/32 -j RETURN
iptables -t mangle -A XRAY -d 224.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 -j RETURN
iptables -t mangle -A XRAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A XRAY -j RETURN -m mark --mark 0xff
iptables -t mangle -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
iptables -t mangle -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j XRAY
# 代理网关本机 v4
iptables -t mangle -N XRAY_MASK
iptables -t mangle -F XRAY_MASK
iptables -t mangle -A XRAY_MASK -p udp --dport 51820 -j RETURN
iptables -t mangle -A XRAY_MASK -p udp --sport 51820 -j RETURN
iptables -t mangle -A XRAY_MASK -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A XRAY_MASK -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN
iptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A XRAY_MASK -j RETURN -m mark --mark 0xff
iptables -t mangle -A XRAY_MASK -p udp -j MARK --set-mark 1
iptables -t mangle -A XRAY_MASK -p tcp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j XRAY_MASK
# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v4
iptables -t mangle -N DIVERT
iptables -t mangle -F 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
三、支持WG
#!/bin/bash
ip rule add fwmark 0x1 table 200
ip route add default via 192.168.124.1 dev ens18 table 200
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t mangle -F
iptables -t mangle -A PREROUTING -p udp --sport 51820 -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p udp --sport 51820 -j MARK --set-mark 1