Glen Pitt-Pladdy :: BlogGit on (Smart) HTTP with read/write authentication | |||
Services like GitHub are a no-brainer for many use cases, but I've just hit a situation where I needed a tiny private repo and just can't justify paying for a Private GitHub repo, especially when I've already got a load of web servers with SSL I could use. Another scenario for this would be for very sensitive "internal only" data or systems that are isolated from the Internet. Trouble is, I need my CICD systems to have read-only access, and development user(s) to have full access to checkin new code and I've only been able to find information on separating these when the read-only is public access. That's definitely not what I'm looking for. After a load of reading up on this I've created my own approach on Apache 2.4 on Debian Jessie, but likely to apply similarly to any recent distro. Some good sources of info I've used for this:
Git (bare) repo for HTTPFirst up you need to install the Git package and that contains everything to get started: $ apt-get install git A normal "git init" will create a .git/ in the current directory and that contains all the Git storage for the repo. When serving Git over HTTP you need a bare repo on the server. What this essentially means is that the storage is in the directory, rather than a .git/ directory within that. We'll be using /var/lib/git/ for our HTTP served repos, but you could put them any location that Apache can access. To create a bare repo: # cd /var/lib/git/ That will:
Making available via HTTPAt this point I'm assuming you have Apache 2.4 installed and a basic site configured with SSL and/or any other restrictions you need, but not authentication. At this stage we will just get the repo available via Smart HTTP. To do this we need to add some config variables and an the CGI component of Git used for Smart HTTP to the site config: SetEnv GIT_PROJECT_ROOT /var/lib/git/ This assumes you are serving your repos below /git from your site. Ensure that you've got CGI configured else this won't work. Reload Apache and you should now be able to access the test repo we created: $ git clone https://address.of.your.server/git/test.git If all that is working then we should be ready to add authentication and authorisation. Controlling access (authentication)First off we need to restrict this to authenticated users. We need to create a htpasswd file for this outside of any directories served (it's a security hazard). Let's assume we're putting the file in /etc/apache2/ where other config is. To add the first user (and create the file), say rwuser, use: # cd /etc/apache2/ Now this create a htpasswd-git file with our user in it. After this, don't use the -c option again as wit will create the file again, blowing away any existing users in the file. We can now add authentication to the Apache site config. This could be done either with a <Files> or <Location> directive. I use <Location> which is URL based: SetEnv GIT_PROJECT_ROOT /var/lib/git/ Essentially this just requires an authenticated user in our htpasswd file. After reloading Apache you should now be required to authenticate if you do a remote Git operation against the repo like above. If that's working then we should be ready to selectively restrict access. Controlling access (authorization)The next thing is to add restrictions on write (push) operations to only allow some users. For this we'll use a group file that sets the users that are allowed this access. For this you need to create a file (I use htgroup-git in /etc/apache2/) containing group name gitwrite and a space separated list of write users (for now just the one), something like: gitwrite: rwuser Then we can update the Apache config to start using this: SetEnv GIT_PROJECT_ROOT /var/lib/git/ What this is doing is reading the group file, but only requiring an authenticated user for access. The <If> directive then applies a regex to identify write (push) operations and adds an additional requirement of being in the gitwrite group. Satisfy all simply requires that all the requirements be met for access and is implicit, but I've included it for clarity. To test we should be able to do the Git operations above as user rwuser still, but now need to also have a restricted user, say rouser which we can add with: # cd /etc/apache2/ This user is not in the gitwrite group so should only be able to read (clone, pull), but authentication should fail for write (push) attempts. Test that to ensure that it's working as expected. You can then clean up and add real repos and users as needed. Going FurtherThis is a basic way of controlling access to a bunch of repos, but if you need per-repo access controls or similar then you can extend this by changing the <Location> directives to match specific repos and adding further groups and group requirements for each repo. Another approach would be to add and modify the logic in the <If> directives to match repos, not just operations. Another addition that you might want to consider is gitweb which provides a web repo viewer and in Debian requires little more than installing and enabling the configuration provided with appropriate access restrictions similar to above.
|
|||
Disclaimer: This is a load of random thoughts, ideas and other nonsense and is not intended to be taken seriously. I have no idea what I am doing with most of this so if you are stupid and naive enough to believe any of it, it is your own fault and you can live with the consequences. More importantly this blog may contain substances such as humor which have not yet been approved for human (or machine) consumption and could seriously damage your health if taken seriously. If you still feel the need to litigate (or whatever other legal nonsense people have dreamed up now), then please address all complaints and other stupidity to yourself as you clearly "don't get it".
Copyright Glen Pitt-Pladdy 2008-2023
|
Comments: