Organisation des Mehrbenutzerzugriffs auf den GIT-Server

Bei der Installation und Konfiguration eines Git-Servers stellt sich die Frage, wie man den Zugriff mehrerer Benutzer auf mehrere Projekte organisieren kann. Ich habe das Problem recherchiert und eine Lösung gefunden, die alle meine Anforderungen erfüllt: einfach, sicher, zuverlässig.

Meine Wünsche sind:

  • Jeder Benutzer verbindet sich mit seinem eigenen Konto
  • Mehrere Benutzer können an einem Projekt arbeiten
  • Derselbe Benutzer kann an mehreren Projekten arbeiten
  • Jeder Benutzer hat nur Zugriff auf die Projekte, an denen er arbeitet
  • Es sollte möglich sein, eine Verbindung über die Befehlszeile herzustellen und nicht nur über eine Art Webschnittstelle

Es wäre auch toll:

  • Gewähren Sie den kontrollierenden Personen nur Leseberechtigungen
  • Verwalten Sie Benutzerzugriffsrechte bequem in Git

Übersicht möglicher Optionen für den Zugriff auf den GIT-Server

Zunächst müssen Sie wissen, woraus Sie wählen können. Hier finden Sie einen kurzen Überblick über die Git-Protokolle.

  • ssh – für den Zugriff auf den Server wird ein speziell erstelltes Benutzerkonto verwendet.
    • Es ist seltsam, dass Git in seinen Empfehlungen die Verwendung eines Kontos für den Zugriff auf alle Repositorys nicht ausschließt. Das entspricht überhaupt nicht meinen Anforderungen.
    • Sie können mehrere Konten verwenden, aber wie können Sie den Benutzerzugriff nur auf bestimmte Verzeichnisse beschränken?
      • Das Abschließen in das Home-Verzeichnis ist nicht geeignet, da es dort schwierig ist, den Schreibzugriff für andere Benutzer zu organisieren
      • Auch die Verwendung von Symlinks aus Ihrem Home-Verzeichnis ist schwierig, da Git sie nicht als Links interpretiert
      • Es ist möglich, den Zugriff auf den Interpreter einzuschränken, es gibt jedoch keine vollständige Garantie dafür, dass er immer funktioniert
        • Sie können für solche Benutzer jedoch grundsätzlich einen eigenen Befehlsinterpreter anbinden
          • Erstens ist das schon eine schwierige Entscheidung,
          • und zweitens kann dies umgangen werden.

    Aber vielleicht ist es kein Problem, dass der Benutzer beliebige Befehle ausführen kann? Im Allgemeinen kann diese Methode nicht ausgeschlossen werden, wenn man genau weiß, wie man sie verwendet. Wir werden später auf diese Methode zurückkommen, betrachten aber zunächst kurz die anderen Alternativen, vielleicht gibt es etwas Einfacheres.

  • Das lokale Git-Protokoll kann in Kombination mit sshfs verwendet werden, es können mehrere Benutzer verwendet werden, aber im Wesentlichen dasselbe wie im vorherigen Fall
  • http – schreibgeschützt
  • Git ist schreibgeschützt
  • https – schwierig zu installieren, man braucht zusätzliche Software, eine Art Control Panel, um den Benutzerzugriff zu organisieren... es sieht machbar aus, aber irgendwie ist alles kompliziert.

Verwenden des SSH-Protokolls zum Organisieren des Mehrbenutzerzugriffs auf den Git-Server

Kehren wir zum SSH-Protokoll zurück.

Da Sie für Git den SSH-Zugriff verwenden, müssen Sie die Sicherheit der Serverdaten gewährleisten. Der Benutzer, der sich über SSH verbindet, verwendet sein eigenes Login auf dem Linux-Server, sodass er sich über den SSH-Client verbinden und auf die Befehlszeile des Servers zugreifen kann.
Es gibt keinen vollständigen Schutz vor einem solchen Zugriff.

Der Benutzer sollte jedoch kein Interesse an Linux-Dateien haben. Wichtige Informationen werden nur im Git-Repository gespeichert. Daher ist es möglich, den Zugriff nicht über die Befehlszeile einzuschränken, sondern mithilfe von Linux-Tools dem Benutzer das Anzeigen von Projekten zu verbieten, mit Ausnahme derjenigen, an denen er teilnimmt.
Die offensichtliche Wahl ist die Verwendung des Linux-Berechtigungssystems.

Wie bereits erwähnt ist es möglich, nur ein Konto für den SSH-Zugriff zu verwenden. Diese Konfiguration ist für mehrere Benutzer unsicher, obwohl sie in der Liste der empfohlenen Git-Optionen enthalten ist.

Um die am Anfang des Artikels genannten Anforderungen umzusetzen, wird folgende Verzeichnisstruktur mit der Zuordnung von Rechten und Eigentümern erstellt:

1) Projektverzeichnisse

dir1(proj1:proj1,0770)
dir2(proj2:proj2,0770)
dir3(proj3:proj3,0770)
...
wo
dir1, dir2, dir3 – Projektverzeichnisse: Projekt 1, Projekt 2, Projekt 3.

proj1:proj1, proj2:proj2, proj3:proj3 sind speziell erstellte Linux-Benutzer, die als Eigentümer der entsprechenden Projektverzeichnisse zugewiesen sind.

Die Berechtigungen für alle Verzeichnisse sind auf 0770 eingestellt – voller Zugriff für den Eigentümer und seine Gruppe und vollständiges Verbot für alle anderen.

2) Entwicklerkonten

Разработчик 1: dev1:dev1,proj1,proj2
Разработчик 2: dev2:dev2,proj2,proj3

Der entscheidende Punkt ist, dass Entwicklern eine zusätzliche Gruppe des Systembenutzerbesitzers des entsprechenden Projekts zugewiesen wird. Dies erledigt der Linux-Serveradministrator mit einem Befehl.

In diesem Beispiel arbeitet „Entwickler 1“ an den Projekten proj1 und proj2 und „Entwickler 2“ an den Projekten proj2 und proj3.

Wenn einer der Entwickler eine Verbindung über SSH über die Befehlszeile herstellt, reichen seine Rechte nicht einmal aus, um den Inhalt von Projektverzeichnissen anzuzeigen, an denen er nicht beteiligt ist. Er selbst kann dies nicht ändern.

Da die Grundlage dieses Prinzips die grundlegende Sicherheit der Linux-Rechte ist, ist dieses Schema zuverlässig. Darüber hinaus ist das Schema sehr einfach zu verwalten.

Lass uns zum Üben übergehen.

Erstellen von Git-Repositorys auf einem Linux-Server

Lass uns das Prüfen.

[root@server ~]# cd /var/
[root@server var]# useradd gitowner
[root@server var]# mkdir gitservertest
[root@server var]# chown gitowner:gitowner gitservertest
[root@server var]# adduser proj1
[root@server var]# adduser proj2
[root@server var]# adduser proj3
[root@server var]# adduser dev1
[root@server var]# adduser dev2
[root@server var]# passwd dev1
[root@server var]# passwd dev2

Ich habe es satt, mit der Hand zu tippen ...

[root@server gitservertest]# sed "s/ /n/g" <<< "proj1 proj2 proj3" | while read u; do mkdir $u; chown $u:$u $u; chmod 0770 $u; done

[root@server gitservertest]# usermod -aG proj1 dev1
[root@server gitservertest]# usermod -aG proj2 dev1
[root@server gitservertest]# usermod -aG proj2 dev2
[root@server gitservertest]# usermod -aG proj3 dev2

Wir sind davon überzeugt, dass es unmöglich ist, über die Befehlszeile auf die Repositorys anderer Personen zuzugreifen und deren Inhalte überhaupt anzuzeigen.

[dev1@server ~]$ cd /var/gitservertest/proj3
-bash: cd: /var/gitservertest/proj3: Permission denied
[dev1@server ~]$ ls /var/gitservertest/proj3
ls: cannot open directory /var/gitservertest/proj3: Permission denied

Arbeiten Sie mit mehreren Entwicklern am selben Projekt in Git zusammen

Es bleibt eine Frage: Wenn ein Entwickler eine neue Datei einführt, können andere Entwickler diese nicht ändern, da er selbst deren Eigentümer ist (z. B. dev1) und nicht der Benutzereigentümer des Projekts (z. B. proj1). Da wir über ein serverseitiges Repository verfügen, müssen wir zunächst wissen, wie das Verzeichnis „.git“ aufgebaut ist und ob neue Dateien erstellt werden.

Erstellen eines lokalen Git-Repositorys und Übertragen auf den Git-Server

Kommen wir zum Client-Rechner.

Microsoft Windows [Version 6.1.7601]
(c) Корпорация Майкрософт (Microsoft Corp.), 2009. Все права защищены.

C:gittest>git init .
Initialized empty Git repository in C:/gittest/.git/

C:gittest>echo "test dev1 to proj2" > test1.txt

C:gittest>git add .

C:gittest>git status
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   test1.txt

C:gittest>git commit -am "new test file added"
[master (root-commit) a7ac614] new test file added
 1 file changed, 1 insertion(+)
 create mode 100644 test1.txt
 
C:gittest>git remote add origin "ssh://[email protected]/var/gitservertest/proj2"

C:gittest>git push origin master
dev1:[email protected]'s password:
Counting objects: 3, done.
Writing objects: 100% (3/3), 243 bytes | 243.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://10.1.1.11/var/gitservertest/proj2
 * [new branch]      master -> master

C:gittest>

Gleichzeitig werden auf dem Server neue Dateien erstellt, die dem Benutzer gehören, der den Push durchgeführt hat

[dev1@server proj2]$ tree
.
├── 1.txt
├── branches
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── 75
│   │   └── dcd269e04852ce2f683b9eb41ecd6030c8c841
│   ├── a7
│   │   └── ac6148611e69b9a074f59a80f356e1e0c8be67
│   ├── f0
│   │   └── 82ea1186a491cd063925d0c2c4f1c056e32ac3
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

12 directories, 18 files
[dev1@server proj2]$ ls -l objects/75/dcd269e04852ce2f683b9eb41ecd6030c8c841
-r--r--r--. 1 dev1 dev1 54 Jun 20 14:34 objects/75/dcd269e04852ce2f683b9eb41ecd6030c8c841
[dev1@server proj2]$

Wenn Sie Änderungen auf den Git-Server hochladen, werden zusätzliche Dateien und Verzeichnisse erstellt, deren Eigentümer tatsächlich der Benutzer ist, der den Upload durchführt. Dann entspricht die Gruppe dieser Dateien und Verzeichnisse aber auch der Hauptgruppe dieses Benutzers, also der Gruppe dev1 für den Benutzer dev1 und der Gruppe dev2 für den Benutzer dev2 (ein Wechsel der Hauptgruppe des Benutzers „developer“ hilft nicht, denn wie kann man dann an mehreren Projekten arbeiten?). In diesem Fall kann Benutzer dev2 die von Benutzer dev1 erstellten Dateien nicht ändern, was zu einem Funktionsausfall führen könnte.

Linux chown – Ändern des Besitzers einer Datei durch einen normalen Benutzer

Der Besitzer einer Datei kann seinen Besitzer nicht ändern. Er kann jedoch die Gruppe einer Datei ändern, die ihm gehört, und diese Datei kann dann von anderen Benutzern geändert werden, die derselben Gruppe angehören. Das ist es, was wir brauchen.

Git-Hook verwenden

Das Arbeitsverzeichnis für Hook ist das Stammverzeichnis des Projekts. Hook ist eine ausführbare Datei, die unter dem Benutzer ausgeführt wird, der den Push durchführt. Mit diesem Wissen können wir unsere Pläne umsetzen.

[dev1@server proj2]$ mv hooks/post-update{.sample,}
[dev1@server proj2]$ sed -i '2,$ s/^/#/' hooks/post-update
[dev1@server proj2]$ cat <<< 'find . -group $(whoami) -exec chgrp proj2 '"'"'{}'"'"' ;' >> hooks/post-update

oder nur

vi hooks/post-update

Kehren wir zum Client-Rechner zurück.

C:gittest>echo "dev1 3rd line" >> test1.txt

C:gittest>git commit -am "3rd from dev1, testing server hook"
[master b045e22] 3rd from dev1, testing server hook
 1 file changed, 1 insertion(+)

C:gittest>git push origin master
dev1:[email protected]'s password:
   d22c66e..b045e22  master -> master

Auf dem Git-Server überprüfen wir nach dem Commit die Funktion des Hook-Post-Update-Skripts

[dev1@server proj2]$ find . ! -group proj2

- leer, alles ist in Ordnung.

Anbindung eines zweiten Entwicklers in Git

Lassen Sie uns die Arbeit des zweiten Entwicklers simulieren.

Auf dem Kunden

C:gittest>git remote remove origin

C:gittest>git remote add origin "ssh://[email protected]/var/gitservertest/proj2"

C:gittest>echo "!!! dev2 added this" >> test1.txt

C:gittest>echo "!!! dev2 wrote" > test2.txt

C:gittest>git add test2.txt

C:gittest>git commit -am "dev2 added to test1 and created test2"
[master 55d49a6] dev2 added to test1 and created test2
 2 files changed, 2 insertions(+)
 create mode 100644 test2.txt

C:gittest>git push origin master
[email protected]'s password:
   b045e22..55d49a6  master -> master

Und gleichzeitig auf dem Server...

[dev1@server proj2]$ find . ! -group proj2

— wieder leer, alles funktioniert.

Löschen eines Git-Projekts und Herunterladen des Projekts vom Git-Server

Nun können Sie noch einmal sicherstellen, dass alle Änderungen gespeichert wurden.

C:gittest>rd /S /Q .
Процесс не может получить доступ к файлу, так как этот файл занят другим процессом.

— Um ein Git-Projekt zu löschen, leeren Sie einfach das Verzeichnis vollständig. Nehmen wir den Fehler in Kauf, der entsteht, da es mit diesem Befehl nicht möglich ist, das aktuelle Verzeichnis zu löschen, aber genau das ist das Verhalten, das wir brauchen.

C:gittest>dir
 Содержимое папки C:gittest

21.06.2019  08:43    <DIR>          .
21.06.2019  08:43    <DIR>          ..

C:gittest>git clone ssh://[email protected]/var/gitservertest/proj2
Cloning into 'proj2'...
[email protected]'s password:

C:gittest>cd proj2

C:gittestproj2>dir
 Содержимое папки C:gittestproj2

21.06.2019  08:46    <DIR>          .
21.06.2019  08:46    <DIR>          ..
21.06.2019  08:46               114 test1.txt
21.06.2019  08:46                19 test2.txt
C:gittestproj2>type test1.txt
"test dev1 to proj2"
"dev1 added some omre"
"dev1 3rd line"
"!!! dev2 added this"

C:gittestproj2>type test2.txt
"!!! dev2 wrote"

Zugriffsfreigabe in Git

Stellen wir nun sicher, dass der zweite Entwickler auch über Git nicht auf das Proj1-Projekt zugreifen kann, an dem er nicht arbeitet.

C:gittestproj2>git remote remove origin

C:gittestproj2>git remote add origin "ssh://[email protected]/var/gitservertest/proj1"

C:gittestproj2>git push origin master
[email protected]'s password:
fatal: '/var/gitservertest/proj1' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Jetzt erlauben wir den Zugriff

[root@server ~]# usermod -aG proj1 dev2

und danach funktioniert alles.

C:gittestproj2>git push origin master
[email protected]'s password:
To ssh://10.1.1.11/var/gitservertest/proj1
 * [new branch]      master -> master

Für weitere Informationen,

Wenn beim Erstellen von Dateien und Verzeichnissen außerdem ein Problem mit den Standardberechtigungen auftritt, können Sie in CentOS den Befehl verwenden

setfacl -Rd -m o::5 -m g::7 /var/gitservertest

Auch in dem Artikel können Sie auf kleine nützliche Dinge stoßen:

  • wie man unter Linux einen Verzeichnisbaum erstellt
  • wie man in sed einen Adressbereich von einer bestimmten Zeile bis zum Ende der Datei übergibt, d. h. in allen Zeilen außer der ersten Zeile eine Ersetzung in sed vornimmt
  • So invertieren Sie eine Suchbedingung in Linux find
  • So übergeben Sie mehrere Zeilen mithilfe eines Einzeilers in der Linux-Shell an eine Schleife
  • So umgehen Sie einfache Anführungszeichen in der Bash
  • So löschen Sie ein Verzeichnis mit seinem gesamten Inhalt in der Windows-Befehlszeile
  • So benennen Sie eine Datei mit bash mv um, ohne sie erneut zu schreiben

Vielen Dank für Ihre Aufmerksamkeit.

Source: habr.com

Kommentar hinzufügen