GIT

From Unix Wiki
Jump to: navigation, search

GIT + LDAP + AUTHORIZATION

This article will describe how to install GIT repository with LDAP authentication and per user/group authorization.

What you need?

  • Linux server/VM;
  • Running Apache instance;
  • gitolite tools;

gitolite

gitolite is a perl script utilities which provides authorization while accessing GIT repository.

Administration of gitolite and git repositories done using special git repo called 'gitolite-admin' and file 'conf/gitolite.conf'. More info about gitolite can be found here.

Apache

Apache will serve as connector between gitolite (git server) and git client. Apache will also provide LDAP authentication mechanism.

gitweb

Gitweb will provide read-only access to our repos. Gitweb will be working with gitolite to provide user authorization.

Configurations

Following section contains stable working configuration files.

gitolite

Configuration instructions can be found here.

# git clone git://github.com/sitaramc/gitolite
# cat gitolite/t/smart-http.root-setup 
#!/bin/bash

# ----------------------------------------------------------------------
# please do not even LOOK at this file without reading doc/http.mkd
# ----------------------------------------------------------------------

die() { echo "$@"; exit 1; }

# scare the sh*t out of people who run it blindly
[ -f /tmp/gitolite-smart-http-test-OK ] || {
    # scary message
    echo '+ rm -rf /'
    # lots of disk activity
    find / >/dev/null 2>/dev/null
    # and it he's still clueless, God bless!
    echo 'root file system erased successfully.  Goodbye and God bless!'
    exit 1
}

id | grep '=0(root)' || die "you must run this as root"

# delete any existing apache conf for gitolite
rm /etc/httpd/conf.d/gitolite.conf

# build your "home within a home"
#cd ~apache
cd /u01
rm -rf gitolite-home
mkdir gitolite-home
export GITOLITE_HTTP_HOME=$PWD/gitolite-home

# get the gitolite sources
cd gitolite-home
#git clone /tmp/gitolite.git gitolite-source
# NOTE: I use a bare repo in /tmp for convenience; you'd use
# 'git://github.com/sitaramc/gitolite'
git clone git://github.com/sitaramc/gitolite gitolite-source

# make the bin directory, and add it to PATH
cd gitolite-source
mkdir         $GITOLITE_HTTP_HOME/bin
./install -ln $GITOLITE_HTTP_HOME/bin
export PATH=$PATH:$GITOLITE_HTTP_HOME/bin

# come back to base, then run setup.  Notice that you have to point HOME to
# the right place, even if it is just for this command
cd $GITOLITE_HTTP_HOME
HOME=$GITOLITE_HTTP_HOME gitolite setup -a admin

# insert some essential lines at the beginning of the rc file
echo '$ENV{PATH} .= ":$ENV{GITOLITE_HTTP_HOME}/bin";'  >> 1
echo >> 1
cat .gitolite.rc >> 1
\mv 1 .gitolite.rc

# fix up ownership
chown -R apache.apache $GITOLITE_HTTP_HOME

# create the apache config.  Note the trailing slashes on the 2 ScriptAlias
# lines.  (The second one is optional for most sites).  NOTE: you also need to
# give the AuthUserFile a better name/location than what I have below.
cat <<EOF1 > /etc/httpd/conf.d/gitolite.conf
SetEnv GIT_PROJECT_ROOT $GITOLITE_HTTP_HOME/repositories
ScriptAlias /git/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/
ScriptAlias /gitmob/ $GITOLITE_HTTP_HOME/gitolite-source/src/gitolite-shell/
SetEnv GITOLITE_HTTP_HOME $GITOLITE_HTTP_HOME
SetEnv GIT_HTTP_EXPORT_ALL

<Location /git>
  AuthType Basic
  AuthName "Private Git Access"
  AuthBasicProvider ldap
  AuthzLDAPAuthoritative on
  AuthLDAPGroupAttribute memberUid
  AuthLDAPGroupAttributeIsDN off
  AuthLDAPURL "ldap://ldap.example.com:389/dc=zuzex,dc=lan?uid?
  Require valid-user
  Order allow,deny
  Allow from all
</Location>
EOF1

# NOTE: this is for testing only
#htpasswd -bc $GITOLITE_HTTP_HOME/gitolite-http-authuserfile admin admin
#map "htpasswd -b $GITOLITE_HTTP_HOME/gitolite-http-authuserfile % %" u{1..6}
#chown apache.apache $GITOLITE_HTTP_HOME/gitolite-http-authuserfile

# restart httpd to make it pick up all the new stuff
service httpd restart

gitweb

# cat /etc/httpd/conf.d/git.conf
Alias /gitweb /var/www/git

<Directory /var/www/git>
  SSLRequireSSL
  Options +ExecCGI
  AddHandler cgi-script .cgi
  DirectoryIndex gitweb.cgi
  AuthType Basic
  AuthName "Private Git Access"
  AuthBasicProvider ldap
  AuthzLDAPAuthoritative on
  AuthLDAPGroupAttribute memberUid
  AuthLDAPGroupAttributeIsDN off
  AuthLDAPURL "ldap://ldap.zuzex.lan:389/dc=zuzex,dc=lan?uid?
  Require valid-user
  Order allow,deny
  Allow from all
</Directory>

Reference for integration gitweb to gitolite can be found here:

# cat /etc/gitweb.conf 
# The gitweb config file is a fragment of perl code. You can set variables
# using "our $variable = value"; text from "#" character until the end of a
# line is ignored. See perlsyn(1) man page for details.
#
# See /usr/share/doc/gitweb-*/README and /usr/share/doc/gitweb-*/INSTALL for
# more details and available configuration variables.

# Set the path to git projects.  This is an absolute filesystem path which will
# be prepended to the project path.
#our $projectroot = "/u01/gitolite-home/repositories";

# Set the list of git base URLs used for URL to where fetch project from, i.e.
# the full URL is "$git_base_url/$project". By default this is empty
#our @git_base_url_list = qw(git://git.example.com
#                            ssh://git.example.com/var/lib/git);

# Enable the 'blame' blob view, showing the last commit that modified
# each line in the file. This can be very CPU-intensive. Disabled by default
#$feature{'blame'}{'default'} = [1];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.blame = 0|1;
#$feature{'blame'}{'override'} = 1;

# Disable the 'snapshot' link, providing a compressed archive of any tree. This
# can potentially generate high traffic if you have large project. Enabled for
# .tar.gz snapshots by default.
#
# Value is a list of formats defined in %known_snapshot_formats that you wish
# to offer.
#$feature{'snapshot'}{'default'} = [];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.snapshot = tbz2,zip; (use "none" to disable)
#$feature{'snapshot'}{'override'} = 1;

# Disable grep search, which will list the files in currently selected tree
# containing the given string. This can be potentially CPU-intensive, of
# course. Enabled by default.
#$feature{'grep'}{'default'} = [0];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.grep = 0|1;
#$feature{'grep'}{'override'} = 1;

# Disable the pickaxe search, which will list the commits that modified a given
# string in a file. This can be practical and quite faster alternative to
# 'blame', but still potentially CPU-intensive. Enabled by default.
#$feature{'pickaxe'}{'default'} = [0];
#
# Allow projects to override the default setting via git config file.
# Example: gitweb.pickaxe = 0|1;
#$feature{'pickaxe'}{'override'} = 1;


################################################################################
# HOME of the gitolite user
my $gl_home = $ENV{HOME} = "/u01/gitolite-home";

my $gl_hosting_user = "apache";
#my $gl_host = $cgi->server_name || "git.example.com";

# Your server hostname and port (if not 80 for http or 443 for https).
# Replace http for https if necessary.
#$my_uri = "https://$gl_host/gitweb";

# the following variables are needed by gitolite; please edit before using
# this should normally not be anything else
$ENV{GL_RC} = "$gl_home/.gitolite.rc";

# this can have different values depending on how you installed.
# if you used RPM/DEB or "root" methods it **might** be this:
#$ENV{GL_BINDIR} = "/usr/local/bin";
# if you used the "non-root" method it **might** be this:
$ENV{GL_BINDIR} = "$gl_home/bin";

# If in doubt take a look at ~/.ssh/authorized_keys; at least one of the lines
# might contain something like:
# command="/home/git/.gitolite/src/gl-auth-command
# and you should use whatever directory the gl-auth-command is in (in this
# example /home/git/.gitolite.src)

# finally the user name
$ENV{GL_USER} = $cgi->remote_user || "apache";

# now get gitolite stuff in...
BEGIN { $ENV{HOME} = "/u01/gitolite-home"; }

use lib "/u01/gitolite-home/gitolite-source/src/lib";
use Gitolite::Easy;

# set project root etc. absolute paths
$REPO_BASE ||= $ENV{GL_REPO_BASE};
$ENV{GL_REPO_BASE_ABS} = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$gl_home/$REPO_BASE" );
$projects_list = $projectroot = $ENV{GL_REPO_BASE_ABS};
 

$export_auth_hook = sub {
my $repo = shift;

# gitweb passes us the full repo path; so we strip the beginning
# and the end, to get the repo name as it is specified in gitolite conf
return unless $repo =~ s/^\Q$projectroot\E\/?(.+)\.git$/$1/;

# check for (at least) "R" permission
return (can_read($repo));
};

Apache

To secure git server you need to configure Apache to server only as https server.

index.html

Redirect from / to /gitweb.

# cat /var/www/html/index.html 
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script>
            location.href = '/gitweb';
        </script>
    </head>
    <body>
    </body>
</html>

GIT troubleshooting

Error:

error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:reason(1112)

Such error happens when git client uses libcurl compiled against openssl 0.9.X and server side uses openssl > 1.0.X.

Solution: replace libcurl with version compiled against openssl > 1.0.X. Check out cURL download page