Il s'agit ici principalement de renforcer la sécurité, et éviter une pollution des journaux par des tentatives d'attaque nombreuses mais primitives.
C'est l'outil de base pour administrer interactivement son serveur, le mettre à jour et l'auditer. Un introduction détaillée se trouve chez openclassrooms.
Le principe est celui d'une paire de clé indissociables:
ssh-add
, sous windows avec pageant
par exemple).
Si votre poste est sous windows, on recommande l'application MobaXterm.
Pour créer une paire de clés asymétriques (coté client, celui qui va se connecter), on peut utiliser la commande suivante:
ssh-keygen -t rsa -b 4096 -a 100 # n'écrasez SURTOUT PAS une clé existante si ce n'est pas ce que vous voulez faire! # saisissez une "passphrase" non triviale pour protéger la paire de clé (c'est très important!)
rappel: ne diffusez pas votre clé privée, elle est … privée! Seuls les
*.pub
doivent habituellement être envoyés (sauf rares cas où vous générez des clés pour vos clients par exemple).
Note: les cryptages DSA and RSA de 1024 bits ou moins sont désormais réputés "obsolètes". Vous pouvez vérifier le type de clés que vous utilisez avec ce petit script:
for k in ~/.ssh/id_*; do ssh-keygen -l -f "$k"; done | uniq
Le principe est d'avoir sa clé publique ajoutée dans le fichier ~/.ssh/authorized_keys
de l'utilisateur sur le serveur distant.
attention chez Scaleway: les fichiers
authorized_keys
pour l'utilisateur root
se font systématiquement écraser au démarrage, par les clés préconfugurées sur leur site (une très bonne idée en cas d'erreur de manipulation)! Il faut ajouter sa clé soit directement dans l'interface en-ligne de scaleway, soit sur le serveur dans le fichier spécial .ssh/instance_keys
puis lancer la commande d'incorporation scw-fetch-ssh-keys --upgrade
.
En temps normal, si l'on peut se logguer sur le compte distant (par exemple via un compte administrateur, ou via un accès root par login et mot de passe), on peut utiliser la commande suivante:
ssh-copy-id untel@mon.serveur.com
Si l'on dispose déjà d'un compte root sur un serveur distant, on peut ajouter sa clé publique directement depuis son poste local en une seule commande:
srv='mon.serveur.com' usr='untel' cat ~/.ssh/id_rsa.pub | ssh root@$srv "sudo -H -u $usr bash -c 'cat >> /home/$usr/.ssh/authorized_keys'"
L'autre approche est de copier sa clé publique vers le serveur, de s'y logguer, puis de l'ajouter en éditant avec vi
ou nano
le fichier authorized_keys
de l'utilisateur ciblé (attention de ne pas écraser les clés qui s'y trouvent déjà!)
On le configure principalement dans le fichier /etc/ssh/sshd_config
du serveur sur lequel on se connecte.
Pensez à redémarrer le serveur SSH après les modifications, avec
service sshd restart
.
Il est utile de configurer le service SSH sur un port non standard (22), afin d'en réduire la visibilité ainsi que la pollution des logs faces aux attaques "brute force" (innombrables!).
Port 12345
Chez Scaleway, on peut judicieusement utiliser les "stateful cloud firewall" pour conserver SSH en port 22 sur le serveur et bénéficier d'un port standard, mais en le masquant et en le faisant correspondre à un port différent en extérieur (ex: 22123 extérieur, connecté au 22 intérieur). On bénéficie alors du meilleur des deux mondes.
Pour brider l'accès SSH en IPv4 (et non IPv4+IPv6):
AddressFamily inet
L'intérêt est de ne pas laisser passer des accès par IPv6 quand on bride IPv4 ;)
Il est recommandable d'interdire les identifications par mot de passe, au profit d'une clé SSH publique: c'est plus rapide, automatisable, et cela évite de devoir gérer ou noter des mots de passes solides et qui ne sont pas eux-mêmes réutilisés partout.
vérifiez bien que vous avez déjà la possibilité de vous logguer via vos clés sur le serveur avant d'interdir l'accès par mot de passe au niveau du serveur. Toujours dans
/etc/ssh/sshd_config
,
PasswordAuthentication no PubkeyAuthentication yes
Si vous voulez pouvoir vous identifier en root directement:
PermitRootLogin prohibit-password
Note: si l'on utilise plutôt PermitRootLogin no
, alors il ne sera pas possible de se logguer en root. Il faudra alors passer par un utilisateur, et qui pourra faire un sudo
(ou su -
). Certains préfèrent cet ajout de sécurité, parfois un peu lourd dans la réalité. C'est utile pour se protéger un peu contre l'usage de clés SSH sans "passphrase" (cf. ci-avant), puisqu'alors il faut se connecter en SSH sur l'utilisateur, puis taper son mot de passe pour basculer en root via sudo
.
Par exemple pour trois utilisateurs:
AllowUsers root martin paul
Vous pouvez aussi restreindre l'accès à un compte directement dans le fichier authorized_keys
de celui-ci. Par exemple pour ne permettre l'accès à un compte que depuis une IP particulière (répétez la ligne si vous voulez plusieurs IPs):
from="11.22.33.44", ssh-rsa AAAAB3AyNChQx...0H1tl jeremie@silex
S'il s'agit d'autoriser non pas sur les clés mais sur la base d'une ou plusieurs IP ou intervalles d'IP, vous pouvez recourir à l'ancienne méthode:
sshd: 11.22.33.44/32, 192.168.1.0/24
dans /etc/hosts.allow
,sshd: ALL
dans le fichier /etc/hosts.deny
Notez la priorité! On s'en doute, ce mécanisme s'applique à d'autres protocoles (dont ALL
, attention!)
Par exemple pour une configuration spécifique à git sur gitolite@mondomaine.com
(cf gitolite):
Host mondomaine.com Match User gitoite ForwardAgent no ForwardX11 no RequestTTY no
Autoriser un "forward X11" permet d'exporter un affichage graphique vers un client SSH, à la condition que le serveur source dispose d'un serveur X. Faites un export DISPLAY=$(echo $SSH_CLIENT|cut -f1 -d\ ):0.0
côté serveur, après avoir fait un xhost +
coté client. Il est cependant probablement plus facile et efficace d'utiliser TigerVNC.
Vous pouvez aussi restreindre les commandes possibles apres la validation d'un accès SSH sur un compte, par exemple:
command="/usr/local/bin/monbackup.sh", ssh-rsa AAAAB3AyNChQx...0H1tl jeremie@silex
Ici, le script /usr/local/bin/monbackup.sh
sera exécuté lors de la connexion SSH. Ce script peut profiter de la variable "$SSH_ORIGINAL_COMMAND" qui contient la commande passée par l'appelant, qui peut donc servir de paramétrage. C'est utilisé par exemple pour ce système de backup.
Notez qu'on peut combiner les deux restrictions précédentes, par exemple si vous avez dans /home/toto/.ssh/authorized_keys
la ligne suivante,
from="11.22.33.44", command="/bin/date;hostname", ssh-rsa AAAAB3AyNChQx...0H1tl jeremie@silex
Alors seul un utilisateur de 11.22.33.44 dont la clé est celle ci-dessus pourra faire un ssh vers le serveur et vers ce compte, mais le résultat sera toujours l'équivalent d'avoir lancé les commandes date;hostname
sur le serveur.
Un tunnel SSH permet de créer localement un service d'écoute sur un port, qui redirige la communication vers un serveur distant et un autre port, tout en la cryptant. C'est quelque part une forme très légère et réduite de VPN pour un service spécifique:
Par exemple si l'on veut ouvrir localement un service distant VNC (bureau virtuel à distance), on exécute localement cette commande:
ssh vnc@tiger.server.com -L 5901:127.0.0.1:5901
On peut aussi créer des tunnels SSH inverses. Leur rôle est d'ouvrir sur le serveur distant un tunnel qui "redescend" vers le poste qui a ouvert le tunnel, ce qui permet d'ignorer les contraintes du réseau local, tant qu'il permet d'utiliser SSH. On n'a pas à se soucier d'adresses, de NAT ou de reconfiguration du gateway ou de la DMZ.
Pour se faire on crée un compte SSH usertssh
que l'on bride à cette seule action, et on le paramètre dans le /etc/ssh/sshd_config
du serveur;
Match User usertssh AllowAgentForwarding no PermitOpen localhost:65432 ForceCommand echo "Ce compte est limité à du tunnel SSH."
On peut vérifier la contrainte en essayant de se logguer interactivement depuis son poste (une fois ajouté dans le .ssh/authorized_keys
de usertssh
):
#ssh usertssh@myserver.com Ce compte est limité à du tunnel SSH. Connection to myserver.com closed.
On va utiliser ici autossh
à la place de SSH, car c'est un outil pratique qui relance automatiquement le tunnel s'il tombe:
# depuis le poste client sudo apt-get install openssh-server autossh autossh -fN -M 3986 -R 65432:localhost:22 usertssh@myserver.com
Cela ouvrira sur le serveur un accès "local" SSH sur le port 65432. Quand on est loggué sur le serveur on peut l'utiliser pour redescendre vers la machine qui a ouvert ce tunnel, tout simplement (et on ressortira ici sur le port 22).
Loggué sur le serveur et avec sa clé publique dans le .ssh/authorized_hosts
de l'utilisateur sur le poste qui a ouvert le tunnel sur le serveur:
# depuis le serveur ssh root@localhost -p 65432
Avec Windows, voyez les options des "sessions" de putty ou de mobaxterm.
Sur un poste client de type unix, on gagne beaucoup à configurer des alias/raccourcis dans ~/.ssh/config
. Attention à vérifier que votre dossier ~/.ssh
n'est pas lisible par les autres utilisateurs du système sinon il sera ignoré (chmod -R go-rwx ~/.ssh
).
Host srv files.tecrd.com alias1 Hostname 51.15.239.195 #Hostname files.tecrd.com User untel
Ainsi ssh srv
fera en fait un ssh untel@files.tecrd.com
, à moins d'avoir explicité n'importe laquelle de ces valeurs par défaut, ex. ssh jeremie@srv
.
Le fichier .ssh/config
permet beaucoup de choses, qui facilitent grandement l'usage d'autres outils tels que git
, scp
ou rsync
.
Par exemple pour git qui utilise SSH sur un port non standard (22123 au lieu du 22 par défaut):
ssh jeremie@tecrd.com > port 22: Connection refused
ssh jeremie@tecrd.com -p 22123 > ok
Pour éviter de devoir à chaque fois spécifier comment on se connecte à un serveur (nom d'utilisateur, port, options particulières), on peut se créer ou bien ajouter des paragraphes au fichier ~/.ssh/config
sous cette forme:
Host git tecrd.com # ce paragraphe ne s'appliquera que pour un accès via l'utilisateur "gitolite" ! Match User gitolite Hostname tecrd.com Port 22123 # # vous pouvez meme spécifier une clé SSH particulière à utiliser, ex. # IdentityFile ~/.ssh/cle_secondaire # C'est comme d'avoir passé: -i ~/.ssh/cle_secondaire'' # # quelques options ssh désactivées pour éliminer des warnings sinon affichés par gitolite: ForwardAgent no ForwardX11 no RequestTTY no Host tecrd.com tecrd Hostname tecrd.com User jeremie Port 22123 ForwardAgent yes ForwardX11 yes # Ces deux lignes garantissent que votre session ssh n'expirera pas. C'est pratique mais # evidemment moins sécurisé si l'on oublie de fermer ses sessions sur un poste qui ne # serait pas physiquement sécurisé. TCPKeepAlive yes ServerAliveInterval 60
Désormais, si vous faites un accès ssh
aux hosts sus-nommés/aliasés, il prendra par défaut les valeurs trouvées dans ce fichier de configuration.
Ici par exemple, en l'absence d'info contradictoire explicite sur la ligne de commande, il utilisera le port 22123 nécessaire: plus besoin de le spécifier à chaque fois dans ssh
, scp
, rsync
, git
…
Et donc:
ssh tecrd
ou ssh tecrd.com
sera équivalent à ssh -p 22009 jeremie@tecrd.com -o <options…>
ssh git
ou bien ssh gitolite@tecrd.com
va utiliser le premier paragraphe, et donc aussi l'utilisateur gitolite
(ce qui est requis pour git)ssh toto@service.valorhiz.com
. Puisque l'on spécifie explicitement l'utilisateur, il se sera pas écrasé avec User jeremie
, et n'utilisera que les autres définitions par défaut.tty-share est un outil sympa qui permet de partager un shell avec d'autres (au sens de co-rédacteur!), y compris via un navigateur web.
La version la moins invasive tourne dans un docker ainsi:
docker run -it elisescu/tty-share --public
Attention aux problèmes évidents de sécurité, mais c'est un bel outil pour demander de l'aide !
De nouveau du côté serveur.
Il est possible de configurer /etc/ssh/sshd_config
pour limiter l'usage de certains comptes à certaines opérations, par exemple pour n'autoriser que sftp
à l'utilisateur partage
:
Subsystem sftp internal-sftp Match User partage ChrootDirectory /home/partage_sftp X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp
Il faut aussi un peu d'administration initiale:
mkdir -p /home/partage_sftp/depo # création de la zone d'échange de fichiers par SFTP chown root:root /home/partage_sftp # propriétaires obligatoires chmod 755 /home/partage_sftp # et droit nécessaires chown root:partage /home/partage_sftp/depot chmod 775 /home/partage_sftp/depot
Ainsi, un utilisateur externe dont la clé SSH publique se trouve dans /home/partage/.ssh/authorized_keys
pourra faire un SFTP vers ce compte, et se retrouvera bridé absolument dans le dossier /home/partage_sftp/
. Il lui sera ainsi impossible de modifier le /home/partage/.ssh
.
Pour écrire, il faut (!?) un sous-dossier, ici /home/partage_sftp/depot
(qui apparaîtra comme dépot
à la racine de l'arborescence vue sous SFTP).
Il est vaguement possible mais complexe de faire pareil pour rsync, qui est un protocole de tranfert de fichier bien plus efficace (il ne copie que ce qui a changé), ainsi que sshfs
(un montage local transparent d'un dossier distant). Voir par exemple aussi ce chroot jail (en anglais).
Il existe aussi un outil qui commence à être "ancien" mais qui est facile d'emploi: rssh
(restricted secure shell). C'est acceptable pour des utilisateurs bien intentionnés (il vaut mieux éviter si c'est un accès publique général – c'est rarement le cas tout de même). C'est surtout utile pour faire des backups du système.
Sur le serveur, on va créer un utilisateur rsyncer
dédié aux transferts:
apt install rssh useradd -m -d /home/rsyncer -s /usr/bin/rssh rsyncer
Puis on ajoute au fichier /home/rsyncer/.ssh/authorized_keys
les clés SSH publiques des comptes qui pourront utiliser ce protocole (pensez toujours au chown -R rsyncer:rsyncer /home/rsyncer/.ssh; chmod -R go-rwx /home/rsyncer/.ssh
)
Si vous essayez de vous y connecter depuis l'extérieur avec un ssh rsyncer@monserveur.com
vous devriez avoir une erreur du type This account is restricted by rssh.
. C'est bon signe.
Il faut en effet maintenant configurer les types d'actions autorisées, en éditant le fichier /etc/rssh.conf
sur le serveur. Par exemple on peut retirer les commentaires devant ces entrées:
allowsftp allowrsync
N'utilisez pas
allowscp
qui a une faille de sécurité non réglée.