最近通过代理登陆 Trac 系统,不管怎么折腾,就是登不上去(包括手工修改浏览器 Cookie),分析了一下 Trac 的 web 模块的代码,发现罪魁祸首原来是 trac.ini 中的 check_auth_ip 设置,默认是启用的:
check_auth_ip = false
单一的代理背后可能是一个代理服务器集群,每次 HTTP 请求会从中随机或依据某种策略选择一个,导致 IP 变化。
不过 IP 检查在一定程度上能防止 Cookie 欺骗和 CSRF 攻击。
基本上按照 Trac 官方安装指导就行, 但有两点要注意.
1. trac.fcgi
这个文件在源代码包里面 (cgi-bin子目录) , egg 发行包是不带的.
2. Apache URL 重写
使用 URL 重写前: http://trac.domain.com/trac.fcgi/blog
使用 URL 重写后: http://trac.domain.com/blog
现在是搜索引擎为王的时代,用 FastCGI 方式部署会在 URL 里面拖着 trac.fcgi,据说会被搜索引擎列为二等公民。
可以用下面的方法去掉 trac.fcgi:
1. 确保 Apache 启用了 mod_rewrite 模块;
在根目录的 .htaccess (如果不存在则创建) 文件内加入:
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteRule ^(static/.*)$ — [L]
RewriteRule ^chrome/(.*)$ static/trac/htdocs/$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ trac.fcgi/$1 [QSA,L]
ssh 登录,用 trac-admin deploy 命令把 Trac 和所有插件的静态文件部署到指定目录,配合上面的 RewriteRule ^chrome/(.*)$ static/trac/htdocs/$1 [QSA,L] 命令,可以把 chrome (Trac 静态文件路径) 重新定向到由 Apache 处理的目录 (static/trac/htdocs),否则 Trac 会使用自带的静态文件处理器来处理 CSS/JS/PNG/ICO 等静态文件,会有比较严重的性能问题。
Trac URL 修正
经过上面的 URL 重写,就能通过 http://trac.domain.com 或 http://trac.domain.com/blog 访问,但页面中的内部链接仍然包含可恶的 “trac.fcgi”。
这是由于 Trac 暂时不支持 URL 重写,不过手工改起来也很简单。只要把 trac/web/_fcgi.py 文件中:
def _sanitizeEnv(self, environ):
"""Ensure certain values are present, if required by WSGI."""
if not environ.has_key('SCRIPT_NAME'):
environ['SCRIPT_NAME'] = ''
改成:
def _sanitizeEnv(self, environ):
"""Ensure certain values are present, if required by WSGI."""
# if not environ.has_key('SCRIPT_NAME'):
environ['SCRIPT_NAME'] = ''
Kill 掉服务器相关的 fastcgi 进程后,重新打开页面,会发现页面中的链接已经不再包含 “trac.fcgi”。
‘SCRIPT_NAME’ 是 wsgi 规范中的一个环境变量,用来指示 Python 脚本名,如果 Trac 安装在某个子目录 — 比如 “http://trac.domain.com/trac/blog“,就需要把 ‘SCRIPT_NAME’ 环境变量设成 “/trac”,只是猜测,未经验证 :-)
另外,用 CGI/WSGI 方式部署的话,只要在 trac.cgi/trac.wsgi 文件第一个 try: 语句块内添加两行代码即可:
try:
import os
os.environ['SCRIPT_NAME'] = "" # 把脚本名置空
if 'TRAC_ENV' not in os.environ and \
'TRAC_ENV_PARENT_DIR' not in os.environ: