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

89

ændrük suggère 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 pouvoir transmettre 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 aux fichiers ou télécharger des fichiers sur le serveur
  • utilisez 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
  • tue le serveur

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

    
posée Lekensteyn 10.06.2011 - 22:04
la source

2 réponses

141

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)

Configurer sshd

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

  • ssh (1)
  • ssh_config (5)
  • sshd (8)
  • sshd_config (5)

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

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

  • Exécution des commandes shell
  • Téléchargement de fichier via sftp
  • Transfert de port
    • Le client transmet un port (dé) utilisé au serveur
    • Le serveur transmet son port au client
    • Le serveur transfère un port d’un autre hôte au client (proxy-ish)
  • Transfert X11 (transfert d’affichage)
  • Transfert de l'agent d'authentification
  • Transfert d'un périphérique de tunnel

Dans la section Authentication de la page de manuel de sshd (8) :

  

Si le client s'authentifie correctement, une boîte de dialogue de préparation   la session est entrée A ce moment, le client peut demander des choses comme    allouer une pseudo-tty, transférer des connexions X11, transférer TCP   connexions, ou transférer la connexion de l'agent d'authentification sur le   canal sécurisé.

     

Ensuite, le client demande un shell ou exécute une commande .   Les côtés entrent alors en mode session. Dans ce mode, chaque côté peut envoyer   données à tout moment, et ces données sont transmises à / depuis le shell ou la commande   côté serveur et le terminal utilisateur du 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, qui peuvent avoir 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 le transfert TCP 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' afin 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 devienne accessible.
  • /etc/ssh/sshd_config - le fichier de configuration système
    • AllowAgentForwarding - Spécifie si le transfert 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 présente. La commande est appelée à l'aide du shell de connexion de l'utilisateur avec l'option -c." / li>
    • 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. utilisé pour spécifier que sshd devrait permettre aux redirections de ports distants de se lier aux adresses non bouclées, permettant ainsi à d'autres hôtes de se connecter. "
    • PermitOpen :
        

      Spécifie les destinations vers lesquelles le transfert de port TCP est effectué.   permis. La spécification de transfert doit être l'une des   formulaires suivants:

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

      Plusieurs versions peuvent être spécifiées en les séparant avec   espace blanc Un argument de 'any' peut être utilisé pour supprimer tout   restrictions et permettre toute demande de transfert. Par défaut tous   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'
    •   
  •   

Appliquer les restrictions

La modification du fichier de configuration à l'échelle du système /etc/ssh/sshd_config permet d'appliquer la configuration même si l'authentification basée sur un mot de passe est appliquée ou si les restrictions de ~/.ssh/authorized_keys sont supprimées accidentellement. Si vous avez modifié les valeurs par défaut globales, vous devez supprimer 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]'

Ajoutez maintenant un utilisateur:

sudo useradd -m limited-user

L'option ForceCommand peut ê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 fera rien.

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

La désactivation de AllowTcpForwarding interdirait également l’utilisation de -R , ce qui irait à l’encontre de l’utilisation d’un tel compte restreint pour le transfert d’un seul port. PermitOpen localhost:62222 suppose que le port 62222 sur le serveur n'est jamais utilisé car le client peut s'y connecter et l'écouter aussi.

Si le transfert TCP est autorisé dans la configuration à l'échelle du système et que l'authentification par mot de passe est désactivée, vous pouvez également utiliser des paramètres par clé. Modifiez ~/.ssh/authorized_keys et ajoutez les options suivantes avant 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 scénarios de test doivent être exécutés. Dans les commandes ci-dessous, host doit être remplacé par l'identifiant réel s'il n'est pas défini dans ~/.ssh/config . Derrière la commande, une commande doit être exécutée sur le client ou 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 - done
  • accéder aux fichiers ou télécharger des fichiers sur le serveur - terminé
  • utilisez le serveur comme proxy (par exemple, webproxy) - done
  • accéder à des services locaux qui n’étaient pas autrement accessibles au public à cause d’un pare-feu - partiellement , le client ne peut pas accéder aux autres ports que 62222, mais peut écouter et se connecter au port 62222
  • tuez le serveur - terminé (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 éventuel attaquant d’exécuter des commandes, de tuer le serveur, etc.)
réponse donnée Lekensteyn 22.06.2011 - 11:11
la source
2

Je suis sûr qu'il y a beaucoup de solutions à cela, et beaucoup plus robustes que celle que je propose. Cependant, cela peut suffire à vos besoins. Pour ce faire, je suppose que l’utilisateur est capable d’effectuer une authentification par clé ssh (putty ou tout autre ssh unix devrait le supporter).

  • Ajoutez un utilisateur comme vous le feriez normalement ("adduser" ou tout autre outil)

  • Créez 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== [email protected]
EOF
  • Désactiver l'accès par mot de passe à ce compte.
your_user $ sudo usermod --lock ssh_forwarder

Maintenant, la seule façon pour l’utilisateur d’entrer dans votre système est d’accéder à la clé ssh appropriée, et ssh exécutera "/ bin / bash -c" en lisant un "", peu importe ce qu’ils tentent d’exécuter. . 'read a' lira simplement jusqu'à une nouvelle ligne, puis le shell quittera, donc l'utilisateur n'a qu'à appuyer sur "enter" pour tuer la connexion.

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

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

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

Cela crée juste un fifo temporaire dans le répertoire home des utilisateurs, puis essaie de le lire. Rien ne va écrire dans ce fichier, donc cela va rester indéfiniment. De plus, si vous souhaitez mettre fin à cette connexion par la force, 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 aller mal dans ce script qui ne se terminerait pas par la fin du shell.

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

Je n'ai pas vu de côté comment vous pouviez permettre à l'utilisateur de transférer à distance ( ssh -R ) mais limite ( ssh -L ). Peut-être que «allowopen» pourrait être utilisé. Google n’a pas été très utile. Il semblerait que quelque chose comme 'no-port-forwarding, allowremoteopen = 10001' serait utile pour autoriser ssh -R 6901:localhost:6901 .

Ceci est une solution une . Il est certain que cela peut être amélioré et que toute ouverture de ports distants doit être examinée. 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 se limitait à elle, je me sentirais raisonnablement en sécurité. Si c'était pour une entreprise, une enquête plus approfondie serait nécessaire. Une chose à savoir est que ssh -N ne demande pas de shell du tout, donc le code 'command =' ne s'exécute pas.

D'autres mécanismes, éventuellement plus sécurisés, peuvent inclure la création d'un shell personnalisé pour l'utilisateur et même son verrouillage avec apparmour.

    
réponse donnée smoser 21.06.2011 - 15:09
la source

Lire d'autres questions sur les étiquettes