如果我有一个服务器A,我可以使用我的ssh密钥login到服务器,并且我可以“sudo su – otheruser”,所以我丢失了密钥转发,因为envvariables被删除,并且套接字只能由我原来的用户读取。 有没有一种方法可以通过“sudo su – otheruser”桥接密钥转发,所以我可以使用转发密钥(我的情况下为git clone和rsync)在服务器B上执行一些操作?
我能想到的唯一方法是将我的密钥添加到其他用户的authorized_keys和“ssh otheruser @ localhost”,但是对于我可能拥有的每个用户和服务器组合,这样做很麻烦。
简而言之:
$ sudo -HE ssh user@host (success) $ sudo -HE -u otheruser ssh user@host Permission denied (publickey).
正如你所提到的,出于安全原因,环境variables被sudo
删除。
但是幸运的是, sudo
是相当可configuration的:由于/etc/sudoers
的env_keep
configuration选项,您可以准确地确定要保留哪些环境variables。
对于代理转发,您需要保留SSH_AUTH_SOCK
环境variables。 为此,只需编辑/etc/sudoers
configuration文件(始终使用visudo
)并将env_keep
选项设置为适当的用户。 如果您希望为所有用户设置此选项,请使用下面的Defaults
行:
Defaults env_keep+=SSH_AUTH_SOCK
man sudoers
更多的细节。
你现在应该可以做这样的事情(假设user1
的公钥存在于user1@serverA
和user2@serverB
~/.ssh/authorized_keys
中, 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
sudo -E -s
这将为您提供一个仍然加载原始密钥的root shell。
允许其他用户访问$SSH_AUTH_SOCK
文件和它的目录,例如通过正确的ACL,然后切换到它们。 该示例假定主机上/etc/sudoers
Defaults:user env_keep += SSH_AUTH_SOCK
:
$ 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用户以及;-)
我发现这也是有效的。
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"
尽pipe如此,这是相当危险的。 你基本上是让系统上的其他用户有权使用你的SSH代理(直到你注销)。 您也可以设置组并将权限更改为770,这可能更安全。 但是,当我尝试改变组,我得到了“不允许的操作”。
如果您有权限sudo su - $USER
,那么您可能会有一个很好的理由,允许您使用ssh -AY $USER@localhost
,并使用您的有效公钥在$ USER的主目录中。 然后,您的身份validation转发将与您一起进行。
你总是可以通过代理转发ssh到localhost,而不是使用sudo:
ssh -A otheruser@localhost
缺点是您需要重新login,但是如果您在屏幕/ tmux选项卡中使用它,这只是一次性的工作,但是,如果从服务器断开连接,套接字(当然)会再次被破坏。 所以如果你不能保持你的screen / tmux会话始终保持打开状态(不过你可以手动更新你的SSH_AUTH_SOCK
env var,如果你很酷的话)。
还要注意,当使用ssh转发时,root可以随时访问你的套接字并使用你的sshauthentication(只要你使用ssh转发login)。 所以确保你可以信任根。
不要使用sudo su - USER
,而是使用sudo -i -u USER
。 为我工作!
不幸的是,当你su给另一个用户(甚至使用sudo),你将失去使用转发的密钥的能力。 这是一个安全function:你不想随机的用户连接到你的SSH代理和使用你的密钥:)
“ssh -Ay $ {USER} @localhost”方法有点麻烦(正如我对David的回答容易破坏的评论所指出的那样),但这可能是你能做的最好的。
结合其他答案的信息,我想出了这个:
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
文件。
testingUbuntu 14.04(不得不安装acl
软件包)。
我觉得你的命令在su
后面有-
(破折号)选项有问题:
sudo su - otheruser
如果您阅读su的手册页,则可能会发现选项-, -l, --login
login以loginshell的forms启动shell环境。 这将为其他用户的环境,而不pipe你运行su
的envvariables。
简而言之,破折号将破坏你从sudo
传递的任何东西。
相反,你应该尝试这个命令:
sudo -E su otheruser
正如@ joao-costa指出的那样, -E
将会保留你运行sudo
的环境中的所有variables。 那么没有短划线, su
会直接使用这个环境。