Trac 和 mod_wsgi
mod_wsgi 是一个 Apache 模块,用于在 Apache Web 服务器上直接运行 WSGI 兼容的 Python 应用程序。mod_wsgi 适配器完全用 C 语言编写,提供了非常好的性能。
概述
trac.wsgi
脚本
Trac 可以借助应用程序脚本在 mod_wsgi 上运行,该脚本是一个以 .wsgi
扩展名保存的 Python 文件。
可以使用 trac-admin <env> deploy <dir>
命令创建此文件的健壮且通用版本,该命令会自动替换所需的路径,请参阅 TracInstall#cgi-bin。该脚本足以满足大多数安装,不需要更多信息的用户可以继续配置 Apache。
如果您将 Trac 用于多个项目,可以在 trac.wsgi
中指定它们的共同父目录
def application(environ, start_request): # Add this when you have multiple projects environ.setdefault('trac.env_parent_dir', '/usr/share/trac/projects') ..
位于 trac.env_parent_dir
中但不是环境目录的目录将在项目索引页上显示错误消息。这些目录可以通过将它们列在 trac.env_parent_dir
中名为 .tracignore
的文件中来排除。Unix shell 风格的通配符模式可以在以换行符分隔的目录列表中使用。
一个非常基础的脚本
最简单的形式,脚本可以是
import os os.environ['TRAC_ENV'] = '/usr/local/trac/mysite' os.environ['PYTHON_EGG_CACHE'] = '/usr/local/trac/mysite/eggs' import trac.web.main application = trac.web.main.dispatch_request
TRAC_ENV
变量自然应该是您的 Trac 环境目录,而 PYTHON_EGG_CACHE
应该是一个 Python 可以临时提取 Python egg 的目录。如果您的目录中有多个 Trac 环境,您也可以使用 TRAC_ENV_PARENT_DIR
而不是 TRAC_ENV
。
在 Windows 上
- 如果在用户会话下运行,Python Egg 缓存可以在
%AppData%\Roaming
中找到,例如os.environ['PYTHON_EGG_CACHE'] = r'C:\Users\Administrator\AppData\Roaming\Python-Eggs'
- 如果在 Windows 服务下运行,您应该为 Python Egg 缓存创建一个目录
os.environ['PYTHON_EGG_CACHE'] = r'C:\Trac-Python-Eggs'
一个更精细的脚本
如果您使用多个 .wsgi
文件(例如每个 Trac 环境一个),则不得使用 os.environ['TRAC_ENV']
来设置 Trac 环境的路径。使用此方法可能会导致 Trac 提供另一个 Trac 环境的内容,因为该变量可能被之前查看的 Trac 环境的路径填充。
要解决此问题,请改用以下 .wsgi
文件
import os os.environ['PYTHON_EGG_CACHE'] = '/usr/local/trac/mysite/eggs' import trac.web.main def application(environ, start_response): environ['trac.env_path'] = '/usr/local/trac/mysite' return trac.web.main.dispatch_request(environ, start_response)
为了清晰起见,您应该给这个文件一个 .wsgi
扩展名。您可能应该将该文件放在自己的目录中,因为它将暴露给 Apache。
如果您已将 Trac 和 Python eggs 安装在与标准路径不同的路径中,则应通过在 wsgi 脚本顶部添加以下代码来添加该路径
import site site.addsitedir('/usr/local/trac/lib/python2.4/site-packages')
根据您安装 Trac 库的路径进行更改。
将请求映射到脚本
准备好 .wsgi 脚本后,将以下内容添加到您的 Apache 配置文件(通常是 httpd.conf
)中
WSGIScriptAlias /trac /usr/local/trac/mysite/apache/mysite.wsgi <Directory /usr/local/trac/mysite/apache> WSGIApplicationGroup %{GLOBAL} # For Apache 2.2 <IfModule !mod_authz_core.c> Order deny,allow Allow from all </IfModule> # For Apache 2.4 <IfModule mod_authz_core.c> Require all granted </IfModule> </Directory>
这里,脚本位于 Trac 环境的一个子目录中。
如果您遵循了生成 Trac cgi-bin 目录的说明,您的 Apache 配置文件应如下所示
WSGIScriptAlias /trac /usr/share/trac/cgi-bin/trac.wsgi <Directory /usr/share/trac/cgi-bin> WSGIApplicationGroup %{GLOBAL} # For Apache 2.2 <IfModule !mod_authz_core.c> Order deny,allow Allow from all </IfModule> # For Apache 2.4 <IfModule mod_authz_core.c> Require all granted </IfModule> </Directory>
为了让 Apache 运行脚本,脚本所在目录的访问权限已对 Apache 完全开放。此外,WSGIApplicationGroup
指令确保 Trac 始终在 mod_wsgi 创建的第一个 Python 解释器中运行。这是必要的,因为 Trac 使用的 Subversion Python 绑定在其他子解释器中并非总能正常工作,并可能导致请求挂起或 Apache 崩溃。添加此配置后,重新启动 Apache,然后它应该可以工作了。
为了测试 Apache、mod_wsgi 和 Python 本身(即不涉及 Trac 和依赖项)的设置,可以使用这个简单的 wsgi 应用程序来确保请求得到服务(作为 .wsgi
脚本中唯一的内容使用)
def application(environ, start_response): start_response('200 OK',[('Content-type','text/html')]) return ['<html><body>Hello World!</body></html>']
有关使用 mod_wsgi 特定的指令的更多信息,请参阅 mod_wsgi 的维基以及更具体的 IntegrationWithTrac 页面。
配置身份验证
以下各节介绍了设置认证的不同方法。另请参阅 Apache 指南中的认证、授权和访问控制。
使用基本认证
使用 Apache 启用认证最简单的方法是创建密码文件。使用 htpasswd
程序如下:
$ htpasswd -c /somewhere/trac.htpasswd admin New password: <type password> Re-type new password: <type password again> Adding password for user admin
创建第一个用户后,您不再需要“-c”选项
$ htpasswd /somewhere/trac.htpasswd john New password: <type password> Re-type new password: <type password again> Adding password for user john
有关完整文档,请参阅 htpasswd
的手册页。
创建用户后,您可以使用TracPermissions设置他们的权限。
现在,您需要在 Apache 配置中启用对密码文件的认证
<Location "/trac/login"> AuthType Basic AuthName "Trac" AuthUserFile /somewhere/trac.htpasswd Require valid-user </Location>
如果您托管多个项目,可以使用相同的密码文件对所有项目进行认证
<LocationMatch "/trac/[^/]+/login"> AuthType Basic AuthName "Trac" AuthUserFile /somewhere/trac.htpasswd Require valid-user </LocationMatch>
请注意,不需要存在名为“login”的文件或目录。另请参阅mod_auth_basic 文档。
使用摘要认证
为了更好的安全性,建议您要么启用 SSL,要么至少使用“摘要”认证方案而不是“基本”认证。
您必须使用 htdigest
命令而不是 htpasswd
来创建您的 .htpasswd
文件,如下所示
$ htdigest -c /somewhere/trac.htpasswd trac admin
上面提到的“trac”参数是“realm”,需要Apache配置中 AuthName 指令中重复使用
<Location "/trac/login"> AuthType Digest AuthName "trac" AuthDigestDomain /trac AuthUserFile /somewhere/trac.htpasswd Require valid-user </Location>
对于多个环境,您可以使用与前述方法相同的 LocationMatch
。
注意:Location
不能在 .htaccess 文件中使用,而必须存在于主 httpd.conf 文件中。如果您在共享服务器上,因此将无法提供这种级别的粒度。
别忘了激活 mod_auth_digest。例如,在 Debian 4.0r1 (etch) 系统上
LoadModule auth_digest_module /usr/lib/apache2/modules/mod_auth_digest.so
另请参阅mod_auth_digest 文档。
使用 LDAP 认证
Apache 中 mod_ldap 认证的配置更复杂(httpd 2.2+ 和 OpenLDAP: slapd 2.3.19)。
- 您需要在 Apache httpd.conf 中加载以下模块
LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
- 您的 httpd.conf 也需要看起来像这样
<Location /trac/> # (if you're using it, mod_python specific settings go here) Order deny,allow Deny from all Allow from 192.168.11.0/24 AuthType Basic AuthName "Trac" AuthBasicProvider "ldap" AuthLDAPURL "ldap://127.0.0.1/dc=example,dc=co,dc=ke?uid?sub?(objectClass=inetOrgPerson)" authzldapauthoritative Off Require valid-user </Location>
- 您可以使用 LDAP 接口作为对 Microsoft Active Directory 进行认证的方式。使用以下内容作为您的 LDAP URL您还需要提供一个 Apache 用于检查凭据的账户。由于此密码将在配置中以纯文本形式列出,因此您需要专门为此任务使用一个账户
AuthLDAPURL "ldap://directory.example.com:3268/DC=example,DC=com?sAMAccountName?sub?(objectClass=user)"
整个部分看起来像这样AuthLDAPBindDN ldap-auth-user@example.com AuthLDAPBindPassword "password"
<Location /trac/> # (if you're using it, mod_python specific settings go here) Order deny,allow Deny from all Allow from 192.168.11.0/24 AuthType Basic AuthName "Trac" AuthBasicProvider "ldap" AuthLDAPURL "ldap://adserver.company.com:3268/DC=company,DC=com?sAMAccountName?sub?(objectClass=user)" AuthLDAPBindDN ldap-auth-user@company.com AuthLDAPBindPassword "the_password" authzldapauthoritative Off # require valid-user Require ldap-group CN=Trac Users,CN=Users,DC=company,DC=com </Location>
注意 1:这是 LDAP 搜索将绕过多个 OU 的情况,连接到 AD 的全局目录服务器部分。请注意端口是 3268,而不是正常的 LDAP 389。GCS 本质上是一个“扁平化”的树,允许在不知道用户属于哪个 OU 的情况下搜索用户。
注意 2:您还可以要求用户是某个 LDAP 组成员,而不仅仅是拥有有效的登录凭据
Require ldap-group CN=Trac Users,CN=Users,DC=example,DC=com
另请参阅
- mod_authnz_ldap,mod_authnz_ldap 的文档。
- mod_ldap,mod_ldap 的文档,它提供了连接池和共享缓存。
- TracHacks:LdapPlugin 用于在 LDAP 中存储TracPermissions。
使用 SSPI 认证
如果您在 Windows 上使用 Apache,可以使用 mod_auth_sspi 提供单点登录。从 SourceForge mod-auth-sspi 项目下载模块,然后将以下内容添加到您的 VirtualHost 中
<Location /trac/login> AuthType SSPI AuthName "Trac Login" SSPIAuth On SSPIAuthoritative On SSPIDomain MyLocalDomain SSPIOfferBasic On SSPIOmitDomain Off SSPIBasicPreferred On Require valid-user </Location>
使用上述方法,Trac 中的用户名将是 DOMAIN\username
的形式,因此您可能需要重新添加权限等。如果您不希望域名成为用户名的一部分,请改为设置 SSPIOmitDomain On
。
SSPI 认证的一些常见问题:#1055、#1168 和 #3338。
使用 CA SiteMinder 认证
设置 CA SiteMinder 以保护您的 Trac 登录 URL,例如 /trac/login
。此外,请确保策略设置为包含 HTTP_REMOTE_USER 变量。如果您的站点允许,您可以在 LocalConfig.conf
中进行设置
RemoteUserVar="WHATEVER_IT_SHOULD_BE" SetRemoteUser="YES"
具体变量取决于站点。请咨询您的站点管理员。如果您的站点出于安全原因不允许使用 LocalConfig.conf
,请让您的站点管理员在服务器上设置策略以设置 REMOTE_USER。
另请在代理配置中添加一个 LogOffUri 参数,例如 /trac/logout
。
然后修改使用 trac-admin <env> deploy <dir>
生成的 trac.wsgi 脚本,添加以下行,它们将提取 HTTP_REMOTE_USER
变量并将其设置为 REMOTE_USER
def application(environ, start_request): # Set authenticated username on CA SiteMinder to REMOTE_USER variable # strip() is used to remove any spaces on the end of the string if 'HTTP_SM_USER' in environ: environ['REMOTE_USER'] = environ['HTTP_REMOTE_USER'].strip() ...
您不需要任何 Apache “Location” 指令。
示例:使用 Apache/mod_wsgi 和基本认证,Trac 位于虚拟主机根目录
根据上面链接的 mod_wsgi 文档,这是一个 Apache 配置示例,它
- 从虚拟主机子域名提供 Trac 实例
- 使用 Apache 基本认证进行 Trac 认证。
如果您想让 Trac 从例如 http://trac.my-proj.my-site.org 提供服务,然后从例如 /home/trac-for-my-proj
文件夹,如果您使用了命令 trac-admin the-env initenv
创建了 the-env
文件夹,并且您使用了 trac-admin the-env deploy the-deploy
创建了 the-deploy
文件夹,那么首先
创建 htpasswd 文件
cd /home/trac-for-my-proj/the-env htpasswd -c htpasswd firstuser ### and add more users to it as needed: htpasswd htpasswd seconduser
出于安全原因,请将文件保存在文档根目录上方。
在 Ubuntu 上创建此文件,例如 /etc/apache2/sites-enabled/trac.my-proj.my-site.org.conf
,内容如下
<Directory /home/trac-for-my-proj/the-deploy/cgi-bin/trac.wsgi> WSGIApplicationGroup %{GLOBAL} Order deny,allow Allow from all </Directory> <VirtualHost *:80> ServerName trac.my-proj.my-site.org DocumentRoot /home/trac-for-my-proj/the-env/htdocs/ WSGIScriptAlias / /home/trac-for-my-proj/the-deploy/cgi-bin/trac.wsgi <Location '/'> AuthType Basic AuthName "Trac" AuthUserFile /home/trac-for-my-proj/the-env/htpasswd Require valid-user </Location> </VirtualHost>
为了使子域名正常工作,您可能还需要修改 /etc/hosts
并将 A 记录添加到您的主机的 DNS 中。
故障排除
使用最新版本
请使用 mod_wsgi
的 1.6、2.4 或更高版本。2.X 分支中 2.4 之前的版本在某些使用 WSGI 文件包装器扩展的 Apache 配置中存在问题。Trac 中使用此扩展来提供附件和静态媒体文件,例如样式表。如果您受到此问题的影响,附件将显示为空,并且 HTML 页面的格式可能由于样式表文件未正确加载而无法正常工作。另一个常见症状是二进制附件下载被截断。请参阅 mod_wsgi 缺陷报告 #100 和 #132。
注意:在我的系统上(Apache 2.2.11 和 Trac 0.11.2.1),使用 mod_wsgi 2.5 和 Python 2.6.1 导致了内部服务器错误。升级到 Python 2.6.2(如此处建议)解决了我的问题
-- Graham Shanks
如果您计划在 Windows 上以嵌入模式或在 Linux 上使用 MPM worker 模式使用 mod_wsgi
,那么您将需要 3.4 或更高版本。有关详细信息,请参阅#10675。
使 Trac 很好地与 SSPI 和 'Require Group' 配合工作
如果您已在 Apache、Win32 上设置 Trac 并配置了 SSPI,但您的 Apache 配置中添加了 'Require group' 选项,那么 SSPIOmitDomain 选项可能无法正常工作。如果它不工作,您的 Trac 用户名可能看起来像 'DOMAIN\user' 而不是 'user'。
这个 WSGI 脚本修复了这个问题
import os import trac.web.main os.environ['TRAC_ENV'] = '/usr/local/trac/mysite' os.environ['PYTHON_EGG_CACHE'] = '/usr/local/trac/mysite/eggs' def application(environ, start_response): if "\\" in environ['REMOTE_USER']: environ['REMOTE_USER'] = environ['REMOTE_USER'].split("\\", 1)[1] return trac.web.main.dispatch_request(environ, start_response)
Trac 与 PostgreSQL
当将 mod_wsgi 适配器与多个 Trac 实例以及 PostgreSQL(或 MySQL?)作为数据库一起使用时,服务器可能会创建大量的打开数据库连接,从而导致大量的 PostgreSQL 进程。
一个有点粗暴的解决方法是在 Trac 中禁用连接池。这通过在 PostgreSQLConnection
类的 trac.db.postgres_backend
中设置 poolable = False
来实现。
但没有必要编辑 Trac 的源代码。trac.wsgi
中的以下行也将起作用
import trac.db.postgres_backend trac.db.postgres_backend.PostgreSQLConnection.poolable = False
或
import trac.db.mysql_backend trac.db.mysql_backend.MySQLConnection.poolable = False
现在 Trac 在服务页面后会断开连接,并且数据库上的连接数将保持在较低水平。
但这并非推荐的方法。另请参阅 mod_wsgi 的 IntegrationWithTrac 维基页面底部的注意事项。
其他资源
有关更多故障排除技巧,另请参阅mod_python 故障排除部分,因为大多数与 Apache 相关的问题都非常相似,此外还有关于使用 mod_wsgi 时潜在的应用程序问题的讨论。wsgi 页面还包含一个与 Trac 集成文档。
另请参阅:TracGuide, TracInstall, FastCgi, ModPython, TracNginxRecipe