web-dev-qa-db-fra.com

Comment créer un utilisateur SSH restreint pour le transfert de port?

ændrük suggère une connexion inversée pour obtenir une connexion SSH facile avec quelqu'un d'autre (pour l'aide à distance). Pour que cela fonctionne, un utilisateur supplémentaire est nécessaire pour accepter la connexion. Cet utilisateur doit pouvoir transférer son port via le serveur (le serveur agit en tant que proxy).

Comment créer un utilisateur restreint qui ne peut rien faire de plus que ce qui est décrit ci-dessus?

Le nouvel utilisateur doit ne pas pouvoir:

  • exécuter des commandes shell
  • accéder à des fichiers ou télécharger des fichiers sur le serveur
  • utiliser le serveur en tant que proxy (par exemple, webproxy)
  • accéder à des services locaux qui n'étaient autrement pas accessibles au public en raison d'un pare-feu
  • tuer le serveur

En résumé, comment créer un utilisateur SSH restreint pouvant uniquement se connecter au serveur SSH sans privilèges, afin de pouvoir me connecter via cette connexion avec son ordinateur?

104
Lekensteyn

TL; DR - aller au bas de la réponse, "Appliquer les restrictions"

L'ajout d'un utilisateur restreint se compose de deux parties: 1. Création de l'utilisateur 2. Configuration du démon SSH (sshd)

Configuration de sshd

Le meilleur endroit pour connaître les possibilités de SSH consiste à lire les pages de manuel correspondantes:

Où le client SSH peut-il effectuer des actions?

Avant de pouvoir limiter quelque chose, vous devez connaître les fonctionnalités de SSH. En parcourant les pages de manuel, vous obtenez:

  • Exécution des commandes shell
  • Téléchargement de fichier via sftp
  • Redirection de port
    • Le client transmet un port (non) utilisé au serveur
    • Le serveur transmet son port au client
    • Le serveur transmet le port d'un autre hôte au client (proxy-ish)
  • X11 forwarding (transfert d'affichage)
  • Transfert d'agent d'authentification
  • Transfert d'un appareil tunnel

De la section Authentification de la page de manuel de sshd (8) :

Si le client s’authentifie avec succès, une boîte de dialogue permettant de préparer la session est ouverte. À ce moment, le client peut demander des choses comme allouer un pseudo-tty, transférer des connexions X11, transférer des connexions TCP ou transférer la connexion de l'agent d'authentification sur le canal sécurisé.

Après cela, le client demande un shell ou l'exécution d'une commande . Les côtés entrent ensuite en mode session. Dans ce mode, l’un ou l’autre côté peut envoyer des données à tout moment, et ces données sont transférées vers/depuis le shell ou la commande côté serveur et le terminal utilisateur côté client.

Options pour restreindre les fonctionnalités SSH

Les fichiers et leurs options qui modifient le comportement sont les suivants:

  • ~/.ssh/authorized_keys - contient les clés autorisées à se connecter auxquelles on peut donner des options:
    • command="command" - La commande fournie par l'utilisateur (le cas échéant) est ignorée. Notez que le client peut spécifier le transfert TCP et/ou X11 à moins qu'il ne soit explicitement interdit . Notez que cette option s'applique à l'exécution du shell, de la commande ou du sous-système.
    • no-agent-forwarding - Interdit le transfert de l'agent d'authentification lorsque cette clé est utilisée pour l'authentification.
    • no-port-forwarding - Interdit TCP transfert lorsque cette clé est utilisée pour l'authentification
    • no-X11-forwarding - "Interdit le transfert X11 lorsque cette clé est utilisée pour l'authentification."
    • permitopen="Host:port" - Limite le transfert de port local 'ssh -L' de sorte qu'il ne puisse se connecter qu'à l'hôte et au port spécifiés.
  • ~/.ssh/environment - Ce fichier est lu dans l'environnement lors de la connexion (s'il existe). Le traitement de l'environnement est désactivé par défaut et est contrôlé via l'option PermitUserEnvironment.
  • ~/.ssh/rc - Contient les routines d'initialisation à exécuter avant que le répertoire de base de l'utilisateur ne soit accessible.
  • /etc/ssh/sshd_config - le fichier de configuration à l'échelle du système
    • AllowAgentForwarding- Spécifie si le transfert ssh-agent (1) est autorisé.
    • AllowTcpForwardingname__
    • ForceCommand- "Force l'exécution de la commande spécifiée par ForceCommand, en ignorant toute commande fournie par le client et ~/.ssh/rc s'il est présent. La commande est appelée à l'aide du shell de connexion de l'utilisateur avec l'option -c."
    • GatewayPorts- "Spécifie si les hôtes distants sont autorisés à se connecter aux ports transférés pour le client. Par défaut, sshd (8) lie les transferts de port distants à l'adresse de bouclage. Ceci empêche d'autres hôtes distants de se connecter aux ports transférés. GatewayPorts peut être utilisé pour spécifiez que sshd doit autoriser les redirections de ports distants à se lier à des adresses autres que des bouclages, permettant ainsi à d'autres hôtes de se connecter. "
    • PermitOpenname __:

      Spécifie les destinations vers lesquelles le transfert de port TCP est autorisé. La spécification de transmission doit être l’une des formes suivantes:

      PermitOpen Host:port
      PermitOpen IPv4_addr:port
      PermitOpen [IPv6_addr]:port
      

      Plusieurs transferts peuvent être spécifiés en les séparant par des espaces. Un argument de 'tout' peut être utilisé pour supprimer toutes les restrictions et permettre toute demande de transfert. Par défaut, toutes les demandes de transfert de port sont autorisées.

    • PermitTunnel- Spécifie si le transfert de périphérique tun (4) est autorisé. La valeur par défaut est "non"
    • X11Forwarding - Spécifie si le transfert X11 est autorisé. La valeur par défaut est "non"

Appliquer les restrictions

La modification du fichier de configuration système /etc/ssh/sshd_config permet d'appliquer la configuration même si l'authentification par mot de passe est appliquée ou si les restrictions de ~/.ssh/authorized_keys sont supprimées par inadvertance. Si vous avez modifié les paramètres globaux par défaut, vous devez supprimer les commentaires en conséquence.

Match User limited-user
   #AllowTcpForwarding yes
   #X11Forwarding no
   #PermitTunnel no
   #GatewayPorts no
   AllowAgentForwarding no
   PermitOpen localhost:62222
   ForceCommand echo 'This account can only be used for [reason]'

Maintenant, ajoutez un utilisateur:

Sudo useradd -m limited-user

L'option ForceCommandpeut être omise si le shell est défini sur un non-shell tel que /bin/false (ou /bin/true), car /bin/false -c [command] ne fait rien.

Désormais, le client ne peut se connecter qu'au port 62222 sur l'adresse de bouclage du serveur via SSH (il n'écoutera pas l'adresse IP publique).

Désactiver AllowTcpForwardinginterdirait également l’utilisation de -R, annulant ainsi l’utilisation d’un tel compte restreint pour le transfert d’un port unique. PermitOpen localhost:62222 suppose que le port 62222 sur le serveur n'est jamais utilisé, car le client peut se connecter à celui-ci et l'écouter.

Si TCP le transfert est autorisé dans la configuration système et si l'authentification par mot de passe est désactivée, vous pouvez également utiliser les paramètres par clé. Éditez ~/.ssh/authorized_keys et ajoutez les options suivantes avant le ssh- (avec un espace entre les options et ssh-):

command="echo 'This account can only be used for [reason]'",no-agent-forwarding,no-X11-forwarding,permitopen="localhost:62222"

Vérifier

Pour être sûr que cela fonctionne comme prévu, certains cas de test doivent être exécutés. Dans les commandes ci-dessous, Hostdevrait être remplacé par le nom de connexion réel s'il n'est pas défini dans ~/.ssh/config. Derrière la commande, une commande est affichée et doit être exécutée soit sur le client, soit sur le serveur (comme spécifié).

# connection closed:
ssh Host
# connection closed (/bin/date is not executed):
ssh Host /bin/date
# administratively prohibited (2x):
ssh Host -N -D 62222 # client: curl -I --socks5 localhost:62222 example.com
ssh Host -N -L 8080:example.com:80 # client: curl -I localhost:8080
sftp Host
# should be possible because the client should forward his SSH server
ssh Host -N -R 8080:example.com:80 # server: curl -I localhost:8080
# This works, it forwards the client SSH to the server
ssh Host -N -R 62222:localhost:22
# unfortunately, the client can listen on that port too. Not a big issue
ssh Host -N -L 1234:localhost:62222

Conclusion

Liste de contrôle: L'utilisateur SSH ne doit pas pouvoir:

  • exécuter les commandes Shell - done
  • accéder aux fichiers ou télécharger des fichiers sur le serveur - done
  • utiliser le serveur en tant que proxy (par exemple, webproxy) - done
  • accéder aux services locaux qui n'étaient autrement pas accessibles publiquement en raison d'un pare-feu - partiellement , le client ne peut pas accéder à d'autres ports que 62222, mais peut écouter et se connecter au port 62222 sur le serveur
  • tuer le serveur - done (notez que ces vérifications sont limitées au serveur SSH. Si vous disposez d'un autre service vulnérable sur la machine, cela pourrait permettre un attaquant possible d’exécuter des commandes, de tuer le serveur, etc.)
162
Lekensteyn

Je suis sûr qu'il existe de nombreuses solutions à ce problème, et beaucoup plus robustes que celle que je propose. Cependant, cela peut suffire à vos besoins. Afin de le faire, je suppose que l'utilisateur peut faire une authentification basée sur une clé ssh (PuTTY ou tout six unix devrait le supporter).

  • Ajouter un utilisateur comme vous le feriez normalement ('adduser' ou tout autre outil)

  • Créez les répertoires .ssh et .ssh/registered_keys des utilisateurs

your_user $ Sudo -Hu ssh_forwarder /bin/bash

ssh_forwarder $ cd ~
ssh_forwarder $ mkdir .ssh
ssh_forwarder $ ( umask 066 && cat > .ssh/authorized_keys ) <<EOF
no-agent-forwarding,no-X11-forwarding,command="read a; exit" ssh-rsa AAAB3NzaC1y....2cD/VN3NtHw== smoser@brickies
EOF
  • Désactiver l'accès par mot de passe à ce compte.
your_user $ Sudo usermod --lock ssh_forwarder

Désormais, le seul moyen pour l'utilisateur d'accéder à votre système consiste à accéder à la clé ssh appropriée. Ssh exécutera "/ bin/bash -c" lira un "" pour eux, quelle que soit la tentative exécutée. 'read a' lira simplement jusqu'à une nouvelle ligne, puis le shell se fermera, l'utilisateur devra donc appuyer sur 'entrée' pour interrompre la connexion.

Il y a beaucoup d'autres choses que vous pourriez faire dans 'command ='. Voir man authorized_keys et recherchez 'commande' pour plus d'informations.

Si vous n'aimez pas le fait que frapper entrée tue la connexion, vous pouvez utiliser quelque chose comme ceci pour l'entrée 'commande =':

command="f=./.fifo.$$ && mkfifo $f && trap \"rm -f $f\" EXIT && read a <$f && echo $a; exit;"

Cela crée simplement un fifo temporaire dans le répertoire de base des utilisateurs, puis tente de le lire. Rien ne sera écrit dans ce fichier, donc ce sera suspendu indéfiniment. De plus, si vous souhaitez mettre fin de manière forcée à cette connexion, vous pouvez procéder comme suit:

 your_user$ echo GOODBYE | Sudo tee ~ssh_forwarder/.fifo.*

Cela devrait utiliser très peu de ressources et rien ne devrait se passer de ce script qui ne finirait pas par mettre fin au shell.

sleep 1h; echo You have been here too long. Good bye.

Je n'ai pas vu d'emblée comment autoriser l'utilisateur à transférer à distance (ssh -R) mais à limiter (ssh -L). Peut-être que "permitopen" pourrait être utilisé. Google n'était pas très utile. Il semblerait que quelque chose comme 'no-port-forwarding, permitremoteopen = 10001' serait utile pour permettre à ssh -R 6901:localhost:6901.

C'est une solution . Cela peut certainement être amélioré et toute ouverture de ports distants devrait être examinée attentivement. Si mon objectif était de permettre à ma grand-mère de se connecter à mon réseau local afin que je puisse utiliser vnc pour afficher son écran, et que l'accès à ces clés lui était réservé, je me sentirais raisonnablement en sécurité. S'il s'agissait d'une entreprise, une enquête plus approfondie serait nécessaire. Une chose à prendre en compte est que ssh -N ne demande pas du tout un shell, aussi le code 'command =' ne s'exécute pas.

D'autres mécanismes, peut-être plus sécurisés, peuvent inclure la création d'un shell personnalisé pour l'utilisateur, et même le verrouiller avec apparmour.

2
smoser