ssh-agent forwarding et sudo à un autre utilisateur

153

Si j'ai un serveur A sur lequel je peux me connecter avec ma clé ssh et que j'ai la possibilité de "sudo su - otheruser", je perds le transfert de clé, car les variables env sont supprimées et le socket est uniquement lisible par mon utilisateur d'origine. Existe-t-il un moyen de relier la transmission de clé via "sudo su - otheruser", afin de pouvoir effectuer des tâches sur un serveur B avec ma clé transférée (git clone et rsync dans mon cas)?

La seule façon dont je peux penser est d’ajouter ma clé à allowed_keys d’autre utilisateur et de "ssh otheruser @ localhost", mais c’est fastidieux à faire pour chaque combinaison utilisateur / serveur que je peux avoir.

En bref:

$ sudo -HE ssh user@host
(success)
$ sudo -HE -u otheruser ssh user@host
Permission denied (publickey). 
kolypto
la source

Réponses:

182

Comme vous l'avez mentionné, les variables d'environnement sont supprimées par sudo, pour des raisons de sécurité.

Mais heureusement, il sudoest assez configurable: vous pouvez indiquer précisément les variables d’environnement que vous souhaitez conserver grâce à l’ env_keepoption de configuration de /etc/sudoers.

Pour le transfert d’agent, vous devez conserver la SSH_AUTH_SOCKvariable d’environnement. Pour ce faire, modifiez simplement votre /etc/sudoersfichier de configuration (en utilisant toujours visudo) et définissez l' env_keepoption sur les utilisateurs appropriés. Si vous voulez que cette option soit définie pour tous les utilisateurs, utilisez la Defaultsligne comme ceci:

Defaults    env_keep+=SSH_AUTH_SOCK

man sudoers pour plus de détails.

Vous devriez maintenant pouvoir faire quelque chose comme ceci ( user1la clé publique fournie est présente dans ~/.ssh/authorized_keysin user1@serverAet user2@serverB, et serverAle /etc/sudoersfichier est configuré comme indiqué ci-dessus):

user1@mymachine> eval `ssh-agent`  # starts ssh-agent
user1@mymachine> ssh-add           # add user1's key to agent (requires pwd)
user1@mymachine> ssh -A serverA    # no pwd required + agent forwarding activated
user1@serverA> sudo su - user2     # sudo keeps agent forwarding active :-)
user2@serverA> ssh serverB         # goto user2@serverB w/o typing pwd again...
user2@serverB>                     # ...because forwarding still works
MiniQuark
la source
1
Ceci est la bonne réponse, devrait être marquée.
Xealot
41
Cela ne fonctionne que si c'est ce qui user2est en haut root! Sinon, user2SSH_AUTH_SOCK sera configuré correctement, mais user2ne pourra pas accéder par exemple à / tmp / ssh-GjglIJ9337 /. roota cet accès. Donc, cela peut résoudre une partie du problème, mais pas les OP: " et la prise est uniquement lisible par mon utilisateur d'origine"
Peter V. Mørch
6
Defaults>root env_keep+=SSH_AUTH_SOCKDevrait s’assurer qu’il n’avance que lorsqu’on passe à la racine. De toute façon, vous ne voulez pas faire cela à d’autres utilisateurs pour des raisons de sécurité. Mieux vaut exécuter un agent ssh distinct pour autrui et ajouter les clés appropriées.
Paul Schyska
1
sudo su -ne fonctionne pas pour moi, il est probable qu'il ne peut pas préserver l'environnement car il ne se trouve pas sudoau moment du démarrage du shell. sudo susemble fonctionner.
Alex Fortuna
3
Je n'ai jamais compris pourquoi les gens utilisent sudo suquand même. Si vous avez besoin d’un shell root, c’est pour quoi sudo -sou sudo -ipour quoi .
eaj
68
sudo -E -s
  • -E préservera l'environnement
  • -s lance une commande, un shell par défaut

Cela vous donnera un shell root avec les clés d'origine encore chargées.

Joao Costa
la source
2
Comme avec le commentaire ci-dessus, cela ne concerne que la question de savoir si vous devenez root, car dans ce cas, il est capable de contourner les autorisations d'accès habituelles sur $ SSH_AUTH_SOCK.
doshea
35

Autorisez un autre utilisateur à accéder au $SSH_AUTH_SOCKfichier et à son répertoire, par exemple par une liste de contrôle d'accès correcte, avant de passer à eux. L'exemple suppose Defaults:user env_keep += SSH_AUTH_SOCKdans /etc/sudoersla machine hôte:

$ ssh -A user@host
user@host$ setfacl -m otheruser:x   $(dirname "$SSH_AUTH_SOCK")
user@host$ setfacl -m otheruser:rwx "$SSH_AUTH_SOCK"
user@host$ sudo su - otheruser
otheruser@host$ ssh server
otheruser@server$

Plus sécurisé et fonctionne aussi pour les utilisateurs non-root ;-)

Viliam Pucik
la source
6
Rappelez-vous qu'en utilisant cette méthode, d'autres personnes connectées en tant que otheruserpeuvent également utiliser votre authentification SSH.
Gitaarik
Cela fonctionne pour moi sauf que je devais changer "sudo su - otheruser" en "sudo su otheruser" (en enlevant le -).
Charles Finkel
1
Pourquoi rwxet pas rw(ou pas rdu tout)?
anatoly techtonik
3
@anatolytechtonik From man 7 unix- sur Linux, la connexion à un socket nécessite des autorisations de lecture et d'écriture sur ce socket. En outre, vous devez disposer des autorisations de recherche (exécuter) et d’écriture sur le répertoire dans lequel vous créez le socket ou uniquement de l’autorisation de recherche (exécuter) lorsque vous vous connectez à ce socket. Ainsi, dans la réponse ci-dessus, l'autorisation d'exécution sur le socket est redondante.
Mixel
au lieu d’avoir à éditer / etc / sudoers, vous pouvez utilisersudo -u otheruser --preserve-env=HOME -s
Sec
14

J'ai trouvé que cela fonctionne aussi.

sudo su -l -c "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK; bash"

Comme d'autres l'ont fait remarquer, cela ne fonctionnera pas si l'utilisateur vers lequel vous basculez n'a pas les autorisations de lecture sur $ SSH_AUTH_SOCK (ce qui correspond à peu près à tout utilisateur autre que root). Vous pouvez contourner ce problème en définissant $ SSH_AUTH_SOCK et le répertoire dans lequel se trouvent les autorisations 777.

chmod 777 -R `dirname $SSH_AUTH_SOCK`
sudo su otheruser -l -c "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK; bash"

C'est assez risqué cependant. Vous donnez à tous les autres utilisateurs du système l'autorisation d'utiliser votre agent SSH (jusqu'à ce que vous vous déconnectiez). Vous pourrez peut-être également définir le groupe et modifier les autorisations sur 770, ce qui pourrait être plus sécurisé. Cependant, lorsque j'ai essayé de changer de groupe, j'ai reçu "Opération non autorisée".

phylae
la source
6
C'est extrêmement risqué. Donner à tous les autres utilisateurs la permission d'utiliser votre agent SSH revient à leur donner toutes vos informations d'identification (et si vous utilisez jamais sudo ou su, leur donner le pouvoir root sur tous les autres utilisateurs du système, ainsi que sur tous les autres systèmes sur lesquels vous êtes ssh!) . Cela ne doit JAMAIS être fait!
Matija Nalis
4
Je ne suis pas d'accord avec l'affirmation selon laquelle "cela ne doit JAMAIS être fait!" Il existe de nombreux cas où ce risque est acceptable. Par exemple, une petite équipe où tout le monde a les mêmes autorisations et vous faites confiance à tous les autres utilisateurs. Cela ne devrait jamais être fait sans comprendre les risques que cela comporte. Mais une fois que ces risques sont compris, il est parfois acceptable.
phylae
6

Si vous êtes autorisé à le faire sudo su - $USER, vous auriez probablement un bon argument pour pouvoir le faire à la ssh -AY $USER@localhostplace, avec votre clé publique valide dans le répertoire de base de $ USER. Ensuite, votre transfert d'authentification sera effectué avec vous.

David Mackintosh
la source
Il a mentionné cela au bas de sa question et a déclaré que ce serait difficile à faire.
Fahad Sadah
Ceci est probablement la meilleure solution , mais il obtient poilue si $ USER est une personne réelle (tm) - ils pourraient supprimer la clé de la SA de authorized_keys ou modifier leur mot de passe ...
voretaq7
Vous pouvez supprimer leur accès en écriture à authorised_keys (mais s'ils sont vraiment déterminés à refuser l'accès à Florian, ils peuvent le supprimer et le recréer, que ce soit dans un répertoire qu'ils possèdent)
Fahad Sadah,
4

Vous pouvez toujours utiliser ssh sur localhost avec le transfert d’agent au lieu d’utiliser sudo:

ssh -A otheruser@localhost

L'inconvénient est que vous devez vous reconnecter, mais si vous l'utilisez dans un onglet screen / tmux, ce n'est qu'un effort ponctuel. Cependant, si vous vous déconnectez du serveur, le socket sera (bien sûr) cassé à nouveau. . Ce n’est donc pas idéal si vous ne pouvez pas garder votre session screen / tmux ouverte à tout moment (toutefois, vous pouvez mettre à jour manuellement votre SSH_AUTH_SOCKvariable d’env si vous êtes cool).

Notez également qu'en utilisant le transfert ssh, root peut toujours accéder à votre socket et utiliser votre authentification ssh (tant que vous êtes connecté avec le transfert ssh). Assurez-vous donc que vous pouvez faire confiance à root.

Gitaarik
la source
Cela ne fonctionne pas si vous avez uniquement accès à otheruservia sudoau lieu de sur SSH (par exemple, vous voulez que les choses SCP soient pareilles www-data)
Gert van den Berg
3

Ne pas utiliser sudo su - USER, mais plutôt sudo -i -u USER. Travaille pour moi!

Fahad Sadah
la source
Quelle version de sudo avez-vous? Mine (1.6.7p5, CentOS 4.8) n'a pas de -i dans sa page de manuel.
David Mackintosh
Sudo version 1.6.9p17en cours d'exécution sur Debian Lenny. Essayez sudo -s?
Fahad Sadah
6
Ca ne marche pas pour moi
Sur Ubuntu, avec Sudo 1.8.9p5, cela ne marche sudo -sni sudo -ipour moi ...
Jon L.
2

En combinant les informations des autres réponses, je suis arrivé à ceci:

user=app
setfacl -m $user:x $(dirname "$SSH_AUTH_SOCK")
setfacl -m $user:rwx "$SSH_AUTH_SOCK"
sudo SSH_AUTH_SOCK="$SSH_AUTH_SOCK" -u $user -i

J'aime ça parce que je n'ai pas besoin d'éditer un sudoersfichier.

Testé sur Ubuntu 14.04 (il fallait installer le aclpaquet).

Warvariuc
la source
1

Je pense qu'il y a un problème avec l' -option (tiret) après sudans votre commande:

sudo su - otheruser

Si vous lisez la page de manuel de su , vous constaterez peut-être que cette option -, -l, --loginlance l’environnement shell en tant que shell de connexion. Ce sera l'environnement pour otheruserindépendamment des variables env où vous exécutez su.

En termes simples, le tiret va saper tout ce que vous avez quitté sudo.

Au lieu de cela, vous devriez essayer cette commande:

sudo -E su otheruser

Comme @ joao-costa l'a souligné, -Etoutes les variables de l'environnement dans lequel vous vous êtes exécuté seront conservées sudo. Ensuite, sans le tiret, suutilisera cet environnement directement.

Koala Yeung
la source
0

Malheureusement, lorsque vous vous adressez à un autre utilisateur (ou même que vous utilisez sudo), vous perdez la possibilité d'utiliser vos clés transférées. Ceci est une fonctionnalité de sécurité: Vous ne voulez pas que des utilisateurs aléatoires se connectent à votre agent ssh et utilisent vos clés :)

La méthode "ssh -Ay $ {USER}" @localhost "est un peu fastidieuse (et comme indiqué dans mon commentaire sur la réponse de David susceptible de se briser), mais c'est probablement ce que vous pouvez faire de mieux.

voretaq7
la source
1
Hmm, mais si je fais cela avec ssh, mon agent est de toute façon accessible par cet utilisateur, ou est-ce que je me trompe?
Si vous faites un SSH sur l'utilisateur cible avec le transfert d'agent, vos demandes d'agent vont rebondir la chaîne là où se trouve le "vrai" agent. Lorsque vous démarrez votre accès depuis ou vers l'utilisateur d'origine, votre socket d'agent SSH ne sera pas (ou ne devrait pas) être accessible - Le répertoire dans lequel il réside est en mode 700 et appartient à l'utilisateur d'origine. (Mise en garde évidente: si vous passez en mode root et réinitialisez l'environnement SSH_AUTH_SOCK, cela fonctionnera peut-être, mais je ne m'appuierai pas dessus)
voretaq7
1
Sur mon serveur (Ubuntu 12.04, version ssh OpenSSH_5.9p1 Debian-5ubuntu1.1, OpenSSL 1.0.1 14 mars 2012), ssh a -aet des -Aarguments. -afait exactement le contraire de ce qui est prévu, il désactive le transfert d’agent! Ainsi, dans la version récente (et probablement la totalité) d’Ubuntu, utilisez -Apour activer le transfert d’agent.
Knite
@knite Vous avez raison - c'est une faute de frappe (de 3 ans!) dans ma réponse. Correction maintenant :-)
voretaq7