5.6 KB


Create a user for managing gitolite-admin

adduser mcfi
su - mcfi

Upload the public key to the server somewhere. It's needed later by gitolite during installation:

scp ... /home/mcfi/.ssh/ ...


Required dependencies

apt-get install gitolite3 apache2 apache2-suexec-pristine libapache2-mod-authnz-external

Gitolite configuration after package installation:

user: gitolite3
home: /var/lib/gitolite3


You can now administer gitolite:

git clone ssh://gitolite3@host:port/gitolite-admin
cd gitolite-admin
vim conf/gitolite.conf

Edit the file like this:

repo gitolite-admin
    RW+ = admin

repo @all
    R = @all

# Add repositories for all the users.
# We need *ALL* repositories to be like <user>/<repo_name>
repo alice/foobar
    RW+    = alice

And push the changes:

git add *
git commit -m "Add some repositories"
git push

Federation actors are also manages using the gitolite-admin repository, so that there is no need to log into the server. MCFI will read the file /var/lib/gitolite3/.gitolite/forgefed/actors that is created when you push the file to the gitolite-admin repo:

cd gitolite-admin
mkdir forgefed
cp <actors-file-from-mcfi-repository> forgefed/


Now we configure gitolite. We want gitolite-shell to be executed as user "gitolite3" and not "www-data". So we create a script to run with suexec:

# The script must be under AP_DOC_ROOT (see /usr/lib/apache2/suexec -V)
mkdir /var/www/mcfi
vim /var/www/mcfi/gitolite-shell-wrapper

Add this content to gitolite-shell-wrapper:

export GIT_PROJECT_ROOT=/var/lib/gitolite3/repositories
export GITOLITE_HTTP_HOME=/var/lib/gitolite3
exec /usr/share/gitolite3/gitolite-shell

Change script rights:

chown -R gitolite3:gitolite3 /var/www/mcfi
chmod -R 0755 /var/www/mcfi

Now we need to add a default anonymous user for unauthenticated "git clone", otherwise gitolite will not allow the operation. Basically when HTTPD did not authenticate the user, the env variable REMOTE_USER is empty, therefore we assign a default username:

vim /var/lib/gitolite3/.gitolite.rc

# Add under the line "rc variables used by various features"
HTTP_ANON_USER => 'unauthenticated',

And we install the post-receive git hook that will be triggered after every push operation. Gitolite docs:

vim /var/lib/gitolite3/.gitolite.rc

# Uncomment this line in the %RC block
LOCAL_CODE => "$ENV{HOME}/local",

mkdir -p /var/lib/gitolite3/local/hooks/common
ln -s /opt/mcfi/git-hooks/post-receive /var/lib/gitolite3/local/hooks/common/post-receive

# This command will create a symbolic link from .git/hooks/post-receive to
# /var/lib/gitolite3/local/hooks/common/post-receive for every existing
# repository. Any new repository will have this created automatically so
# you don't have to run this.
gitolite setup

Make the "actors" file world readable so that HTTPD can read it when authenticating users. If the forgefed directory doesn't exist yet, first create it by pushing to the gitolite-admin repository (see CLIENT section above).

chmod 0755 /var/lib/gitolite3/.gitolite
chmod -R 0755 /var/lib/gitolite3/.gitolite/forgefed

Now we configure HTTPD to serve repositories under http://host/user/repo.git

a2enmod alias cgi env proxy_http suexec authnz_external
vim /etc/apache2/sites-available/mcfi.conf

Add this into mcfi.conf:

<VirtualHost *:80>
  ServerName ...
  CustomLog ${APACHE_LOG_DIR}/access.log combined
  ErrorLog ${APACHE_LOG_DIR}/error.log

  # Run as user gitolite3
  SuexecUserGroup gitolite3 gitolite3

  # Map all "/user/repo.git" URLs to the gitolite shell
  ScriptAliasMatch "^/(.+/.+\.git.*)" /var/www/mcfi/gitolite-shell-wrapper/$1

  # Define a custom authorization provider
  # We could use .htpasswd files but instead we use a custom script so that
  # we use the same users defined as "actors" in the federation server.
  AddExternalAuth mcfi_actors /opt/mcfi/
  SetExternalAuthMethod mcfi_actors pipe

  # Directives for "/user/repo.git" URLs
  # Allow all read requests, ask authorization for write requests
  <LocationMatch "^/.+/.+\.git.*">
    <If "%{QUERY_STRING} =~ /service=git-receive-pack/ || %{REQUEST_URI} =~ /git-receive-pack$/">
      AuthType Basic
      AuthName "Write operation requires login."
      AuthBasicProvider external
      AuthExternal mcfi_actors
      Require valid-user
       Require all granted

  # Directives for every URL that does not match "/user/repo.git"
  # Forward all requests to the MCFI server
  <LocationMatch "^/(?!.+/.+\.git).*">
    ProxyPreserveHost On
    ProxyPassMatch    http://localhost:9000
    ProxyPassReverse  http://localhsot:9000

Restart HTTPD:

# sudo a2dissite 000-default
sudo a2ensite mcfi
sudo service apache2 restart

Now install the mcfi federation following the instruction inside


  • To create a new actor, edit gitolite-admin/forgefed/actors (used by HTTPD authentication and for federation)

  • To create a new repo, edit gitolite-admin/conf/gitolite.conf

  • Useful documentation for smart-http can be found at