Ubuntu – Using a non-root to deploy a git repo to the web root

apache-2.2gitpermissionssudoUbuntu

What is the best way to set up users and permissions for a production web server that uses git to deploy to the server?

Background

Running Ubuntu 12.04, I have apache serving files under /var/www as www-data. I also had a bare git repo under the root users directory that would checkout to /var/www/example.com in the post-receive hook.

This worked fine, but considering it's a production server, I wanted to button up some security and remove the repo from the root user. So I created a git user and set up the repo under /home/git. But now I have permissions issues over the fact that one user owns the repo while another user owns the web root.

I've read many forums and tutorials online. Most seem to just use the root user, others seem to have worse security issues (such as giving www-data read permissions over the repo). I'm looking for insights from real-world experience because there are many ways this could be done.

As a note, the post-receive hook does more than checkout. It also performs some build processes such as running Composer and some other php scripts that can take several minutes.

I have tried several solutions:

I tried adding the git user to the www-data group, then chowning the web root back to www-data at the end of the hook. This has two issues. First, I have to modify the sudoers file, and the results I get from that are hit and miss. Second, during those several minutes while the hook is running, the checked-out files are owned by git, not www-data, so users on the site might get read errors.

I tried putting the contents of the post-receive in another file, and executing it with sudo. Again, this requires editing the sudoers files, so that the git user can sudo without a password.

Or it could be that leaving the repo under the root user is the lesser evil and I'm doing all this for nothing.

Is there a better solution that I haven't tried?

Best Answer

Create a new group, and add the git and www-data user into it. Then setup your bare Git repository to always use the group you created as the gid for the repository files. With a new bare repository you do this with git init --shared=group. (Ref) This will permit the www-data account to read the repository.

Update your sudoers to permit the git account to run commands as www-data without a password.

# file: /etc/sudoers.d/gitpush
# permissions should be 0440
# git user is allowed to basically do anything as the www-data user
git ALL=(www-data) NOPASSWD: ALL

Then simply have your post-receive script sudo -u www-data for all the commands needed to perform the check/fixes.