139 votes

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

Ændrük a suggéré une connexion inverse pour obtenir une connexion SSH facile avec quelqu'un d'autre (pour une aide à distance). Pour que cela fonctionne, un utilisateur supplémentaire est nécessaire pour accepter la connexion. Cet utilisateur doit être capable de faire suivre son port par le serveur (le serveur agit comme un proxy).

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

Le nouvel utilisateur doit no être capable de :

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

En résumé, comment puis-je créer un utilisateur SSH restreint qui ne peut se connecter qu'au serveur SSH sans privilèges, afin que je puisse me connecter à son ordinateur via cette connexion ?

207voto

Lekensteyn Points 162346

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

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

Configuration de sshd

Le meilleur moyen de se familiariser avec les possibilités de SSH est de lire les pages de manuel correspondantes :

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

Avant de pouvoir restreindre quelque chose, vous devez connaître les caractéristiques de SSH. Cracher à travers les pages du manuel donne :

  • Shell.
  • Téléchargement de fichiers par sftp
  • Transfert de port
    • Le client transmet un port (non) utilisé au serveur.
    • Le serveur transmet son port au client
    • Le serveur transmet un port d'un autre hôte au client (proxy-ish).
  • Transfert X11 (transfert d'affichage)
  • Transfert d'agent d'authentification
  • Transfert d'un dispositif de tunnel

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

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

Après cela, le client peut soit demande un Shell ou l'exécution d'une commande . Les parties passent alors en mode session. Dans ce mode, chaque partie peut envoyer des données à tout moment, et ces données sont transmises vers/depuis le Shell ou la commande du côté serveur, et le terminal utilisateur du côté client.

Options de restriction des fonctions SSH

Les fichiers et leurs options qui modifient le comportement sont :

  • ~/.ssh/authorized_keys - contient les clés qui sont autorisées à se connecter et 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 de TCP et/ou de X11, sauf si cela est explicitement interdit. . Notez que cette option s'applique à l'exécution de Shell, de commandes ou de sous-systèmes.
    • no-agent-forwarding - Empêche le transfert de l'agent d'authentification lorsque cette clé est utilisée pour l'authentification.
    • no-port-forwarding - Interdit le transfert de TCP lorsque cette clé est utilisée pour l'authentification.
    • no-X11-forwarding - "Interdit le transfert de X11 lorsque cette clé est utilisée pour l'authentification."
    • permitopen="host:port" - Limite le transfert de port local 'ssh -L' de manière à ce qu'il puisse uniquement se connecter à 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é par l'option PermitUserEnvironment.
  • ~/.ssh/rc - Contient les routines d'initialisation à exécuter avant que le répertoire personnel de l'utilisateur ne devienne accessible.
  • /etc/ssh/sshd_config - le fichier de configuration du système

    • AllowAgentForwarding - Spécifie si le transfert de ssh-agent(1) est autorisé.

    • AllowTcpForwarding

    • ForceCommand - " Force l'exécution de la commande spécifiée par ForceCommand, en ignorant toute commande fournie par le client et ~/.ssh/rc si elle est présente. La commande est invoquée en utilisant le login de l'utilisateur Shell 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 ports distants à l'adresse de bouclage. Cela empêche les autres hôtes distants de se connecter aux ports transférés. GatewayPorts peut être utilisé pour spécifier que sshd doit autoriser les transferts de ports distants à se lier à des adresses non loopback, permettant ainsi aux autres hôtes de se connecter."

    • PermitOpen :

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

      PermitOpen host:port
      PermitOpen IPv4_addr:port
      PermitOpen [IPv6_addr]:port

      Il est possible de spécifier plusieurs avances en les séparant par des des espaces blancs. Un argument de type 'any' peut être utilisé pour supprimer toutes les restrictions et autoriser toutes les demandes 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 'no'.

    • X11Forwarding - Spécifie si le transfert X11 est autorisé. La valeur par défaut est "no".

Application des restrictions

Modifier le fichier de configuration du système /etc/ssh/sshd_config permet à la configuration d'être appliquée même si l'authentification basée sur un mot de passe est appliquée ou si les restrictions de l'option ~/.ssh/authorized_keys sont accidentellement retirés. Si vous avez modifié les valeurs par défaut globales, vous devez décommenter les options 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 ForceCommand peut être omis si le Shell est défini à un non-Shell comme /bin/false (ou /bin/true ) comme /bin/false -c [command] ne fera rien.

Maintenant, le client peut uniquement se connecter au port 62222 sur l'adresse de bouclage du serveur par SSH (il n'écoutera pas sur l'adresse IP publique).

Désactivation de AllowTcpForwarding interdit également l'utilisation de -R Il est donc impossible d'utiliser un tel compte restreint pour le transfert d'un seul port. PermitOpen localhost:62222 suppose que le port 62222 du serveur n'est jamais utilisé car le client peut s'y connecter et l'écouter également.

Si la redirection TCP est autorisée dans la configuration de l'ensemble du système et que l'authentification par mot de passe est désactivée, vous pouvez également utiliser des paramètres par clé. Modifier ~/.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 qu'il fonctionne comme prévu, certains cas de test doivent être exécutés. Dans les commandes ci-dessous, host doit être remplacé par le nom d'utilisateur réel s'il n'est pas défini dans le champ ~/.ssh/config . Derrière la commande, une commande est affichée qui 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 des commandes Shell - fait
  • accéder aux fichiers ou télécharger des fichiers vers le serveur - fait
  • utiliser le serveur en tant que proxy (par exemple, webproxy) - fait
  • accéder à des services locaux qui n'étaient pas accessibles au public en raison d'un pare-feu. partiellement le client ne peut pas accéder à d'autres ports que le port 62222, mais il peut écouter et se connecter au port 62222 du serveur.
  • tuer le serveur - fait (Notez que ces vérifications sont limitées au serveur SSH. Si vous avez un autre service vulnérable sur la machine, cela pourrait permettre à un attaquant éventuel d'exécuter des commandes, de tuer le serveur, etc. )

3voto

jfs Points 13605

Je suis sûr qu'il existe de nombreuses solutions à ce problème, et beaucoup plus robustes que celle que je propose. Cependant, celle-ci peut être suffisante pour vos besoins. Pour ce faire, je suppose que l'utilisateur est capable de faire une authentification basée sur une clé ssh (putty ou tout autre ssh unix devrait le supporter).

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

  • Créer les utilisateurs .ssh dir et .ssh/authorized_keys

    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

Maintenant, le seul moyen pour cet utilisateur d'accéder à votre système est d'avoir accès à la clé ssh appropriée, et ssh exécutera "/bin/bash -c 'read a'" pour lui, peu importe ce qu'il tente d'exécuter. 'read a' lira simplement jusqu'à une nouvelle ligne, puis le Shell sortira, de sorte que l'utilisateur n'aura qu'à appuyer sur 'enter' pour tuer la connexion.

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

Si vous n'aimez pas le fait que le fait d'appuyer sur la touche Entrée interrompt la connexion, vous pouvez utiliser quelque chose comme ce qui suit pour l'entrée 'command=' :

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 personnel de l'utilisateur, et essaie ensuite de lire à partir de celui-ci. Rien n'écrira dans ce fichier, donc cela se bloquera indéfiniment. De plus, si vous voulez mettre fin à la connexion de manière forcée, vous pouvez faire quelque chose comme.. :

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

Cela devrait utiliser très peu de ressources, et rien ne devrait pouvoir aller mal dans ce script qui ne se terminerait pas par la terminaison du script.

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

Je n'ai pas vu d'emblée comment vous pourriez permettre à l'utilisateur d'avancer à distance ( ssh -R ) mais limite ( ssh -L ). On pourrait peut-être utiliser "permitopen". Sur Google : n'a pas été très utile. Il semblerait que quelque chose comme "no-port-forwarding,permitremoteopen=10001" soit utile pour permettre à l'utilisateur d'accéder à l'Internet. ssh -R 6901:localhost:6901 .

C'est a solution. Elle peut très certainement être améliorée, et toute ouverture de ports distants doit être examinée de près. Si mon objectif était de permettre à ma grand-mère de se connecter à mon réseau local afin que je puisse utiliser vnc pour voir son écran, et que l'accès à ces clés était limité à elle, je me sentirais personnellement raisonnablement en sécurité. Si c'était pour une entreprise, une enquête plus approfondie serait nécessaire. Une chose dont il faut être conscient est que ssh -N ne demande pas du tout un Shell, donc le code 'command=' ne s'exécute pas.

D'autres mécanismes, peut-être plus sûrs, peuvent inclure la création d'un Shell personnalisé pour l'utilisateur, et même le verrouillage de ce dernier avec apparmour.

0voto

user14118720 Points 1

Essayez command="exit"

Cela obligerait les utilisateurs à utiliser cette commande pour transférer les données.

ssh -NfR EXTERNAL_PORT:localhost:INTERNAL_PORT usr@server -i key

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X