跬步 On Coding

透明代理实践:技术小结与方案演进

1. 路由拓扑

在家中,我们采用了中国移动提供的千兆宽带服务,通过移动自带的光猫进行拨号连接。紧随其后是一台搭载OpenWRT系统的路由器,负责管理Wi-Fi以及局域网的网络地址转换(NAT)。由于光猫已占用了192.168.1.1网段,我们将路由器配置为192.168.2.1,以便更好地管理IPv4流量。在IPv4网络中,数据流经过光猫和路由器的双层NAT进行处理。

对于IPv6网络,由于路由器无法直接获取地址前缀,我们配置了IPv6 DHCP Relay功能,确保局域网内的每个设备都能够获取IPv6地址。

以下是我们在OpenWRT路由器上的相关配置:

# cat /etc/config/network
config interface 'lan'
	option type 'bridge'
	option ifname 'eth0 ra0 ra1 rai0 rai1'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '192.168.2.1'
	option macaddr 'C8:BF:4C:87:EE:68'

在这里,我们通过将LAN口的MAC地址固定设置,以避免LAN IPv6地址的变化。

# cat /etc/config/dhcp
config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '12h'
	option ra_slaac '1'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option ra 'relay'
	option ndp 'relay'
	option dhcpv6 'relay'
	option force '1'
	list dns 'fe80::cabf:4cff:fe87:ee68'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'
	option dhcpv6 'relay'
	option ra 'relay'
	option ndp 'relay'
	option master '1'

此处,我们配置了IPv6 DHCP Relay功能,直接从光猫获取IPv6地址,并指定LAN口IPv6地址作为IPv6 DNS通告,以确保局域网内的设备的DNS配置无论是IPv4还是IPv6地址都是OpenWRT路由器。

2. DNS分流透明代理

为了满足一些特殊需求,我们需要对特定域名进行代理,以确保局域网内的每个设备都能轻松无配置地享受代理服务。为此,我们在OpenWRT路由器上配置了透明代理。

为了实现只有特定域名走代理的目的,我们首先需要在DNS层面进行分流。下面是一个更为紧凑的DNS分流示意图:

Image1

  • Dnsmasq负责DNS分流,将命中代理域名列表的域名分流到SmartDNS,并将查询的IP放入ipset中。对于直连的域名,直接通过光猫进行DNS查询。
  • SmartDNS负责代理域名的DNS查询,通过TCP DNS查询走透明代理到远端的代理服务器上,查询代理服务器上最佳的IP地址。
  • ipt2socks是一个将透明代理转换为Socks5代理的小工具,通过这个工具可以降低路由器负载。真正的代理程序运行在局域网内的NAS上。

Dnsmasq分流配置示例:

server=/example.com/127.0.0.1#5335
ipset=/example.com/vpn

这样,命中分流列表的域名会被发送到SmartDNS,同时查询到的IP地址会被放入ipset vpn中。

SmartDNS配置示例:

bind :5335 -no-dualstack-selection -no-speed-check -force-aaaa-soa

server-tcp 8.8.8.8
server-tcp 1.1.1.1

SmartDNS将UDP DNS查询转换为TCP DNS查询,通过iptables路由到ipt2socks,最终在远端的代理服务器上查询。SmartDNS还强制执行SOA IPv6的DNS查询,以防止代理流量通过IPv6直接走到光猫而绕过路由器NAT。

TCP分流示意图:

Image2

当目标IP命中ipset vpn流量时,重定向到ipt2socks进行代理。直连的流量则直接通过系统出口。

iptables配置示例:

# 创建ipset
ipset create vpn hash:ip

iptables -t nat -N V2RAY # 新建一个名为 V2RAY 的链
iptables -t nat -A V2RAY -p tcp -m set --match-set vpn dst -j REDIRECT --to-ports 12345 # 命中ipset vpn的流量重定向到ipt2socks
iptables -t nat -A PREROUTING -p tcp -j V2RAY # 对局域网其他设备进行透明代理
iptables -t nat -A OUTPUT -p tcp -j V2RAY # 对本机进行透明代理

ipt2socks启动命令:

/usr/bin/ipt2socks -R -4 -j 2 -s 192.168.2.141 -p 1080 -l 12345

这一方案的具体实现通过OpenWRT的Passwall插件,使得配置变得非常便捷。尽管这个方案在日常使用中表现良好,但也存在3个主要问题:

  1. 分流的DNS需要通过远端代理查询,虽然我们利用DNS缓存来减轻影响,但仍可能影响首次响应速度。
  2. 对于一些走CDN的网站,是否将其IP加入ipset不太确定,这可能导致一些网站无法正常访问。
  3. ipset变大以后影响iptables匹配效率

3. Fake IP透明代理

最近我了解到一种称为Fake IP的代理方案,将其应用到我的现有解决方案中,成功解决了旧方案存在的三个问题。新方案更为简洁高效,无需依赖SmartDNS和Passwall插件,直接手动搭建即可。

DNS查询示意图:

Image3

在DNS查询中,Dnsmasq通过分流后,命中代理域名的查询会被引导至v2ray的Fake DNS上,该Fake DNS返回一个固定网段的Fake IP。不再需要设置ipset,方案更为简化。

TCP流量示意图:

Image4

在TCP流量方面,命中固定网段的iptables规则后,流量将被重定向至ipt2socks。ipt2socks将透明代理转换为Socks5代理,并将流量发送至v2ray。v2ray检测到目标IP为Fake IP后,填充成域名并发送至远端代理服务器,实现代理域名的解析。

v2ray配置参考:

{
  "log": {
    "loglevel": "warning"
  },
  "fakedns": {
    "ipPool": "198.18.0.0/15",
    "poolSize": 65535
  },
  "dns": {
    "servers": [
      "fakedns"
    ],
    "queryStrategy": "USE_IP4"
  },
  "inbounds": [
    {
      "port": 5335,
      "tag": "dns-in",
      "protocol": "dokodemo-door",
      "settings": {
        "address": "119.29.29.29",
        "port": 53,
        "network": "udp"
      }
    },
    {
      "port": 1080,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "fakedns"
        ],
        "metadataOnly": false
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      # 出口协议
    },
    {
      "protocol": "dns",
      "tag": "dns-out"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "dns-in"
        ],
        "outboundTag": "dns-out"
      }
    ],
    "strategy": "rules"
  }
}

iptables规则示例:

iptables -t nat -N V2RAY
iptables -t nat -A V2RAY -d 198.18.0.0/15 -p tcp -j REDIRECT --to-ports 12345
iptables -t nat -A PREROUTING -p tcp -j V2RAY
iptables -t nat -A OUTPUT -p tcp -j V2RAY

这一新方案通过Fake IP的代理机制成功解决了旧方案存在的问题,更加简洁高效。其中,v2ray的配置和iptables规则的设置使得整个方案在实践中更为可行和稳定。

4. 总结

通过实践与不断的尝试,我们成功实现了一套高效、简洁的透明代理方案,让家中网络更具灵活性和隐私保护。通过采用Fake IP透明代理,我们解决了旧方案中存在的DNS查询速度、CDN网站不确定性等问题。新方案无需依赖繁杂的插件,通过手动配置即可轻松搭建。

这一方案的精髓在于利用v2ray的Fake DNS功能,将特定域名的DNS查询引导至Fake IP,进而实现透明代理。同时,通过iptables的规则设置,我们成功将流量重定向至代理,实现了透明代理的高效运作。这不仅提高了网络使用体验,同时也加强了网络隐私和安全。

这篇文章详细介绍了家庭网络的拓扑结构、IPv4与IPv6的配置以及三个阶段的透明代理方案演进。通过本文的分享,希望读者在搭建自己的透明代理方案时能够有所借鉴,更好地定制适合自己需求的网络环境。网络技术的不断发展,也让我们对未来的网络体验充满期待。

在科技的道路上,我们将不断追求创新,不断完善,让科技更好地服务于我们的生活。希望这篇文章对您有所启发,为您的网络探索之路提供一些有益的参考。