Squid使用SSLBump正向代理

背景:最近需要使用nodeJs访问一个历史久远的网站,那个网站的服务器证书是错误的,且使用的协议是TLSv1.0。浏览器上不得不使用IE并关闭各种安全设置和设置为兼容模式才能正常访问。Nodejs的新版本已经不支持这种不安全的协议,所以需要搭建一个代理服务进行访问。刚开始使用的是mitmproxy ,当时的最新版本对于SSL错误会报错,所以将源码中校验部分去掉就可以正常使用了。但部署到生产环境,会出现cpu占用过高的情况。所以后面换了Squid。 部署Squid参考了一篇文章,原文:here,下面是简单翻译。 Squid是个很强大的Web代理,它可以应用于无线认证、重定向、用户身份验证、日志记录等。但其在SSL方面一直存在局限性。在3.2版本之前,Squid的策略只是简单地传递SSL加密流量,因为它无法校验受信任的SSL链接。对于每个SSL连接也无法给用户做预警。但3.5版本后允许更多的控制,但要注意仍然无法校验受信任的SSL链接。 这里不会过多地介绍使用SSL Bump配置Squid以外的知识,对于编译和配置squid的细节你最好看下官方文档。 如果通过代理自动监测,通知浏览器连接到代理服务器,这样是挺简单的。但有些用户可能会试图规避这一点,并尝试直接连接。 在这种情况下,我们需要强制这些用户通过截取流量来使用代理。SSL Bumping的前提是中间人攻击,但由于这是在您的用户清楚所有流量都是检查过的环境中完成的,因此这并不是真正的攻击,这只是一种策略。Squid用于执行SSL Bumping有一些新方法,但是我会总结出最具实战性的方法:Squid收到一个https请求,然后为用户建立安全连接。 远程连接建立后,Squid会重新加密所有流量; 这时候的加密使用的是本地私钥,以及本地证书颁发机构即时创建出来的证书。 所以我们首先要确保的是你已经安装了3.5或更高版本的Squid。尽管3.2,3.3以及3.4版本也能实现,但3.5版本后SSL Bump的指令有了些显著变化。另外,编译Squid时需要带上‘–with-openssl’参数。 在CentOS我使用以下参数来编译Squid(foam:我带上–enable-ipf-transparent参数会报错,所以我是去掉再编译的) ./configure \ --prefix=/usr \ --exec-prefix=/usr \ --includedir=/usr/include \ --datadir=/usr/share \ --libdir=/usr/lib64 \ --libexecdir=/usr/lib64/squid \ --localstatedir=/var \ --sysconfdir=/etc/squid \ --sharedstatedir=/var/lib \ --with-logdir=/var/log/squid \ --with-pidfile=/var/run/squid.pid \ --with-default-user=squid \ --enable-silent-rules \ --enable-dependency-tracking \ --with-openssl \ --enable-icmp \ --enable-delay-pools \ --enable-useragent-log \ --enable-esi \ --enable-follow-x-forwarded-for \ --enable-ipf-transparent \ --enable-auth 接下来我们需要生成本地的SSL证书,这里我使用的是简单的命令,没有在意怎么去加密。 # Generate Private Key openssl genrsa -out example.com.private 2048 然后是创建Certificate Signing Request(CSR),即证书注册请求。 ...

2017-09-23 · 3 分钟 · 630 字

关于Tokens你需要知道的10件事

关于Tokens你需要知道的10件事 ——进一步探讨基于Token认证的一些常见问题 原文链接:Here 原作者:Matias Woloski 几周前我们发表了一篇短文《cookies与tokens在单页应用中的对比》(主要以AngularJs应用为例)。社区里对这个话题很感兴趣,于是我们接着发表了第二篇《在socket.io等实时框架中基于Token的认证》。趁着大家对这个话题还保持着热情,我们决定再写一篇文章进一步探讨基于Token认证的常见问题。我们开始吧~ 1.Tokens需要保存在Local Storage、Session Storage或Cookies中 在Tokens被应用于单页应用的背景下,有人提出了问题:在浏览器中刷新页面时,token会发生什么变化。答案很简单:你需要将token保存在Local Storage、Session Storage或客户端内置的Cookies中,在浏览器不支持Session Storage的情况下,它会被polyfills为cookies。 你或许想问“但如果我将token保存在cookie的话,岂不是很危险”。其实不然,这种情况下,你使用的cookies只是作为存储机制而非验证机制(即是说,web框架不会使用cookie来验证用户,因此不存在XSRF攻击的危险) 2.Tokens像Cookies一样会过期,但你有更多的控制权 Tokens具有生命周期(在JSON Web Tokens中由exp属性控制),否则用户就可以登录一次却永远无需认证了。Cookies由于相同的原因也具有生命周期。 在Cookies中,如下不同情况生命周期也不一样: 1.当关闭浏览器时,Cookies会被销毁(如Session Cookies) 2.你也可以实现一个服务端检查机制(通常由Web框架帮你完成),你可以设置生命周期或滑动窗口生命周期。 3.Cookies在一段时间内可以是永久的(即使关闭浏览器也不会被销毁) 在Tokens中,一旦过期,你只需要获取一个新的token。你可以写一个端点来更新token: 1.验证旧的token 2.检查用户是否还处于登录状态或者在访问你的网站 3.产生一个重新续时的新token 你甚至可以将token生成的时间写入其中,并在大约两周后强制用户重新登录。 app.post('/refresh_token', function (req, res) { // verify the existing token var profile = jwt.verify(req.body.token, secret); // if more than 14 days old, force login if (profile.original_iat - new Date() > 14) { // iat == issued at return res.send(401); // re-logging } // check if the user still exists or if authorization hasn't been revoked if (!valid) return res.send(401); // re-logging // issue a new token var refreshed_token = jwt.sign(profile, secret, { expiresInMinutes: 60*5 }); res.json({ token: refreshed_token }); }); 3.Local/Session Storage无法跨域,请使用Cookies作标记 如果你将cookie的作用域名设置为.yourdomain.com,那么它可以在yourdomain.com和app.yourdomain.com中被访问。如果用户在主域登录却被重定向到app.yourdomain.com,要验证cookie也是很方便的。 Tokens存储在local/session storage中,这意味着不同域名之间是无法相互访问的(即使是子域名)。那么你该怎么做呢? 其中一种做法是,当用户在app.yourdomain.com中验证完毕后,你生成一个token并设置一个作用域名为.yourdomain.com的Cookie标记用户已经登录。 $.post('/authenticate, function() { // store token on local/session storage or cookie .... // create a cookie signaling that user is logged in $.cookie('loggedin', profile.name, '.yourdomain.com'); }); 然后,你可以在yourdomain.com验证cookie的存在并重定向到app.yourdomain.com。而Token可以在app的子域中使用(如果token依然合法)。 可能会出现cookie存在而token已经被删除的情况。这种情况下,用户必须重新登录。这里需要强调的是,正如我们之前所说,我们并不将cookie当作验证机制,而仅仅把它作为能够跨域保存信息的存储机制。 4.每个CORS请求都会先发一个预请求 有人指出,Authorization报头并非一个简单的报头,因此在向特定URLs发送请求前都需要发送一个预请求。 OPTIONS https://api.foo.com/bar GET https://api.foo.com/bar Authorization: Bearer .... OPTIONS https://api.foo.com/bar2 GET https://api.foo.com/bar2 Authorization: Bearer .... GET https://api.foo.com/bar Authorization: Bearer .... 这时你需要发送Content-Type: application/json。 提醒下,OPTIONS请求自身并没有Authorization报头信息,所以你的web框架需要对OPTIONS和后续的请求作一些处理(提示:微软的IIS因为某些原因在这方面存在一些问题)。 ...

2015-08-12 · 2 分钟 · 324 字

关于知乎收藏和译文

知乎收藏分类下的所有文章均来自知乎。知乎是一个好平台,至少现在还是。有时候看到一些好文章,不忍私藏,权当与大家学习共勉吧。 译文分类下的文章均由我翻译,当作锻炼英文水平吧。 至于版权,两个分类下的所有文章均得到原作者同意如果你需要转载,请直接联系原作者哦

2015-07-27 · 1 分钟 · 3 字