如何在路由器中实现透明代理?
目前整个互联网环境,被破坏最严重地部分,是 Web 服务体验。当直接破坏难以实现时,就会从流程链的上下游着手,如:DNS 污染。
其它地互联网服务类型,例如:邮件,可能小部分会受到 Web 服务上下游破坏地余震,但整体上基本不受影响。
Web 服务的提供方式有三种:
HTTP 方式数据公开,因此最容易被破坏。
HTTPS 方式数据全程加密,中间人攻击很难达成,因此 DNS 污染 和 IP 封锁 较多。
SPDY 方式目前可能因为关注不多,所以无破坏。
透明转发操作可以直接交由 iptables 完成,REDIRECT
操作是其内核自带地。
代理服务选择 shadowsocks-libev ,当前的 v1.4 版本已经实现了对 iptables REDIRECT
支持。
DNS 服务选择 dnsmasq 完成。
转发调度操作选择 iptables geoip 模块,使访问国内 Web 服务时直连,绕过代理。
代理调度服务选择 privoxy ,但其作为前置透明代理时,一样有着不支持 HTTPS 地通病。
DNS 可靠性验证选择 iptables u32 模块,初步防御。
该列表太大了!诸多条目可能是我今生都不会访问地…何必非要强迫路由吃下?
花五分钟大概了解一下各种配置格式,然后针对性地配置即可。
本节与下一节中,所有待自行设定地项,统一写作 <NAME>
格式。请注意调整。
使用 /usr/bin/ss-local
作为 socks5 代理服务器程序,远端端口勿必使用 1080 、 3128 、 8080 这种代理服务典型端口。
其余各种不提。
主配置 /etc/privoxy/config
中增加一条 actionsfile freedom.action
指令,文件名随意。
写入以下内容到上述指令对应地文件中:
{+forward-override{forward-socks5 127.0.0.1:<SS-LOCAL-PORT> .} \
}
注意:<SS-LOCAL-PORT> 是 /usr/bin/ss-local
本地端口。**
准备 geoip 数据库后,在终端执行:
iptables -t nat -N freedom
iptables -t nat -A freedom -d <SS-LOCAL-SERVER> -j RETURN
iptables -t nat -A freedom -d <NAT-NET> -j RETURN
iptables -t nat -A freedom -d 127/8 -j RETURN
iptables -t nat -A freedom -m geoip --dst-cc CN -j RETURN
iptables -t nat -A freedom -p tcp --dport 80 -j REDIRECT --to-ports <PRIVOXY-PORT>
iptables -t nat -I PREROUTING -p tcp -m multiport --dports 80,443 -j freedom
iptables -t mangle -N freedom
iptables -t mangle -A freedom -m u32 --u32 "0x0&0xf000000=0x5000000&&0x16&0xffff@0x10=0xd8ddbcb6,0xd8eab30d,0xf3b9bb27,0x4a7d7f66,0x4a7d9b66,0x4a7d2771,0x4a7d2766,0xd155e58a" -j DROP
iptables -t mangle -A freedom -m u32 --u32 "0x0&0xf000000=0x5000000&&0x16&0xffff@0x10=0xcab50755,0xcb620741,0xcba1e6ab,0xcf0c5862,0xd0381f2b,0xd1244921,0xd1913632,0xd1dc1eae,0xd35e4293,0xd5a9fb23" -j DROP
iptables -t mangle -A freedom -m u32 --u32 "0x0&0xf000000=0x5000000&&0x16&0xffff@0x10=0x422dfced,0x480ecd63,0x480ecd68,0x4e10310f,0x5d2e0859,0x80797e8b,0x9f6a794b,0xa9840d67,0xc043c606,0xca6a0102" -j DROP
iptables -t mangle -A freedom -m u32 --u32 "0x0&0xf000000=0x5000000&&0x16&0xffff@0x10=0x42442b2,0x807c62d,0x253d369e,0x2e52ae44,0x3b1803ad,0x402158a1,0x4021632f,0x4042a3fb,0x4168cafc,0x41a0db71" -j DROP
iptables -t mangle -A PREROUTING -p udp --sport 53 -j freedom
注意:<SS-LOCAL-SERVER> 是远端 shadowsocks 服务器 IP。**
注意:<NAT-NET> 是本地局域网网段,如:192.168.1/24
。**
注意:<PRIVOXY-PORT> 是 privoxy 端口。**
使用 /usr/bin/ss-redir
作为 iptables REDIRECT
代理服务器程序。
在终端执行:
iptables -t nat -N freedom-https
iptables -t nat -A freedom-https -j ACCEPT
iptables -t nat -A freedom -j freedom-https
iptables -t nat -A freedom -p tcp -j REDIRECT --to-ports <SS-REDIR-PORT>
注意:<SS-REDIR-PORT> 是 /usr/bin/ss-redir
本地端口。**
以 Youtube 为例,其同时提供了 HTTP 和 HTTPS 两种方式地服务。页面可以基于 HTTP 方式打开,但视频就只能基于 HTTPS 方式。
在 /etc/privoxy/freedom.action
配置文件尾部追加一行:
.youtube.com
重启 privoxy。
如果依旧无法访问,则在 /etc/dnsmasq.conf
配置文件尾部追加一行:
server=/youtube.com/218.102.23.228
重启 dnsmasq。
注意:218.102.23.228
是香港网上行电信服务商提供地 DNS 服务器地址,您也可以更换成自己更习惯地真实 DNS 。
查询域名对应地 IP 地址后,在终端执行:
iptables -t nat -I freedom-https -d <SERVICE-IP> -j RETURN
注意:<SERVICE-IP> 是相应服务的 IP 地址或网段。**
选择使用 iptables 、 dnsmasq 、 privoxy 和 shadowsocks-libev 最主要地原因,是绝大多数 Linux 发行版都可以通过包管理快速安装,其中也包括了 OpenWRT。
但实际使用时,会发现在访问国外服务时,总是有点慢…一来是因为国外服务的 DNS TTL 都设得很低,二来是因为无论有没有需要,其实都是通过 privoxy 了地。
怎么破?
如果是拿单独一台机器作网关来扮演路由地角色,那么利用好大内存,可以:
dnsmasq + pdnsd
使用 pdnsd 地本地 DNS 缓存机制,可以强制改变 DNS 记录的 TTL ,进一步减少 DNS 重询次数。
保留 dnsmasq ,则是因为还得靠它来提供 DHCP 服务。
privoxy -> squid
使用 squid 地页面缓存机制,同样是强制改变页面缓存的时间,降低对真实服务地访问频次。
目前基于路由器的自制内嵌系统,活得还算可以地,貌似也就 OpenWRT 一家了。所以暂时就只关注这个。
路由器的内存如何合理利用?几乎是一个永恒地难题。基础就那么一丁点,怎么都难以玩出花来。所以:
dnsmasq + pdnsd
仍然需要使用 pdnsd ,主要原因是针对被修复地国外服务,对其 DNS 地查询也是在境外完成地,速度慢再所难免。而搭上 dnsmasq 这么一太实诚的队友,就有点不好地感觉了。
privoxy ->
放弃费力不讨好的 privoxy 吧!跑一个小时, privoxy 能吃到 40M+ 内存,让人怎么活?
警告:此项操作会直接导致一些公共服务平台无法访问,诸如 .blogspot.com
、 .wordpress.com
等等。这是一个艰难地抉择!
/usr/bin/ss-local
->
舍弃与 privoxy 配合地 shadowsocks socks5 服务,直接将需要地请求全部转给 /usr/bin/ss-redir
处理。
这时, iptables nat 表 freedom 链就得动一下小手术了(参见 2.3 和 3.2 小节)。调整之后地命令如下:
iptables -t nat -N freedom
iptables -t nat -A freedom -d <SS-LOCAL-SERVER> -j RETURN
iptables -t nat -A freedom -d <NAT-NET> -j RETURN
iptables -t nat -A freedom -d 127/8 -j RETURN
iptables -t nat -A freedom -m geoip --dst-cc CN -j RETURN
iptables -t nat -A freedom -j freedom-https
iptables -t nat -A freedom -p tcp -j REDIRECT --to-ports <SS-REDIR-PORT>
对所有非 shadowsocks 服务器、非局域网、非本机、非国内的地址,统统进行检查。只要不是在标记列表内,直连。