基于SNIProxy的路由端网络流量定制分发方案

标题感觉很高大上,其实写得乱七八糟。

前序文章:
SNIProxy Bind Outgoing Interface
Build SNIProxy Debian Package for EdgeRouter
Ubnt EdgeRouter Lite 和 EdgeRouter X 上安装使用SNIProxy

不急,上边三篇可能会在本文内提及。

首先,sniproxy不解释了,但是如标题所属,sniproxy的版本不支持我要的功能,所以我就fork然后改了。
具体思路参考上述第一个链接。

接下来,直接进入正题。

按之前的玩法,我使用路由表来控制流量。这是一个很典型,也很正确的做法;但是也是一个很不好用的玩法。
参考文章:Set up OpenVPN Site-to-Site on UBNT EdgeRouter Lite, EdgeOS PPTP VPN客户端配置
PS:我维护了一份自己的路由表,地址在 https://ip.rst.im/blocks/sskaje

为了让定制化程度高一些,我配了一个Socks代理,实际上是在vpn对端配置的,本地路由做了个DNAT,转发过去了。这样我就可以用firefox+foxyproxy实现本地定制化规则。
参考文章:UBNT VPN + Socks5 代理Set up dante-server on Ubuntu

后来考虑到上述用起来麻烦,又趁着回老家的时候,在家里的ac68u merlin上实践了下WPAD,不过没有在自己家里的edgerouter上搞。
参考文章:Setup WPAD on Asus Merlin

此外,还试了一下基于源IP的firewall modify。印象中没单写blog,但是提过和用路由表的方案的优劣。
基本思路是:定义一个源地址的firewall network group;配置protocol static table;在LAN口的防火墙规则里增加modify,根据源地址组强行修改路由表。

从实际经验看,路由表不是最佳选择。
好处不必提,稳定,稳定,稳定。
坏处是,启动、更新慢慢慢。

而且现阶段,大量网站都用了诸如 cloudflare, amazon cloudfront,akamai,fastly之类的CDN服务,单纯按网段切路由,很不现实也很不灵活。
所以趁着需求,改造了一下sniproxy。
用的时间不长,所以暂时没法评估稳定性。

首先,软件部署在路由上。edgerouter lite 和 edgerouter x的包都打好了,1.9.0的固件可以直接装,下载地址在前边三个链接里有。

为了达到我要的目的,条件如下:
1 需要有本地DNS服务器(我的路由上有dnsmasq);
2 需要有稳定的VPN设备(我的是openvpn site2site,设备名vtun0)。
我的路由LAN IP是 192.168.32.1/24,设备eth0。

首先,为当前路由添加一个新的IP(我的是192.168.32.2/24),与默认IP同网段。
这里,命令行操作的时候务必别写错了设备名。其他没什么要注意的。
大致命令如下:

其次,配置好dnsmasq,将需要劫持的域名解析到 192.168.32.2。解析的配置参考下列例子

实际的经验是,不要用 set service dns forwarding options 来设置dnsmasq,自己维护一个配置文件,放在 /config/ 下,link/etc/dnsmasq.d

第三步,安装配置我的版本的sniproxy,假定监听端口分别问 192.168.32.2:3080 和 192.168.32.2:3443,分别用于接收 80端口和443端口的请求。
安装步骤参考最前边的链接。
配置文件参考

最后,配置DNAT,将192.168.32.2:80和192.168.32.2:443分别转到3080和3443,防止80和443的请求到达路由的lighttpd。

基于SNIProxy的路由端网络流量定制分发方案 by @sskaje: https://sskaje.me/2016/11/%e5%9f%ba%e4%ba%8esniproxy%e7%9a%84%e8%b7%af%e7%94%b1%e7%ab%af%e7%bd%91%e7%bb%9c%e6%b5%81%e9%87%8f%e5%ae%9a%e5%88%b6%e5%88%86%e5%8f%91%e6%96%b9%e6%a1%88/

PHP Man-in-The-Middle TCP Proxy

After learning modern PHP in past few days, I decide GIVING UP this language now. :(

I wrote an MiTM proxy in PHP for TCP connection forwarding and hijacking, code can be found on github.

This project is based on ReactPHP.

It can be also installed from composer / packagist.org.

I’ve coded some examples in that project, you can try those out and write your own. Including: forward DNS TCP query, forward HTTP query, modify HTTP request.

If you have a linux router/box, you can add some iptables rules forwarding requests to your running instance.

Have fun!

PHP Man-in-The-Middle TCP Proxy by @sskaje: https://sskaje.me/2016/10/php-man-in-the-middle-tcp-proxy/

Incoming search terms:

静态资源代理服务

之前为了让blog能被大陆地区正常访问(主要是G家css和字体),在ngnix上配了一些替换规则

之前blog强制走https,也加了一些乱七八糟的nginx规则。
现在单独拿出一个域名干这事情,p.rst.im,这样一来,可能有些资源可以被直接被第三方引用:

例如 jquery 的google cdn:https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js
可以使用 https://p.rst.im/p/ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js

也可以用 //p.rst.im

目前启用的规则包括下列域名及子域名:

  • google.com
  • googleapis.com
  • googleusercontent.com
  • gstatic.com
  • jquery.com
  • bootstrapcdn.com

替换做得比较简单粗暴,所以可能有部分js无法正常访问。
有问题欢迎反馈,有需要添加域名的也请提出来。

这里只尽量保证静态资源能正常被使用,想拿这个当web proxy的还是歇了吧。

如果你的blog使用nginx/tengine并且启用了 ngx_http_substitutions_filter_module,可以参考如下配置:

静态资源代理服务 by @sskaje: https://sskaje.me/2016/08/web-static-resource-proxy/

Querying IP Blocks from Radb.net

Whois is an old tool but an awesome tool querying ip blocks.

There are many providers maintaining their route list, called Internet Routing Registry, IRR, in their databases, such as RADB, LEVEL3. A full list of Internet Routing Registries can be found: http://www.irr.net/docs/list.html

As facebook says, you can use

finding out which ips are used by facebook crawlers.

You can also try ‘-i origin AS32934’ on www.radb.net.

Try ‘-K -i origin AS15169′(one of Google’s), you’ll find:
1 Route list can be simplified
2 There are too many duplicated entries.

What’s more, there is an upper level above these ASnnnnnns, e.g. AS-GOOGLE.
Try ‘-K -T as-set AS-GOOGLE’ on radb.net, you’ll find all google’s ASnnnnnns.

AS-YAHOO is a good example.

I wrote a project querying IP ranges on radb.net, you can find project here: https://github.com/sskaje/radb

Usage:

Examples:

A list of known sets:

You can also get a collection of ip ranges if you need to set up your router: http://ip.rst.im/blocks/.

Querying IP Blocks from Radb.net by @sskaje: https://sskaje.me/2016/07/querying-ip-blocks-radb-net/

自建 6in4 Tunnel Server (iproute2)

IPv4下连IPv6有无数种解决方案,传统的6to4, 6in4, TEREDO…没兴趣讲优缺点,可以在wikipedia的页面上看看各家都用了啥。

TunnelBroker.net 应该是没IPv6的地方最流行的上IPv6的解决方案了。
如果你觉得它不爽,其实自己搞一个也没那么难。

上边wikipedia页面里说HE的技术实现是Unknown。其实自己试过一次大概都能知道应该往哪个方向去研究它的技术实现了。

贴一个我路由器上的IPv6 Tunnel信息。

首先,UBNT给我创建的interface是tun0;其次 Link encapsulation 是 IPv6-in-IPv4,也就是传说中的 6in4;再往下看,POINTOPOINT
再加上TunnelBroker的Example Configurations里给了一个iproute2的配置方法:

思路很简单了。

假设服务器端为S,用户路由为R,则两边的参数逻辑应该是:
S:

Remote: R.ipv4
Local: S.ipv4
V6 IP: S.ipv6
Route: v6子网/CIDR

R:

Remote: S.ipv4
Local: R.ipv4
V6 IP: R.ipv6
Route: ::/0 即默认路由

具体来说,假设你S的IP为1.1.1.1,可支配的IPv6 pool为 2400:1234:5678:9abc::/64,R的IP为2.2.2.2,上述的配置可能是:

S.ipv4 = 1.1.1.1
S.ipv6 = 2400:1234:5678:9abc:1000::1/80

v6子网/CIDR = 2400:1234:5678:9abc:2000::/80

R.ipv4 = 2.2.2.2
R.ipv6 = 2400:1234:5678:9abc:1000::2/80

命令还不会的,可以阅读Setup of point-to-point tunnel

接下来还有一个问题,我的公网不是固定IP怎么办?
简单。
对于S端来说,Remote依旧是R.ipv4,必须是确定的IP。
对于R端来说,Local可以是0.0.0.0。
每次R更换IP后,需要通知S来更新Remote。

再搞不定?
没问题,看我的github项目:https://github.com/sskaje/6in4

另外,Linode 可以申请IPv6的池子,可以是 /56 或者 /64,可以自建tunnel玩。

自建 6in4 Tunnel Server (iproute2) by @sskaje: https://sskaje.me/2016/01/create-your-own-tunnelbroker-net-iproute2/

Incoming search terms: