Running git-daemon under an unprivileged user

Some more notes about the setup I’m following for the vserver (where this blog and xine’s bugtracker’s run, the last one I think was similar, but about awstats. You can see the running thread: running stuff as user rather than root, especially if the user has no access to any particular resource.

So this time my target is git-daemon; I already set it up some time ago to run as nobody (just changed the start-stop-daemon parameters) but there is some problem with that: you either give access to the git repositories to world, or to nobody, which might be used by other services too. Also, there has been a lot of development in git-daemon in the past months, to the point that now it really looks like a proper daemon, included privilege dropping, which makes it very nice with respect to security issues.

So here we go with setting up git-daemon to run as unprivileged user; please note first of all that I’ll also apply along these lines the fix to bug 238351 (git-daemon reported crashed by OpenRC), since I’m doing the same thing locally and it looks quite nicer to do it at once rather than multiple times.

I’m also going to assume a slightly different setup than the one I’m using myself, as it’s the one I’d like to convert soon enough: multi-user setup, with multiple system users (not gitosis-based) being able to publish their GIT repositories. This means that together with a git-daemon user, we’re going to have a git-users group for the users who are able to publish (and thus write to) git repositories:

# useradd -m -d /var/lib/git -s /sbin/nologin git-daemon
# groupadd git-users
# chmod 770 /var/lib/git
# setfacl -d -m u:git-daemon:rx /var/lib/git
# setfacl -m g:git-users:rwx /var/lib/git
# setfacl -d -m:git-users:- /var/lib/git

This way, the users in the git-users group may create subdirectories (and files) in /var/lib/git, but only git-daemon (-and other git-users-) would be able to access them in reading (-the users can then further restrict the access by removing git-users access to their subdirectories, either directly or through a script-; edit: I modified the commands so that other git-users don’t have, by default, access to other users’ subdirectories, they can extend it further). Since most likely you want to provide gitweb (or equivalent) access to the repositories, you might want also to allow your webserver to access that; in my case, gitweb run as the lighttpd user (I haven’t got around to split the various CGIs yet), so I add this:

# setfacl -m u:lighttpd:rx /var/lib/git
# setfacl -d -m u:lighttpd:rx /var/lib/git

This way lighttpd will have access to /var/lib/git and by default to all the subdirectories created.

Now it’s time to set up the init script correctly, since the one that dev-util/git ships at the moment will execute git-daemon only as root. We’re going to change both the start and stop functions, and generically the init script too. The first step is to add a PIDFILE variable outside the functions, we’re going to call it /var/run/git-daemon.pid. The proper fix for the bug linked above allows an override for PIDFILE, but this is not important, to me at least, and should stay only in the official script. Of course /va/rrun is not accessible to the git-daemon user, but this is not the problem; since git-daemon can drop privileges by itself, it will create the pid file beforehand. In my original idea, I was thinking of using start-stop-daemon directly to change the git-daemon user so that it wouldn’t run at root at all, but since the wrapper is mostly a hack, to run as a different user, I decided (for now) to let git-daemon handle its privileges dropping. (It would be nice if some security people assessed what’s the best way to handle this to make it official policy to follow); in that case, a subdirectory to /var/run was needed, since it had to be accessed by an unprivileged user.

After adding the PIDFILE variable, you’ll have to change the invocation of start-stop-daemon; you have to remove the --background option to ssd and replace it with the --detach option to git-daemon itself, and add to the latter also the --pid-file, --user and --group options; you also need to add the --pidfile (look here: no dash!) option to both invocations of ssd (not to the git-daemon parameters!). At that point, just restart git-daemon and you’re done. The final script looks like this:

#!/sbin/runscript
# Copyright 1999-2008 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/dev-util/git/files/git-daemon.initd,v 1.3 2008/09/16 17:52:15 robbat2 Exp $

PIDFILE=/var/run/git-daemon.pid

depend() {
        need net
        use logger
}

start() {
        ebegin "Starting git-daemon"
                start-stop-daemon --start 
                --pidfile ${PIDFILE} 
                --exec /usr/bin/git -- daemon ${GITDAEMON_OPTS} 
                --detach --pid-file=${PIDFILE} 
                --user=git-daemon --group=nogroup
        eend $?
}

stop() {
        ebegin "Stopping git-daemon"
                start-stop-daemon --stop --quiet --name git-daemon 
                --pidfile ${PIDFILE}
        eend $?
}

I also dropped the --quiet option to ssd since I had to look for some error at startup some time ago (I also have –syslog option configured through the conf.d file).

Although most of these changes could be handled by conf.d alone, I think it’d be nice if the default script shipped with dev-util/git included not only the fix for the bug but also the privilege dropping: running git-daemon as root is, in my opinion, craziness.

Exit mobile version