项目

常规

个人资料

操作

使用Apache、mod_dav_svn和mod_perl的仓库访问控制

概述

在本文档中,我们将配置Apache以将身份验证委托给mod_perl。它已在apache2 (apache2-mpm-prefork) 和mysql、postgresql上进行了测试,但应适用于几乎所有有perl DBD模块的数据库。使用高速线程模型的Apache2可能无法正确加载Perl (apache2-mpm-worker)。

您需要在您的SVN服务器上有一个工作的Apache,并且您必须安装一些模块,至少包括mod_dav_svn、mod_perl2、DBI和DBD::mysql(或您数据库的DBD驱动程序,因为它应在几乎所有数据库上工作)。

在Debian/ubuntu上,您可以这样做

sudo aptitude install libapache2-svn libapache-dbi-perl \
libapache2-mod-perl2 libdbd-mysql-perl libdigest-sha1-perl \
libauthen-simple-ldap-perl

在Turnkey Redmine虚拟机中,您可以这样做

apt-get install libapache2-svn libapache-dbi-perl \
libapache2-mod-perl2 libauthen-simple-ldap-perl

在Turnkey Redmine虚拟机v 15.0及更高版本中,您可以这样做

apt-get install libapache2-mod-svn libapache-dbi-perl libapache2-mod-perl2 libauthen-simple-ldap-perl

如果仓库不是由reposman.rb自动创建的,则确保仓库名称与Redmine中的项目标识符相同非常重要,否则Redmine.pm将无法验证用户。例如,如果仓库的路径是/path/to/repository/foo-bar,则设置页面上的项目标识符必须是foo-bar

启用Apache模块

在Debian/ubuntu上

sudo a2enmod dav
sudo a2enmod dav_svn # if you want to use svn
sudo a2enmod dav_fs  # if you want to use git
sudo a2enmod perl

Subversion仓库的Apache配置

首先需要将Redmine.pm复制或链接到/usr/lib/perl5/Apache/Redmine.pm
  • Redmine.pm可以在$REDMINE_DIR/extra/svn/Redmine.pm中找到
  • 在Debian安装中,它在/usr/share/redmine/extra/svn/Redmine.pm中找到

然后向您的Apache配置中添加以下Location指令(例如在/etc/APACHE_DIR/conf.d/中)

  • 旧的如何操作指南建议使用两个不同的位置/svn/svn-private,可以避免
  • 使用Apache的Satisfy any关键字,您可以定义不同的身份验证策略
  • 从redmine-server或任何已验证用户读取访问
  • 仅允许已验证用户写入访问
   # enables connection pooling (very useful for checkouts with many files)
   PerlModule Apache::DBI
   PerlOptions +GlobalRequest

   # /svn location for users
   PerlLoadModule Apache::Redmine
   <Location /svn>
     DAV svn

     ### uncomment the following line when using subversion 1.8 or newer (see https://subversion.org.cn/docs/release-notes/1.8.html#serf-skelta-default)
     # SVNAllowBulkUpdates Prefer

     SVNParentPath "/var/svn" 
     Order deny,allow
     Deny from all
     Satisfy any
     # If a client tries to svn update which involves updating many files,
     # the update request might result in an error Server sent unexpected
     # return value (413 Request  Entity Too Large) in response to REPORT
     # request,because the size of the update request exceeds the limit
     # allowed by the server. You can avoid this error by disabling the
     # request size limit by adding the line LimitXMLRequestBody 0
     # between the <Location...> and </Location> lines. 
     LimitXMLRequestBody 0

     # Only check Authentication for root path, nor again for recursive
     # folder.
     # Redmine core does only permit access on repository level, so this
     # doesn't hurt security. On the other hand it does boost performance
     # a lot!
     SVNPathAuthz off

     PerlAccessHandler Apache::Authn::Redmine::access_handler
     PerlAuthenHandler Apache::Authn::Redmine::authen_handler
     AuthType Basic
     AuthName "Redmine SVN Repository" 
     AuthUserFile /dev/null

     #read-only access    
     <Limit GET PROPFIND OPTIONS REPORT>
        Require valid-user
        Allow from redmine.server.ip
        # Allow from another-ip
         Satisfy any
     </Limit>
     # write access
     <LimitExcept GET PROPFIND OPTIONS REPORT>
       Require valid-user
     </LimitExcept>

     ## for mysql
     RedmineDSN "DBI:mysql:database=databasename;host=my.db.server" 
     ## for postgres
     # RedmineDSN "DBI:Pg:dbname=databasename;host=my.db.server" 
     ## for SQLite3
     # RedmineDSN "DBI:SQLite:dbname=database.db" 

     RedmineDbUser "redmine" 
     RedmineDbPass "password" 
  </Location>

测试配置:

重新加载Apache配置后,您可以使用以下内容尝试浏览一些仓库

svn ls http://my.svn.server/svn/myproject

任何非公开仓库都应该要求用户名和密码。

要测试允许Redmine服务器读取所有仓库的身份验证

读取私有仓库

svn ls http://my.svn.server/svn/myproject

尝试写入存储库
svn mkdir http://my.svn.server/svn/myproject/testdir

这应该会失败并要求输入密码。

可选的LDAP身份验证

如果您想将LDAP身份验证连接到Apache,您可以安装Authen::Simple::LDAP perl模块。我发现连接到我的LDAP服务器进行每次请求的认证可能会相当慢。我在我的配置中添加了以下内容,并获得了显著的性能提升。如果您已经配置了到LDAP服务器的加密连接,您将需要IO::Socket::SSL模块。

注意:上面的措辞有些混淆。我将在以下段落中尝试澄清我遇到的问题。

首先,请确保您已安装Net::LDAP模块。我通过CPAN安装了Authen::Simple::LDAP,但发现什么都没用。最终我弄清楚,这是因为Authen::Simple::LDAP不需要Net::LDAP模块作为依赖项,但在这里我们的目的需要它。我在CentOS上这样做,似乎Net::LDAP模块可以通过yum安装(yum install perl-LDAP),但Authen::Simple::LDAP必须通过CPAN安装,因为在CentOS存储库中没有它的RPM包。

要使用CPAN安装Authen::Simple::LDAP,请使用以下命令

cpan
cpan> install Authen::Simple::LDAP

如果由于某些依赖项而导致安装失败,请首先解决这些依赖项。

我的第二个观点与下面的Apache配置有关。《PerlLoadModule Authen::Simple::LDAP》实际上不是必需的,以便通过LDAP进行用户认证。如果上述两个模块都已安装,它将自动发生。所以下面的配置片段和上面的配置片段之间实际上没有区别,除了《RedmineCacheCredsMax 50》行之外,这可能是个好主意,尽管它可能导致已从Redmine中删除或移除的用户仍然可以访问存储库,至少在一小段时间内。

   PerlLoadModule Apache::Redmine
   PerlLoadModule  Authen::Simple::LDAP
   # PerlLoadModule  IO::Socket::SSL
   <Location /svn>
     DAV svn
     # If a client tries to svn update which involves updating many files, the
     # update request might result in an error Server sent unexpected return
     # value (413 Request  Entity Too Large) in response to REPORT request,
     # because the size of the update request exceeds the limit allowed by the
     # server. You can avoid this error by disabling the request size limit by
     # adding the line LimitXMLRequestBody 0 between the <Location...> and
     # </Location> lines. 
     LimitXMLRequestBody 0

     # Only check Authentification for root path, nor again for recursive folder
     # Redmine core does only permit acces on repository level, so this doesn't
     # hurt security. On the other hand it does boost performance a lot!
     SVNPathAuthz off

     SVNParentPath "/var/svn" 

     AuthType Basic
     AuthName redmine
     Require valid-user

     PerlAccessHandler Apache::Authn::Redmine::access_handler
     PerlAuthenHandler Apache::Authn::Redmine::authen_handler

     ## for mysql
     RedmineDSN "DBI:mysql:database=databasename;host=my.db.server" 
     ## for postgres
     # RedmineDSN "DBI:Pg:dbname=databasename;host=my.db.server" 

     RedmineDbUser "redmine" 
     RedmineDbPass "password" 
     #Cache the last 50 auth entries
     RedmineCacheCredsMax 50
  </Location>

Git存储库的Apache配置

待办事项:这可能应该移动到如何配置Redmine以进行高级Git集成

现在,由于reposman.rb可以创建git存储库,您可以使用Redmine.pm以与subversion相同的方式访问它们。

您首先需要将Redmine.pm复制或链接到/usr/lib/perl5/Apache/Redmine.pm,然后将其添加到Apache的配置中

PerlLoadModule Apache::Authn::Redmine

SetEnv GIT_PROJECT_ROOT /path/to/git/repos
SetEnv GIT_HTTP_EXPORT_ALL

ScriptAlias /git/ /usr/bin/git-http-backend/

<Location /git>
  AuthType Basic
  Require valid-user
  AuthName "Git" 

  PerlAccessHandler Apache::Authn::Redmine::access_handler
  PerlAuthenHandler Apache::Authn::Redmine::authen_handler

  RedmineDSN "DBI:mysql:database=redmine;host=localhost" 
  RedmineDbUser "redmine" 
  RedmineDbPass "password" 
  RedmineGitSmartHttp yes
</Location>

Alias /git-private /var/git

<Location /git-private>
   Order deny,allow
   Deny from all
   <Limit GET PROPFIND OPTIONS REPORT>
      Options Indexes FollowSymLinks MultiViews
   Allow from 127.0.0.1
   </Limit>
</Location>

要验证您可以通过Redmine.pm访问存储库,您可以使用curl

% curl --netrc --location https:///git/ecookbook/HEAD   
ref: refs/heads/master

Mercurial存储库的Apache配置

待办事项:这可能应该移动到如何配置Redmine以进行高级Mercurial集成

在"hgwebdir.cgi"所在的文件夹中创建一个名为"hgweb.config"的文件。此文件夹将是根存储库文件夹。然后使用类似以下内容编辑"hgweb.config"

[paths]
/=/path/to/root/repository/**

[web]
allow_push = *
allowbz2 = yes
allowgz = yes
allowzip = yes

按照描述安装Redmine.pm并按如下配置Apache。

    RewriteEngine on
    PerlLoadModule Apache2::Redmine
    PerlLoadModule Authen::Simple::LDAP
    ScriptAliasMatch ^/hg(.*)  /path/to/the/hgwebdir.cgi/$1
    <Location /hg>
        AuthType Basic
        AuthName "Mercurial" 
        Require valid-user

        #Redmine auth
        PerlAccessHandler Apache::Authn::Redmine::access_handler
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler
        RedmineDSN "DBI:mysql:database=redmine;host=localhost" 
        RedmineDbUser "DB_USER" 
        RedmineDbPass "DB_PASSWD" 
    </Location>

    # Note: Do not use hg-private as the rewrite rule above will cause strange things to occur.
    Alias /private-hg /path/to/hg/repos

    <Location /private-hg>
        Order deny, allow
        Deny from all
        <Limit GET PROPFIND OPTIONS REPORT>
            Options Indexes FollowSymLinks MultiViews
            Allow from 127.0.0.1
        </Limit>
    </Location>

注意事项

如果您在Phusion Passenger中运行此操作,请确保不要打开PassengerHighPerformance。如果您这样做,将绕过捕获subversion dav的重写,并在日志中记录一些有趣的输出。
示例

ActionController::RoutingError (没有路由匹配"/svn/rm-code" with {:method=>:get})

(如果您的存储库命名为rm-code)

当使用Authen::Simple::LDAP进行认证时,仅拥有管理员角色不足以访问存储库。用户必须拥有允许用户浏览、读取或写入存储库的具体角色。

Jim McAleer 更新 约5年前 · 47次修订