Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Tag: Ssh

Niveau :      
Résumé : ssh-agent ; ssh-add

Comme je l'ai déjà expliqué il y a quelque temps, il est possible grâce à ssh-agent de réutiliser sa clé ssh. C'est bien, mais en pratique, comment fonctionne cet agent ?

L'agent est un processus qui gère vos clés. Il communique à travers une socket. Ssh-add lit une clé sur votre compte utilisateur et demande de l'ajouter à travers la socket. Le client ssh lui va demander les clés disponibles à la socket pour se connecter quelque part.

Lorsque vous vous connectez en ssh avec l'option -A (en général présente par défaut), ssh tunnelle simplement une socket sur la machine de destination vers la machine de départ. Ce qui veut dire que l'agent que vous utiliserez sur cette machine distante est celui de la machine d'origine. Autrement dit vous disposez des clés de la machine de départ, mais ssh-add ajoutera des clés de la machine de destination sur la machine de départ. Testez, vous verrez c'est amusant.

Maintenant puisque la communication se fait à travers une socket, n'importe quel processus peut communiquer avec elle. C'est en partie vrai, car les socket respectent les droits établis par le système de fichier. Donc en gros seul root et vous peuvent communiquer avec cette socket. Ainsi, si vous vous connectez à une machine sur laquelle vous avez déjà un agent qui tourne vous pouvez le réutiliser.

Pour avoir la liste des agents disponibles :

$ ls -ld /tmp/ssh-* | grep `whoami`

Mais attention, cela contient aussi les socket ouvertes pas les ssh qui se sont connectés avec le forwarding d'agent. Pour les différencier, vous devrez utiliser la date. Vous pouvez aussi avoir quelques info supplémentaire avec netstat :

$  netstat -lnp --unix | grep ssh-

Maintenant, pour la réutiliser, il suffit simplement d'affecter la variable adaptée :

$ export SSH_AUTH_SOCK=/tmp/ssh-lwksuR6740/agent.6740
$ ssh nouvelle.machine
# et voila !

C'est bien pratique, mais n'oubliez pas une chose, cela signifie que root a accès à vos clés sans passphrase. Cela signifie aussi que vous ne devez jamais forwarder votre agent lorsque que vous vous connectez sur une machine avec un compte partagé. Cela signifierait que vos associés auraient accès à toute les clés dont vous disposez sur votre machine de départ. Si vous ne pouvez pas vous en passer, essayez au moins d'utiliser l'option -t de ssh-add qui limite en temps la validité de la clé.

$ ssh-add -t 600

Niveau :      
Résumé : xchat ; screen irssi

Allez-vous sur irc de temps en temps ? Non alors je vais vous couper la tête !

Introduction

Irc, Internet Relay Chat est LE moyen de discuter sur internet. Contrairement à la messagerie instantanée, l'irc a pour principe de base de discuter avec des groupes de personnes et non pas avec une personne en particulier. Bien sur, ceux qui veulent discuter seul à seul le peuvent aussi. Je vous passe les bases du protocole, mais il est assez simple. Le principe est de faire passer toute communication par un serveur, lequel redistribue le message vers les clients concernés. Comme il ne peut y avoir un serveur unique, les serveurs sont connectés entre eux et se redistribuent les messages à travers le net (comme pour les newsgroup).

Au départ l'irc était comme le mail, tout le monde pouvait parler à tout le monde, mais l'histoire ainsi que des désaccords sur la façon de gérer ce réseau on fait que l'irc est maintenant divisé en réseaux qui ne communiquent pas entre eux. Ces réseaux portent des noms comme efnet, dalnet, freenode ... on les compte par centaines. Et c'est bien dommage, car il est assez difficile de s'y retrouver.

Sur un réseau irc, on retrouve de nombreux canaux, un canal est un lieu de discussion dont le nom commence généralement par #. On en trouve des dizaines de milliers, chacun avec un sujet différent. C'est dire si vous pouvez y trouver votre bonheur.

Un client simple

Pour vous connecter sur irc, il existe un outil sympathique nommé xchat. Il a l'avantage de connaître la plupart des réseaux et la plupart des serveurs associés. Il vous permettra de vous connecter à plusieurs serveurs et à de nombreux canaux simultanément ?

Son interface graphique est simple et intuitive, et la plupart des actions peuvent être effectuées sans taper une seule commande.

Un client avancé

Mais ce n'est pas pour vous parler de xchat que je fais cet article. Un autre client irc populaire chez les linuxiens est irssi. Ce client fonctionne purement en mode texte. C'est à la fois un avantage et un inconvénient. Inconvénient car les débutants devront apprendre le commandes irc de base. Mais un avantage car il est possible de le lancer à peu près partout avec ou sans interface graphique et qu'on peut le combiner avec screen.

Détaillons donc ce que cela veut dire. Si vous disposez d'une machine connectée en permanence à internet, vous pourrez y lancer irssi pour ne jamais l'arrêter, jamais ... Vous ne perdrez plus une miette des discussions, et on pourra vous écrire même quand vous n'êtes pas là.

Pour le lancer :

$ screen -S irc
$ irssi 

Puis pour vous y reconnecter :

$ screen -d -r irc

Sachant qu'il vous arrivera de vous connecter à distance de temps en temps sur cette machine, créez vous un alias pour vous connecter à irc :

alias irc="ssh serveur.reseau.net 'screen -d -r irc'"

Irssi dispose de thèmes permettant de changer l'apparence des clients. Personnellement je préfère les thèmes alignés comme dot. Irssi dispose aussi de nombreux plugins permettant d'étendre celui-ci directement en perl. J'utilise par exemple hilightwin.pl qui permet d'avoir une fenêtre supplémentaire pour tous les messages qui vous concernent sur les canaux auxquels vous êtes connectés.

Niveau :      
Résumé : ssh root@<tab>

Rappelons le contexte, on veut pouvoir faire de la complétion automatique sur les noms de machine. La plupart des distributions ont déjà défini un fichier /etc/bash_completion qui fait ceci. Pour le faire, il lit le fichier ~/.ssh/known_hosts. On veut donc récupérer un fichier known_hosts complet pour permettre la complétion automatique. Et ô magie, il existe un outil presque tout fait pour faire ca : ssh-keyscan. C'est un outil qui va récupérer pour vous toutes les clés publiques des serveurs ssh que vous lui demandez. Mieux, il les met au format known_hosts, mieux il sait le faire en parallèle. Donc reprenons notre script d'hier et adaptons :

#!/bin/sh

# fichier hosts
FILE=~/.hosts

# domaines à scanner
DOMAINS="toto.net mamachine.net"

# machines à ajouter à la main (plus d'ip du tout)
cat > $FILE << EOF
mamachine.youpi.fr
tamachine.youpi.fr
EOF

for domaine in $DOMAINS
do
    dig $domaine axfr | egrep "IN[[:space:]]+A" | awk '{print  $1}' >> $FILE
done

# grep pour quelques petits bugs
grep -v "[#_*]" $FILE | ssh-keyscan -t rsa,dsa -f - > ~/.ssh/known_hosts

Petit inconvénient, ssh-keyscan s'arrête dès qu'il y a une erreur de résolution de nom. Pas cool, vous devez le relancer en filtrant mieux lorsque vous tombez sur une erreur.

Et voilà !

Enfin presque, car vous avez bien récupéré les clés, c'est pratique pour votre utilisation de ssh, mais qu'en est-il des nouvelles machines auxquelles vous accédez ? Elles sont naturellement ajoutées au fichier known_hosts, mais il existe deux méthodes pour stocker les noms de machine dans le known_hosts, soit en clair, soit hashé.

Et pour que la complétion fonctionne, il faut nécessairement que ce soit en clair. Donc option "HashKnownHosts no " dans .ssh/config. Mais attention, l'option a été inventée pour qu'en cas de compromission de votre machine l'attaquant ne sache pas quelles sont les machines que vous administrez régulièrement (pour tenter de s'y attaquer).

Vous abandonnerez donc une protection (somme toute légère), et en contrepartie vous avez une complétion avancée sous bash. Mieux, si votre agent tourne et que vous avez poussé vos clés sur les machines en question, la complétion fonctionnera aussi sur les noms de fichiers distants, exemple :

$ scp toto@machine:/<tab><tab> # root c'est mâaal !

Victoire !

Niveau :      
Résumé : ssh root@<tab>

Je suis sûr qu'il vous arrive souvent de taper ssh toto@mamachine.monreseau.net. Tellement souvent que vous avez fini par modifier votre ~/.ssh/config pour y mettre des alias. Pour ceux qui ont oublié comment faire voici la ligne à mettre :

Host machine
    Hostname mamachine.monreseau.net

Au passage vous pouvez ajouter le port et le login par défaut dans cette configuration.

Host machine
    Hostname mamachine.monreseau.net
    Port 1022
    User toto

Bien, passons maintenant quelque chose de tout aussi sympathique. Il est possible de demander à bash de compléter ces noms de machine, plutôt que de les entrer tout seul comme un grand. En effet, bash dispose de la complétion sur les noms de machine. Le simple fait de préfixer un nom par @ permet à bash de supposer que c'est un nom de machine. Mais alors comment fait-il pour les connaître tous ? Il lit la variable $HOSTFILE qui doit contenir le nom d'un fichier au format /etc/hosts. Si elle est vide il lit le fichier /etc/hosts.

Donc : ssh root@l</tab><tab> complète toujours au moins par localhost (ou presque).

Bien, mais nous n'allons pas remplir le fichier /etc/hosts à la main tout de même !

Non, nous allons faire mieux. Hop un script shell :


continue reading...

Niveau :      
Résumé : ssh -o VerifyHostKeyDNS=yes

Vous avez tous déjà touché à un ssh. Rappelez-vous votre première connexion :

$ ssh 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
RSA key fingerprint is d9:16:53:ef:84:cf:1a:ce:42:03:55:09:86:5c:0e:50.
Are you sure you want to continue connecting (yes/no)?

Mais qu'est-ce que c'est que ce bin's ? Bon aujourd'hui vous êtes grands, vous le savez, il s'agit de vérifier que la machine à laquelle on parle est bien celle à laquelle on voulait parler. Pour faire cette vérification, il faut aller demander à une personne de confiance qui administre ou qui s'est déjà connectée à la machine, si l'empreinte que vous avez sous les yeux est la bonne.

En pratique personne ne le fait ! Si vous l'avez toujours fait, soit vous ne vous êtes jamais connecté avec ssh, soit vous êtes Rain-Man. Sinon vous êtes à peu près normal.

Par conséquent vous faites confiance aux pirates de tout poil pour ne pas avoir attaqué votre serveur au moment de votre première session. Question qui ne se pose plus par la suite où vous faites implicitement confiance à vos connexions précédentes.

Confiance relative

Que faire pour éviter le désagrément de cette première connexion ? Tout dépend de votre confiance. Vous pouvez avoir une confiance absolue en votre réseau de machines :

$ ssh -o StrictHostKeyChecking=no mamachine.toto.net

Ou alors vous pouvez avoir une confiance nulle et considérer toute connexion dont la clé n'a pas été ajoutée à la main comme une première connexion :

$ ssh -o StrictHostKeyChecking=yes mamachine.toto.net

La valeur par défaut est ask et est écrite dans /ect/ssh/ssh_config (ou ~/.ssh/config si vous en avez un).


continue reading...

Niveau :      
Résumé : Match

Savez vous qu'en ssh vous pouvez imposer des contraintes à certains utilisateurs seulement.

Exemple pour interdire l'utilisation de mots de passe à un groupe d'utilisateurs (à mettre dans /etc/ssh/sshd_config) :

Match Group glandus
PasswordAuthentication no

Attention, toutes les lignes qui suivent un match sont liées à ce match juqu'au prochain match ou à la fin du fichier de configuration. Placez donc vos directives match à la fin du fichier.

Pour forcer l'utilisation d'une commande à un utilisateur donné :

Match User toto
ForceCommand /bin/cat /etc/php5/apache2/php.ini

Pour forcer l'affichage d'un texte d'avertissement avant la connexion pour les machines venant d'un certain réseau :

Match Host *.linux.fr
Banner /etc/ssh_warn

Pour interdire le forwarding de port à une machine (un utilisateur un peu doué saura bien sûr contourner ça) :

Match Address 192.168.1.1
AllowTcpForwarding no 

Niveau :      
Résumé : scp machine1:~/file machine2:~/

FXP

Le FXP est un détournement du protocole FTP. Le FTP utilisant une connexion différente pour les données et pour les commandes, il est possible d'ouvrir une connexion de commande sur 2 machines et de leur demander d'ouvrir la connexion de données entre elles deux, rien ne passe par vous. Explication plus détaillée.

En pratique, la plupart des clients ftp supportent ce système nativement (même en ligne de commande).

SCP

Maintenant supposons que vous n'ayez que ssh à disposition. Hé bien il est possible de faire le même genre de chose :

$ scp user1@machine1:/my/file/1 user2@machine2:/your/path

Le processus est alors le suivant :

  • scp vous connecte sur machine 1 (avec mot de passe si besoin)
  • puis depuis machine1, il tente de se connecter à user2@machine2 pour faire la copie (sans interaction cette fois).

Ceci a 2 inconvénients :

  • si le flux ssh n'est pas ouvert de machine1 vers machine2 vous êtes coincés
  • il faut que vous puissiez vous connecter de machine1 à machine2 sans mot de passe (avec une clé et un forward d'agent)

Si le flux est ouvert de machine2 vers machine1 (dans l'autre sens) ou si vous n'avez pas de clé ssh, vous pouvez aussi utiliser la commande suivante :

$ ssh user2@machine2 "scp user1@machine1:/my/file/1 /your/path"

Et si aucun flux n'est ouvert entre machine1 et machine2 il vous reste une dernière solution : passer par votre machine de commande. Pour ne pas avoir à stocker le fichier sur votre machine (transit uniquement) utilisez la commande suivante :

$ ssh user1@machine1 "cat /my/file/1" | ssh machine2 "cat > /your/path/1"

PS : Dans vos commandes scp, il est possible d'écrire "machine:" comme équivalent de "machine:~/"

PS2 : Dans vos commandes, si le nom d'un fichier local contient un ":", il vous faut donner un chemin contenant un / pour ne pas confondre avec un nom de machine. Ex:

$ scp machine:~/toto ./mon:repertoire/