December 2011 Archives

有一种错误的观念是,对于不太敏感的内容(例如论坛之类),只要用 https 保护登录过程中提交密码的部分就足够了。例如国内非常流行的网易邮箱,很早以前便提供了"SSL安全登录"的选项,这样做显然是比完全不提供SSL登录选项的新浪邮箱要强多了[注1],但是仍然是不够的。

为什么呢?因为通过明文传输的网页没有提供任何保护,而通过 https 传输的内容则是提供端到端(从服务器到客户的浏览器)的安全保证的。例如,代理服务器可以根据需要按URL(这是非常成熟的技术)来替换掉页面,而配合 DNS 攻击,或者攻击者掌握了受害人使用的网络基础设施,便可以在对方不知情的情况下把敏感数据传到攻击者控制的服务器上。假如采用了 https,攻击者能够选择的选项就大大减少了(例如,攻击者必须能够伪造适当的证书,并劫持、解密所有流量,等等)。

当然,使用 https 并不能阻止用户访问钓鱼网站并在其中输入敏感数据。这类用户应远离 Internet。


[注1] 不过很讽刺的是,新浪邮箱的登录首页实际上是有 https 版本的,但是这个 https 版本并不处理提交;而网易邮箱则完全没有提供 https 版本的登录首页。

用 fcgiwrap 来跑 Movable Type

| 2 Comments | No TrackBacks

我的 blog 在之前一直是用 Apache HTTPD 来作为 CGI 引擎来跑 Movable Type。在迁移到北美之前,使用两个域名/IP来分别运行静态页面 (lighttpd) 和 CGI 内容。后来因为全面转向 nginx,在迁移过程中改成了使用一个域名、使用 nginx 在前面跑静态页,并作为反向代理来连接后端的 Apache 1.3.x 实例(先前是 Apache 2.2.x,由于这个实例只用来跑 CGI,所以采用了较低版本的 Apache 以节省资源)。

之前一直有完全停用 Apache HTTPD 的想法,不过一直没有时间去实作。由于 Apache 1.3.x 早已是不再维护的分支,近期发现的 CVE-2011-3368 虽然和我的用法完全没有关系,但 FreeBSDport 已经被标记为 "FORBIDDEN" 状态,于是最近找时间学习了一下如何在 nginx 上跑这些 cgi。现在,这台服务器已经完全停用 Apache HTTPD 了。

nginx 有很多跑 CGI 的办法,但是没有一种是原生的。官方推荐的方法是使用 thttpd,然而大概看了看代码之后发现 thttpd 虽然代码量很少,但不支持使用 Unix socket 连接,而且我只要能支持 FastCGI 接口就好,并不真的需要封好 HTTP,所以改为用 fcgiwrap (ports/www/fcgiwrap)。

fcgiwrap 没有什么特别的配置。 FreeBSD 上提供了一个 rc.d 脚本,直接拿来用。

对应的 rc.conf.local 配置如下:

fcgiwrap_enable="YES"
fcgiwrap_socket="unix:/var/run/www/fcgiwrap.sock"
fcgiwrap_user="www"
fcgiwrap_group="www"

这里没有使用通常的 /var/run/fcgiwrap.sock, 而是单独建立了一级目录 (/var/run/www/),其 owner 用户和组均为 www。上述配置令 rc.d 系统在启动时使用 www 身份,如果不单独建立目录,则系统会无法创建对应的 socket 文件。

fcgiwrap 信任来自 Web 服务器的路径。下面是告诉 nginx 如何透过 FastCGI 接口传递这些参数:

	location ~ ^/mt(/[^/]*)(/.*)?$ {
		root <此处填写具体的cgi-bin/mt目录>/;
		fastcgi_split_path_info (^/mt/[^/]*)(.*)$;
		include fastcgi_params;
		fastcgi_param GATEWAY_INTERFACE CGI/1.1;
		fastcgi_param SCRIPT_FILENAME $document_root$1;
		fastcgi_param PATH_INFO $fastcgi_path_info;
		fastcgi_param PATH_TRANSLATED $document_root$2;
		fastcgi_pass unix:/var/run/www/fcgiwrap.sock;
	}

去掉原先的代理配置,启动 fcgiwrap,然后稍作测试即可。

来自新浪微博:王小山:同意的请转,郑重承诺:拒绝蒙牛一切产品,从我做起,从现在做起:不为蒙牛打工,不使用蒙牛产品,告诉别人蒙牛是垃圾企业,不接蒙牛订单,不接蒙牛广告,不买有蒙牛广告的报纸,不看蒙牛赞助的节目,微博辩论再不说对方"脑残",只说"喝蒙牛长大的吧"。

我们也许没有办法改变监管体制,但我们至少可以拒绝那些有问题的企业。监管部门不让它们倒闭,消费者就必须让它们倒闭!请爱惜自己的家人和生命。

idprio和rtprio

| No Comments | No TrackBacks

记一笔,没啥特别。

Unix 系统的分时调度中,nice值(通过 nice(1) 来控制)是管理员告诉调度器的一个参数,这个参数令内核在考虑就绪进程优先级时,根据其值适当增大或减少执行绪的动态优先级。很明显,如果采用抢占式调度,如果执行绪等待时间较长,或者由于某种原因获得了优先级奖励(例如I/O导致的等待),即使有更重要的任务需要执行,内核还是会将这个执行绪调度进来并进行执行;反之,如果执行绪使用的 CPU 很多(计算密集型任务,如压缩等等),即使这个执行绪进行的就是最重要的任务,它仍然可能被置入休眠状态。

FreeBSD 的及时调度 (real-time scheduling) 实现中,增加了32个'及时(realtime)'优先级和32个'闲时调度(idle)'优先级。用户态进程可以通过 rtprio(2) 或 rtprio_thread(2) 系统调用来为进程或线程指定这些优先级。这些优先级不会动态调整,故在抢占式调度中可以一直获得时间片,或只有在系统闲时才获得时间片。

为了方便管理员使用,FreeBSD提供了与之对应的 rtprio(1)idprio(1) 命令。出于显然的安全考虑,rtprio 和减少 nice 值一样需要超级用户权限,而 idprio 默认也需要超级用户权限(目前,持锁执行绪可能由于优先级太低而被抢断,从而导致死锁),但可以通过将 security.bsd.unprivileged_idprio 设为 1 来允许非特权用户使用它。

典型的用法包括:

将 Xorg 设为 realtime 优先级,以改善其响应。这个命令必须以 root 身份运行。

副作用:如果 Xorg 陷入死循环,将没有机会令其终止。

# rtprio 31 -`pgrep Xorg`

以 idle 优先级运行 make buildworld。需要以 root 身份运行或将 sysctl security.bsd.unprivileged_idprio 设为 1。

# idprio 31 make buildworld

对于单机运行的网站来说,也可以用类似的方法来做后台的日志分析处理。

密码阴谋论

| 5 Comments | 1 TrackBack

大家都喜欢阴谋论,所以今天说个关于密码的。话说,假如你拿到了一个大网站的密码数据库,然后恰好这个数据库里面的密码又都是明文,但这个数据有点旧了,怎么样才能立即得到其中的活跃用户的密码呢?

假设你可以控制若干家网络公司所使用的网络基础设施,例如事先装了一些监控非法活动的防火墙的话,方法就很简单了:公布这个数据库,或者公布至少其中的一部分,然后做简单的监听就可以了。这个过程不但可以知道他们的新密码是什么,而且可以知道旧密码是否是对的,还可以知道他们的安全习惯如何,要知道,假如没有这个事件,绝大多数人可能正靠着他们的简单密码睡大觉。

当然,攻击者显然还会注意到,这些网站,以及很多其他网站,多数还都没有对用户做最起码的保护,即使用 https 来保护登录过程。

配合 svn 使用 git 时可能会遇到许多问题,例如两个人分别做了 git svn clone,然后希望合并到同一个 git 库中。如何做合并呢?假定两个库分别是 old, new,将这两个库对应的分支和对应的源分支 (svn/*) 通过 .git/config 分别复制到不同的分支名字下面,例如 svn/releng/8.2 和 old-svn/releng/8.2。假定需要合并的分支是 old/my8.2,则做以下操作:

git checkout my8.2 # 签出一份工作副本
git rebase old-svn/releng/8.2 # 更新到原始上游的最新状态
git rebase --onto svn/releng/8.2 old-svn/releng/8.2 # 用新库作为基础重新rebase;
git push origin my8.2 # 将结果push回代码库

把本地新建分支推到上游:

git push origin 分支名

问题:首次push时会收到 git post-receive remote: fatal: Invalid revision range 0000000000000000000000000000000000000000..XXXXXXXXXXX,不过并不影响push本身。这个错误是由于post-receive的hook里面引用了git提供的旧版本,但查了一下似乎没有很好的办法知道这个分支的上游是谁?(基本逻辑应该大致是:和库中已经存在的所有其他分支进行比较并找到公共版本与本分支HEAD距离最近的一个,返回那个版本号)。

删除远程代码库中的分支:

git push origin :分支名

Monthly Archives

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.2.3