如何在没有tty的情况下通过ssh检索用于执行sudo命令的用户标识

时间:2016-07-13 11:48:13

标签: bash unix ssh ksh sudo

没有tty,最好的方法是通过ssh取回通过系统验证的用户ID并执行以下命令(作为示例)。

由于这些命令将通过pssh执行并在许多系统中自动执行,因此从技术上讲是不可能的。

>ssh -q node1 "sudo su - idm -c 'who am i'"
>ssh -q node1 "sudo su - idm -c 'echo hello'"
hello
>ssh -q node1"sudo su - idm -c 'logname'"
logname: no login name

2 个答案:

答案 0 :(得分:0)

可能不是最好的解决方案,但有一种方法可以在实际执行预期命令之前捕获用户名,如下所示:ssh -q node1 'sudo su - idm -c "echo $USER"'

USER变量将包含用于连接到“node1”的用户,因为它在登录期间初始化,有或没有tty。在运行ssh之后和sudo命令启动之前,将替换该变量。 使用的引号很重要,因为在实际启动ssh之前不应替换变量。 如果你想从脚本内部启动命令,这是没有用的,除非你为该脚本提供$ USER作为参数,然后在参数列表内部使用它。

另一种可能性是使用父PI​​D,另一个可用的变量可以通过爬回过程树找到: ssh -q node1 'sudo su - idm -c "ps -hp $PPID -o user"'会显示“sshuser”。

或者从脚本内部(不太好但是有效):

# cat ~idm/test.sh
#!/bin/bash -x
SSHUSER=$(ps -hp $(ps -hp $(ps -hp $PPID -o ppid) -o ppid) -o user)
echo $SSHUSER

执行:

# ssh node1 'sudo su - idm -c "./test.sh"'
sshuser

有3个“ps”命令,因为脚本的父级是“su”,“su”的父级是“sudo”,最后“sudo”的父级持有你需要的用户名。 / p>

我希望它可以帮到你。

答案 1 :(得分:0)

我首先要说的是我无法复制您的问题。

$ ssh -T pc "sudo su - ghoti2 -c 'whoami'"
ghoti2
$ ssh -T pc "sudo su - ghoti2 -c 'logname'"
ghoti

-T选项应该禁用tty但logname静止功能的分配。在我们运行的操作系统中,这可能是一个微妙的不同。我使用FreeBSD。你还没有提到你正在使用的东西。

也就是说,如果问题是sudo隐藏了您的登录使用,您可能希望查看广告调整sudo配置和使用情况。

例如,以下sudo配置使登录用户对正在运行的命令可见:

    Defaults>root          !set_logname

此选项的文档来自man sudoers,声明:

   set_logname     Normally, sudo will set the LOGNAME, USER and USERNAME
                   environment variables to the name of the target user
                   (usually root unless the -u option is given).  However,
                   since some programs (including the RCS revision control
                   system) use LOGNAME to determine the real identity of
                   the user, it may be desirable to change this behavior.
                   This can be done by negating the set_logname option.
                   Note that if the env_reset option has not been
                   disabled, entries in the env_keep list will override
                   the value of set_logname.  This flag is on by default.

请注意,无论是否设置此选项,当您使用sudo错误地使用su启动$ ssh -T pc sudo su - ghoti2 -c env TERM=su BLOCKSIZE=K MAIL=/var/mail/ghoti2 PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/home/ghoti2/bin SHELL=/bin/tcsh HOME=/home/ghoti2 USER=ghoti2 HOSTTYPE=FreeBSD VENDOR=amd OSTYPE=FreeBSD MACHTYPE=x86_64 SHLVL=1 PWD=/home/ghoti2 LOGNAME=ghoti2 GROUP=unknown HOST=pc 时,都会忽略此功能。即使在我的sudo配置中禁用了此选项,我也会得到以下结果:

su -

在这种情况下,虽然sudo可能会离开LOGNAME,USER和USERNAME变量,但它们会被sudo覆盖。

但如果我正确使用$ ssh pc sudo -u ghoti2 env PATH=/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/ghoti/bin:/usr/X11R6/bin:/usr/games TERM=su LC_COLLATE=C SHELL=/bin/tcsh LOGNAME=ghoti2 USER=ghoti2 USERNAME=ghoti2 MAIL=/var/mail/ghoti2 HOME=/home/ghoti2 SUDO_COMMAND=/usr/bin/env SUDO_USER=ghoti SUDO_UID=1001 SUDO_GID=1001 选项,我也可以这样做:

$SUDO_USER

请注意su -变量。它是作为环境的一部分提供给sudo运行的任何内容。当然,在您的使用中,它不可用,因为您通过运行man su来消除这部分环境。 (您应该$ ssh node1 "sudo su - idm -c '/path/to/script $USER'" 了解详情。)

或者,如果改进你的sudo使用不是一个选项,那么将登录用户作为参数提供给通过sudo运行的任何内容呢?

$USER

这将包括由连接的客户端扩展的$ ssh node1 'sudo su - idm -c "/path/to/script $USER"' 变量。或者,通过反转引号:

$USER

您可以确保在远程端展开script

然后,从$1开始,变量import XCTest import CoreLocation class ExampleTests: XCTestCase { var okay: ext! // this test works fine func testOkay(){ okay = ext() XCTAssertNotNil(okay) } // this test crashes with EXC_BAD_ACCESS(code=1, address=0x10) func testNotOkay(){ let notOkay: ext notOkay = ext() XCTAssertNotNil(notOkay) } } extension ExampleTests { class ext : CLPlacemark{ } } 将是使用sudo进行身份验证的用户名。