用 fcgiwrap 来跑 Movable Type
我的 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 虽然和我的用法完全没有关系,但 FreeBSD 的 port 已经被标记为 “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,然后稍作测试即可。