Utilisation De SSH

SSH est un outils qui permet d’accéder a un shell distant de façon sécurisé mais pas que.

Installation du serveur

apt install openssh-server

Les fichiers de configuration pour le mode client et serveur sont disponible dans /etc/ssh/.

La configuration par défaut du serveur fait que le service est en écoute sur le port 22.

Connexion

Selon le moyen d’accès à la machine distante.

ssh user@ip
ssh user@hostname
ssh user@ma.machine.distante

On peut également lancer des applications en mode graphique… si on dispose d’un mode graphique sur le poste client et sur le poste serveur.

L’interface du serveur sera visible sur le post client. Biensur toute les action réalisé sur l’interface, le seront sur le post serveur.

ssh -X user@hostname

C’est l’option -X qui permet cela.

Configuration client

Dans le répertoire ~/.ssh on peu creer un fichier de configuration du nom de config.

Ce fichier va surcharger la configuration par défaut du client présente dans /etc/ssh/ssh_config.

Définir une configuration pour un host

Dans le fichier ~/.ssh/config :

host serveur1
  hostname 192.168.20.2 # au choix: ip, fqdn, 
  user mon_user
  port 22
  compression yes
  IdentityFile ~/.ssh/id_ed25519

Maintenir une connexion vers un host pour accélérer les connexions suivante

Dans le fichier ~/.ssh/config on va ajouter les lignes suivantes :

host * 
# Gestion automatique des sessions
  ControlMaster auto
# stockage des sessions : Le répertoire qui stockera le 'bus' de données
  ControlPath ~/.ssh/mux/%r@%h:%p
# Persitance de session 10 minutes
  ControlPersist 10m

En terme de sécurité, cette fonction peu être dangereuse. En effet, il n’est plus necessaire d’entrer sa clef pour se connecter à un bus ouvert…

Utiliser un host comme proxy

On veut se connecter à une machine serveur 2.

  • serveur2 n’est pas accessible depuis internet.
  • La machine serveur1 est sur le même réseau et peut voir seveur2.
  • On va donc utiliser serveur1 pour accéder à serveur2.

La configuration est la suivante :

host serveur2
  hostname 192.168.20.6 # au choix: ip, fqdn, 
  user mon_user
  port 22
  compression yes
  IdentityFile ~/.ssh/id_ed25519
  ProxyJump serveur1 # avec cette commande, on précise la machine via laquel on se connecte.

Execution distante

Execution d’un script local sur une machine distante

Le script est disponible sur la machine local dans le ~/script.sh.

ssh login@machine2 bash < ~/script.sh

Execution d’un script distant sur une machine distante

Le script est disponible sur la machine distance dans le ~/script.sh.

ssh login@machine2 ~/script.sh

Sécurisation

Ressource

Connexion par clef

On génère une clef avec la commande suivante :

ssh-keygen

Ce qui va généré par défaut un couple de clefs : id_dsa la clef privé et id_dsa.pub la clef publique.

La commande suivante, sert à l’export la clef publique sur une machine distance afin de réaliser à l’avenir une connexion par la clef et plus par mot de passe.

ssh-copy-id user@host

On vous demandera alors le mot de passe lié au login et la clef publique sera copié.

La clef publique est inséré dans le fichier ~/.ssh/authorized_keys à la suite de celle déjà présente.

Point important :

  • Il ne faut jamais partager sa clef privé avec qui que ce soit. La personne qui aurait votre clef, si elle n’est pas protegé par un mot de passe, pourrait usurper vos accès sur les machines où la clef publique est déployé.
  • Si possible on protège sa clef privé avec un mot de passe (ssh-agent est un démon qui gère les mots de passe de clef de façon à ne pas les taper 50 fois par session)

Changer le port d’écoute par défaut

ça ne change rien, si l’attaquant prend sont temps pour ses tests, il saura déterminer a quoi sert un port ouvert mais ça aura le mérite de limiter les attaques configuré sur port par défaut. Le port 22 étant très solicité sur le net…

dans le fichier /etc/ssh/sshd_config, on trouve la ligne #Port 22 qu’il faut décommenter et changer.

On redémarre ensuite le service avec la comande suivante :

systemctl restart sshd

Il faut savoir qu’en redémarrant le service, la connexion en cour ne sera pas interromppu.

Il ne faut pas la couper avant d’avoir tenter une connexion avec la nouvelle configuration… ce serait dommage de se retrouver à la porte de son serveur.

fail2ban

Fail2ban est un outil qui va scruter les logs d’un service afin de detecter les tentatives de connection infructueuse. Souvent elle sont le signe d’attaque par force brute (Brute force) ou l’attaquant tente de se connecter a un service et essayant soit toutes les permutations possible, soit une liste prédéfini de login et de mot de passe.

apt install fail2ban

Plus d’information sur le wiki ubuntu-fr.

sshguard

C’est une alternative a fail2ban que je ne connais pas encore mais qui a le merite d’être légère et avoir un bon retour de la communauté. Le projet est activement maintenu. Quoi qu’il en soit je n’ai aucun sousi avec fail2ban… Comme fail2ban l’outil est en mesure de protéger plusieurs protocol différent. il n’est pas limité à ssh.

Le fichier : authorized_key

La documentation sur ce fichier est disponible dans le man.

man authorized_keys

Le fichier est présent dans le répertoire $HOME/.ssh/.

Le fichier contient la liste des clefs public autorisé à se connecter au compte.

Une entrée prend une ligne et est de la forme :

OPTIONS ssh-ed25519 sziuqfhligubiusfgbqlirgqer3gb1q3e51bh3etbetb!qetbq# ma_clef@mon_pc

Le champ option n’est pas initialisé lorsque l’on déploie une clef vie l’outils de déploiement ssh-copy-id.

On va placer dans ce fichier certain paramètre limitant l’utilisation du compte. Ces paramètre sont séparé par des ,.

La liste des options est dans le man.

Exemple

On peu construire un shell capable de limiter à des actions précises.

Par exemple, un script qui limite l’accès à l’utilisation de scp :

#!/bin/bash

if [[ \"$SSH_ORIGINAL_COMMAND\" =~ ^scp.? ]]
then
    $SSH_ORIGINAL_COMMAND
    exit 0
else 
    echo Access Denied
    exit 1
fi

Ce script doit être appelé lors de la connexion. C’est ce que l’instruction command= placé dans le champ “option” doit nous permetre.

Il n’y a pas de limitation concernant le langage, un script python peut aussi servir de validateur.

#!/usr/bin/env python3

from os import environ
import logging
from logging.handlers import TimedRotatingFileHandler
#from logging.handlers import RotatingFileHandler

log = logging.getLogger()
log.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s :: %(module)s :: %(levelname)s :: %(message)s')

file_handler = TimedRotatingFileHandler(environ['HOME']+'/.ssh/limitation.log',
                                         when='D',
                                         interval=1,
                                         backupCount=7)

#file_handler = RotatingFileHandler(environ['HOME']+'/.ssh/limitation.log', 'a', 1000000, 1)
file_handler.setFormatter(formatter)
log.addHandler(file_handler)

if 'SSH_ORIGINAL_COMMAND' in environ.keys():
    log.debug(environ["SSH_ORIGINAL_COMMAND"])
    import subprocess
    cmd = environ['SSH_ORIGINAL_COMMAND']
    cmds = cmd.split(" ")
    if 'scp' in cmd or 'tar' in cmd or 'mkdir' in cmd or 'rm' in cmd :
        if 'scp' in cmds[0]:
            log.debug("Commande de transfert identifié")
        if 'tar' in cmds[0]:
            log.debug("Commande d'archivage identifié")
        if 'mkdir' in cmds[0]:
            log.debug("Commande de création de répertoire identifié")
        if 'rm' in cmds[0]:
            log.debug("Commande de suppression identifié")
        subprocess.run(cmds)
        exit(0)
    else:
        log.error("La commande ne contient pas le bon mot clef.")
        exit(1)
else:
    log.error("L'env ne contient pas la variable 'SSH_ORIGINAL_COMMAND'.")
    exit(1)

Debug

Les log du serveur sshd sont disponible dans /var/log/auth.log on peut également voir des traces sur /var/log/syslog.

Coté client l’option -vvvvv passe les log au niveau debug ce qui donnera un déroulé des étapes de négociation d’une connexion ssh.

Droit sur les répertoires

ssh refuse de fonctionner si les droits sur le répertoire parent du répertoire .ssh donne la fonction o+w soit l’écriture au autres ;).

Donc le plus simple reste d’être le seul a avoir un accès en lecture/écriture sur ses dossiers perso.

nithir [drwx------]
└── .ssh [drwx------]