Contents
xray
在RaspberryPi上实现透明代理
设置网关
- 用网线将树莓派接入路由器 LAN 口,假设分给树莓派的 IP 是 192.168.1.253。
树莓派开启 IP 转发(需要开启 IP 转发才能作为网关)。命令为echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf && sysctl -p 。执行后将出现 net.ipv4.ip_forward=1 的提示。
- 手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.253。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)。
安装xray
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
准备XRay Client 配置文件
tproxy-tls-ws.json
root@raspberrypi:~/xray# cat /etc/xray/tproxy-tls-ws.json
{
"inbounds": [
{
"tag":"transparent",
"port": 12345,
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
},
"streamSettings": {
"sockopt": {
"tproxy": "tproxy" // 透明代理使用 TPROXY 方式
}
}
},
{
"port": 1089,
"protocol": "socks", // 入口协议为 SOCKS 5
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
},
"settings": {
"auth": "noauth"
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless", // 代理服务器
"settings": {
"vnext": [
{
"address": "对应的域名",
"port": 443,
"users": [
{
"id": "2b0a831c-968c-4f0d-8c12-28a5e3", //替换为对应的ID
"encryption": "none",
"alterId": 0
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"allowInsecure": false,
"show": false
},
"wsSettings": {
"path": "/99eab497c4?ed=2048",
"headers": {}
}
},
"streamSettings": {
"sockopt": {
"mark": 255
}
},
"mux": {
"enabled": true
}
},
{
"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": {
"servers": [
"8.8.8.8", // 非中中国大陆域名使用 Google 的 DNS
"1.1.1.1", // 非中中国大陆域名使用 Cloudflare 的 DNS(备用)
"114.114.114.114", // 114 的 DNS (备用)
{
"address": "223.5.5.5", //中国大陆域名使用阿里的 DNS
"port": 53,
"domains": [
"geosite:cn",
"ntp.org", // NTP 服务器
"brightmoon.top" // 此处改为你 VPS 的域名
]
}
]
},
"routing": {
"domainStrategy": "IPOnDemand",
"rules": [
{ // 劫持 53 端口 UDP 流量,使用 V2Ray 的 DNS
"type": "field",
"inboundTag": [
"transparent"
],
"port": 53,
"network": "udp",
"outboundTag": "dns-out"
},
{ // 直连 123 端口 UDP 流量(NTP 协议)
"type": "field",
"inboundTag": [
"transparent"
],
"port": 123,
"network": "udp",
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
// 设置 DNS 配置中的国内 DNS 服务器地址直连,以达到 DNS 分流目的
"223.5.5.5",
"114.114.114.114"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
// 设置 DNS 配置中的国内 DNS 服务器地址走代理,以达到 DNS 分流目的
"8.8.8.8",
"1.1.1.1"
],
"outboundTag": "proxy" // 改为你自己代理的出站 tag
},
{ // 广告拦截
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{ // BT 流量直连
"type": "field",
"protocol":["bittorrent"],
"outboundTag": "direct"
},
{ // 直连中国大陆主流网站 ip 和 保留 ip
"type": "field",
"ip": [
"geoip:private",
"geoip:cn"
],
"outboundTag": "direct"
},
{ // 直连中国大陆主流网站域名
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
}
]
}
}以上是 V2Ray 透明代理的参考配置,关于配置有一些注意点及说明:
- dokodemo-door 是用来接收透明代理的入站协议,followRedirect 项须为 true 以及 sockopt.tproxy 项须为 tproxy,建议开启 snifing,否则路由无法匹配域名;
- 本节添加了 DNS 配置,用来对国内外域名进行 DNS 分流,需要 DNS 配置、DNS 入站、DNS 出站和路由四者配合,在本例中 DNS 入站直接使用透明代理入站,可参考DNS 及其应用
在 DNS 配置中,依次配置了 Google、Cloudflare、114 和阿里的 DNS,由于在阿里的 DNS 中指定了 domain,所以匹配的域名会用阿里的 DNS 查询,其他的先查询 Google 的 DNS,如果查不到的话再依次查 Cloudflare 及 114 的。所以达到了国内外域名 DNS 分流,以及 DNS 备用。要注意把 NTP 服务器和你自己 VPS 域名也加入到直连的 DNS,否则会导致 V2Ray 无法与 VPS 正常连接;
- DNS 配置只是说明哪些域名查哪个 DNS,至于哪个 DNS 走代理哪个 DNS 直连要在 routing 里设置规则;
- routing 也要设置 123 端口的 UDP 流量直连,不然的话要是时间误差超出允许范围(90s),要使用 NTP 校准时间就要先连上代理,但是连代理又要确保时间准确,结果就是既连不上代理,也无法自动校准时间;
- freedom 的出站设置 domainStrategy 为 UseIP,以避免直连时因为使用本机的 DNS 出现一些奇怪问题;
注意要在 dokodemo inbound 和所有的 outbound 加一个 255 的 mark,这个 mark 与下文 iptables 命令中 iptables -t mangle -A V2RAY_MASK -j RETURN -m mark --mark 0xff 配合,以直连 V2Ray 发出的流量(blackhole 可以不配置 mark)。
确认Raspberry可以FK GFW
执行 curl -so /dev/null -w "%{http_code}" google.com -x socks5://127.0.0.1:1089
确认 V2Ray 已经可以翻墙(命令中 socks5 指 inbound 协议为 socks,1089 指该 inbound 端口是 1089)。
如果执行这个命令出现了 301 或 200 这类数字的话代表可以翻墙
如果长时间没反应或者是 000 的话说明不可以翻墙。
配置iptables 脚本
配置好用于tproxy的iptable脚本
配置透明代理
root@raspberrypi:~/xray# cat iptables_tproxy.sh
# 设置策略路由 ip rule add fwmark 1 table 100 ip route add local 0.0.0.0/0 dev lo table 100 # 代理局域网设备 iptables -t mangle -N XRAY 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 # 直连局域网,避免 V2Ray 无法启动时无法连网关的 SSH,如果你配置的是其他网段(如 10.x.x.x 等),则修改成自己的 iptables -t mangle -A XRAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS) iptables -t mangle -A XRAY -d 10.0.0.0/8 -p tcp -j RETURN # 直连局域网,避免 V2Ray 无法启动时无法连网关的 SSH,如果你配置的是其他网段(如 10.x.x.x 等),则修改成自己的 iptables -t mangle -A XRAY -d 10.0.0.0/8 -p udp ! --dport 53 -j RETURN # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS) iptables -t mangle -A XRAY -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 XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 # 给 UDP 打标记 1,转发至 12345 端口 iptables -t mangle -A XRAY -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 XRAY # 应用规则 # 代理网关本机 iptables -t mangle -N XRAY_MASK 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 # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS) iptables -t mangle -A XRAY_MASK -d 10.0.0.0/8 -p tcp -j RETURN # 直连局域网 iptables -t mangle -A XRAY_MASK -d 10.0.0.0/8 -p udp ! --dport 53 -j RETURN # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS) iptables -t mangle -A XRAY_MASK -j RETURN -m mark --mark 0xff # 直连 SO_MARK 为 0xff 的流量(0xff 是 16 进制数,数值上等同与上面V2Ray 配置的 255),此规则目的是避免代理本机(网关)流量出现回环问题 iptables -t mangle -A XRAY_MASK -p udp -j MARK --set-mark 1 # 给 UDP 打标记,重路由 iptables -t mangle -A XRAY_MASK -p tcp -j MARK --set-mark 1 # 给 TCP 打标记,重路由 iptables -t mangle -A OUTPUT -j XRAY_MASK # 应用规则 # 新建 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
确认开机启动的脚本
xray.service
root@raspberrypi:~/xray# cat /etc/systemd/system/xray.service
[Unit] Description=XRay Service 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/bin/xray -config /etc/xray/tproxy-tls-ws.json Restart=on-failure RestartPreventExitStatus=23 LimitNPROC=500 LimitNOFILE=1000000 [Install] WantedBy=multi-user.target
tproxyrule.service
配置开机自动启动
root@raspberrypi:~/xray# cat /etc/systemd/system/tproxyrule.service
[Unit] Description=Tproxy rule After=network.target Wants=network.target [Service] Type=oneshot RemainAfterExit=yes # 注意分号前后要有空格 ExecStart=/sbin/ip rule add fwmark 1 table 100 ; /sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; /sbin/iptables-restore /etc/iproute2/rules-xray.v5 ExecStop=/sbin/ip rule del fwmark 1 table 100 ; /sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; /sbin/iptables -t mangle -F # 如果是 nftables,则改为以下命令 # ExecStart=/sbin/ip rule add fwmark 1 table 100 ; /sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; /sbin/nft -f /etc/nftables/rules.v4 # ExecStop=/sbin/ip rule del fwmark 1 table 100 ; /sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; /sbin/nft flush ruleset [Install] WantedBy=multi-user.target
systemctl enable tproxyrule
systemctl enable xray
设定 DHCP(可选)
在路由器上设定 DHCP,将网关地址指向网关设备,在本文的举例中即为树莓派的 IP 192.168.1.253; DNS 随意,因为已经配置了劫持 53 端口的 UDP,当然填常规的 DNS 也更是没有问题的。
