Project

General

Profile

HowTo configure Redmine for advanced git integration » History » Revision 24

Revision 23 (Mr. DTTH, 2013-08-08 05:23) → Revision 24/25 (Vladimir Skubriev, 2013-10-04 08:03)

h1. HowTo configure Redmine for advanced git integration 

 {{>TOC}} 

 h2. Scope 

 _Install on Centos 6.x_ 

 This HowTo explains how to serve git repositories on apache through the http-based "git-smart-http protocol":http://progit.org/2010/03/04/smart-http.html introduced in git 1.6.6.  

 The git-smart-http offers various advantages over ssh or git-based access: you can use redmine access control as-is, no need for extra ssh keys or whatnot, you can secure it through SSL as needed, and there's generally less problems with firewalls and https/https ports than exist with ssh and git ports. git-smart-http also doesn't have some of the drawbacks of its "dumb" predecessor, as it doesn't require any complex DAV setup. 

 This HowTo is mainly written from memory and was conducted on a setup which was already serving [[Repositories_access_control_with_apache_mod_dav_svn_and_mod_perl|svn repositories integrated with redmine]], so it might be possible that I forgot some things or take them for granted.  

 This is a wiki page, feel free to correct or amend anything you find lacking :-) You can also "drop me a line":/users/3866. 

 Another option to integrate grack with redmine is the "modified grack+redmine plugin":http://github.com/friflaj/redmine_grack or "any other grack modified for redmine":http://github.com/search?q=grack&type=Everything&repo=&langOverride=&start_value=1, though those ones lack documentation and I haven't tried them, so I can't say much about those. 

 h2. Prerequisites 

 * Apache with mod_perl (access control) 
 * git (version at least 1.6.6) 
 * A way to serve git-smart-http 
 ** mod_cgi (or mod_cgid) if you want to use the stock "git-http-backend":http://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html 
 ** a rack server if you want to use "grack":http://github.com/schacon/grack (basically a rack wrapper around the right git commands) or 
 "git-webby":http://git.io/BU7twg (another implementation based on grack but written in Sinatra). 

 You should already have a rack server to run redmine, and that's why I chose grack as the backend and which I will describe in this tutorial.  

 Using the stock git-http-backend should be quite straightforward though (skip the [[HowTo_configure_Redmine_for_advanced_git_integration#Install-grack|grack installation]] part and get your install with the git-http-backend going (the "git-http-backend manpage":http://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html has some examples), when that's done go on with the [[HowTo_configure_Redmine_for_advanced_git_integration#Access-control|access control]] part). 

 h2. Install Git 

 <pre><code class="bash"> 
 yum install git 
 </code></pre> 

 h2. Install grack 

 h3. Get the sources 

 Fetch grack from its "github repository":http://github.com/schacon/grack, I checked out mine to @/var/www/grack@ 

 <pre><code class="bash"> 
 cd /var/www 
 git clone http://github.com/schacon/grack.git 
 </code></pre> 

 And create a directory for repositories : 

 <pre><code class="bash"> 
 mkdir /opt/repositories 
 mkdir /opt/repositories/git 
 chown -R apache:apache /opt/repositories/git 
 </code></pre> 

 

 h3. Configuration 

 Edit the @config.ru@ file and adapt it to your local configuration. @project_root@ must contain the path to the directory containing your git repositories, @git_path@ must obviously contain the path to the git, mine looks like this (on gentoo): 

 <pre><code class="bash"> 
 vi /var/www/grack/config.ru 
 </code></pre> 

 And edit file : 

 <pre><code class="ruby">$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/lib') 

 use Rack::ShowExceptions 

 require 'grack' 

 require 'git_adapter' 

 config = { 
   :project_root => "/opt/repositories/git", 
   :git_path => '/usr/bin/git', 
   :upload_pack => true, 
   :receive_pack => true, 
 } 

 run GitHttp::App.new(config) 
 </code></pre> 

 If you use the latest version of grack, then may be this config.ru file is usable 


 <pre><code class="ruby"> 

 $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/lib') 

 use Rack::ShowExceptions 

 require 'grack' 

 require 'git_adapter' 

 config = { 
   :project_root => "/opt/repositories/git", 
   :git_path => '/usr/bin/git', 
   :upload_pack => true, 
   :receive_pack => true, 
   :adapter => Grack::GitAdapter, 
 } 

 run Grack::App.new(config) 

 </code></pre> 

 h3. Integrate with Apache 

 You could obviously use any rack server you like at this point, but the access control mechanism @Redmine.pm@ is written for apache with mod_perl, so you will at least need to reverse proxy your rack server through apache.  

 My rack server of choice is "passenger":http://modrails.com/ (solid performance, apache module, mostly simple configuration) and it is already configured on my system.  

 As passenger installation and configuration is not within the scope of this HowTo, please refer to the "passenger documentation":http://modrails.com/documentation.html or to the passenger installation guide from your distribution. 

 There's a little more work to do here to get passenger to work with this, you will need to create the directories @public@ and @tmp@ in the grack directory.  

 Please also be aware that in the standard configuration, passenger will run the grack application with the same user and group owning the @config.ru@ file. This user must have read- and write-access as needed to the git repositories! 

 Create directories 'public' and 'tmp' in /var/www/grack for apache : 

 <pre><code class="bash"> 
 cd /var/www/grack 
 mkdir public 
 mkdir tmp 
 chown -R apache:apache /var/www/grack 
 </code></pre> 

 Edit config file "/etc/httpd/conf/httpd.conf" for support multi virtualhost by remove comment : 

 <pre><code class="bash"> 
 NameVirtualHost *:80 
 </code></pre> 

 Create a file virtualhost : 

 <pre><code class="bash"> 
 vi /etc/httpd/conf.d/git.conf 
 </code></pre> 

 with text : 

 <pre><code class="apache"> 
 <VirtualHost *:80> 
     ServerName git.yourdomain.com 
     DocumentRoot "/var/www/grack/public" 
     <Directory "/var/www/grack/public"> 
         Options None 
         AllowOverride None 
         <IfVersion < 2.3 > 
         Order allow,deny 
         Allow from all 
         </IfVersion> 
         <IfVersion >= 2.3> 
         Require all granted 
         </IfVersion> 
      </Directory> 
  </VirtualHost> 
 </code></pre> 

 In controlpanel DNS record at domain name page, create a subdomain with name "git.yourdomain.com" and point to your IP server. 

 At this point, if you have a repository in "/opt/repositories/git/myrepo", you should be able to access it through "http://git.yourdomain.com/myrepo", for example : 

 Use a git client as Gitbash or TortoiseGit to clone repos : 

 <pre><code class="apache"> 
 git clone http://git.yourdomain.com/myrepo 
 </code></pre> 

 If it successful, git on server and connection is very good! 

 h2. Access control 

 You now have a working git server, albeit with no access control. Currently, the shipped perl module for access control @Redmine.pm@ (in @extra/svn/@ in your redmine directory) does not support access control for the git-smart-http protocol, the patch in #4905 aims to implement that. 

 h3. Applying the patch 

 _If you are using Redmine >= 2.1.0, step over to Configuring Apache_ 

 Download the latest (or better: correct) version of the patch from #4905 to your redmine directory. In the redmine directory, apply the patch: @patch -p1 < the-patch-file.patch@ should work (if it tells you stuff about being unable to apply a hunk, the patch is incompatible with your @Redmine.pm@ version, if it says other stuff, try @patch -p0 < the-patch-file.patch@ or @patch Redmine.pm < the-patch-file.patch@, if it still borks, ask for advice on #4905). 

 -You will possibly still need to edit the file from here, because the current version of the patch only works for repositories served from @http://git.myhost.com/git/myrepo@ though the above example uses @http://git.myhost.com/myrepo@.- This step isn't needed anymore, the patch has been updated to take the information from the @Location@ block from apache into account. 

 h3. Configuring Apache 

 You now have to make Apache aware of your new authentication module (if you already had done this step for subversion integration, you can go to the @Location@ directives directly).  

 Copy or link @Redmine.pm@ (from your @extra/svn/@ directory) to @/usr/lib/perl5/Apache/Redmine.pm@ (ubuntu) or wherever your distribution puts its apache perl modules (e.g. gentoo puts them in @/usr/lib64/perl5/vendor_perl/5.8.8/Apache/@, fedora puts them in @/usr/lib64/perl5/vendor_perl/Apache/@). 

 Having done that, reload apache to make sure everything in the patching phase went well (if not, remove the link or the file create in the step just before and restart apache to get apache back up, try to find the error in your Redmine.pm file). Now edit your vhost configuration to look somewhat like (same as above but with more stuff): 

 <pre><code class="bash"> 
 vi /etc/httpd/conf.d/git.conf 
 </code></pre> 

 with : 

 <pre><code class="bash"> 

 <VirtualHost *:80> 

     ServerName git.yourdomain.com 

     DocumentRoot "/var/www/grack/public" 

     <Directory "/var/www/grack/public"> 

         Options None 

         AllowOverride None 

         <IfVersion < 2.3 > 

         Order allow,deny 

         Allow from all 

         </IfVersion> 

         <IfVersion >= 2.3> 

         Require all granted 

         </IfVersion> 

      </Directory> 

      PerlLoadModule Apache::Redmine 
     <Directory "/var/www/grack/public"> 

         Options None 

         AllowOverride None 

         <IfVersion < 2.3 > 

         Order allow,deny 

         Allow from all 

         </IfVersion> 

         <IfVersion >= 2.3> 

         Require all granted 

         </IfVersion> 

      </Directory> 

     
      <Location "/"> 

        AuthType Basic 

        AuthName "Redmine git repositories" 

        Require valid-user 

        PerlAccessHandler Apache::Authn::Redmine::access_handler 
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler 
   
        RedmineDSN "DBI:mysql:database=your_database;host=localhost:3306" 

        RedmineDbUser "user_database" 
        RedmineDbPass "password_database"        
        RedmineGitSmartHttp yes 
      </Location> 

  </VirtualHost> 
 </code></pre> 

 Restart your apache, and everything should be good and well :-) 

 h2. Known issues 

 If you are using the stock git-http-backend directly under apache and you are finding errors like "Request not supported: '/git/your-git-repo'" in your apache error log, you may need to add "SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER" to the to the list of environment variables that you are setting in your apache configuration.   

 Unfortionately, this setting may cause redmine to borke.    If so, you will need to set the variable for only the requests that are passed through git-http-backend.    One way to accomplish this is with mod_rewrite.    Below is a sample apache configuration from a Fedora 17 system that uses git-http-backend and mod_rewrite. 

 In httpd.conf: 

 <pre><code class="apache">Listen xxx.xxx.xxx.xxx:80 
 <VirtualHost xxx.xxx.xxx.xxx:80> 
    DocumentRoot /var/www/redmine/public 
    ServerName servername.domain:80 
    Include conf/servername.conf 
 </VirtualHost> 

 Listen xxx.xxx.xxx.xxx:443 
 <VirtualHost xxx.xxx.xxx.xxx:443> 
    DocumentRoot /var/www/redmine/public 
    ServerName servername.domain:443 
    Include conf/servername.conf 
    Include conf/ssl.conf 
 </VirtualHost></code></pre> 

 In servername.conf: 

 <pre><code class="apache">PerlLoadModule Apache::Authn::Redmine 

 SetEnv GIT_PROJECT_ROOT /git-1/repositories 
 SetEnv GIT_HTTP_EXPORT_ALL 

 <IfModule mod_rewrite.c> 
    RewriteEngine On 

    RewriteCond %{HTTPS} ^off$ 
    RewriteCond %{REQUEST_URI} !^/git-private/ 
    RewriteRule ^.*$ https://servername.domain$0 [R=301,L] 
    RewriteRule ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /git-1/repositories/$1 [L] 
    RewriteRule ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /git-1/repositories/$1 [L] 
    RewriteRule ^/git/(.*)$ /usr/libexec/git-core/git-http-backend/$1 [E=REMOTE_USER:$REDIRECT_REMOTE_USER,H=cgi-script,L] 
 </IfModule> 

 <Directory /usr/libexec/git-core> 
    <Files "git-http-backend"> 
       Options +ExecCGI 
    </Files> 
 </Directory> 

 <Location /git> 
    AuthType Basic 
    AuthName "CAMPUS" 
    AuthBasicProvider external 
    AuthExternal pwauth 
    Require valid-user 

    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 /git-1/repositories 

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

 <Directory "/var/www/redmine/public"> 
    RailsEnv production 
    RailsBaseURI / 

    Options -MultiViews 
    AllowOverride All 
 </Directory></code></pre> 

 In conf/ssl.conf: 

 <pre><code class="apache">LogLevel warn 
 SSLEngine on 
 SSLProtocol all -SSLv2 
 SSLCipherSuite RC4-SHA:AES128-SHA:ALL:!ADH:!EXP:!LOW:!MD5:!SSLV2:!NULL 
 SSLCertificateFile /etc/pki/tls/certs/your-server.crt 
 SSLCertificateKeyFile /etc/pki/tls/private/your-server.key 
 SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt 
 SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt 

 <Files ~ "\.(cgi|shtml|phtml|php3?)$"> 
     SSLOptions +StdEnvVars 
 </Files> 
 <Directory "/var/www/cgi-bin"> 
     SSLOptions +StdEnvVars 
 </Directory> 

 SetEnvIf User-Agent ".*MSIE.*" \ 
          nokeepalive ssl-unclean-shutdown \ 
          downgrade-1.0 force-response-1.0 
 </code></pre> 

 In conf.d/ssl.conf: 

 <pre><code class="apache">LoadModule ssl_module modules/mod_ssl.so 
 SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog 
 SSLSessionCache           shmcb:/var/cache/mod_ssl/scache(512000) 
 SSLSessionCacheTimeout    300 
 SSLMutex default 
 SSLRandomSeed startup file:/dev/urandom    256 
 SSLRandomSeed connect builtin 
 SSLCryptoDevice builtin 
 </code></pre> 

 You will also need to have the perl modules Net::LDAP, Authen::Simple, and Authen::Simple::LDAP installed.    The first two are available in Fedora's default package repositories.   

 The third must be installed after the other two and it must be obtained directly from cpan.    Below are the commands that I used to install these packages on Fedora 17. 

 yum -y install gcc make perl-LDAP perl-Authen-Simple 
 cpan 
 cpan> install Authen::Simple::LDAP