Linux Server setup

Tutorial: Git Server selbst hosten

In diesem Tutorial werden wir auf unserem Cloud Server einen Git Service hosten.

Ein Git Service lässt sich relativ schnell installieren. Für den sicheren und produktiven Einsatz, braucht es jedoch noch weitere Einstellungen am Server. Außerdem soll der Git Server unter einer Subdomain adressiert sein und nicht die ganze Cloud Ressource einnehmen.

Ziel dieses Tutorials ist, Gitea unter einer verschlüsselten Subdomain in einem Unterordner zu hosten: https://git.linuxserversetup.com/gitea.

Falls Du den Git Server eher versteckt halten möchtest, solltest Du die Adresse nicht zu offensichtlich gestalten. Es empfiehlt sich also, eher neutrale Bezeichnungen für die Subdomain und den Unterordner zu wählen. In diesem Zusammenhang trägt der Unterordner deutlich mehr zur Sicherheit bei, denn der müsste sozusagen erraten werden. Die Subdomain hingegen steht in der öffentlich zugänglichen DNS Zonefile.

Wir starten damit eine Subdomain mit TLS vorzubereiten, so dass wir anschließend einen beliebigen Git Service installieren können. Als Versionsverwaltungssoftware mit grafischer Weboberfläche nehmen wir Gitea. Es ist kostenlos und Open Source. Die Vorgehensweise Gitea zu implementieren ist eigentlich klar, lässt aber im Detail viele Einstellungen zu. Die Feinheiten kannst Du in der Konfigurationsdatei und über die Weboberfläche für Dich anpassen.

Die nächsten Schritte


DNS Subdomain Eintrag

Wie eine Subdomain in die DNS Zonefile eingetragen wird, wurde bereits in DNS Einträge bearbeiten beschrieben.

Beispielhaft nenne ich die Subdomain git. Aus genannten Gründen macht es aber Sinn, einen nicht so offensichtlichen Namen zu vergeben. Der A-Record dazu wäre:


git  IN  A  116.203.69.89

Bei mir sieht die finale Zonendatei dann so aus:


$ORIGIN linuxserversetup.com.

; SOA Records
$TTL 86400
@    IN  SOA  hydrogen.ns.hetzner.com. dns.hetzner.com. (
      2021123100  ; serial
      86400       ; refresh
      10800       ; retry
      3600000     ; expire
      3600        ; negatives caching
)

; NS Records
@    IN  NS  hydrogen.ns.hetzner.com.
@    IN  NS  oxygen.ns.hetzner.com.
@    IN  NS  helium.ns.hetzner.de.

; MX Records
@    IN  MX  10 mail

; A Records
@    IN  A  116.203.69.89
mail IN  A  116.203.69.89
www  IN  A  116.203.69.89
dev  IN  A  116.203.69.89
git  IN  A  116.203.69.89


Nginx Weiterleitung mit HTTPS

In diesem Abschnitt gehen wir ähnlich vor, wie in Nginx Subdomain Server Block und Let's Encrypt Zertifikat für die Subdomain.

Dieser Abschnitt besteht aus vier Schritten:

  • Nginx Server Konfigurationsdatei anlegen
  • leere HTML Seite erstellen
  • Let's Encrypt Zertifikat beziehen
  • TLS in die Konfigurationsdatei implementieren

Nginx Server Konfiguration

Wir legen erst eine Nginx Konfigurationsdatei an:


__$ sudo nano /etc/nginx/sites-available/com.linuxserversetup.git.conf
 

Der Inhalt von com.linuxserversetup.git.conf ist vorläufig:

/etc/nginx/sites-available/com.linuxserversetup.git.conf


server {
  listen      80;
  listen      [::]:80;
  server_name git.linuxserversetup.com;

  root        /var/www/com.linuxserversetup.git/;
  index       index.htm;

  location / {
    try_files $uri $uri/ /index.htm;
  }

  location = /favicon.ico { access_log off; log_not_found off; }
}
 

Leere HTML Seite erstellen

Die leere HTML Seite soll unter /var/www/com.linuxserversetup.git liegen. Wir erstellen erst den Verzeichnispfad:


__$ mkdir /var/www/com.linuxserversetup.git
 

Und darin dann eine index.htm:


__$ nano /var/www/com.linuxserversetup.git/index.htm
 

Mit dem Inhalt:

/var/www/com.linuxserversetup.git/index.htm


<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>git.linuxserversetup.com</title>
  </head>
  <body></body>
</html>
 

Die Konfigurationsdatei verknüpfen wir mit einem symbolischen Link im Ordner /etc/nginx/sites-enabled:


__$ sudo ln -s /etc/nginx/sites-available/com.linuxserversetup.git.conf /etc/nginx/sites-enabled/
 

Und aktivieren die Seite, indem wir Nginx überprüfen und neustarten.


__$ sudo nginx -t
__$ sudo systemctl restart nginx
 

Die Adresse http://git.linuxserversetup.com sollte jetzt mit einem Browser abrufbar sein.

Let's Encrypt Zertifikat beziehen

Mit Certbot beantragen wir ein Zertifikat von Let's Encrypt:


__$ sudo certbot certonly -d git.linuxserversetup.com --rsa-key-size 4096
 

Es startet folgender Dialog:

  • Place files in webroot directory (webroot): 2
  • Enter email address
  • Input the webroot for git.linuxserversetup.com: /var/www/com.linuxserversetup.git

Die neuen Zertifikate sollten dann unter /etc/letsencrypt/live/git.linuxserversetup.com/ liegen. Genauer gesagt, liegen dort Verknüpfungen zu den tatsächlichen Dateien.


__$ sudo ls -la /etc/letsencrypt/live/git.linuxserversetup.com
	

Nginx Konfigurationsdatei auf HTTPS umstellen

Die Zertifikate können wir jetzt in die vorhin erstellte Konfigurationsdatei implementieren und nehmen noch folgende Änderungen vor:

  • HTTPS soll erzwungen werden
  • TLS Implementation
  • git.linuxserversetup.com soll mit der leeren HTML Seite antworten
  • git.linuxserversetup.com/gitea leitet auf den internen Port 3800 weiter

Der Standard Port von Gitea ist eigentlich 3000. Ich werde den später auf 3800 ändern, daher hier schon die Vorbereitung dazu.

Konfigurationsdatei öffnen und editieren:


__$ sudo nano /etc/nginx/sites-available/com.linuxserversetup.git.conf
 

Der geänderte Inhalt mit den Änderungen sieht dann so aus:

/etc/nginx/sites-available/com.linuxserversetup.git.conf


# force https
server {
  listen      80;
  server_name git.linuxserversetup.com;
  return      301 https://$server_name$request_uri;
}

# main block
server {
  listen      443 ssl http2;
  listen      [::]:443 ssl http2;
  server_name git.linuxserversetup.com;

  root        /var/www/com.linuxserversetup.git/;
  index       index.htm;

  location / {
    try_files $uri $uri/ /index.htm;
  }

  location /gitea/ {
    proxy_pass http://localhost:3800/;
  }

  location = /favicon.ico { access_log off; log_not_found off; }

  ssl_certificate /etc/letsencrypt/live/git.linuxserversetup.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/git.linuxserversetup.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/git.linuxserversetup.com/chain.pem;

  # dhparam
  ssl_dhparam /etc/ssl/certs/dhparam.pem;

  # HSTS
  add_header Strict-Transport-Security "max-age=31536000";
}

Nginx muss aufgrund der Änderung wieder neu gestartet werden:


__$ sudo nginx -t
__$ sudo systemctl restart nginx
 

Damit wäre die Subdomain eingerichtet und wir können mit der Installation vom Git Server beginnen.

Zu Sicherheit kann die Adresse https://git.linuxserversetup.com mit dem Browser überprüft werden.


Git installieren

Gitea ist abhängig von der Versionsverwaltungssoftware Git. Wir installieren Git mit apt.

Erst die Paketquellen aktualisieren:


__$ sudo apt update
 

Git installieren:


__$ sudo apt install -y git
 

Git Version abrufen:


__$ git --version
 

Git Benutzer erstellen

Für alle Versionsverwaltungsaufgaben soll ein Systembenutzer git verantwortlich sein. Diesem werden wir später die Gitea Systemdateien zuordnen.

Den Benutzer git mit adduser erstellen:


__$ sudo adduser --system --group --disabled-password git
	

Datenbank für Gitea anlegen

MySQL installieren und einrichten hatten wir bereits in einem vorherigen Kapitel erledigt. Jetzt brauchen wir nur noch einen MySQL Benutzer gitea mit gleichnamiger Datenbank erstellen. Das Passwort ist hier Beispielhaft gitea123.


__$ sudo mysql
__gt CREATE USER 'gitea'@'localhost' IDENTIFIED BY 'gitea123';
__gt GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'localhost';
__gt FLUSH PRIVILEGES;
__gt CREATE DATABASE gitea;
__gt exit;
	

Gitea herunterladen und konfigurieren

Wir beziehen Gitea von der offiziellen Quelle mit wget und speichern es unter /usr/local/bin/gitea. Zum Zeitpunkt des Schreibens ist die aktuelle Version 1.16.9:


__$ sudo wget -O /usr/local/bin/gitea https://dl.gitea.io/gitea/1.16.9/gitea-1.16.9-linux-amd64
 

Die heruntergeladene Datei muss dann noch ausführbar gemacht werden:


__$ sudo chmod +x /usr/local/bin/gitea
 

Wir erstellen für Gitea eine Ordnerstruktur unter /var/lib. Dort platzieren wir auch einen Ordner für eigene Einstellungen, die die Standard Konfiguration überschreibt. Dadurch lässt sich Gitea aktualisieren, ohne dass die eigenen Einstellungen zurückgesetzt werden.


__$ sudo mkdir -p /var/lib/gitea/custom/conf
__$ sudo mkdir -p /var/lib/gitea/data
__$ sudo mkdir -p /var/lib/gitea/log
 

Wie schon erwähnt, soll der Systembenutzer git Eigentümer der Gitea Dateien sein. Zusätzlich ändern wir auch die Verzeichnisrechte auf 750.


__$ sudo chown -R git:git /var/lib/gitea/
__$ sudo chmod -R 750 /var/lib/gitea/
 

Gitea braucht noch einen /etc/gitea Systemordner. git ist auch Eigentümer dieser Dateien. Die Verzeichnisrechte sollen vorläufig 770 sein.


__$ sudo mkdir /etc/gitea
__$ sudo chown git:git /etc/gitea
__$ sudo chmod 770 /etc/gitea
 

Mit dem ersten Start wird die Software installiert und dadurch weitere Systemdateien in /etc/gitea erstellt. Danach können die Verzeichnisrechte wieder geändert werden. Wir kommen später darauf zurück.

Damit Gitea automatisch startet, erstellen wir einen Linux Service /etc/systemd/system/gitea.service. Eine Standard Datei ist zum Beispiel hier zu finden githubusercontent.com/go-gitea.

Wir erstellen die Datei:


__$ sudo nano /etc/systemd/system/gitea.service
 

Mit diesem Inhalt:

/etc/systemd/system/gitea.service


[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
###
# Don't forget to add the database service dependencies
###
#
Wants=mysql.service
After=mysql.service
#
#Wants=mariadb.service
#After=mariadb.service
#
#Wants=postgresql.service
#After=postgresql.service
#
#Wants=memcached.service
#After=memcached.service
#
#Wants=redis.service
#After=redis.service
#
###
# If using socket activation for main http/s
###
#
#After=gitea.main.socket
#Requires=gitea.main.socket
#
###
# (You can also provide gitea an http fallback and/or ssh socket too)
#
# An example of /etc/systemd/system/gitea.main.socket
###
##
## [Unit]
## Description=Gitea Web Socket
## PartOf=gitea.service
##
## [Socket]
## Service=gitea.service
## ListenStream=
## NoDelay=true
##
## [Install]
## WantedBy=sockets.target
##
###

[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock file
# (manually creating /run/gitea doesn't work, because it would not persist across reboots)
#RuntimeDirectory=gitea
ExecStart=/usr/local/bin/gitea web --config /var/lib/gitea/custom/conf/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
# If you install Git to directory prefix other than default PATH (which happens
# for example if you install other versions of Git side-to-side with
# distribution version), uncomment below line and add that prefix to PATH
# Don't forget to place git-lfs binary on the PATH below if you want to enable
# Git LFS support
#Environment=PATH=/path/to/git/bin:/bin:/sbin:/usr/bin:/usr/sbin
# If you want to bind Gitea to a port below 1024, uncomment
# the two values below, or use socket activation to pass Gitea its ports as above
###
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_BIND_SERVICE
###

[Install]
WantedBy=multi-user.target

Es handelt sich im Grunde um die oben erwähnte Standard Datei mit lediglich zwei Änderungen:

  • Wants=mysql.service und After=mysql.service sind einkommentiert.
  • Der Pfad zur Web Konfigurationsdatei zeigt auf die eigenen Einstellungen: /var/lib/gitea/custom/conf/app.ini.

Fehlt noch die Web Konfigurationsdatei /var/lib/gitea/custom/conf/app.ini. Auch dazu hat Gitea eine Standard app.example.ini Datei veröffentlicht. In dieser Datei stehen alle möglichen Optionen, von denen wir nicht alle übernehmen müssen. Auch in der folgenden Beispiel Datei sind manche überflüssig, sie sollen nur für eine schnellere Nachbearbeitung mit eingetragen werden.

Wir erstellen die Datei:


__$ sudo nano /var/lib/gitea/custom/conf/app.ini
 

Mit diesem Inhalt:

/var/lib/gitea/custom/conf/app.ini


APP_NAME = Gitea
RUN_USER = git
RUN_MODE = prod

[security]
INSTALL_LOCK   = false
SECRET_KEY     =
INTERNAL_TOKEN =

[database]
DB_TYPE  = mysql
HOST     = 127.0.0.1:3306
NAME     = gitea
USER     = gitea
PASSWD   = gitea
SCHEMA   =
SSL_MODE = disable
CHARSET  = utf8
PATH     = /var/lib/gitea/data/gitea.db

[repository]
ROOT = /home/git/gitea-repositories

[server]
PROTOCOL         = http
SSH_DOMAIN       = linuxsrvsetup.com
DOMAIN           = git.linuxsrvsetup.com/gitea
HTTP_PORT        = 3800
REDIRECT_OTHER_PORT = true
ROOT_URL         = https://git.linuxsrvsetup.com/gitea
DISABLE_SSH      = false
SSH_PORT         = 22123
LFS_START_SERVER = true
LFS_CONTENT_PATH = /var/lib/gitea/data/lfs
LFS_JWT_SECRET   =
OFFLINE_MODE     = false

[mailer]
ENABLED = true
SUBJECT_PREFIX = GITEA:
FROM = "GITEA" <gitea@linuxservrsetup.com>
USE_SENDMAIL = true
SENDMAIL_PATH = /usr/sbin/sendmail

[service]
REGISTER_EMAIL_CONFIRM            = false
ENABLE_NOTIFY_MAIL                = true
DISABLE_REGISTRATION              = false
ALLOW_ONLY_EXTERNAL_REGISTRATION  = false
ENABLE_CAPTCHA                    = false
REQUIRE_SIGNIN_VIEW               = true
DEFAULT_KEEP_EMAIL_PRIVATE        = true
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING       = true
NO_REPLY_ADDRESS                  = noreply@linuxservrsetup.com

[picture]
DISABLE_GRAVATAR        = false
ENABLE_FEDERATED_AVATAR = true

[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false

[session]
PROVIDER = file

[log]
MODE      = file
LEVEL     = info
ROOT_PATH = /var/lib/gitea/log

[repository]
DEFAULT_BRANCH = main

Folgende Parameter sind hier zu beachten:

  • alle Domainnamen
  • alle E-Email-Adressen
  • der HTTP_PORT
  • der SSH_PORT
  • SECRET_KEY, INTERNAL_TOKEN und LFS_JWT_SECRET werden automatisch generiert

Die Datei müssen wir auch dem Benutzer git übergeben.


__$ sudo chown -R git:git /var/lib/gitea/
 

Wir können Gitea starten und richten den Dienst auch gleich so ein, dass er beim Serverneustart immer mit hochfährt.


__$ sudo systemctl enable gitea
__$ sudo systemctl start gitea
	

Gitea installieren und Administrator erstellen

Gitea ist jetzt bereit den ersten Start auszuführen, was durch INSTALL_LOCK = false einen Installationsprozess auslöst. Die Optionen, die jetzt beim Web Installer gemacht werden, überschreiben automatisch die zuletzt erstellte Konfigurationsdatei /var/lib/gitea/custom/conf/app.ini. Wir rufen also die Gitea Webadresse https://git.linuxserversetup.com/gitea auf und legen unter anderem darüber einen Administrator an. Die Option "E-Mail-Benachrichtigungen" kann an dieser Stelle auch aktiviert werden (ENABLE_NOTIFY_MAIL). Dadurch werden Repository Beobachter per E-Mail über Ereignisse benachrichtigt.

Noch ein Hinweis: Im nächsten Abschnitt wird beschrieben, wie die öffentliche Registrierung deaktiviert werden kann. Das kann auch schon bereits jetzt im Installationsprozess über die Weboberfläche eingestellt werden.

Gitea installieren und Administrator erstellen:
Gitea Web Installer
Fehlerseite nach der Installation

Nach der Installation landen wir auf einer Fehlerseite, was typisch ist. Die Seite muss dann einfach nur neu geladen werden.

Gitea Dashboard
Gitea Einstellungen öffnen
Gitea Einstellungen

Der Git Server ist jetzt fertig und betriebsbereit.

Falls der Ordner /etc/gitea nach der Installation noch existiert, was in neueren Gitea Versionen eventuell nicht mehr sein sollte, können die Zugriffsrechte davon wieder herabsetzen:


__$ sudo chmod 750 /etc/gitea
 

Öffentliche Registrierung deaktivieren

Wenn Du Gitea nicht öffentlich teilen möchtest, solltest Du die Registrierung DISABLE_REGISTRATION aktivieren:

Wir öffnen wieder die Webkonfiguration:


__$ sudo nano /var/lib/gitea/custom/conf/app.ini
 

Und ändern den Parameter:

Auszug aus /etc/systemd/system/gitea.service


...
DISABLE_REGISTRATION = true
...

Gitea neustarten, um die Änderungen zu übernehmen:

/etc/systemd/system/gitea.service


__$ sudo systemctl restart gitea
 

Alle Einstellungen sind unter Gitea Configuration Cheat Sheet dokumentiert.


Gitea deinstallieren

Wie Gitea deinstalliert wird, soll hier nur der Vollständigkeit halber beschrieben werden.

Gitea stoppen:


__$ sudo systemctl stop gitea
	

Firewall Regeln ausgeben lassen:


__$ sudo ufw status numbered
 

Gitea Firewall Regel mit Nummer löschen:


__$ sudo ufw delete [RULENUMBER]
 

Gitea Dateien löschen:


__$ sudo rm -R /etc/gitea
__$ sudo rm /etc/systemd/system/gitea.service
__$ sudo rm -R /var/lib/gitea
__$ sudo rm /usr/local/bin/gitea
	

git Systembenutzer löschen:


__$ sudo deluser --remove-home git
__$ sudo groupdel git
	

Gitea MySQL Benutzer und Datenbank über die MySQL löschen:


__$ sudo mysql
__gt DROP DATABASE gitea;
__gt DROP USER 'gitea'@'localhost';
__gt exit;
	

systemd aktualisieren:


__$ sudo systemctl daemon-reload
	

Überprüfen, ob der Gitea Service noch existiert:


__$ sudo systemctl status gitea
	

Nützliche Gitea Befehle

Gitea starten, stoppen, neustarten, Status:


__$ sudo systemctl start gitea
__$ sudo systemctl stop gitea
__$ sudo systemctl restart gitea
__$ sudo systemctl status gitea
 

systemd Protokoll vom Gitea Service (folgen -f):


__$ sudo journalctl -u gitea -f
	

Gitea Logs (wenn MODE = file):


__$ sudo ls /var/lib/gitea/log/
__$ sudo less /var/lib/gitea/log/gitea.log
__$ sudo tail -f /var/lib/gitea/log/gitea.log