透明代理,其实就是借助代理软件和iptables,用服务器做网关,在局域网中对其他设备的所有流量进行代理。由于其他设备上不需再安装任何代理软件就可以实现代理上网,故称为透明代理。

v2ray 方案

安装v2ray.

运行v2ray --config=/etc/v2ray/config.json类似的命令指定配置文件运行。

使用的config.json示例如下。这种方案中,通过对已经经过一层v2ray代理的流量打上标记,就不会再被iptables重新转发给v2ray。

{
  "inbounds": [
    {
      "tag":"transparent",
      "port": 10808,
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp",
        "followRedirect": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      },
      "streamSettings": {
        "sockopt": {
          "tproxy": "tproxy", // 透明代理使用 TPROXY 方式
          "mark":255
        }
      }
    },
    {
      "port": 1080, 
      "protocol": "socks", // 入口协议为 SOCKS 5
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      },
      "settings": {
        "auth": "noauth"
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess", // 代理服务器
      "settings": {
        "vnext": 
          [{
        "address": "1.2.3.4", 
        "port": 65536, 
        "users": [{ "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }]
      }]
      },
      "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": [
      {
        "address": "223.5.5.5", //中国大陆域名使用阿里的 DNS
        "port": 53,
        "domains": [
          "geosite:cn",
          "ntp.org",   // NTP 服务器
          "$myserver.address" // 此处改为你 VPS 的域名
        ]
      },
      {
        "address": "114.114.114.114", //中国大陆域名使用 114 的 DNS (备用)
        "port": 53,
        "domains": [
          "geosite:cn",
          "ntp.org",   // NTP 服务器
          "$myserver.address" // 此处改为你 VPS 的域名
        ]
      },
      {
        "address": "8.8.8.8", //非中国大陆域名使用 Google 的 DNS
        "port": 53,
        "domains": [
          "geosite:geolocation-!cn"
        ]
      },
      {
        "address": "1.1.1.1", //非中国大陆域名使用 Cloudflare 的 DNS
        "port": 53,
        "domains": [
          "geosite:geolocation-!cn"
        ]
      }
    ]
  },
  "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"
      }
    ]
  }
}

然后借助iptables进行流量过滤。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 224.0.0.0/4 -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 10808 --tproxy-mark 1 # 给 UDP 打标记 1,转发至 12345 端口
iptables -t mangle -A V2RAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 10808 --tproxy-mark 1 # 给 TCP 打标记 1,转发至 12345 端口
iptables -t mangle -A PREROUTING -j V2RAY # 应用规则

# 代理网关本机
iptables -t mangle -N V2RAY_MASK 
iptables -t mangle -A V2RAY_MASK -d 224.0.0.0/4 -j RETURN 
iptables -t mangle -A V2RAY_MASK -d 255.255.255.255/32 -j RETURN 
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN # 直连局域网
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS)
iptables -t mangle -A V2RAY_MASK -j RETURN -m mark --mark 0xff    # 直连 SO_MARK 为 0xff 的流量(0xff 是 16 进制数,数值上等同与上面V2Ray 配置的 255),此规则目的是避免代理本机(网关)流量出现回环问题
iptables -t mangle -A V2RAY_MASK -p udp -j MARK --set-mark 1   # 给 UDP 打标记,重路由
iptables -t mangle -A V2RAY_MASK -p tcp -j MARK --set-mark 1   # 给 TCP 打标记,重路由
iptables -t mangle -A OUTPUT -j V2RAY_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

clash 方案

这个clash方案本来还可以做DNS的,但是我在实际使用过程中发现,只要一用自己的DNS就没法上网了。。所以DNS还是用114.114.114.114算了。

clash去github上下载Premium版的。链接:Release (dreamacro.workers.dev)

# port: 7890

# socks-port: 7891

tproxy-port: 7892

allow-lan: true

# This is only applicable when `allow-lan` is `true`
bind-address: '*'

# Clash router working mode
# rule: rule-based packet routing
# global: all packets will be forwarded to a single endpoint
# direct: directly forward the packets to the Internet
mode: rule

# Clash by default prints logs to STDOUT
# info / warning / error / debug / silent
# log-level: info

# When set to false, resolver won't translate hostnames to IPv6 addresses
ipv6: false

# hosts:
#   "assets1.xboxlive.cn": 117.185.135.35
#   "assets2.xboxlive.cn": 117.185.135.35
#   "dlassets.xboxlive.cn": 117.185.135.35
#   "dlassets2.xboxlive.cn": 117.185.135.35
#   "d1.xboxlive.cn": 117.185.135.35
#   "d2.xboxlive.cn": 117.185.135.35  

#   "dl.delivery.mp.microsoft.com": 117.185.135.35
#   "tlu.dl.delivery.mp.microsoft.com": 117.185.135.35

#   "assets1.xboxlive.com": 192.168.1.104
#   "assets2.xboxlive.com": 192.168.1.104
#   "dlassets.xboxlive.com": 192.168.1.104
#   "dlassets2.xboxlive.com": 192.168.1.104
#   "d1.xboxlive.com": 192.168.1.104
#   "d2.xboxlive.com": 192.168.1.104

#   "atum.hac.lp1.d4c.nintendo.net": 184.28.218.89
#   "ctest.cdn.nintendo.net.akamaized.net": 184.28.223.179
  # 'mtalk.google.com': 108.177.125.188
  # '*.clash.dev': 127.0.0.1
  # '.dev': 127.0.0.1
  # 'alpha.clash.dev': '::1'

# DNS server settings
# This section is optional. When not present, DNS server will be disabled.
dns:
  enable: true                                                                                                                                                                             
  listen: 0.0.0.0:53
  ipv6: false 

  default-nameserver:
    - 223.5.5.5

  nameserver:
    - 114.114.114.114
    - 223.5.5.5
    - 119.29.29.29


  fallback:
    - 1.1.1.1
    # - https://1.1.1.1/dns-query
    # - https://1.1.1.1/resolve

  fallback-filter:
    geoip: true
    geoip-code: CN
    domain:
      - '+.google.com'
      - '+.facebook.com'
      - '+.youtube.com'

  nameserver-policy:
    # '+.jsdelivr.net': 'https://1.1.1.1/dns-query'
    '+.zhihu.com': '114.114.114.114'
    '+.zhimg.com': '114.114.114.114'
  #   '+.apple.com': '223.5.5.5'
  #   '+.apple.com.cn': '223.5.5.5'
  #   '+.akadns.net': '223.5.5.5'
  #     - '+.youtube.com'

proxies:
  - name: "IPLC"
    type: vmess
    server: 1.2.3.4
    port: 65536
    uuid: aaaaaaaa-ffff-dddd-cccc-xxxxxxxxxxx
    alterId: 0
    cipher: auto
    udp: true


proxy-groups:

  - name: "PROXY"
    type: select
    proxies:
      - IPLC

rule-providers:
  reject:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/reject.txt"
    path: ./ruleset/reject.yaml
    interval: 86400

  icloud:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/icloud.txt"
    path: ./ruleset/icloud.yaml
    interval: 86400

  apple:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/apple.txt"
    path: ./ruleset/apple.yaml
    interval: 86400

  google:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/google.txt"
    path: ./ruleset/google.yaml
    interval: 86400

  proxy:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/proxy.txt"
    path: ./ruleset/proxy.yaml
    interval: 86400

  direct:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/direct.txt"
    path: ./ruleset/direct.yaml
    interval: 86400

  private:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/private.txt"
    path: ./ruleset/private.yaml
    interval: 86400

  gfw:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/gfw.txt"
    path: ./ruleset/gfw.yaml
    interval: 86400

  greatfire:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/greatfire.txt"
    path: ./ruleset/greatfire.yaml
    interval: 86400

  tld-not-cn:
    type: http
    behavior: domain
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/tld-not-cn.txt"
    path: ./ruleset/tld-not-cn.yaml
    interval: 86400

  telegramcidr:
    type: http
    behavior: ipcidr
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/telegramcidr.txt"
    path: ./ruleset/telegramcidr.yaml
    interval: 86400

  cncidr:
    type: http
    behavior: ipcidr
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/cncidr.txt"
    path: ./ruleset/cncidr.yaml
    interval: 86400

  lancidr:
    type: http
    behavior: ipcidr
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/lancidr.txt"
    path: ./ruleset/lancidr.yaml
    interval: 86400

  applications:
    type: http
    behavior: classical
    url: "https://cdn.jsdelivr.net/gh/Loyalsoldier/clash-rules@release/applications.txt"
    path: ./ruleset/applications.yaml
    interval: 86400


rules:
  - IP-CIDR,120.226.29.0/24,DIRECT
  - IP-CIDR,23.216.159.0/24,DIRECT
  - IP-CIDR,112.65.203.0/24,DIRECT
  - IP-CIDR,106.38.179.0/24,DIRECT
  - IP-CIDR,223.119.50.0/24,PROXY
  - DOMAIN-SUFFIX,xboxlive.cn,DIRECT

  - DOMAIN,dl.delivery.mp.microsoft.com,DIRECT
  - DOMAIN,tlu.dl.delivery.mp.microsoft.com,DIRECT
  - DOMAIN,assets1.xboxlive.com,DIRECT
  - DOMAIN,assets2.xboxlive.com,DIRECT
  - DOMAIN,dlassets.xboxlive.com,DIRECT
  - DOMAIN,dlassets2.xboxlive.com,DIRECT
  - DOMAIN,d1.xboxlive.com,DIRECT
  - DOMAIN,d2.xboxlive.com,DIRECT

  - DOMAIN,ctest.cdn.nintendo.net.akamaized.net,DIRECT
  - DOMAIN,atum.hac.lp1.d4c.nintendo.net,DIRECT
  - IP-CIDR,184.28.218.89/24,DIRECT

  - RULE-SET,applications,DIRECT
  - DOMAIN,clash.razord.top,DIRECT
  - DOMAIN,yacd.haishan.me,DIRECT
  - RULE-SET,private,DIRECT
  - RULE-SET,reject,REJECT
  - RULE-SET,icloud,DIRECT
  - RULE-SET,apple,DIRECT
  - RULE-SET,google,DIRECT
  - RULE-SET,proxy,PROXY
  - RULE-SET,direct,DIRECT
  - RULE-SET,lancidr,DIRECT
  - RULE-SET,cncidr,DIRECT
  - RULE-SET,telegramcidr,PROXY
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

需要时将上面的配置文件中的服务器配置更换为自己的即可。

使用的iptables规则如下:

#!/bin/bash
# ROUTE RULES
ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100

# CREATE TABLE
iptables -t mangle -N clash

# RETURN LOCAL AND LANS
iptables -t mangle -A clash -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A clash -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A clash -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A clash -d 192.0.0.0/24 -j RETURN
iptables -t mangle -A clash -d 192.0.2.0/24 -j RETURN
iptables -t mangle -A clash -d 198.18.0.0/15 -j RETURN
iptables -t mangle -A clash -d 198.51.100.0/24 -j RETURN
iptables -t mangle -A clash -d 203.0.113.0/24 -j RETURN
iptables -t mangle -A clash -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A clash -d 100.64.0.0/10 -j RETURN
iptables -t mangle -A clash -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A clash -d 240.0.0.0/4 -j RETURN

# FORWARD ALL
iptables -t mangle -A clash -p udp -j TPROXY --on-port 7892 --tproxy-mark 1
iptables -t mangle -A clash -p tcp -j TPROXY --on-port 7892 --tproxy-mark 1

# REDIRECT
iptables -t mangle -A PREROUTING -j clash