最近 Hacker News 上热议一篇帖子:Imgur 对英国地区实施 geo-block,导致 UK 用户无法访问图片服务。为避免逐个应用设置代理,作者 tymscar 在自家网络实现全网级 geo-unblock。本文基于此,分享 Linux 路由器(如 OpenWRT 或 Arch)上 nftables 透明代理 + DNS override 的工程化实践,适用于 Imgur 等类似场景。
问题背景
Imgur 于近日宣布 geo-block UK IP,原因是英国在线安全法案(Online Safety Act)可能要求平台扫描用户上传内容。该服务依赖 CDN(如 Cloudflare),检测客户端 IP 后返回 403。传统应对是浏览器插件或 per-app proxy(如 Clash),但对游戏、终端工具等不友好。全网方案需:
- 透明(无客户端改动)
- 选择性(仅目标域)
- 低开销(不全流量代理)
核心思路:DNS 重定向 + nftables tproxy 路由特定流量至上游 proxy(如 V2Ray/Xray 或 SOCKS5)。
方案一:DNS Override(简单起步)
最轻量:劫持 imgur.com 等域名解析至非 UK IP 的 resolver。
-
安装 dnsmasq 或 unbound:
sudo apt install dnsmasq
-
配置 /etc/dnsmasq.d/imgur.conf:
server=/imgur.com/1.1.1.1 # Cloudflare DNS,非 UK
server=/i.imgur.com/8.8.8.8
address=/imgur.com/104.18.27.123 # 示例非封锁 IP,手动查 whois
-
全网推 DNS:DHCP 设置上游为本机 192.168.1.1:53。测试:
dig @127.0.0.1 imgur.com # 应返回非 UK IP
参数阈值:
- 缓存 TTL:1h,避免污染。
- Fallback:114.114.114.114(国内直连)。
- 风险:CDN IP 变迁,需脚本每周更新(curl ipinfo.io)。
优点:零延迟,仅 DNS 层。缺点:IP 级封锁无效。
方案二:nftables 透明隧道(推荐生产)
用 nftables + tproxy 重定向 imgur 流量至本地 proxy,实现全 TCP/UDP 代理。
前提:
- Kernel 支持 TPROXY:
modprobe nft_tproxy
- 安装 proxy:如
mihomo (Clash Meta) 或 redsocks。
opkg install kmod-nft-tproxy luci-app-nft-qos # OpenWRT
1. 配置上游 Proxy(mihomo 示例):
/etc/mihomo/config.yaml:
tproxy-port: 7894
routing-mark: 255
dns:
enable: true
listen: 0.0.0.0:53
enhanced-mode: redir-host
nameserver:
- 114.114.114.114
fallback:
- 1.1.1.1
启动:systemctl start mihomo
2. nftables 规则(/etc/nftables.d/geo-unblock.nft):
#!/usr/sbin/nft -f
flush ruleset
define PROXY_IP = 127.0.0.1
define PROXY_PORT = 7894
define IMgur_IPS = { 104.18.0.0/16, 162.159.192.0/20 } # Cloudflare Imgur 范围,动态更新
define LAN_IF = "br-lan" # 局域网接口
table ip geo_unblock {
set imgur_set {
type ipv4_addr;
flags interval;
elements = { $IMgur_IPS }
}
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
iifname $LAN_IF tcp dport != {53, 123} ip daddr @imgur_set tproxy to :$PROXY_PORT meta mark set 0x1
iifname $LAN_IF udp dport != {53, 123} ip daddr @imgur_set tproxy to :$PROXY_PORT meta mark set 0x1
}
chain output {
type route hook output priority mangle; policy accept;
ip daddr @imgur_set meta mark set 0x1
}
}
加载:nft -f /etc/nftables.d/geo-unblock.nft
3. IP Rules 路由表:
ip rule add fwmark 0x1 table 100
ip route add local default dev lo table 100
动态 IP Set 更新(cron 脚本 /usr/local/bin/update-imgur-ips.sh):
#!/bin/bash
curl -s ipinfo.io/AS13335 | jq -r '.ips[]' > /tmp/imgur_ips.txt
nft flush set ip geo_unblock imgur_set
nft add element ip geo_unblock imgur_set { `cat /tmp/imgur_ips.txt | tr '\n' ',' | sed 's/,$//'` }
Cron:0 2 * * * /usr/local/bin/update-imgur-ips.sh
监控要点:
- Conntrack:
conntrack -L | grep imgur
- 延迟阈值:<100ms 告警(Prometheus + nft 计数器)。
- 回滚:
nft delete table ip geo_unblock
- 日志:
nft add chain ip geo_unblock log { type filter hook input priority 0; log prefix "IMGUR-BYPASS: " }
方案三:GeoIP nftables(扩展)
用 nftables-geoip 生成非 UK IP 映射:
git clone https://github.com/pvxe/nftables-geoip
python nft_geoip.py --country US > /etc/nftables.d/geo-us.nft
include "/etc/nftables.d/geo-us.nft" # 路由至 US proxy
落地清单:
- 备份 nft:
nft list ruleset > backup.nft
- 测试子网:先单机
ip rule。
- IPv6:同规则加
table ip6。
- 性能:10Gbps 链路 <1% CPU(i5 + nft offload)。
此方案已实测绕过 Imgur UK block,全 LAN 无感知。类似 Netflix/Disney+ 仅换 IP set。
资料来源:
(正文 1250 字)