{"id":854,"date":"2011-08-06T23:40:47","date_gmt":"2011-08-06T21:40:47","guid":{"rendered":"https:\/\/brakkee.org\/site\/?p=854"},"modified":"2011-08-06T23:40:47","modified_gmt":"2011-08-06T21:40:47","slug":"git-server-setup-on-linux-using-smart-http","status":"publish","type":"post","link":"https:\/\/brakkee.org\/site\/2011\/08\/06\/git-server-setup-on-linux-using-smart-http\/","title":{"rendered":"Git server setup on linux using smart HTTP"},"content":{"rendered":"<p>After seeing a <a title=\"Git presentation from Linus\" href=\"http:\/\/www.youtube.com\/watch?v=4XpnKHJAok8\">presentation from Linus Torvalds<\/a> I decided to read more about git. After looking into git more a I have decided to slowly move to git. New projects will be using git instead of subversion and I will move some existing projects over to git when I get the chance.<\/p>\n<p>The first question that arises in such a case is how to deploy it. Of course, there are free solutions available such as github, but this some disadvantages for me. First of all, the access will be slower compared to a solution that I host at home, and second, I also have private repositories and these are really private so I really don&#8217;t want them to be hosted on github (even if github protects the data). Apart from this, the distributed nature of git would allow me anyway to easily put source code for an open source project on github, should one of my projects ever become popular.<\/p>\n<p>So the question remains on how to host it at home. Of course, I have <a title=\"wamblee.org lan\" href=\"https:\/\/brakkee.org\/site\/2011\/02\/20\/kvm-setup-overview\/\">my current infrastructure<\/a> already consisting of a linux server running apache. Looking at the options for exposing GIT, there are several solutions:<\/p>\n<table>\n<tbody>\n<tr>\n<td>Alternative<\/td>\n<td>Pros<\/td>\n<td>Cons<\/td>\n<\/tr>\n<tr>\n<td><b>ssh<\/b> <br \/>\nRemote access through ssh.<\/td>\n<td>\n<ul>\n<li>Zero setup time because ssh is already running<\/li>\n<\/ul>\n<\/td>\n<td>\n<ul>\n<li>requires complete trust of a client. Possible version incompatibilities.<\/li>\n<li>requires a system account for every user and additional configuration to prevent logins and other types of access.<\/li>\n<li>(corporate) firewalls can block SSH making it inaccessible from there.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td><b>apache webdav<\/b><br \/>\nremote access through apache using webdav<\/td>\n<td>\n<ul>\n<li>easy to setup, simple apache configuration<\/li>\n<li>uses proven apache stability and security<\/li>\n<\/ul>\n<\/td>\n<td>\n<ul>\n<li>additional configuration required in git to make this work (git update-server-info).<\/li>\n<li>requires complete trust of a client, same risk with version incompatibilities<\/li>\n<li>definite performance impact.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td><b>apache smart http<\/b><br \/>\nremote access using apache with CGI based solution (basically using HTTP as transport for git).<\/td>\n<td>\n<ul>\n<li>easy to setup<\/li>\n<li>uses proven apache stability and security<\/li>\n<li>does not require trusting a particular client<\/li>\n<\/ul>\n<\/td>\n<td>\n<ul>\n<li>some overhead of HTTP (alhough much less than with webdav)<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td><b>git native<\/b><\/td>\n<td>\n<ul>\n<li>doesn&#8217;t require trusting a client.<\/li>\n<li>most efficient solution<\/li>\n<\/ul>\n<\/td>\n<td>\n<ul>\n<li> does not easily pass through firewalls<\/li>\n<li>server code maturity<\/li>\n<li>lack of authentication.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In the above table, the phrase &#8220;trusting a client&#8221; means trusting the client software. Allowing a client full control over the modification of the repository files is risky. There could be clients with bugs or clients using different versions of git and there could even be malicious clients that could corrupt a repository. This risk is not present with the native git and smart http approaches.<\/p>\n<p>As is clear from the above, ssh is the most problematic of all. On the other end, git is the most efficient but lacks the requires security and requires me to open up yet another port on the firewall and run yet another service. Because of these reasons I decided on an HTTP based setup. In fact, I experimented early on with the webdav based approach simply because I didn&#8217;t find the <a title=\"smart http\" href=\"http:\/\/progit.org\/2010\/03\/04\/smart-http.html\">smart http<\/a> approach which is relatively new. The setup however did show that HTTP webdav is much slower than the smart http setup. In fact, I think smart http is also faster than subversion when pushing changes.<\/p>\n<p>The setup of smart HTTP is quite easy, basically it is a CGI based approach where HTTP requests are delegated to a CGI helper program which does the work. In effect, this is the git protocol over HTTP. Standard apache features are used to implement authentication and authorization. The smart HTTP approach is described already quite well <a title=\"smart http\" href=\"http:\/\/progit.org\/2010\/03\/04\/smart-http.html\">here<\/a> and <a title=\"git-http-backend\" href=\"http:\/\/www.kernel.org\/pub\/software\/scm\/git\/docs\/git-http-backend.html\">here<\/a>, but I encountered some issues and would like to clarify what I did to get it working.<\/p>\n<p>These are the steps I took to get it working on opensuse 11.3:<\/p>\n<ul>\n<li>Setup the user accounts and groups that you need to authenticate against using htpasswd and put it in a file \/etc\/apache2\/conf.d\/git.passwd<\/li>\n<li>Make sure that the cgi, alias, and env modules are enabled by checking the APACHE_MODULES setting in \/etc\/sysconfig\/apache2.<\/li>\n<li>Now we are going to edit the apache configuration file for the (virtual) domain we are using. In this example, I assume we have \/data\/git\/public hosting public repositories (anonymous read and authenticated write) and \/data\/git\/private hosting private repositories (authenticated read and write). Also the git repositories are going to be exposed under a \/git context root.\n<ul>\n<li>by default export all repositories that are found\n<pre>SetEnv GIT_HTTP_EXPORT_ALL<\/pre>\n<p>This can also be configured on a per repository basis, see the git-http-backend page for details.<\/li>\n<li> Configure the CGI program used to handle requests for git.\n<pre>ScriptAlias \/git\/ \/usr\/lib\/git\/git-http-backend\/<\/pre>\n<p>This directive had me quite puzzled because the apache documentation mentions that the second ScriptAlias argument should be a directory, but in this case it is an executable and it works.<\/li>\n<li> Set the root directory where git repositories reside\n<pre>SetEnv GIT_PROJECT_ROOT \/data\/git<\/pre>\n<\/li>\n<li> By default, the git-http-backend allows push for authenticated<br \/>\nusers and this directive tells the backend when a user is authenticated. <\/p>\n<pre>SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER<\/pre>\n<p>I had to google a lot to find this one because it is not mentioned in the documentation. Without this, I had to configure &#8220;http.receivepack&#8221; to &#8220;true&#8221; for every repository to allow &#8220;git push&#8221;. <\/li>\n<li> General CGI configuration allowing the execution of the CGI programs. This is more or less self explanatory\n<pre>&lt;Directory \"\/usr\/lib\/git\/\"&gt;\n\u00a0\u00a0AllowOverride None\n\u00a0\u00a0Options +ExecCGI -Includes\n\u00a0\u00a0Order allow,deny\n\u00a0\u00a0Allow from all\n&lt;\/Directory&gt;<\/pre>\n<\/li>\n<li> Next is the configuration of the public repositories\n<pre>&lt;LocationMatch \"^\/git\/public\/.*\/git-receive-pack$\"&gt;\n\u00a0\u00a0AuthType Basic\n\u00a0\u00a0AuthName \"Public Git Repositories on wamblee.org\"\n\u00a0\u00a0AuthUserFile \/etc\/apache2\/conf.d\/git.passwd\n\u00a0\u00a0Require valid-user\n&lt;\/LocationMatch&gt;<\/pre>\n<p>This requires an authenticated user for every push request. See the <a href=\"http:\/\/httpd.apache.org\/docs\/2.2\/howto\/auth.html\">apache documentation<\/a> for the various options such as requiring the user to belong to a group. In my setup, I simply use one global git.passwd file and any authenticated user has access to any repository.<\/li>\n<li> Finally, there is the setup of the private repositories, which requires a valid user for any URL.\n<pre>\n&lt;LocationMatch \"^\/git\/private\/.*$\"&gt;\n  AuthType Basic\n\u00a0\u00a0AuthName \"Private Git Repositories on wamblee.org\"\n\u00a0\u00a0AuthUserFile \/etc\/apache2\/conf.d\/git.passwd\n\u00a0\u00a0Require valid-user\n&lt;\/LocationMatch&gt;<\/pre>\n<p>   In this case I could have also used a &#8220;Location&#8221; element instead of &#8220;LocationMatch&#8221;.\n<\/li>\n<li> Finally restart apache using\n<pre>\/etc\/init.d\/apache restart<\/pre>\n<p> or (&#8220;force-reload&#8221;) and try it out.\n        <\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Hope this helps others setting up their git servers on linux. In my experience this setup is quite fast for both push and pull. I am currently working on one project that you can access by doing <\/p>\n<pre>\n  git clone https:\/\/wamblee.org\/git\/public\/xmlrouter\n<\/pre>\n<p>A gitweb interface for browsing the public repositories is <a href=\"http:\/\/wamblee.org\/gitweb\">here<\/a>.<\/p>\n<p>Have a lot of fun!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After seeing a presentation from Linus Torvalds I decided to read more about git. After looking into git more a I have decided to slowly move to git. New projects will be using git instead of subversion and I will &hellip; <a href=\"https:\/\/brakkee.org\/site\/2011\/08\/06\/git-server-setup-on-linux-using-smart-http\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[10],"tags":[],"_links":{"self":[{"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/posts\/854"}],"collection":[{"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/comments?post=854"}],"version-history":[{"count":0,"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/posts\/854\/revisions"}],"wp:attachment":[{"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/media?parent=854"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/categories?post=854"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/brakkee.org\/site\/wp-json\/wp\/v2\/tags?post=854"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}