2013-09-22

GoAgent证书问题一例

昨天准备在老婆的电脑上用一下GoAgent,结果发现很多网站都不能用。很奇怪的是,Twitter页面能打开,但CSS/JS看起来基本上都不对。而在我自己的电脑(LAN内部)上却是好的。所以很明显是Local而不是Network的问题。
看GoAgent控制台上的日志,问题似乎跟SSL的连接建立有关系。再把Chrome的“审查元素”功能打开,Console里面一堆错误。随便挑了个页面试图打开,好了,这下清楚了,证书有问题。
看了看GoAgent的官方Q&A,基本上只提到说证书需要导入。很多在网上问这类问题的人,得到的也是类似回答。但问题在于,证书的导入是没有问题的,重新导入也没有效果。而且并不是所有网站都不能通过GoAgent代理。

其实问题很简单:GoAgent仿冒的证书被占用啦。
官方其实也提到过这个事情:
因为GAE平台限制,没法支持真正的ssl加密,goagent只能通过伪造证书的方式做到代理ssl加密的网站,这个证书就是用来欺骗浏览器的。
GoAgent实际上相当于一个“中间人”。当访问HTTPS站点时,就得采用SSL中间人攻击的类似方式,才能完成代理的工作。SSL中间人攻击怎么弄?导入受信任的根证书,然后利用这个根证书签发的证书把内容拆开后重新组装、加密、封包,骗完甲方骗乙方,欺骗通讯双方。否则两端任何一方觉得这内容不对劲,SSL传输就会失败。这其实也就是为什么必须要干掉CNNIC相关的根证书的原因

所以,对于每一个HTTPS站点,GoAgent都会生成一份用自己根证书签发的数字证书。看看GoAgent的local目录下,如果访问过HTTPS站点,则一定会有一个certs目录。这生成的证书,就放在这个certs目录下。其实一看这个目录里面都有些什么文件,就很明白了:
这次的问题在于,GoAgent有不同的版本,其携带的根证书也是变化过的。至少我机器上随便打开CertMgr就见到了五个不同的版本:
如果升级的时候不把certs目录清空,就有可能会有部分站点对应的证书还是以前的老的、用旧的根证书签发出来的。GoAgent客户端一看,噢,证书已经有了,就不再重新生成了。但Chrome觉得证书不对,于是SSL握手就被挡了。

解决办法很简单,每次升级GoAgent的时候,把local/certs目录删掉。或者干脆每次用新目录来升级好了。

2013-09-21

自己给iOS7升级下载加速

通知出来了好几天了,今天准备给老婆的手机升iOS7。于是先把iTunes升到11.1(下载速度还不错),然后连上手机。一检查,嗬,1.19G,告诉我下载要18个小时。
按照惯例,打开IE设上代理,准备用GoAgent加速。现在估计用时只要不到一个小时,完全可以接受。
但是担心的事情来了,免费GAE的每个AppID有1G/天的流量限制,而我的GoAgent没能及时切换到下一个可用的AppID,结果iTunes这边报了个错,然后下载又重新开始了。没想到这iOS升级包的下载居然不支持断点续传。我又试了下,哪怕是手动点“暂停”,也没法进行续传,每次下载都会重头开始。看来这乔布斯死了之后,苹果真是要没落了。

接下来的时间,我考虑了以下解决方案:
1. 开VPN:可手头上的VPN速度都跟直接下载差不多。何况有些VPN还有流量限制。不肯花钱的后果就出来了。
2. 找代理:手头上没现成的。不管是去搜Google还是开ProxyHunter都得花时间。懒得去找了。
3. SSH Tunnel:目前手头上访问起来快一点的只有台H3C的交换机,大概是深圳的地址。不过SSH没开,要想架隧道还得要我去帮它开。由于担心被抓去集中营活摘器官,并且从这台交换机到appldnld.apple.com的ping值并不好,所以最后还是放弃了。

最终,还是自己找了组appldnld.apple.com比较快的地址,解决了这个问题。100ms左右的ping值,偶尔丢包。放在hosts里用上去之后,显示的估计用时也是不到一小时,跟开GoAgent加速的效果相当。那就先这样用吧。话说这苹果的DNS设置咋自己就解析不到这组地址上去呢?是我RP问题?

2013-09-10

写了个批量测试服务器Ping值的小工具

不时有人问我要hosts,但是很多时候也不敢贸然的给。担心泄漏是一方面。另外一方面,我这边可以用的hosts,在别人那边可能用不了。我这边用起来很快的hosts,在人家那边可能像乌龟爬。叫别人ping一下当然不是什么太麻烦的事情,但如果连试好几个IP都不行,有时候也是很头大的事。效率也很低下。

因此想,要是有个能批量Ping,并且能很容易看到输出结果的工具,就好了。用批处理做个批量Ping是很容易的,但结果并不是特别一目了然。于是干脆自己动手做了一个。
启动时会加载当前目录下的server.list文件,文件中每行写一个地址(这几个地址有些人可能一看就知道是什么东西了)就可以了。写域名也是可以的,但我这里输出结果中并不包含域名解析的结果。
目前只打算简单做成这样,反正只当小工具用用。如果觉得网络不顺的时候,就启动起来跑一跑看看。然后也可以把一堆IP丢给别人自己校验去。

有需求的朋友可以去拿来用下。工具的下载地址:Dropbox镜像 Mega下载页面
为了减少CRT依赖性,上面的发布版本是静态链接的。如果想用动态链接版本,或者担心木马、病毒什么的,就下载下面的源代码自己编译吧。VC6就可以。反正自己也没写多少代码,许可证什么的就懒得去弄了。
源代码下载地址:Dropbox镜像 Mega下载页面

2013-09-09

斯诺登关于NSA解密能力爆料的解读

斯诺登最近大概向媒体爆了些料,有不少人被吓着了。比如这篇文章一开头就这样写道:
美英三家媒体联合报道称,美国情报机构通过向企业产品注入漏洞等手段,破解HTTPS、SSL、VPN等全球互联网主要加密技术,实施监听;美国国家情报总监克拉珀回应称此事“不是新闻”
看起来很吓人对吧?HTTPS、SSL、VPN,这些几乎是我们日常用得最多的翻墙技术手段。如果NSA能搞定,那么墙国要山寨过来也就只是时间问题。很多看到的人就是这样推理的。
那么,到底是不是真的有那么吓人呢?

个人觉得,财新网这篇文章的摘要,写得相当的不严谨。不过国内的媒体一贯习惯博人眼球,这样写也很正常。其实如果能认真读完全文,大概不至于被吓得不敢上网。相比之下,《纽约时报》的一篇报道就要更为准确一些:
最新披露的文件显示,美国国家安全局(National Security Agency,简称NSA)在长期的加密技术秘密战争中占了上风,它利用超级计算机、技术花招、法院指令和幕后劝说,对互联网时代保护日常通讯隐私的主要工具造成了损害。
这段话里面,明确提到了这么几个手段,我觉得基本上可以比较准确地概括全文的内容:

  • 超级计算机:也就是硬来,霸王硬上弓,利用超级计算机+分布式计算的强大计算能力,暴力破解猜密码。这个没啥好怕的。你要是能让政府动用举国之力来对付你,你大概也不会因为这些事情而害怕了,多少会是个英雄/领袖什么的吧?换句话说,要是在中国,找几个人把你关起来拷问,大概成本会低很多,估计也更合领导的意。不小心弄死了参照李旺阳处理就行。
  • 技术花招:也就是第一篇文章所提到的,利用(甚至主动引入)产品、协议、服务的漏洞,或者植入软件/硬件木马,试图在加密前或解密后获取到信息。既然是叫做“花招”,那么就是一些旁门左道的东西,有用是有用,但并不是说整个Internet的安全体系就此崩塌了,防漏堵缺就可以了。
  • 法院指令:要求企业交出密钥或解密后的明文,或者获得访问权限。在美国这算事儿,在天朝大伙儿应该都习惯了吧?没什么好害怕的。
  • 幕后劝说:相对于“法院指令”,其实也就是红脸和白脸的区别而已。我觉得在天朝根本不需要什么“幕后”劝说。所以也一样,没什么好怕的。

所以,看吧。NSA也不是说真的拥有了什么颠覆性的力量。现有的Internet安全体系还在,强如NSA也只能绕着边儿想办法。谍报机关嘛,真逼急了啥办法不会想?真没必要自个儿吓自个儿。

2013-09-06

一例C000001D错误的分析

公司客服收到用户反映,说我们的软件使用到某个功能的时候,报了一个错误。错误信息只有“External exception C000001D”这么一段文字。

搜一下C000001D,很容易就能知道对应的含义是STATUS_ILLEGAL_INSTRUCTION,也就是说程序使用了当前CPU所不支持的指令集。我们自己的程序并没有使用太新的指令集,但有一些第三方的接口库可就未必了。由于功能基本上是计算密集型的,所以这些第三方的库如果没注意编译开关,完全有可能造成这种情况。

让客服电话采集了一下用户的硬件信息,果不出所料:AMD Athlon XP 3000+。根据维基百科的资料显示,2003年面市,这是一款可以称得上老旧的CPU。支持的指令集:MMX、SSE、3DNow,并不算多,关键是没有SSE2

为什么会怀疑到SSE2上面呢?因为前不久刚看了一篇博文,说Win8需要CPU支持SSE2才能安装。这说明SSE2所能提供的,已经几乎是现在开发的新软件所必需的基本能力了。另外很多编译器已经默认把SSE2优化给打开了。也难怪——这年头,还有谁在用Pentium III吗?

总之,合理怀疑之后,先来看看是不是这么一回事。这种事情如果要通过正常途径去沟通,不见得效果好。说不定那个当初负责编译出这个库的程序员早换工作了。就算人还在,编译选项和指令集之间的关系搞不清的程序员大有人在。问还不如自己动手看。以下是用dumpbin对其中一个第三方DLL库反汇编出来的某个函数的部分代码:
1001314E: 66 0F 6F 06        movdqa      xmm0,xmmword ptr [esi]
10013152: 66 0F 6F 4E 10     movdqa      xmm1,xmmword ptr [esi+10h]
10013157: 66 0F 6F 56 20     movdqa      xmm2,xmmword ptr [esi+20h]
1001315C: 66 0F 6F 5E 30     movdqa      xmm3,xmmword ptr [esi+30h]
10013161: 66 0F 7F 07        movdqa      xmmword ptr [edi],xmm0
10013165: 66 0F 7F 4F 10     movdqa      xmmword ptr [edi+10h],xmm1
1001316A: 66 0F 7F 57 20     movdqa      xmmword ptr [edi+20h],xmm2
1001316F: 66 0F 7F 5F 30     movdqa      xmmword ptr [edi+30h],xmm3
10013174: 66 0F 6F 66 40     movdqa      xmm4,xmmword ptr [esi+40h]
10013179: 66 0F 6F 6E 50     movdqa      xmm5,xmmword ptr [esi+50h]
1001317E: 66 0F 6F 76 60     movdqa      xmm6,xmmword ptr [esi+60h]
10013183: 66 0F 6F 7E 70     movdqa      xmm7,xmmword ptr [esi+70h]
10013188: 66 0F 7F 67 40     movdqa      xmmword ptr [edi+40h],xmm4
1001318D: 66 0F 7F 6F 50     movdqa      xmmword ptr [edi+50h],xmm5
10013192: 66 0F 7F 77 60     movdqa      xmmword ptr [edi+60h],xmm6
10013197: 66 0F 7F 7F 70     movdqa      xmmword ptr [edi+70h],xmm7
1001319C: 8D B6 80 00 00 00  lea         esi,[esi+00000080h]
100131A2: 8D BF 80 00 00 00  lea         edi,[edi+00000080h]
100131A8: 49                 dec         ecx
100131A9: 75 A3              jne         1001314E
SSE2的指令集可以参见这里。其实看到movdqa就已经很明白了。这个DLL库的确用了SSE2,那么,报错就是很正常的事情。

在分析这个问题的时候,我花了一点时间,希望能找到一个能够列出程序所使用的指令集的静态分析工具,但没有找到答案。当然,就这次的情况而言,我能通过XMM寄存器很容易地找到并筛选出SSE2的指令。但要是能有一个自动化工具,就更好了。也许还是有这种工具的,只是我目前还不知道吧。如果有谁知道,还望不吝告知。

2013-09-05

GAE升级Python27折腾手记

Google把GAE的Python运行环境从2.5升级到2.7,已经有好一些日子了。因为只扔了自己的两个小小的应用在上面,所以一直没去处理。最近总算有些时间,于是把这个折腾完了,还很花了一些工夫,特记录一下。

去看了GAE的在线文档。中文的文档是只有2.5的部分,繁体中文也只是对2.7给出了一个链接而已。技术方面的东西还是直接参考英文资料来得好。

具体的做法,官方文档上写得很清楚,就不在这里说了。但是我的升级过程并不是很顺利。最后总结一下有这么几个问题,供大家参考:
  • 按照文档,app.yaml里面的handle script要从.py改成.app,但千万别手贱去把.py文件真的改名成.app。其实只是app.yaml里面要改而已,文件还得是.py为后缀名。
  • app.yaml中还要引入webapp2这个library,这个在官方文档中没有明确地指出。具体写法是:
libraries:
- name: webapp2
  version: "2.5.1"
其实version可以写latest,但要承担最新库无法向下兼容的风险。
  • 要更新就索性别留旧版(Python 2.5)的程序在GAE上,否则页面顶部的警告一直会有。
其余过程还算顺利,至少升级到2.7算是成功了。