题 ssh-agent转发和sudo给另一个用户


如果我有一个服务器A,我可以使用我的ssh密钥登录,并且我有能力“sudo su - otheruser”,我丢失密钥转发,因为env变量被删除  套接字只能由我的原始用户读取。有没有办法可以通过“sudo su - otheruser”来桥接密钥转发,所以我可以用转发的密钥(我的情况下是git clone和rsync)在服务器B上做东西?

我能想到的唯一方法是将我的密钥添加到otheruser的authorized_keys和“ssh otheruser @ localhost”,但这对我可能拥有的每个用户和服务器组合来说都很麻烦。

简而言之:

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

144
2018-01-28 13:52






答案:


如您所述,环境变量将被删除 sudo,出于安全原因。

但幸运的是 sudo 是完全可配置的:你可以准确地告诉它你想要保留哪些环境变量 env_keep 配置选项 /etc/sudoers

对于代理转发,您需要保留 SSH_AUTH_SOCK 环境变量。为此,只需编辑您的 /etc/sudoers 配置文件(总是使用 visudo)并设置 env_keep 适当用户的选项。如果要为所有用户设置此选项,请使用 Defaults 像这样的行:

Defaults    env_keep+=SSH_AUTH_SOCK

man sudoers 更多细节。

你现在应该能够做这样的事情(提供 user1的公钥出现在 ~/.ssh/authorized_keys 在 user1@serverA 和 user2@serverB,和 serverA/etc/sudoers 文件设置如上所示):

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

168
2018-03-03 21:24



这是正确的答案,应该标记。 - Xealot
这个 只要 工作,如果 user2 以上是 root!除此以外, user2 将SSH_AUTH_SOCK设置正确,但是 user2 将无法访问,例如的/ tmp / SSH-GjglIJ9337 /。 root 确实有这种访问权限。所以这可以解决部分问题,但不是OP:“和 套接字只能由我的原始用户读取“ - Peter V. Mørch
Defaults>root env_keep+=SSH_AUTH_SOCK 应确保它只在sudoing时前进 至 根。出于安全原因,您不希望对其他用户执行此操作。最好为另一个运行单独的ssh-agent,并添加适当的密钥。 - Paul Schyska
sudo su - 对我来说不起作用,大概它不能保护环境,因为它不是 sudo 在shell启动时。 sudo su 似乎工作。 - Alex Fortuna
我永远不明白为什么人们会使用它 sudo su 无论如何。如果你需要一个root shell,那就是那个 sudo -s 要么 sudo -i 是为了。 - eaj


sudo -E -s
  • -E将保护环境
  • -s运行命令,默认为shell

这将为您提供一个仍然加载原始密钥的root shell。


54
2018-01-01 15:31



与上面的注释一样,这只会解决您是否成为root用户的问题,因为在这种情况下,root可以绕过$ SSH_AUTH_SOCK的常用访问权限。 - doshea


允许 otheruser 访问 $SSH_AUTH_SOCK 文件及其目录,例如通过正确的ACL,然后切换到它们。这个例子假设 Defaults:user env_keep += SSH_AUTH_SOCK 在 /etc/sudoers 在主机上:

$ 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$

更安全,适用于非root用户;-)


33
2017-11-15 10:58



请记住,使用此方法时,其他人登录为 otheruser 也可以使用你的ssh身份验证。 - gitaarik
这对我有用,除了我不得不将“sudo su - otheruser”更改为“sudo su otheruser”(删除 - )。 - Charles Finkel
为什么 rwx 并不是 rw (要么 r 在所有)? - anatoly techtonik
@anatolytechtonik来自 man 7 unix  - 在Linux上连接到套接字需要对该套接字具有读写权限。此外,您还需要在创建套接字的目录上搜索(执行)和写入权限,或者在连接到此套接字时仅搜索(执行)权限。所以在上面的回答中,socket的执行权限是多余的。 - mixel


我发现这也有效。

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

正如其他人所指出的那样,如果您切换到的用户对$ SSH_AUTH_SOCK没有读取权限(除root之外几乎是任何用户),这将不起作用。你可以通过设置$ SSH_AUTH_SOCK及其所在的目录来获得权限777。

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

但这很危险。您基本上是允许系统上的每个其他用户使用您的SSH代理(直到您注销)。您也可以设置组并将权限更改为770,这可能更安全。但是,当我尝试更换组时,我得到了“不允许操作”。


16
2018-03-21 00:01



这是非常危险的。授予每个其他用户使用SSH代理的权限等同于为他们提供所有凭据(如果您曾使用过sudo或su,则为他们提供系统上所有其他用户的root权限,以及您使用的所有其他系统!) 。绝不能做到这一点! - Matija Nalis
我不同意“这绝不可能完成!”的说法。在许多情况下,这种风险是可以接受的。例如,一个小团队,每个人都拥有相同的权限,并且您信任所有其他用户。如果不了解其涉及的风险,就不应该这样做。但是,一旦了解了这些风险,有时风险是可以接受的。 - phylae


如果您被授权 sudo su - $USER那么你可能会被允许做一个很好的论据 ssh -AY $USER@localhost 相反,使用$ USER主目录中的有效公钥。然后您的身份验证转发将随身携带。


6
2018-01-28 14:08



他提到在他的问题的底部,并说它很难做到。 - Fahad Sadah
这可能是最好的解决方案,但如果$ USER是真人(tm),它会变得毛茸茸 - 他们可能会从authorized_keys删除SA的密钥或更改密码...... - voretaq7
您可以删除对authorized_keys的写访问权限(但如果它们确实设置为拒绝Florian访问权限,则可以删除并重新创建它,它位于他们拥有的目录中) - Fahad Sadah


您可以随时使用代理转发ssh到localhost而不是使用sudo:

ssh -A otheruser@localhost

缺点是您需要再次登录,但如果您在屏幕/ tmux选项卡中使用它,那只是一次性的努力,但是,如果您断开与服务器的连接,套接字将(当然)再次被破坏。因此,如果您无法始终打开屏幕/ tmux会话,那么这是不理想的(但是,您可以手动更新您的 SSH_AUTH_SOCKenv var如果你很酷)。

另请注意,使用ssh转发时,root可以始终访问您的套接字并使用您的ssh身份验证(只要您使用ssh转发登录)。因此,请确保您可以信任root。


4
2017-11-27 14:56





不要用 sudo su - USER, 反而 sudo -i -u USER。适合我!


3
2018-01-28 16:51



你有什么版本的sudo?我的(1.6.7p5,CentOS 4.8)在其手册页中没有-i。 - David Mackintosh
Sudo version 1.6.9p17 在Debian Lenny上运行。尝试 sudo -s? - Fahad Sadah
对我不起作用。
在Ubuntu上,使用Sudo 1.8.9p5,都没有 sudo -s 也不 sudo -i 为我工作...... - Jon L.


结合其他答案的信息我想出了这个:

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

我喜欢这个,因为我不需要编辑 sudoers 文件。

在Ubuntu 14.04上测试过(必须安装 acl 包)。


2
2018-06-10 17:39





不幸的是,当你su给另一个用户(甚至使用sudo)时,你将失去使用转发密钥的能力。这是一个安全功能:您不希望随机用户连接到您的ssh-agent并使用您的密钥:)

“ssh -Ay $ {USER} @localhost”方法有点麻烦(正如我对David的答案容易出现破损的评论中所述),但它可能是你能做的最好的。


1
2018-01-28 16:52



嗯,但如果我用ssh这样做,那么无论如何我的代理人都可以访问,或者我错了?
如果您通过代理转发SSH连接到目标用户,则代理请求会将链条反弹到“真正的”代理所在的位置。当你su或sudo远离原始用户时,你的SSH代理套接字将不会(或不应该)可访问 - 它所在的目录是模式700并由原始用户拥有。 (明显的警告:如果您切换到root并重置SSH_AUTH_SOCK环境,它可能会起作用,但我不会依赖它) - voretaq7
在我的服务器上(Ubuntu 12.04,ssh版本OpenSSH_5.9p1 Debian-5ubuntu1.1,OpenSSL 1.0.1 2012年3月14日),ssh有 -a 和 -A 参数。 -a 与预期完全相反,它会禁用代理转发!因此,在最近(也可能是所有)版本的Ubuntu下,使用 -A 启用代理转发。 - knite
@knite你是对的 - 在我的回答中这是一个(3岁!)错字。现在修复:-) - voretaq7


我认为这是一个问题 - (破折号)选项之后 su 在你的命令中:

sudo su - otheruser

如果您阅读了该手册页 ,你可能会发现这个选项 -, -l, --login 以shell身份启动shell环境。这将是环境 otheruser 无论你运行的env变量如何 su

简单地说,破折号将破坏你传递的任何东西 sudo

相反,您应该尝试以下命令:

sudo -E su otheruser

正如@ joao-costa指出的那样, -E 将保留您运行的环境中的所有变量 sudo。然后没有破折号, su 将直接使用该环境。


0
2018-04-05 10:03