Create a user for managing gitolite-admin
adduser mcfi
su - mcfi
ssh-keygen
Upload the public key to the server somewhere. It's needed later by gitolite during installation:
scp ... /home/mcfi/.ssh/id_rsa.pub ...
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:
#!/bin/sh
export GIT_PROJECT_ROOT=/var/lib/gitolite3/repositories
export GIT_HTTP_EXPORT_ALL=
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: https://gitolite.com/gitolite/cookbook.html#adding-other-non-update-hooks
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/webserver_auth.py
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
</If>
<Else>
Require all granted
</Else>
</Location>
# 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
</LocationMatch>
</VirtualHost>
Restart HTTPD:
# sudo a2dissite 000-default
sudo a2ensite mcfi
sudo service apache2 restart
Now install the mcfi federation following the instruction inside README.md
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 https://git-scm.com/docs/git-http-backend