在 OpenWRT 上搭建透明代理
透明代理是指在路由(网关)上部署代理设置,使路由下所有设备连接到外网时自动应用该代理配置。即该代理配置对路由下的设备是透明的。
需要解决的问题
一般访问大中华区之外的部分网站,会遇到的问题主要有以下三种:
- DNS 缓存投毒 ,针对 DNS 协议,伪装成 DNS 服务器,给查询者返回伪造的 DNS 响应包
- IP 封锁 ,即使在绕过第一道屏障得到真实 IP 之后,在黑名单内的网站 IP 也是被封锁的
- 敏感词过滤 ,对于没在名单内的外部网站,凡检测到 TCP 报文中带有相关的敏感内容, 即向请求端和返回端分别伪装对方发送重置信号。
针对 DNS 污染,可以采用 DNS over HTTP 或者 ss-tunnel 远程解析,对于 IP 封锁和敏感词过滤直接使用 ss-redir 将相关数据包转发到代理服务器上,经由 shadowsocks 代理访问。
准备工作
安装配置 shadowsocks
安装 shadowsocks-libev-spec , shadowsocks-libev 针对 OpenWRT 的特殊版本。安装完成后 /usr/bin/ 下会有 ss-redir 和 ss-tunnel 两个二进制可执行文件。
配置 shadowsocks,编写 shadowsocks 连接到远程服务端的配置文件。创建 /etc/shadowsocks.json , 格式如下:
{ "server": "<远程服务器主机>", "server_port": "<远程服务器端口>", "method": "<服务器采用的加密方式>", "timeout": 30, "local_port": 7777 }
为 shadowsocks 配置开机启动服务(init scripts),创建 /etc/init.d/shadowsocks ,内容如下:
#!/bin/sh /etc/rc.common START=95 SERVICE_USE_PID=1 SERVICE_WRITE_PID=1 SERVICE_DAEMONIZE=1 CONFIG=/etc/shadowsocks.json start() { service_start /usr/bin/ss-redir -c $CONFIG -b 0.0.0.0 service_start /usr/bin/ss-tunnel -c $CONFIG -b 0.0.0.0 -l 5353 -L 8.8.8.8:53 -u } stop() { service_stop /usr/bin/ss-redir service_start /usr/bin/ss-tunnel }
安装配置 GeoIP
安装 iptables-geoip 模块:
opkg update opkg install iptables-mod-geoip opkg install iptables-mod-nat-extra
启用模块: modprobe xt_geoip
生成 GeoIP 数据库
接下来的操作引用自 How to block network traffic by country on Linux ,需要在路由外的设备上进行。首先从 xtables-addons 的官方网站下载源码包,然后按照下面的指令 编译安装它:
wget http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.10.tar.xz tar xf xtables-addons-2.10.tar.xz cd xtables-addons-2.10 ./configure make sudo make install
xtables-addons 的源码包中带有两个帮助脚本,它们被用来从 MaxMind 下载 GeoIP 数据库并将它转化为 xt_geoip 可识别的二进制形式文件;它们可以在源码包中的 geoip 目录下找到。请遵循下面的指导来在你的系统中构建和安装 GeoIP 数据库。
cd geoip ./xt_geoip_dl ./xt_geoip_build GeoIPCountryWhois.csv # 将数据库文件上传至路由上的 /usr/share/xt_geoip 目录下 scp -r {BE,LE} openwrt:/usr/share/xt_geoip
启动 shadowsocks 服务
执行 chmod +x /etc/init.d/shadowsocks ,将权限改为可执行。然后启动服务: /etc/init.d/shadowsocks start ,检查一下是否启动成功: ps | grep ss-redir
配置 iptables 转发规则
编辑 /etc/firewall.user 添加以下内容:
# 在 nat 表中创建新链
iptables -t nat -N SHADOWSOCKS
# 跳过 shadowsocks 代理服务器
iptables -t nat -A SHADOWSOCKS -p tcp --dport <远程主机端口> -j RETURN
iptables -t nat -A SHADOWSOCKS -d <远程主机 IP> -j RETURN
# 跳过本地 IP 段
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN
# 过滤 geoip 匹配到国家代码为 CN 的数据
iptables -A prerouting_rule -t nat -m geoip -p tcp --dst-cc CN -j RETURN
# 将其余所有数据包转发到 ss-redir 监听的端口
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 7777
# 在 PREROUTING 链前插入 SHADOWSOCKS 链,使其生效
iptables -t nat -I PREROUTING -p tcp -j SHADOWSOCKS
执行 /etc/init.d/firewall restart 重启 iptables,以应用以上规则。
现在使用路由下的设备访问 google.com,即可验证是否成功。