12/16/2017

Git Protocol with Systemd

How to use Git Protocol with Systemd


The documentation from https://git-scm.com/book/gr/v2/Git-on-the-Server-Git-Daemon explains how to execute the git daemon manually and gives an example of an Upstart script to start the daemon. On my Fedora system, I wanted to use Systemd to start this daemon as a service.

I've found the files to make it possible to start the git daemon with Systemd in the /usr/lib/systemd/system directory. They were installed from the git-daemon package. They could be installed with the following command run as root:

# dnf install -y git-daemon

Here's what they look like:

git.socket

[Unit]
Description=Git Activation Socket

[Socket]
ListenStream=9418
Accept=true

[Install]
WantedBy=sockets.target

git@.service

[Unit]
Description=Git Repositories Server Daemon
Documentation=man:git-daemon(1)

[Service]
User=nobody
ExecStart=-/usr/libexec/git-core/git-daemon --base-path=/var/lib/git --export-all --user-path=public_git --syslog --inetd --verbose
StandardInput=socket

Enable and Start git.socket

If you don't need to customize the service, then you can enable it and start it now. Otherwise, you may want to wait until you have customized the git.socket file.

# systemctl enable git.socket --now

Allow Git Home Directory SELinux Access

If getenforce returns either permissive or enforicing, you should enable SELinux to allow access to user home directories if desired by executing:

# setsebool -P git_system_enable_homedirs=true

Verify Listening git.socket

# ss -tlpn '( sport = :9418 )'

State       Recv-Q Send-Q       Local Address:Port                      Peer Address:Port
LISTEN      0      128                     :::9418                                :::*                   users:(("systemd",pid=1,fd=32))


Open Firewall Port

# firewall-cmd --add-port 9418/tcp --permanent
# firewall-cmd --add-port 9418/tcp 

Customizing git@.service

With the --export-all option used in the git@.service file by default, repositories do not even need to contain the magic file daemon-export-ok.

If you have root access, then you can change the git@.service file, but copy it to /etc/systemd/system directory. 

# cp /usr/lib/systemd/system/git@.service /etc/systemd/system

Then, modify the /etc/systemd/system/git@.service file, so your changes will not be overwritten on system package updates.

Here are some things to consider changing:
--base-path to use a different directory instead of /var/lib/git
--user-path to use a different directory instead of public_git for user home directories
--export-all remove to require the daemon-export-ok file before exporting a directory
User=nobody to specify a different user to user to run the service

The User that is specified will need to have permission to access the directories specified with either the --base-path or --user-path options. 

On my system, the repositories that were under the --user-path were failing until I discovered I needed to allow execute(x) access to my home directory. I didn't like the idea of giving that permission to the nobody user, so I added a gitd user:

useradd -r -d /var/lib/git -s /sbin/nologin gitd

Here's my updated /etc/systemd/system/git@.service:

[Unit]
Description=Git Repositories Server Daemon
Documentation=man:git-daemon(1)

[Service]
User=gitd
ExecStart=-/usr/libexec/git-core/git-daemon --base-path=/var/lib/git --user-path=public_git --syslog --inetd --verbose 
StandardInput=socket 
# removed --export-all and changed from nobody to gitd User

Git Repository Sharing

To share the your git repository over your network, you can place it's directory under /var/lib/git. By default, only the root user has permissions to add files in this directory. If you are using SELinux be sure that you copy files or clone them into this location and do not move them there!

As an ordinary user, you would do the following one time:

$ setfacl -m u:nobody:x $HOME # nobody is the User for the service

If you customized the git@.service file, then be sure to use the User specified in that file, such as "gitd" instead of "nobody".

$ mkdir $HOME/public_git # create the directory for --user-path
$ restorecon -Rv $HOME/public_git # if using SELinux

For each repository to share, an ordinary user would do:

$ cd  $HOME/public_git  
$ git clone --bare (repository) (repository).git
$ touch /(repository).git/git-daemon-export-ok # if --export-all

Accessing Remote Repositories

Base Path Repositories (root user)

If the repository is placed in a directory under the --base-path=/var/lib/git such as /var/lib/git/git-new, then it could be cloned remotely by:

git clone git://(host or ip)/git-new


Using tail -f /var/log/messages shows the log from the server 10.0.0.5 when I connected from the client 10.0.0.46:

Dec 16 17:47:32 future audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=git@1-10.0.0.5:9418-10.0.0.46:41646 comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
Dec 16 17:47:32 future git-daemon[25679]: Connection from 10.0.0.46:41646
Dec 16 17:47:32 future git-daemon[25679]: Extended attributes (13 bytes) exist
Dec 16 17:47:32 future git-daemon[25679]: Request upload-pack for '/git-new'

Dec 16 17:47:32 future audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=git@1-10.0.0.5:9418-10.0.0.46:41646 comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'


User Path Repositories (normal user)


If the repository is placed in a directory under the --user-path=public_git such as:

/home/kwright/public_git/simple.git

Then, it could be cloned remotely by one of the following:

git clone git://(host or ip)/~kwright/simple.git

git clone git://future/~kwright/simple.git

git clone git://10.0.0.5/~kwright/simple.git

Notice that the public_git portion of the path must be omitted in the request.
Using tail -f /var/log/messages shows the log from the server 10.0.0.5 when I connected from the client 10.0.0.46:

Dec 16 17:48:31 future audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=git@2-10.0.0.5:9418-10.0.0.46:41634 comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
Dec 16 17:48:31 future git-daemon[25583]: Connection from 10.0.0.46:41634
Dec 16 17:48:31 future git-daemon[25583]: Extended attributes (13 bytes) exist
Dec 16 17:48:31 future systemd[1]: Started Git Repositories Server Daemon (10.0.0.46:41634).
Dec 16 17:48:31 future git-daemon[25583]: Request upload-pack for '~kwright/simple.git'
Dec 16 17:48:31 future git-daemon[25583]: userpath , request <~kwright/simple.git>, namlen 8, restlen 8, slash
Dec 16 17:48:54 future audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=git@2-10.0.0.5:9418-10.0.0.46:41634 comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'



No comments:

About Me - WrightRocket

My photo

I've worked with computers for over 30 years, programming, administering, using and building them from scratch.

I'm an instructor for technical computer courses, an editor and developer of training manuals, and an Android developer.