Category Archives

15 Articles

使用lua-nginx-module缓存JSONP

0   664 转为繁体

最近给畅言加上了单点登录,也就是可以用网站的帐号来在畅言上发射评论。畅言会通过你设置的一个接口来获得用户名,头像等。但是我发现队友畅言会频繁请求这个接口,有时候会达到单个用户一秒钟好几次??

虽然在php层有redis,压力不会很大,但是这样频繁的请求还是会中防CC的策略,影响用户正常的浏览。所以我决定在CDN上做个缓存。

Read More

ipip.tk地理位置查询

2   1930 转为繁体

基于OpenResty ,MaxMind GeoIP数据库和从bgp.he.net生成的ASN数据库,因为没有经纬度的需求所以没有显示。下文有源代码的链接,如果需要可以自行修改加上经纬度或者将输出变为JSON等。

这里有chrome插件

使用方法

查询当前IP地理位置

$ curl https://ipip.tk/
x.x.x.x
Country, City
ASN number

查询当前IP

$ curl https://ipip.tk/ip
x.x.x.x

查询指定IP的地理位置

$ curl https://ipip.tk/74.125.203.199
74.125.203.199
United States, Mountain View
AS15169 Google Inc.

查询域名的地理位置

$ curl https://ipip.tk/www.google.com.hk
74.125.203.199
United States, Mountain View
AS15169 Google Inc.

查询域名的IP

$ curl https://ipip.tk/www.google.com.hk/ip
74.125.203.199

查询域名的IP和CNAME(如果存在)

$ curl https://ipip.tm/www.google.com.hk/dns
www-wide.l.google.com 74.125.203.199

源代码

在这里https://gist.github.com/fffonion/44e5fb59e2a8f0efba5c1965c6043584

需要ngx_http_geoip_module, echo-nginx-module, lua-nginx-module,安装libgeoip,并将maxmind的旧版geoip数据库放在/usr/share/GeoIP

通过bgp.he.net生成ASN数据库

Read More

用 OpenResty 写了一个 SNI 代理

0   2906 转为繁体

功能类似于dlundquist/sniproxy

推荐 OpenResty 加上 stream 模块和 ngx_stream_lua_module 模块。在 1.9.15.1 上测试通过。

示例配置:

A Lua table sni_rules should be defined in the init_worker_by_lua_block directive.

The key can be either whole host name or regular expression. Use . for a default host name. If no entry is matched, connection will be closed.

The value is a table containing host name and port. If host is set to nil, the server_name in SNI will be used. If the port is not defined or set to nil, 443 will be used.

Rules are applied with the priority as its occurrence sequence in the table. In the example above, twitter.com will match the third rule rather than the fourth.

If the protocol version is less than TLSv1 (eg. SSLv3, SSLv2), connection will be closed, since SNI extension is not supported in these versions.

Let’s Encrypt集中化管理

9   2196 转为繁体

Let’s Encrypt的证书签发原理实际上和传统的PKI一样,只不过自动化完成了生成CSR和私钥、提交CSR、取回证书的过程。

此外还要验证域名所属,这一部分和传统的签发机构是一样的,不过传统的签发机构还允许我们使用域名whois中填写的邮箱来验证,而Letsencrypt貌似只能通过http challenge的方式来验证。即和验证服务器约定一个uri和随机字符串,验证服务器请求这一uri,如果得到的内容和约定的随机字符串相同,则验证通过。如图所示:

letsencrypt_howitworks

官网上抄的)

这意味着我们得在每台部署https的前端的负载均衡服务器上都装一个letencrypt工具。有没有什么集中化管理的办法的呢?

实际上,由于challenge的uri的有规律,我们可以将前端服务器收到的这类请求代理到同一台专门用来签发、更新证书的服务器上。如图所示:

letsencrypt_howitworks_proxypass

  1. 当在服务器B上发起域名a.example.com新的签发请求后,Let’s Encrypt的签发服务器返回一个challange uri (8303)和response (ed98)。
  2. 服务器B使用webroot插件将这个uri和response写入本地磁盘上对应的文件。
  3. Let’s Encrypt的签发服务器为了验证example.com的所属,查询到example.com指向前端服务器A,于是发送一个HTTP请求/.well-known/acme-challenge/8303到服务器A
  4. 服务器A反代这一请求到服务器B
  5. B读取刚才第二步时写入到response,返回到A;A返回到Let’s Encrypt的签发服务器
  6. 验证成功,发证!

然后,我们只要从服务器A上取回存储在B上到证书就可以了。可以在B上做一个RESTful的api。注意要配置allow和deny。

A服务器(前端)的nginx配置如下:

B服务器的nginx配置如下:

然后在B上运行:

搭建一个不被审查的串流站点

17   36297 转为繁体

原标题:被害妄想症该如何生存

先看配置:

假设:

审查机关拥有运营商级别的入侵检测设备(比如GFW)

说明:

  1. 全站使用https,关闭SSLv3,关闭弱加密组件
  2. default_server开启80端口,使用自签名证书;真实需要访问的域名(example.com)必须使用有效的证书,或者在本地信任根证书。注意example.com不能开启80端口,且与default_server使用的证书不能相同。不要使用泛域名证书。这是为了防止审查机关通过直连IP查看返回的证书中的Common Name来得到真实域名。这样配置之后,直连IP https://xxx.xxx.xxx.xxx默认是返回自签名证书,无法得到真实example.com。
  3. 选择性开启autoindex,通过cookie鉴别。注意也可以通过HTTP Basic Authenication认证。对匹配文件夹的uri(”/”结尾)做认证,示例中只有带cookie coo=coo的请求才会返回autoindex,否则返回404。
  4. 在location /中禁用目录末尾自动加斜杠,因为如果自动加斜杠,审查机关可以通过暴力猜测出服务器上有哪些目录确实存在(返回了301到末尾加/的url)。方法是if (-d $request_filename)返回404。