Audit de validation Git

16

J'ai un serveur git fonctionnant sur ssh et chaque utilisateur a un compte unix sur le système.

Étant donné que deux utilisateurs ont accès à un référentiel, comment puis-je être sûr de quel utilisateur a effectué quel commit, puisque le nom d'utilisateur et l'e-mail de validation sont soumis et contrôlés par le client git.

Je crains qu'un utilisateur ne tente d'usurper l'identité d'un autre, même s'il dispose des mêmes droits d'autorisation.

yannisf
la source
Je suis confus. Vous dites dans la question que chaque utilisateur a son propre compte shell, mais dans un commentaire vous dites qu'ils partagent tous un seul compte et utilisent des clés distinctes pour l'authentification. Quel est-il, ou est-ce les deux?
Scott Pack
Ça pourrait être l'un ou l'autre. La configuration actuelle est celle décrite dans la question (un compte ssh par utilisateur), mais cela ne s'adapte pas bien et je pourrais vouloir utiliser un seul utilisateur / plusieurs clés à l'avenir. Je cherche juste la solution la plus polyvalente qui ne me bloquera pas dans l'une ou l'autre méthode d'authentification.
yannisf
1
Il convient de souligner que «la personne qui fait le commit» et «la personne qui pousse certains commits à ce dépôt» ne sont pas nécessairement les mêmes dans le cas général. Je pourrais retirer vos commits de votre repo puis les pousser (comme moi) vers un repo tiers.
nickgrim

Réponses:

13

Si cela vous inquiète, il existe deux façons de résoudre le problème.

  1. Faites signer vos commits par vos utilisateurs, la signature GPG est prise en charge.
  2. Ne donnez pas aux utilisateurs le droit de valider le référentiel principal, demandez-leur de valider leur propre sous-référentiel, puis demandez à un utilisateur de confiance d'apporter les modifications dans le référentiel principal. C'est pourquoi si vous regardez les messages du journal pour certains projets git (tels que git lui-même), vous verrez que ce sont des champs séparés pour "Author" - la personne qui a créé la modification. et "Committer" - la personne qui a validé la modification dans le référentiel.
Abizern
la source
1. Cette suggestion semble être la plus appropriée à mes fins. Pourtant, existe-t-il un mécanisme pour rejeter les validations non signées côté serveur? 2. En ce qui concerne cette solution, l'utilisateur qui se retire du référentiel subordonné devra vérifier que le committer n'a pas utilisé un nom d'utilisateur / e-mail falsifié. Vrai?
yannisf
Attention cependant, vous pouvez signer un commit avec toutes les identités de committer et d'auteur que vous souhaitez choisir. De toute évidence, vous pourrez voir qui a fait la contrefaçon (ou qui n'a pas pris soin de sa clé privée).
CB Bailey
D'où ma mise en garde sur le fait que seuls les utilisateurs de confiance s'engagent dans le référentiel principal.
Abizern
@Abizern: Assez juste. Comme je l'ai lu, vos (1) et (2) semblaient décrire des options alternatives.
CB Bailey
1
@yannisf Concernant votre première question, le hook de mise à jour (exécuté côté serveur) peut vérifier les signatures et sinon rejeter la mise à jour des références respectives. Jetez un oeil à l' .git/hooks/update.sampleinspiration. S'il vous plaît @ informez-moi si vous posez une question à ce sujet à SO, ce serait intéressant pour moi aussi
Tobias Kienzler
9

Je vois deux bonnes façons d'obtenir ce genre d'informations. L'une consiste à augmenter la journalisation à partir de sshd lui-même et l'autre à effectuer une surveillance plus approfondie du référentiel git sur le disque. Étant donné qu'aucun d'eux ne vous donne individuellement les informations que vous souhaitez, vous pouvez faire les deux et corréler les données de journal à l'aide d'un moteur d'analyse de journal externe ou à la demande à l'aide des yeux humains et d'horodatages.

Modifications de sshd

Par défaut, comme vous l'avez sans doute vu, vous pouvez voir quand un utilisateur s'est connecté et d'où, en utilisant les journaux d'authentification ssh. Ce que vous voulez faire, c'est changer le niveau auquel vous vous déconnectez de sshd. Modifiez donc votre /etc/ssh/sshd_configet trouvez la ligne qui ressemble à

#LogLevel INFO

et changer cela en

LogLevel VERBOSE

puis redémarrez le service sshd. Cela augmente le niveau de journalisation de sshd d'une étape, ce qui donne beaucoup plus d'informations. Consultez cet extrait de journal de mon accès à distance après avoir apporté cette modification.

Nov  2 08:37:09 node1 sshd[4859]: Connection from 10.10.10.5 port 50445
Nov  2 08:37:10 node1 sshd[4859]: Found matching RSA key: f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06
Nov  2 08:37:10 node1 sshd[4860]: Postponed publickey for scott from 10.10.10.5 port 50445 ssh2
Nov  2 08:37:10 node1 sshd[4859]: Found matching RSA key: f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06
Nov  2 08:37:10 node1 sshd[4859]: Accepted publickey for scott from 10.10.10.5 port 50445 ssh2
Nov  2 08:37:10 node1 sshd[4859]: pam_unix(sshd:session): session opened for user scott by (uid=0)
Nov  2 08:37:10 node1 sshd[4859]: User child is on pid 4862
Nov  2 08:40:27 node1 sshd[4862]: Connection closed by 10.10.10.5
Nov  2 08:40:27 node1 sshd[4862]: Transferred: sent 30632, received 7024 bytes
Nov  2 08:40:27 node1 sshd[4862]: Closing connection to 10.10.10.5 port 50445
Nov  2 08:40:27 node1 sshd[4859]: pam_unix(sshd:session): session closed for user scott 

Les choses importantes à noter ici sont doubles

  1. Nous voyons l'empreinte digitale de la clé publique utilisée pour m'authentifier
  2. Nous voyons l'horodatage de ma déconnexion

L'utilisation du sshd LogLevel (INFO) par défaut ne consigne aucun de ces éléments. Obtenir l'empreinte digitale d'une clé est une étape supplémentaire. Vous devez traiter le authorized_keysfichier approprié avec ssh-keygen en tant que tel.

[root@node1 ssh]# ssh-keygen -l -f /home/scott/.ssh/authorized_keys
4096 f2:9e:a1:ca:0c:33:02:37:9b:de:e7:63:d5:f4:25:06 /home/scott/.ssh/authorized_keys (RSA)

Alors maintenant, vous connaissez les informations suivantes:

  1. Nom d'utilisateur connecté
  2. Heure à laquelle cet utilisateur s'est connecté
  3. Quelle clé publique a été utilisée pour l'authentification
  4. Heure à laquelle l'utilisateur s'est déconnecté

Maintenant que nous avons un moyen d'attribuer l'action de l'utilisateur à un moment précis, en supposant que les deux utilisateurs n'étaient pas connectés en même temps, nous pouvons commencer à examiner les modifications apportées au référentiel.

Surveillance d'annuaire avec Auditd

Comme l'a dit sysadmin1138, cela pourrait être un excellent cas d'utilisation pour le sous-système auditd. Si vous n'utilisez pas une distribution basée sur RedHat, il y a probablement un analogue, mais vous devrez le trouver. La configuration pour auditd est assez intense et a un nombre redonkulous d'options de configuration. Pour avoir une idée de certaines des options, veuillez consulter cette question sur notre site partenaire pour les professionnels de la sécurité de l'information .

Au minimum, je recommanderais de configurer ce qu'on appelle une "surveillance" sur le répertoire sur le disque qui contient votre dépôt git en question. Cela permet au module du noyau de signaler les tentatives d'effectuer des appels d'accès aux fichiers, tels que open()ou creat(), sur les descripteurs de fichiers pointant vers les fichiers ou répertoires que nous listons.

Voici un exemple de configuration qui ferait cela, et seulement cela. Veillez donc à lire et comprendre votre existant /etc/audit/audit.rulesafin d'intégrer les changements de manière appropriée.

# This file contains the auditctl rules that are loaded
# whenever the audit daemon is started via the initscripts.
# The rules are simply the parameters that would be passed
# to auditctl.

# First rule - delete all
-D

# Increase the buffers to survive stress events.
# Make this bigger for busy systems
-b 1024

-w /path/to/git/repos-p wa

# Disable adding any additional rules - note that adding *new* rules will require a reboot
-e 2
Scott Pack
la source
merci beaucoup pour votre réponse détaillée! Il est vraiment complet du point de vue des administrateurs système. Ce que je cherchais cependant, c'était une solution qui n'aurait pas besoin d'être résolue à un audit de si bas niveau, et idéalement empêchera les commits falsifiés plutôt que de se résoudre à la criminalistique après coup.
yannisf
2
Eh bien, vous avez posé la question sur un site d'administration des systèmes et je suis examinateur en médecine légale .... :)
Scott Pack
5

La seule approche technique que vous pouvez adopter consiste à faire confiance à l'identité de la connexion ssh. Vous pouvez ensuite faire en sorte que chaque utilisateur ne pousse que les validations qu'il a faites en validant le commit de chaque nouvelle validation poussée.

Pour que cela soit fiable, vous ne voulez certainement pas donner à vos utilisateurs un accès illimité du shell à la boîte où réside le référentiel; vous voudriez garantir l'utilisation de quelque chose comme ça git-shellsinon les restrictions sont facilement contournées.

Cependant, les utilisateurs pourraient toujours se faire passer pour des auteurs. Vous pouvez également restreindre cela, mais cela perdrait des flux de travail courants tels que la sélection et la modification de la cerise et peut-être même la ramification (en fonction de votre implémentation du crochet), de sorte que vous ne voudrez peut-être pas le faire.

À un moment donné, dans une certaine mesure, vous devez faire confiance à vos développeurs.

CB Bailey
la source
3

De nombreux démons ssh font une entrée /var/log/audit.logou quelque chose de similaire lorsqu'une connexion ssh est reçue. Le croisement de ce journal avec le journal de validation devrait vous donner une idée de l'utilisateur ssh utilisé pour émettre une validation. Il s'agit d'une étape d'audit, à utiliser après coup pour vérification.

L'application effective de l'utilisateur ssh correct à l'utilisateur git approprié est l'une des autres réponses ici.

sysadmin1138
la source
Il y a toujours la configuration selon laquelle les utilisateurs se connectent avec le même utilisateur ssh mais utilisent des clés différentes (autorisées). Cela rend l'audit encore plus difficile.
yannisf
@yannisf: Vous avez raison, cela change un peu les choses. Avec un peu de chance, j'ai aidé à répondre à votre besoin supplémentaire de gérer l'accès au compte non attribuable.
Scott Pack
0

Si tous les utilisateurs ont des comptes shell avec un accès en écriture au référentiel, vous ne pourrez pas configurer un journal d'audit fiable: ils pourraient toujours modifier le référentiel sans écrire dans le journal, et ils pourraient écrire ce qu'ils veulent dans le journal.

Pour pouvoir faire confiance au journal d'audit, vous devez empêcher l'accès direct en écriture de niveau fichier au référentiel, au lieu d'utiliser quelque chose comme gitolite (qui s'exécute sur son propre compte) pour assurer l'accès au référentiel.

SamB
la source