User:Rominet

From FlightGear wiki
Jump to navigation Jump to search

Most end-users will probably be interested in the procedure described below, that can be used to clone a Git repository such as FGData using the SSH protocol and modify a single file so that future updates of the repository are done with the HTTPS protocol. To this date, this is the easiest way, as far as I know, to retrieve FGData in a secure and reliable way (probably because of (1) its sheer size as compared to the other repositories of the FlightGear project, and (2) some technical problems in the SourceForge Git infrastructure; other repositories can be cloned with HTTPS without any problem). This procedure is explained in full detail in English and more summarily in French.

Users who are willing to take the time to read moderately technical explanations may be interested in the tutorial on creating a pair of SSH keys, setting up an SSH agent and using it to do all Git transfers with the SSH protocol (in French). This is an alternate method, is quite secure and convenient when set up, but requires users to understand a few technical points regarding SSH public key authentication. They are all explained below, though, for those who are prepared to read carefully.

English

Motivation

A Git client can use various protocols to communicate with a remote server: the old git protocol, https as well as ssh. When one runs a command such as

git clone ssh://...

or

git clone https://...

the word preceding :// tells the Git client which protocol to use to communicate with the remote server.

Pros and cons of each of these protocols:

  • With the old git protocol, data is not encrypted and there is no authentication to guarantee that the remote computer is really the one you intended to contact. This implies in particular that malicious actors who can intercept and inject packets between your computer and the legitimate server can make you download what they want, instead of what the legitimate server would normally have sent (this is called a man-in-the-middle attack). This risk is partially mitigated in the particular case of Git, at the condition that after every update performed using the unsafe git protocol, you double-check from a known-good source that the last commit identifier you got for each branch of the downloaded repository is the same as on the legitimate server. Needless to say, nobody does that. Besides, the SHA-1 algorithm that Git uses to compute commit identifiers has been somewhat weakened during the last years[1]; therefore, even if it's not the case at the time of this writing, one can't dismiss the possibility that at some point in the future, “bad guys” might be able to prepare malicious commits having the same identifier as one of the commits of the legitimate repository. For these reasons (especially the possibility of a man-in-the-middle attack), it is a good idea to avoid using the obsolete git protocol. In other words, don't use git:// when you clone a Git repository.
  • With the https protocol, all transferred data is encrypted and, more importantly here, the server you connect to is authenticated. The main problem here is that this protocol is not well implemented at SourceForge: cloning a large repository such as FGData using https (almost?) always fails. As far as I know, this problem doesn't happen with smaller repositories, nor does it happen when simply updating a large one that has already been cloned (it is indeed possible to clone a repository with a given protocol and later update it using another protocol; all one has to do for that is to modify the .git/config file inside the repository—this is precisely the method we are going to describe next, step by step).
  • With the ssh protocol, all transferred data is encrypted and the server you connect to is authenticated (this is done differently, but offers similar guarantees as the https protocol). The main problem in this case, which is generally a minor one, is that in order to download via the ssh protocol, you have to authenticate yourself to the server (in contrast with https, which allows anonymous downloads). This requires you to either enter a password or to use a (public, private) pair of SSH keys—the latter method being called public key authentication. On the other hand, getting yourself authenticated to the server is an advantage for development, because this allows server administrators to possibly grant you write access to the repository, should you be able and willing to contribute to the project (i.e., administrators could then allow you to run commands such as git push that update the remote repository).

When download_and_compile.sh clones a new repository, it uses by default the https protocol. This works fine except for FGData, for the reasons we have just explained (very large repository, transfer problems with SourceForge). Since using the git protocol is not an acceptable solution either, I recommend to clone the FGData repository using the ssh protocol. FGData can then be updated using https, and other repositories can be cloned as well as updated using https. The next section will explain step by step how to do that.

Another option is to use the ssh protocol in all cases. If you use an SSH agent in conjunction with public key authentication, this is quite a fine solution. But in case you don't, this method would require you to enter your SourceForge password every time a Git command needs to contact the remote server—assuming all repositories you work with are hosted there, which is the case for the FlightGear core repositories. Needless to say, this would be quite cumbersome unless you rarely interact with the remote server. Since setting up public key authentication requires more learning and work for users who are not already familiar with it, we are going to present the easier method here: using the ssh protocol for cloning FGData (i.e., only for the initial download) and https for all other communications initiated by the Git client on your computer. For those interested, the method based on public key authentication is explained in detail in French on this very page.

Getting started with download_and_compile.sh

The text that was temporarily here has been moved to its final location in the Scripted Compilation on Linux Debian/Ubuntu article.

Notations

The text that was temporarily here has been moved to its final location in the Scripted Compilation on Linux Debian/Ubuntu article.

Getting download_and_compile.sh the “right way”

The text that was temporarily here has been moved to its final location in the Scripted Compilation on Linux Debian/Ubuntu article.

Using download_and_compile.sh to build FlightGear

The text that was temporarily here has been moved to its final location in the Scripted Compilation on Linux Debian/Ubuntu article.

Using download_and_compile.sh to update FlightGear

The text that was temporarily here has been moved to its final location in the Scripted Compilation on Linux Debian/Ubuntu article.

Français

Vocabulaire technique français/anglais

authentification (authentication)
Action consistant à s'assurer que la personne/le serveur/etc. « en face » (de manière figurée) est bien celle/celui à qui l'on croit avoir affaire.
chiffrement (encryption)
Transformation réversible de données, de sorte qu'un tiers n'ayant pas la clé de déchiffrement ne puisse extraire aucune information utile à partir du contenu chiffré. La cryptographie symétrique utilise la même clé pour chiffrer et déchiffrer. À l'inverse, en cryptographique asymétrique, on travaille avec une paire de clés : une clé privée et une clé publique, les deux étant associées. Pour chiffrer un message, on utilise la clé publique du destinataire. Pour le déchiffrer, celui-ci utilise sa clé privée. On peut réaliser une signature numérique en utilisant la clé privée puis la clé publique (ceci est une description simplifiée de ce que font les logiciels tels que GnuPG lorsqu'ils produisent une signature numérique ; en effet, il est de bon ton d'ajouter quelques métadonnées au message pour garantir son intégrité).
empreinte numérique (hash, fingerprint)
Donnée numérique (c'est-à-dire qui peut être représentée par un nombre entier) servant à identifier un « objet » (un commit Git, un serveur, une clé numérique...). Il s'agit donc d'une sorte d'empreinte digitale, à ceci près qu'elle est numérique, qu'elle n'est a priori pas stockée sur les doigts et qu'elle identifie un objet à préciser, lequel n'est pas nécessairement une personne. L'identifiant d'un commit Git est une empreinte numérique obtenue à partir du contenu de ce commit (y compris de ses métadonnées, dont font partie les identifiants des commits parents). Exemple d'identifiant de commit Git : 44b411964109e6d0224577147c6e92d240c7a6cc.
dépôt (repository) [Git, Subversion, etc.]
Ensemble de fichiers et répertoires avec des métadonnées permettant de reconstituer toutes les versions antérieures « enregistrées » de chacun des fichiers. On peut obtenir une copie locale d'un dépôt existant en faisant git clone adresse_du_dépôt_source. L'opération de clonage est donc la première qui amène un dépôt donné sur votre système (disque dur, etc.). Une fois un dépôt cloné, on peut le mettre à jour avec des commandes telles que git pull --rebase. Si vous utilisez download_and_compile.sh, c'est lui qui se charge d'appeler Git avec les commandes adéquates pour cloner et mettre à jour. Il ne vous reste qu'à choisir le protocole à utiliser ; ce qui suit devrait vous aider dans ce choix.

Motivation

Git peut utiliser divers protocoles pour communiquer avec le serveur : le vieux protocole git, le protocole https ainsi que ssh. Quand on fait quelque chose comme

git clone ssh://...

ou

git clone https://...

le mot précédant :// indique quel protocole Git doit utiliser.

Avantages et inconvénients des trois protocoles :

  • Avec le vieux protocole git, les données transférées ne sont pas chiffrées et le serveur n'est pas authentifié. Cela signifie que quelqu'un qui est « bien situé » sur le réseau peut non seulement voir ce que vous téléchargez, mais aussi qu'il peut se faire passer pour le site depuis lequel vous croyez télécharger. Le deuxième point est assez embêtant, car il signifie qu'on peut vous refiler un dépôt contenant un malware (virus, cheval de Troie, etc.). Ce risque est potentiellement limité dans le cas particulier d'un dépôt Git, à condition de vérifier le hash du dernier commit après chaque mise à jour de chaque dépôt et de le comparer à une source sûre (qui fait cela ?). Et encore, l'algorithme utilisé pour les hash des commits Git, SHA-1, a déjà été beaucoup étudié[2] ; il n'est pas exclu qu'un de ces jours, on puisse fabriquer un commit foireux qui a le « bon hash », c'est-à-dire celui du dernier commit dans le dépôt officiel. Pour cette raison, il vaut mieux éviter ce protocole.
  • Avec le protocole https, les données transférées sont chiffrées et le serveur est authentifié. Le principal problème est que ce protocole n'a pas l'air parfaitement implémenté chez SourceForge : il est souvent impossible de cloner un dépôt très volumineux comme FGData. Pas de problème avec les dépôts de taille plus modeste à ma connaissance. Pas de problème non plus, en général, pour mettre à jour un dépôt volumineux déjà cloné (il est possible de cloner avec un protocole et mettre à jour avec un autre : il suffit de modifier le fichier .git/config à l'intérieur d'un dépôt pour changer le protocole utilisé lors des mises à jour).
  • Avec le protocole ssh, les données transférées sont chiffrées et le serveur est authentifié. Le principal problème est que pour utiliser ce protocole, il faut soi-même s'authentifier auprès du serveur (alors que l'on peut lire « anonymement » avec https), ce qui nécessite soit d'entrer un mot de passe, soit d'utiliser une paire de clés privée/publique. C'est en revanche un avantage pour le développement, car l'authentification permet d'exécuter des commandes git push si le serveur est configuré pour vous autoriser à le faire.

Quand download_and_compile.sh clone un nouveau dépôt, il utilise par défaut le protocole https. Ceci fonctionne bien sauf pour FGData, à cause de ce qui vient d'être dit (dépôt très volumineux, problème probable chez SourceForge). Comme le protocole git n'est pas satisfaisant non plus, je propose de cloner les dépôts hébergés chez SourceForge avec le protocole ssh. En appelant download_and_compile.sh de la manière suivante :

$ download_and_compile.sh --git-clone-site-params SourceForge=ssh:username DATA

on dit à download_and_compile.sh de cloner ou mettre à jour FGData. Si ce dépôt existe déjà à l'endroit attendu par download_and_compile.sh, il sera mis à jour en utilisant le protocole indiqué dans le fichier .git/config à l'intérieur du dépôt (qui, sauf si vous l'avez modifié, est celui utilisé lorsque le dépôt a été cloné). Sinon, il sera cloné et comme on a passé l'option --git-clone-site-params SourceForge=ssh:username et que FGData est situé chez SourceForge, download_and_compile.sh utilisera pour cette opération de clonage le protocole ssh ; il dira au serveur chez SourceForge que vous êtes l'utilisateur username, et il faudra donc prouver à SourceForge que c'est bien le cas (il faut bien sûr remplacer username par votre nom d'utilisateur chez SourceForge).

La manière la plus simple d'apporter une telle preuve consiste à entrer votre mot de passe SourceForge, mais il faudra alors le faire pour chaque opération de clonage ou de mise à jour du dépôt via ssh. Si vous travaillez avec plusieurs dépôts, par exemple si vous faites :

$ download_and_compile.sh --git-clone-site-params SourceForge=ssh:username

(commande qui clone ou met à jour, puis compile SimGear et FlightGear, et clone ou met à jour FGData), il faudra entrer le mot de passe pour chaque dépôt. Vous devinez que cela devient vite pénible. Il est cependant possible de seulement cloner avec SSH, puis changer le protocole pour chaque dépôt cloné grâce au .git/config à l'intérieur du dépôt et ainsi faire en sorte que les mises à jour des dépôts utilisent le protocole https, qui ne nécessite ni de créer vous-même une paire de clés, ni d'entrer un mot de passe. Si vous êtes pressé, c'est la méthode que je conseillerais. Voir ci-dessous pour plus de détails sur cette méthode.

Plutôt que d'envoyer son mot de passe SourceForge au serveur par SSH, il y a une autre manière de prouver à SourceForge que vous êtes bien l'utilisateur username : elle utilise la cryptographie asymétrique, autrement dit une paire de clés (privée, publique) au lieu d'un mot de passe. Cette méthode est sûre et permet de n'entrer le mot de passe de votre clé privée[3] qu'une fois pour tous les dépôts, jusqu'à ce que vous éteigniez votre ordinateur[4], ou jusqu'à épuisement d'un certain temps, ou encore jusqu'à ce que vous décidiez de mettre fin à la « mémorisation » de votre clé par l'agent SSH (notion qui sera présentée plus loin). Le but de la section suivante est de vous apprendre à mettre en place cette méthode d'authentification sûre et pratique, qui est valable dans le cadre général de l'utilisation de SSH.

Authentification SSH par paire de clés privée/publique

À l'exception des manipulations effectuées sur les pages web de SourceForge, ce qui suit est valable pour toute connexion entre un client et un serveur SSH. Si l'accent est mis sur SourceForge dans ce document, c'est pour pouvoir donner des exemples concrets et parce qu'il s'adresse en priorité aux personnes souhaitant compiler FlightGear ; or les dépôts concernés, essentiellement SimGear, FlightGear et FGData, sont tous situés chez SourceForge.

  1. Créez un compte sur SourceForge ici si vous n'en avez pas déjà un. Pour la suite, nous supposerons que le nom d'utilisateur associé à ce compte (le login) est username.
  2. Générez une paire de clés ssh. Sur votre Linux en utilisateur normal (on va dire que votre nom d'utilisateur est toto), lancez le programme ssh-keygen du package openssh-client :
    $ ssh-keygen -t rsa -b 4096
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/toto/.ssh/id_rsa):
    Created directory '/home/toto/.ssh'.
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/toto/.ssh/id_rsa.
    Your public key has been saved in /home/toto/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:p7fJx8tKBv1G92BOGxaE4sCbOd6Pu2UoydyPz5DG7wc toto@machine
    The key's randomart image is:
    +---[RSA 4096]----+
    |       .     ..  |
    |        o . ..   |
    |         * .  .  |
    |        =..    . |
    |       .Soo . B  |
    |       o.B.=E* = |
    |        * @+=.o .|
    |         B.&+ .  |
    |          OBOo   |
    +----[SHA256]-----+
    

    (Le choix des options -t rsa et -b 4096 passées à ssh-keygen dépend des connaissances publiques actuelles en cryptanalyse... Il faudra sans doute supprimer ces options ou les adapter dans quelques années, si/quand les clés RSA longues de 4096 bits seront considérées comme non sûres.)

    Vous disposez désormais d'une paire de clés associées situées dans le répertoire /home/toto/.ssh, utilisables avec la suite de logiciels OpenSSH (notamment avec ssh, ssh-add et ssh-agent). L'une est appelée publique, l'autre privée, et elles sont associées : ce qui est chiffré par l'une ne peut être déchiffré que par l'autre, dans l'état actuel des connaissances. C'est ce que l'on appelle la cryptographie asymétrique, par opposition à la cryptographie symétrique, où la même clé est utilisée pour chiffrer et pour déchiffrer un message.

    Il ne faut jamais envoyer la clé privée sur Internet : dans le cas qui nous concerne (authentification avec ssh), elle joue le rôle d'un mot de passe particulièrement costaud. Par sécurité au cas où quelqu'un vous volerait votre ordinateur ou s'introduirait dedans à distance, la clé privée est elle-même protégée par un mot de passe : celui que vous a demandé ssh-keygen ci-dessus (ssh l'appelle “passphrase”, autrement dit « phrase de passe », et vous suggère ce faisant de choisir quelque chose d'assez long). La clé publique, en revanche, peut être divulguée à un tiers sans que cela présente de risque, sauf bien sûr bug majeur dans ssh ou si l'on découvrait une manière de « casser » les algorithmes cryptographiques utilisés. Nous allons d'ailleurs communiquer notre clé publique au site SourceForge, ce qui nous permettra de nous authentifier grâce à la clé privée associée sans la communiquer à quiconque, simplement grâce à un calcul faisant intervenir la clé privée (pas de panique, ssh s'occupe de tout !).

    Si vous avez utilisé la commande ssh-keygen ci-dessus, votre clé privée fraîchement générée se trouve a priori dans le fichier /home/toto/.ssh/id_rsa, et la clé publique associée dans le fichier /home/toto/.ssh/id_rsa.pub. Cette dernière ressemble à ceci :

    ssh-rsa AAAAB3Nza...neeEw== toto@machine

    Le toto@machine est un commentaire ajouté automatiquement ; il peut aider à s'y retrouver quand on a plein de clés publiques, mais je vous conseille de ne pas l'inclure si vous communiquez votre clé publique à quelqu'un, par exemple à SourceForge, puisqu'il révèle votre nom d'utilisateur local ainsi que celui de votre ordinateur. Si, en revanche, vous copiez la clé publique sur une machine de votre réseau local à la maison, laisser le commentaire en place est nettement moins problématique (les seules personnes pouvant exploiter les renseignements présents dans le commentaire auraient nécessairement déjà un accès à une de vos machines).

  3. Copiez votre clé SSH publique sur SourceForge comme suit.
    • Allez dans votre espace personnel sur SourceForge.
    • Cliquez sur Account Settings dans la liste déroulante Me (ou Moi) en haut à droite.
    • Cliquez sur SSH Settings.
    • Dans la zone de texte en face de SSH Public Keys, faites un copier/coller de votre clé publique (c'est-à-dire du contenu de /home/toto/.ssh/id_rsa.pub à l'exception du commentaire final du type toto@machine). Autrement dit, dans mon exemple ci-dessus, il s'agit de coller une seule longue ligne de la forme
      ssh-rsa AAAAB3Nza...neeEw==
    • Il est possible d'uploader plusieurs clés publiques de cette façon en en mettant une par ligne.
    • Cliquez sur Save.
  4. Vous pouvez désormais vous authentifier auprès de SourceForge avec le nom username de votre compte SourceForge, grâce à la clé privée contenue dans /home/toto/.ssh/id_rsa. Ceci fonctionne car SourceForge dispose maintenant de la partie publique de cette paire de clés et sait que cette clé appartient à username.
    Note  Il n'est pas nécessaire de préciser quelle clé on utilise avec cette méthode. Quand le client SSH tente d'établir une connexion avec un ordinateur qui fait tourner le serveur SSH, il envoie au serveur la liste des clés publiques à sa disposition — sauf si votre configuration SSH l'interdit. Si le serveur reconnaît une des clés autorisées par une procédure telle que ce que nous avons fait au point c), il répond au client : « OK, cette clé publique, je la connais ; prouve-moi que tu as la clé privée associée » (cela s'appelle un “challenge”). Il s'agit pour le client de chiffrer un certain paquet d'octets choisi par le serveur, avec la fameuse clé privée. Le client s'exécute, envoie le paquet sous forme chiffrée, le serveur le déchiffre (il le peut car il a la clé publique) et compare le résultat à ce qu'il avait demandé. Simple comme bonjour, n'est-ce pas ? :-)

    Si vous avez bien suivi, n'importe qui disposant de la clé publique pouvait déchiffrer le paquet envoyé par le client, mais seul quelqu'un possédant la clé privée pouvait préparer le paquet sous cette forme — dans l'état actuel des connaissances publiques. En fait, ce qu'a fait le client ici, c'est ce qu'on appelle une signature numérique du paquet d'octets choisi par le serveur. Si l'on avait chiffré avec la clé publique, seule la clé privée permettrait de déchiffrer le message : dans ce cas, ce serait un véritable chiffrement et non une signature. Mais les opérations mathématiques sont a priori les mêmes ; on choisit simplement la clé utilisée en premier — publique ou privée — en fonction de l'usage souhaité.

    Note  Si vous souhaitez utiliser cette méthode, appelée public key authentication, pour vous connecter par SSH à un serveur quelconque sur lequel vous avez un compte, vous pouvez ajouter votre clé publique au fichier ~/.ssh/authorized_keys dans votre compte sur le serveur, avec des permissions du genre -rw------- (mettre une clé par ligne). Le programme ssh-copy-id peut être utilisé pour automatiser ce genre d'opération. L'étape c) ci-dessus revient à faire cela pour votre compte chez SourceForge.

    Lorsqu'un client SSH utilise ainsi une paire de clés (publique, privée) pour s'authentifier auprès d'un serveur SSH, on voit en principe une invitation à entrer la “passphrase” que vous avez donnée ci-dessus à ssh-keygen et qui protège votre clé privée. Cette demande peut apparaître dans le terminal depuis lequel le client SSH a été appelé (par exemple avec une commande telle que git clone ssh://...) ou bien dans une fenêtre graphique qui apparaît au moment opportun (voir ci-dessous). En tout état de cause, cette demande de mot de passe, ou “passphrase”, doit provenir de votre ordinateur, et la “passphrase” ne sort pas de votre ordinateur ; elle sert juste à ce que ssh puisse déverrouiller votre clé privée et s'en servir, sans la transmettre, pour prouver au serveur SSH (situé chez SourceForge en ce qui nous concerne ici) que vous êtes bien en possession de la clé privée correspondant à la clé publique uploadée à l'étape c).

  5. Il est temps de faire les premiers tests. Par exemple :

    $ cd /tmp
    $ git clone ssh://username@git.code.sf.net/p/flightgear/fgmeta
    

    (j'ai choisi FGMeta parce que c'est assez petit)

    Vous devriez voir un message de ce genre :

    The authenticity of host 'git.code.sf.net (216.105.38.16)' can't be established.
    ECDSA key fingerprint is SHA256:FeVkoYYBjuQzb5QVAgm3BkmeN5TTgL2qfmqz9tCPRL4.
    Are you sure you want to continue connecting (yes/no)?

    Votre client SSH vous prévient qu'il ne peut pas garantir que le serveur en face (ici, se présentant comme git.code.sf.net) est bien celui que vous voulez. Il se pourrait qu'un attaquant bien placé ait répondu à sa place et se fasse passer pour le « vrai » git.code.sf.net. Bon. Heureusement, on peut s'en sortir sans passer par la prière. Ouvrez dans votre navigateur préféré la page chez SourceForge qui donne les empreintes numériques des machines accessibles au public, vérifiez que le cadenas indique bien une connexion sécurisée et que l'empreinte (fingerprint) de la clé mentionnée dans le message ci-dessus est bien celle d'un serveur de SourceForge ayant un nom DNS suivant le motif *.code.sf.net. En clair, avec le message ci-dessus, il faut vérifier que la page indiquée liste bien un hash de type SHA-256 égal à FeVkoYYBjuQzb5QVAgm3BkmeN5TTgL2qfmqz9tCPRL4 pour *.code.sf.net. Si c'est le cas, tout va bien, répondez yes. Sinon, répondez no et lisez le paragraphe SSH Host Key Verification de la même page.

    Dans la suite, nous supposerons qu'il n'y a pas eu de problème et que vous avez donc répondu yes. Ceci implique que SSH va mémoriser l'empreinte du serveur dans le fichier ~/.ssh/known_hosts. La question précedente ne vous sera donc plus posée tant que le même serveur renverra la même clé pour se présenter. Mais si un jour vous vous reconnectez au même serveur SSH et que celui-ci s'annonce avec une empreinte différente, SSH va vous prévenir qu'il y a danger à poursuivre la connexion. En effet, un tel évènement pourrait signifier que quelqu'un essaie de se faire passer pour le serveur auquel vous souhaitez vous connecter, mais n'en possède pas la clé privée. SSH et la cryptographie asymétrique fournissent donc une protection efficace contre ce type d'attaque. En pareil cas, on peut se reporter à la page déjà mentionnée... en espérant qu'elle n'a pas été piratée. Bref, la situation, si elle se produit, doit appeler à une grande vigilance (rassurez-vous, il est quasi impossible de se retrouver dans cette situation et de ne pas s'en rendre compte : le message affiché par ssh en pareil cas est très visible et explicite !).

  6. Si vous avez été rapide à valider l'empreinte du serveur à l'étape e), vous devez avoir un clone de FGMeta tout neuf dans /tmp. Sinon, il suffit de relancer la commande

    $ git clone ssh://username@git.code.sf.net/p/flightgear/fgmeta
    

    Comme l'empreinte du serveur est désormais connue de votre client SSH, cela devrait passer comme une lettre à la poste. SSH va juste vous demander la “passphrase” pour déverrouiller votre clé privée, comme je l'ai expliqué au point d). C'est celle que vous avez donnée à ssh-keygen lorsque vous avez généré votre paire de clés.

  7. Reprenons : vous pouvez cloner un dépôt Git depuis SourceForge avec le protocole SSH. On aurait sans doute pu faire cela sans la paire de clés, avec un « simple » mot de passe, mais il y a trois avantages à utiliser l'authentification par clé publique comme nous venons de faire :
    • Votre clé privée est équivalente à un très gros mot de passe, que vous seriez sans doute incapable de mémoriser.
    • Vous ne la transmettez jamais à SourceForge ni aucun tiers. Le système challenge-response permet de prouver que vous avez la clé sans la transmettre. Il est toujours préférable, lorsque c'est possible, de ne pas donner de mot de passe à des tiers (de toute façon, vous n'utilisez pas le même mot de passe pour des sites différents, n'est-ce pas ?).
    • Lorsqu'on s'authentifie par mot de passe, chaque commande qui contacte le serveur, telle que git clone, git pull ou git fetch, nécessite d'entrer le mot de passe. Vu le nombre de dépôts qu'il faut mettre à jour avec FlightGear (SimGear, FlightGear, FGData et éventuellement FGAddon), ce n'est pas pratique du tout. Mais nous allons voir qu'avec l'authentification par clé publique, l'agent SSH permet de n'entrer qu'un mot de passe, une fois pour toutes, jusqu'à ce que vous le terminiez (par exemple, par fermeture de la session) ou jusqu'à expiration d'un “timeout”, si vous utilisez ssh-agent et avez choisi l'option correspondante.
  8. Introduction à l'agent SSH

    L'agent SSH est un programme dont le rôle est de garder en mémoire les clés que vous lui confiez et de les passer à ssh chaque fois que c'est nécessaire. Le projet OpenSSH comporte un agent appelé ssh-agent ; il est sans doute déjà installé sur votre ordinateur si vous avez ssh.

    Lorsqu'une clé (privée) est confiée à l'agent, on vous demande la “passphrase” nécessaire pour la déverrouiller, de la même façon qu'au point d) ci-dessus. La clé privée déverrouillée est alors gardée en mémoire par l'agent. Tant que l'agent SSH fonctionne et a votre clé privée, il est possible de se connecter à un serveur SSH (par exemple avec une commande du type git clone ssh://...) au moyen de cette clé sans avoir à entrer la “passphrase” qui la protège.

    Le fait que la clé privée soit stockée sous forme déverrouillée en mémoire RAM n'est pas vraiment un problème, car pour qu'un individu malveillant puisse la lire dans l'espace mémoire du processus correspondant à l'agent SSH, il faudrait qu'il soit déjà installé dans votre compte, auquel cas c'est GAME OVER. Reste le fait que la mémoire vive peut être copiée vers la zone de swap en principe, et donc sur un disque dur. Mais ce problème ne se pose pas a priori pour ssh-agent, car il prend des mesures spécifiques pour que la clé ne se retrouve pas en zone de swap. J'espère que les autres agents SSH font de même.

    Pour qu'un processus puisse bénéficier de l'agent SSH, il faut qu'il voie dans son environnement une variable lui permettant de communiquer avec l'agent ; il s'agit de la variable SSH_AUTH_SOCK. Pour la mettre en place, il y a plusieurs manières de procéder. Comme l'agent SSH est souvent lancé d'office au début de la session graphique X11 afin que tous les programmes de la session graphique puissent en bénéficier[5], on peut commencer par regarder s'il n'est pas déjà lancé chez vous. Je vous propose de lancer la commande suivante afin d'examiner le contenu de la variable d'environnement SSH_AUTH_SOCK :

    $ env | grep SSH_AUTH_SOCK
    SSH_AUTH_SOCK=/home/toto/.cache/keyring-TRIOXN/ssh
    
    • Si vous obtenez une ligne de ce genre, vous avez a priori déjà un agent SSH disponible pour toto.
    • Si cette commande ne renvoie rien, vous n'avez aucun agent SSH disponible pour toto. Nous allons voir dans un instant comment en activer un : allez directement au point (i) dans ce cas.

    À partir d'ici, nous nous plaçons dans l'hypothèse où la variable d'environnement SSH_AUTH_SOCK est positionnée et non vide, c'est-à-dire dans le premier cas ci-dessus. Cette variable indique à tout processus comment contacter l'agent SSH, qu'il s'agisse du programme ssh-agent de la suite OpenSSH ou d'un logiciel compatible tel que le composant ssh de gnome-keyring-daemon. Nous allons justement essayer de savoir quel est le programme qui joue ce rôle sur votre système. Pour cela, assurons-nous déjà qu'il est activé, en lançant par exemple :

    • En tant que toto (votre compte utilisateur normal) :
      $ echo "$SSH_AUTH_SOCK"
      /home/toto/.cache/keyring-TRIOXN/ssh
      
    • En tant que super utilisateur (root) :
      # fuser /home/toto/.cache/keyring-TRIOXN/ssh
      /home/toto/.cache/keyring-TRIOXN/ssh:  8825
      

    La socket /home/toto/.cache/keyring-TRIOXN/ssh (valeur de SSH_AUTH_SOCK) a donc été ouverte par le processus dont l'identifiant (PID) est 8825. Cherchons maintenant qui est ce processus :

    En tant que toto :

    $ ps -eo pid,cmd | grep -Ee '^ *8825 +'
     8825 /usr/bin/gnome-keyring-daemon --daemonize --login
    

    Ici, le processus de PID 8825 qui a ouvert la socket dont le nom est contenu dans la variable d'environnement SSH_AUTH_SOCK est donc gnome-keyring-daemon. C'est lui qui, sur le système utilisé pour cet exemple, joue le rôle de l'agent SSH. Si le programme jouant le rôle d'agent SSH avait été ssh-agent, on aurait trouvé ssh-agent dans la sortie de la commande ps -eo pid,cmd | grep -Ee '^ *8825 +' ci-dessus. On obtient notamment quelque chose comme ceci lorsque ssh-agent est lancé par /etc/X11/Xsession.d/90x11-common_ssh-agent grâce à l'option use-ssh-agent du fichier /etc/X11/Xsession.d/Xsession.options (sous Debian) :

    $ ps -eo pid,cmd | grep -Ee '^ *8825 +'
    8825 /usr/bin/ssh-agent /usr/bin/im-launch x-session-manager
    

    Avec ce qui précède, vous devez être en mesure de déterminer si vous disposez sur votre compte d'un agent SSH (programme offrant un service compatible avec ssh-agent sur la socket indiquée par SSH_AUTH_SOCK) et, le cas échéant, si ce service est fourni par le programme ssh-agent qui vient avec OpenSSH ou par gnome-keyring-daemon. Notez qu'il existe d'autres programmes fournissant un tel service, par exemple GnuPG Agent si l'on active l'option correspondante ; on en trouvera quelques-uns sur le wiki d'Arch Linux.

  9. Comment lancer un agent SSH ?

    Cette étape présente plusieurs façons de lancer un agent SSH tel que le programme ssh-agent ou celui fourni par gnome-keyring-daemon. Si l'étape précédente vous a permis d'établir qu'il y en a déjà un pour votre compte utilisateur normal, vous pouvez passer à l'étape suivante.

    Sous Debian, le programme ssh-agent est automatiquement lancé au démarrage d'une session graphique X11 si le paquet openssh-client est installé et l'option use-ssh-agent n'est pas commentée dans /etc/X11/Xsession.d/Xsession.options ; pensez à relancer la session graphique si vous venez juste d'activer l'option. Cette manière de procéder s'applique à tous les utilisateurs dès lors qu'ils travaillent dans une session graphique. L'agent SSH lancé de cette manière est le programme ssh-agent livré avec OpenSSH.

    Comme indiqué plus haut, GNOME Keyring fournit aussi un composant qui peut jouer le rôle d'agent SSH. On peut l'activer sous XFCE en allant dans le menu XFCE, puis SettingsSession and startup, onglet Advanced, et enfin cocher Launch GNOME services on startup. Il semble que cette méthode ait priorité sur la précédente lorsque les deux sont simultanément actives, peut-être car dans ce cas, c'est gnome-keyring-daemon qui est lancé en dernier et impose donc la valeur finale de SSH_AUTH_SOCK, qui permet de le contacter. Il y a certainement des méthodes similaires pour les environnements de bureau autres que XFCE.

    Note  Certaines personnes bricolent pour lancer gnome-keyring-daemon sans le composant qui offre le service d'agent SSH, car ils souhaitent vraiment utiliser le programme ssh-agent d'OpenSSH. L'intention me semble tout à fait légitime, mais les bricolages en question n'ont pas l'air très jolis... Il y a une autre méthode donnée sur le wiki d'Arch Linux. Je précise que je n'ai testé aucune de ces méthodes.

    Citons enfin deux autres manières plus artisanales mais tout aussi valables de lancer un agent SSH, en l'occurrence ssh-agent. La première consiste à passer une commande en argument à ssh-agent. Par exemple, si l'on exécute la commande suivante dans un terminal :

    Remplacez bash par votre shell préféré (a priori, $SHELL) :

    $ ssh-agent bash

    on obtient un nouveau shell supervisé par ssh-agent, dans lequel la variable SSH_AUTH_SOCK est positionnée comme il faut pour contacter l'agent (on dispose aussi de SSH_AGENT_PID pour trouver son PID). Toute commande lancée depuis ce nouveau shell bénéficie de la présence de l'agent. On peut terminer ce nouveau shell et l'agent avec exit ou en faisant Ctrl-D en début de ligne dans le nouveau shell.

    La deuxième manière « artisanale » de lancer ssh-agent consiste à exécuter l'une des commandes suivantes dans un shell :

    $ eval $(ssh-agent -s)  # pour un shell de type Bourne (Bash, Zsh...)

    ou

    $ eval $(ssh-agent -c)  # pour un shell dérivé de csh

    Contrairement à la méthode précédente, celle-ci ne crée pas de nouveau shell : elle se contente de lancer ssh-agent et de positionner les variables d'environnement SSH_AUTH_SOCK et SSH_AGENT_PID de sorte que tout programme lancé depuis le shell où vous avez exécuté l'une des deux commandes eval ci-dessus soit en mesure de contacter l'agent SSH.

  10. Utilisation de ssh-add et de l'agent SSH pour se faciliter la vie

    Vous savez maintenant comment lancer un agent SSH. Dans ce qui suit, je suppose qu'il s'agit soit de ssh-agent, soit de l'agent SSH fourni par gnome-keyring-daemon. Dans un cas comme dans l'autre, la variable d'environnement SSH_AUTH_SOCK doit avoir une valeur non vide (faire echo $SSH_AUTH_SOCK dans un terminal). Si ce n'est pas le cas, retournez à l'étape précédente.

    1. Premier cas : l'agent SSH est gnome-keyring-daemon

      Le fonctionnement est assez simple : si vous lancez une commande faisant appel à un client SSH et si l'authentification peut se faire avec une clé privée que gnome-keyring-daemon « voit » (fichiers id_algo et id_algo.pub présents dans ~/.ssh/, je suppose), alors l'agent SSH procédera automatiquement à l'authentification grâce à cette clé, en vous demandant la “passphrase” nécessaire pour déverrouiller la clé, si cela n'a pas déjà été fait. Tant que gnome-keyring-daemon n'est pas arrêté, d'autres connexions peuvent être établies avec des serveurs SSH sans qu'aucune “passphrase” ne soit pas demandée, à condition que l'authentification auprès de ces serveurs puisse se faire avec une clé déjà déverrouillée. Lorsqu'une “passphrase” est demandée, cela se passe dans une fenêtre “pop-up” graphique, pas dans un terminal — contrairement à ce qui se passe avec la configuration par défaut de ssh-agent.

      Vous pouvez tester cela en lançant des commandes telles que

      $ git clone ssh://username@git.code.sf.net/p/flightgear/fgmeta
      

      et les autres indiquées ci-dessous (pour celle-ci, placez-vous dans un répertoire temporaire car vous allez récupérer un clone de FGMeta dans le répertoire courant).

    2. Deuxième cas : l'agent SSH est ssh-agent

      Plaçons-nous donc dans un shell sous sa supervision (la commande env | grep SSH_ doit montrer que les variables d'environnement SSH_AUTH_SOCK et SSH_AGENT_PID sont positionnées et non vides). Lancez la commande suivante :

      $ ssh-add -l
      The agent has no identities.
      

      Cela signifie que l'agent SSH est là mais qu'on ne lui a pas encore confié de clé. Transmettons-lui notre clé SSH privée (il faut entrer la “passphrase” pour la déverrouiller), puis relançons ssh-add -l :

      $ ssh-add ~/.ssh/id_rsa
      Enter passphrase for /home/toto/.ssh/id_rsa:
      Identity added: /home/toto/.ssh/id_rsa (toto@machine)
      $ ssh-add -l
      4096 SHA256:p7fJx8tKBv1G92BOGxaE4sCbOd6Pu2UoydyPz5DG7wc toto@machine (RSA)
      

      Ceci confirme que ssh-agent est désormais en possession d'une clé dont ssh-add nous précise la taille en nombre de bits, le type et l'empreinte.

      Note  On peut se contenter de lancer ssh-add sans argument : il essaie alors d'ajouter les clés éventuellement contenues dans ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa et ~/.ssh/id_ed255190.
      Tip  Une différence notoire avec le cas où l'agent SSH est gnome-keyring-daemon est qu'ici, on a dû utiliser ssh-add pour confier la clé à l'agent (cela se fait automatiquement lorsque l'agent SSH est gnome-keyring-daemon). Avec une ligne telle que AddKeysToAgent yes dans ~/.ssh/config, il est possible de faire en sorte que ssh ajoute automatiquement chaque clé utilisée à ssh-agent, comme cela se passe avec gnome-keyring-daemon. Il y a également d'autres possibilités de configuration avec ce paramètre, qui peut prendre chacune des valeurs yes, confirm, ask et no (voir la page de manuel ssh_config(5)).
      Note  Il est possible de « reprendre » des clés confiées à ssh-agent avec les options -d et -D de ssh-add. L'option -t de ssh-agent permet, quant à elle, de spécifier une durée maximale de rétention des clés par l'agent (un timeout, d'où le nom de l'option). De toute façon, la rétention des clés sous forme déverrouillée par ssh-agent se passe exclusivement en mémoire RAM ; du fait de l'utilisation de mlock(2), la ou les pages mémoire concernées ne peuvent être envoyées dans la zone de swap. Les clés sont retirées à l'agent lorsqu'il est terminé, en particulier lorsque que vous arrêtez ou redémarrez votre ordinateur (où même seulement la session graphique, si c'est elle qui lance l'agent dans votre configuration).
  11. Voilà, c'est terminé. Depuis n'importe quel shell s'exécutant sous la supervision de l'agent SSH, vous pouvez désormais lancer n'importe quelle commande faisant appel à un client SSH : si l'authentification peut se faire avec une clé privée que vous avez confiée à l'agent, la connexion sera établie sans qu'il soit nécessaire d'entrer un quelconque mot de passe. Depuis un tel shell, vous pouvez donc lancer des commandes utilisant l'authentification par SSH, par exemple :

    Pour télécharger un clone de FGMeta dans le répertoire courant :

    $ git clone ssh://username@git.code.sf.net/p/flightgear/fgmeta
    

    Pour cloner FGData avec le protocole SSH, à supposer que download_and_compile.sh ne l'ait pas encore cloné ici (sinon, il va simplement mettre à jour FGData en utilisant le protocole indiqué dans install/flightgear/fgdata/.git/config, qui n'est pas forcément SSH) :

    $ download_and_compile.sh --git-clone-site-params SourceForge=ssh:username DATA
    

    Même chose pour les trois dépôts SimGear, FlightGear et FGData correspondant aux arguments optionnels SIMGEAR, FGFS et DATA de download_and_compile.sh. Vous pouvez mettre en place un alias ou un mini-script pour ne pas vous embêter à retenir l'option un peu longue.

    $ download_and_compile.sh --git-clone-site-params SourceForge=ssh:username
    

    Pour obtenir de l'aide relative à la commande suivante (voir le service shell de SourceForge) :

    $ ssh username@shell.sourceforge.net
    

    Pour démarrer un shell chez SourceForge :

    $ ssh -t username@shell.sourceforge.net create
    

Autre méthode : clonage avec SSH et mises à jour avec HTTPS

Voici une autre méthode pour obtenir et mettre à jour de manière sûre les dépôts avec download_and_compile.sh :

  1. Créez un compte sur SourceForge ici si vous n'en avez pas déjà un. Pour la suite, nous supposerons que le nom d'utilisateur associé à ce compte (le login) est username.
  2. Clonez les dépôts qui vous intéressent avec le protocole SSH :

    $ download_and_compile.sh --git-clone-site-params SourceForge=ssh:username
    

    ou bien, par exemple :

    $ git clone ssh://username@git.code.sf.net/p/flightgear/fgmeta
    

    À moins que vous ne vous soyez déjà connecté à git.code.sf.net avec le protocole SSH, vous devriez voir un message de ce genre :

    The authenticity of host 'git.code.sf.net (216.105.38.16)' can't be established.
    ECDSA key fingerprint is SHA256:FeVkoYYBjuQzb5QVAgm3BkmeN5TTgL2qfmqz9tCPRL4.
    Are you sure you want to continue connecting (yes/no)?

    Reportez-vous ici et revenez une fois que vous avez ajouté la clé (il s'agit de vérifier que la clé présentée par le serveur en guise de carte d'identité est bien celle de git.code.sf.net et de confirmer ce fait à SSH en répondant yes à la question posée ; par la suite, SSH ne posera plus cette question tant que le serveur enverra la même clé).

    Une fois l'authenticité du serveur confirmée, SSH commence à cloner le ou les dépôts que vous avez choisi(s). À moins d'avoir, comme expliqué dans la première méthode, mis en place un agent SSH et uploadé une clé SSH publique à l'endroit prévu pour cela dans votre compte chez SourceForge, il faut alors entrer votre mot de passe SourceForge une fois pour chaque dépôt à cloner.

  3. Nous supposons maintenant que l'étape précédente s'est déroulée sans erreur. Vous avez donc un ou des dépôts tout neuf(s), fraîchement cloné(s). Dans chacun de ces dépôts, il y a un fichier .git/config qui contient quelque chose comme ceci :

    [remote "origin"]
            url = ssh://username@git.code.sf.net/p/flightgear/fgmeta
            fetch = +refs/heads/*:refs/remotes/origin/*
    

    La première ligne indique à Git le nom de la remote correspondant à la source utilisée lors du clonage, donc ici un serveur chez SourceForge (par défaut, la remote s'appelle origin). La ligne commençant par url = précise le protocole utilisé pour communiquer avec cette remote. Ici, nous avons le protocole ssh car c'est lui qui a été utilisé pour l'opération de clonage. Changez-le en https en remplaçant la ligne :

    url = ssh://username@git.code.sf.net/p/flightgear/fgmeta
    

    par

    url = https://git.code.sf.net/p/flightgear/fgmeta
    

    (fgmeta est pris comme exemple ici, mais vous devez bien sûr laisser le nom du dépôt tel que vous l'avez trouvé).

    Tip  Plutôt que de modifier manuellement le fichier .git/config dans chaque dépôt, on peut aussi utiliser git remote set-url remote url à l'intérieur de chaque dépôt. Par exemple, pour FGMeta, il suffit d'aller dans le répertoire correspondant et de lancer :
    git remote set-url origin https://git.code.sf.net/p/flightgear/fgmeta
    
  4. Répétez l'opération précédente pour chaque dépôt.
  5. Pour les mises à jour:
    • Si vous utilisez download_and_compile.sh, une fois le clonage initial effectué, il n'est plus nécessaire de lui passer l'option --git-clone-site-params, car les mises à jour se font toujours avec le protocole indiqué dans le fichier .git/config de chaque dépôt (donc ici, avec https).
    • Si vous n'utilisez pas download_and_compile.sh, mettez à jour vos dépôts normalement avec git pull ou git pull --rebase.

Les mises à jour étant moins volumineuses que le clonage initial en général, cette méthode assez simple devrait apporter satisfaction (sécurité et pas de problème de fiabilité).

Références / References

  1. See for instance this Google report.
  2. Voir par exemple ces travaux de Google.
  3. À ne pas confondre avec le mot de passe de votre compte chez SourceForge !
  4. Pour simplifier : nous donnerons des conditions plus précises ci-dessous.
  5. Ceci car les variables d'environnement d'un processus sont, sauf indication contraire, transmises à ses processus fils.