Saturday, 9 January 2010

Git Daemon - "who's been sitting on my port?"

Stuck in Germany this weekend by the snow back home, I went into work today (Saturday) to make up some lost time (already!) and get an extra day's billing (yay contracting!!)

I've been doing some work on our SUSE9 servers with the Git DVCS, and I've had no trouble setting up the daemon process which is needed to allow external users access to your shared repositories - just run git daemon --detach and you're pretty much done.

Today I wanted to do the same thing on a SUSE10 server.  I'd had to build Git from source for SUSE9, but the opensuse website provided a pre-built RPM for version 10, which saved some messing around.  Unfortunately it caused some more as well...

The problem I had was that git daemon would run okay on the server, but git clone on the client kept telling me that the remote had closed the connection.  Even plumbing commands like git ls-remote failed.  Very strange.

Rolling up my sleeves, telnet server 9418 showed me that something was listening to the default Git port, but what?

I thought I would get the answer using the netstat program.  I usually run this with the -r (--route) flag to look at the routing table when I'm trying to work out why computers won't talk to each other, but today I used -l (--listening), -t (--tcp) and -p (--program) on the server to see who was listening to which ports.  It was partially successful, because one line identified the local address as *:git, but it listed the program name as "-".  Great - I already knew something was listening to the Git port!  Though it was interesting that the name "git" was listed rather than the port number "9418" as this showed that something had updated /etc/services to list the port name (in hindsight I suspect the RPM installer did it).

Google came to my aid, locating this post about auditing open ports.  The author talked about the netstat command which I already knew about, but also mentioned lsof, which was new to me.  Although the name stands for "list open files" it also list ports that are being listened to.  Piping the output through grep soon showed me that xinetd was listening to the Git port.  QED.  But why?  I hadn't set it up (or so I thought).

On SUSE10, xinetd is initialised from /etc/xinetd.conf which in turn reads all the configuration files in the /etc/xinetd.d directory.  And what should be there but a file called git, telling xinetd to listen to port 9418 and launch the git daemon process to handle requests.  This file was dropped in place by the git-daemon RPM I'd downloaded earlier.  Gotcha!

Not surprisingly the configutation didn't match my needs as it used the --base-path flag to limit the daemon to serving repositories under the /srv/git directory, which didn't exist on my system.  A quick edit with vi to correct the path, followed by service xinetd restart to load the new config, and everything was working.  Job done.

One good thing to come out of this is that I've seen how easy it is to set up git-daemon to run from xinetd, so I'll be able to do this on the SUSE9 machines too rather than messing around with a cron job to start and monitor the process.  This will save me more time than I lost investigating the problem.

No comments:

Post a Comment