aboutsummaryrefslogtreecommitdiffstats
path: root/posts/git_server_centos.md
blob: 7be21bd2442c9fac18b4afced28d20616535a5b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
---
title: Running a Git server on CentOS
published: 2018-05-24
modified: 2019-08-08
---

This should really be easier. I guess that is why so many software exists to 
make this "work", adding more bloat in the process. So, I spent some time using
only the basic tools to make hosting your own Git repositories work.

All software is available in the default repository or EPEL. Everything should
also work in Fedora.

We'll be using:

* [git](https://git-scm.com/)
* [cgit](https://git.zx2c4.com/cgit/about/)

The features that should work:

* work over SSH (clone, push)
* work with SELinux
* work over HTTPS (clone)
* able to fetch an archive pointing to a specific commit

### Installation

Make sure you have the EPEL repository enabled:

    $ sudo yum -y install epel-release

Install the software:

    $ sudo yum -y install git \
        cgit \
        python36-pygments \
        python36-markdown \
        highlight

The Python components are required to convert markdown files to HTML, i.e. the
README.md file with the `about-filter` option. The `highlight` is for syntax 
hightlighting, the `source-filter` option. If you are not interested in either
of that you can leave those dependencies out.

### Configuration

Add `git-shell` to list of shells:

    $ echo '/bin/git-shell' | sudo tee -a /etc/shells

Add system user `git`, but leave the default shell for now:

    $ sudo adduser git -m -r -d /var/lib/git

We'll switch to the `git` user to perform the following steps:

    $ sudo -i -u git

The following commands are run as the `git` user in the directory 
`/var/lib/git`, you should be put in the directory automatically because of the
`-i` flag.

Now create the SSH directory to configure the public key(s) that have access
to the repositories:

    $ mkdir ${HOME}/.ssh
    $ chmod 0700 ${HOME}/.ssh
    $ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAag0uPObPcRcVf4h2gRioOBGdXVZkc98NtQ5U4BsQol fkooman@fralen-tuxed-net' | tee ${HOME}/.ssh/authorized_keys
    $ chmod 0600 ${HOME}/.ssh/authorized_keys

Create a bare repository:

    $ mkdir php-oauth2-client.git
    $ cd php-oauth2-client.git
    $ git --bare init

Return to our 'normal' account:

    $ exit

Now we are almost there, except for a little SELinux issue where `sshd` won't 
be able to read the `/var/lib/git/.ssh/authorized_keys` file:

    $ sudo semanage fcontext -a -t ssh_home_t '/var/lib/git/\.ssh(/.*)?'
    $ sudo restorecon -R /var/lib/git

Modifying the policy this way will make sure it also "survives" a relabling of
the filesystem.

Make sure the file permissions of `/var/lib/git` are correct for cgit to access
them:

    $ sudo chmod 0711 /var/lib/git

Change the shell for the `git` user now:

    $ sudo chsh -s /bin/git-shell git

Now you are ready to test SSH login from your host with the private key that
belongs to the public key that you configured above:

    $ ssh git@HOST

You'll get this error if all is correct:

    fatal: Interactive git shell is not enabled.
    hint: ~/git-shell-commands should exist and have read and execute access.

After this, it is possible to mirror your existing repository to your own 
server:

    $ git clone --bare git@github.com:/fkooman/php-oauth2-client.git
    $ cd php-oauth2-client.git
    $ git push --mirror git@HOST:php-oauth2-client.git

If you want to add your own server as a remote to an existing clone:

    $ git remote add my-server git@HOST:php-oauth2-client.git
    $ git push my-server master

#### cgit

Now all that is left is point cgit to this repository, add at the bottom of 
the file `/etc/cgitrc`:

    repo.url=php-oauth2-client
    repo.path=/var/lib/git/php-oauth2-client.git
    repo.desc=Simple OAuth 2.0 Client
    repo.owner=fkooman@tuxed.net

Some other changes in `/etc/cgitrc` are helpful:

    readme=:README.md
    clone-url=https://HOST/cgit/$CGIT_REPO_URL git@HOST:$CGIT_REPO_URL
    snapshots=zip tar.xz
    about-filter=/usr/libexec/cgit/filters/about-formatting.sh
    source-filter=/usr/libexec/cgit/filters/syntax-highlighting.sh

Now restart Apache:

    $ sudo systemctl restart httpd

Now you can browse to `https://HOST/cgit` assuming you set up your HTTP server
with TLS.

If you want to run cgit on its own (sub)domain, you can use the following 
configuration directives in the Apache virtual host, don't forget to update
the `clone-url` as well:

    DocumentRoot /usr/share/cgit
    Alias /cgit-data /usr/share/cgit
    ScriptAlias / /var/www/cgi-bin/cgit/

If you are playing with the configuration options, you may need to remove the
cache as cgit will cache the output it sends to the browser:

    $ sudo rm -f /var/cache/cgit/*