解决 GAppProxy Set-Cookie 和 HTTPS Cert Bugs

研究 GAppProxy 有两个原因:一、最近 Twitter 不能用,而我常用的 GAppProxy 却不支持我登录 Twitter;二、我最近在琢磨 SSL 证书的问题,正好用 GAppProxy 登录 Twitter 也有证书错误。

第一个 BUG:Set-Cookie Bug

GAPPProxy 目前对 Cookie 的处理有一些问题,主要出在对 header 中的多个 Set-Cookie 域处理错误,就会导致用户登录一些网站错误,无法获得正确的会话 Cookie。

举例,当服务器返回的 header 中有多个 Set-Cookie 域时,比如一般的 wordpress 返回的 header 中,Set-Cookie 域至少有三个:

Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-content/plugins; httponly
Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-admin; httponly
Set-Cookie:
wordpress_logged_in_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C545dcea44d5e69aec5c1203c64bee061;
path=/; httponly

GAPPProxy 会把它作为一个串传给本地浏览器:

Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-content/plugins; httponly,
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-admin; httponly,
wordpress_logged_in_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C545dcea44d5e69aec5c1203c64bee061;
path=/; httponly

这样本地浏览器对 Cookie 的设置就会错误。解决办法很简单,将这个长串用
split(', ')切开,同样设置三个 Set-Cookie 域即可。

Patch:

Index: proxy.py
===================================================================
--- proxy.py    (revision 92)
+++ proxy.py    (working copy)
@@ -237,6 +237,11 @@
             (name, _, value) = line.partition(':')
             name = name.strip()
             value = value.strip()
+            if name == 'Set-Cookie':
+              value_list = value.split(', ')
+              for value in value_list:
+                self.send_header(name, value)
+              continue
             self.send_header(name, value)
             # check Content-Type
             if name.lower() == 'content-type':

第二个 BUG:HTTPS Cert Bug

简单地来说,GAppProxy HTTPS 连接的实现是一个欺骗本地浏览器的过程,类似于中间人攻击。它首先用 GAE 获得页面的明文,抓到本地,然后假冒 HTTPS 站点与本地浏览器通信。因此它就需要提供一个 SSL 证书,来完成 HTTPS 连接的建立。

但这就有一个问题,SSL 证书哪儿来的?目前 GAppProxy 对所有的站点都使用一个证书,而且这个证书是未经任何授权 CA 认证的证书,因此就会产生很多错误。首先,该证书中的授权机构不是可信 CA,Firefox 和 IE 中捆绑的证书中没有该 CA 的证书;其次,该证书的 CN (Common Name)与站点域名不同,不可用于站点的通信。因此可能每次都需要用户自己点击添加证书例外。

为了避免这种缺陷,我想出来的做法是——自己做 CA,正所谓做事情要专业,要骗就骗彻底点,骗得浏览器神不知鬼不觉。首先,建立 CA 的密钥,自己给自己签发一个证书作为 CA 的根证书,将该 CA 的证书安装到 Firefox 浏览器中,在运行时使用该 CA 为每个 HTTPS 连接的站点签发对应于该站点的证书。由于 Firefox 中已经安装了该 CA 的证书,那么所有该 CA 签发的证书都能够通过 Firefox 的检测了。

这个方法比较麻烦,而且需要电脑上有 openssl,对于 Linux 完全没有问题,对于 Windows 可能就有点儿困难了。所以我这里就给出个思路,具体实现就不谈了。

没有评论: