it-swarm.cn

停止从客户端打印motd的ssh登录?

我已经设置了无密码的SSH,但是它在登录时会打印MoTD。是否有任何方法可以阻止客户端发生这种情况?

我已经试过ssh -q,但是不起作用。我既不想使用~/.hushlogin,也不想更改服务器设置。唯一可行的方法是使用>/dev/null 2>&1使所有输出静音。但是,如果有实际问题,我不想忽略错误。即使执行>/dev/null也无效,因为ssh似乎将motd打印到stderr。

更新和推理我正在cron中运行备份。除非发生错误,否则我不希望收到Cron电子邮件。但是,如果打印了motd,我将始终收到一封电子邮件。

我想保留印刷品,因为这有法律影响。 motd说“禁止未经授权的访问”。您需要在其中使用这种声明,以合法地阻止人们访问它(例如禁止擅自进入的标志)。因此,我不想一直禁用它。

45
Rory

我不确定您为什么不喜欢正确执行此操作-在服务器上还是

PrintMotd no
PrintLastLog no

#/etc/pam.d/ssh
# Print the message of the day upon successful login.
# session    optional     pam_motd.so

或为每个用户添加〜/ .hushlogin。

提示,对于〜/ .hushlogin,将其添加到/ etc/skel中,以便使用该文件创建新的用户主目录。

更新:

在没有有关备份cron作业的更多信息的情况下,我唯一的建议是将命令的输出重定向到文件(或让cron在电子邮件中捕获它),并将ssh会话的输出重定向到/ dev/null。就像是:

0 0 * * * ssh backuphost "backup_script_that_writes_to_a_log" >/dev/null

要么

0 0 * * * ssh backuphost "backup_command 2>&1" >/dev/null

我将不得不处理一些命令,但这应该可以帮助您入门。

58
jtimberman

如果您希望按用户使用,只需执行touch ~/.hushlogin,即可使用OpenSSH。

更新:如其他地方所指出,pam_motd可以配置为不使用每个用户的.hushlogin;检查/etc/login.defs中的HUSHLOGIN_FILE。它可以配置为以/etc/hushlogins或类似名称列出所有用户。

16
towo

@note所有示例均假设您已将变量connectionString设置为类似[email protected]

我如何解决

使用ssh -T应该适用于简单的命令。例如,这不会打印任何其他信息:

ssh -T $connectionString "echo 'blah'"

问题是当您尝试使用here-doc运行许多命令时。例如-波纹管将不起作用-它将回显当天的消息(MoTD),并且可能还会显示“ stdin:不是tty”。

somethingLocal='something local'
ssh -T $connectionString <<EOC
    echo 'blah'
    echo "blah $somethingLocal"
EOC

要变通解决此问题,您需要首先将命令保存到本地变量,然后将其发送到远程服务器。

somethingLocal='something local'
read -r -d '' commands <<EOC
    echo 'blah'
    echo "blah $somethingLocal"
EOC
ssh -T $connectionString "$commands"

但这很乱...

最终解决方案

创建一个通用函数(请注意,它可以将字符串或HEREDOC用作命令)。

function silentSsh {
    local connectionString="$1"
    local commands="$2"
    if [ -z "$commands" ]; then
        commands=`cat`
    fi
    ssh -T $connectionString "$commands"
}

例子

这样使用:

somethingLocal='something local'
silentSsh $connectionString <<EOC
    echo 'blah'
    echo "blah $somethingLocal"
EOC

或者像这样:

silentSsh $connectionString "echo 'blah'"

或者像这样:

silentSsh $connectionString <<'EOC'
    echo 'blah'
    somethingRemote=`echo 'whatever'`
    echo "blah $somethingRemote"
EOC

甚至像这样:

silentSsh $connectionString < getlines.sh
11
Nux

这个骇客如何? ;-P

ssh -t [email protected] '/bin/bash'

以下是not有效:

传递-T到ssh以禁用tty分配:

ssh -T machineName 'echo foo'
10
Kyle Brandt

这是什么操作系统?在某些系统(例如ubuntu)上,motd不是由ssh服务器(/ etc/ssh/sshd_config中的PrintMotd)打印的,而是由pam和pam_motd打印的。如果是这种情况,那么您可能无法从客户端控制它。

3
theotherreceive

不要由cron直接执行ssh命令。

制作一个帮助bash脚本,执行ssh作业并在需要时获取输出,错误和错误代码;最终解析它们以便从错误消息(在您的情况下为MoTD)中删除不需要的字符串,然后在bash脚本输出和错误流上重新打印以这种方式获得的结果。

比把这个bash脚本放到cron中并过得开心:)

注意:这是一个通用解决方案,无论您通过ssh必须执行什么工作,它都必须工作。也是客户端,它也可以满足您的需求...客户端对服务器配置的唯一依赖是您知道要从标准错误或ssh客户端切出的确切消息的知识

2
drAlberT

您必须在服务器上执行此操作:

PrintMotd no
PrintLastLog no

在debian/ubtuntu上,还使用pam_motd.so对该行进行哈希处理:

#/etc/pam.d/ssh
# Print the message of the day upon successful login.
# session    optional     pam_motd.so
2
ThorstenS

您没有尝试描述的内容,或者服务器配置错误!

这是我刚刚在RHEL5上尝试过的方法:

workstation ~ $ ssh [email protected]
server ~ # echo "MOTD" > /etc/motd
server ~ # ^D
workstation ~ $ ssh [email protected]
MOTD
server ~ # ^D
workstation ~ $ ssh [email protected] echo notice the lack of motd
notice the lack of motd
workstation ~ $ 

我不认为您需要将免责声明发送到非交互式外壳,对吗? (如果有人声称您愿意,请帮帮我,把它们踢疯了。)因为这就是为什么交互式shell和非交互式shell有所区别的原因。

但是无论如何,这是我要做的,因为我不喜欢来自cron的邮件:我将输出通过管道传送到记录器。只需将其通过尾部插入即可删除无意义的免责声明的前几行(假设为3)(未经测试的代码,我无法访问我的脚本):

( tail -n +3 | logger -i -t mycronjob -s -p cron.crit ) <&6 &
exec 2>&6
cron_fsckin_job
2
niXar

这里的解决方案:

如果您不负责服务器,并且无法更改motd或sshd配置,请使用以下命令:

将STDERR重定向到STDOUT以获取远程命令,以便您可以看到它。然后将ssh的STDERR重定向到/ dev/null。 MOTD转到STERR并以/ dev/null结尾。将会显示来自远程命令的任何标准AND错误消息(进入STDOUT时)

变式1-如果您关心远程执行命令的退出状态:

ssh remotehost "(remote_command1 && remote_command2; remote_command3) 2>&1" 2>/dev/null || echo SSH connection or remote command failed - either of them returned non-zero exit code $?

变体2-如果您想忽略远程命令的退出代码-只需将true作为最后一个远程命令执行即可

ssh remotehost "(remote_command; true) 2>&1" 2>/dev/null || echo SSH connection failed

错误消息示例:

范例1:

 ssh remotehost“失败_remote_command 2>&1“ 2>/dev/null || echo SSH连接失败,或者远程命令返回了非零退出代码
bash:failed_remote_command:找不到命令
 SSH连接或远程命令失败-他们两个都返回了非零的退出代码127

范例2:

 ssh remotehost“失败_remote_command 2>&1; 真正“ 2>/dev/null || echo SSH连接失败
bash:failed_remote_command:找不到命令

示例3a:

 ssh remotehost“失败_remote_command 2>&1; true” 2>/dev/null || echo SSH连接失败
#未显示任何消息

示例3b:

 ssh 不存在的主机 ”失败_remote_command 2>&1; true” 2>/dev/null || echo SSH连接失败
SSH连接失败
1
Chris

据我了解,您可能出于其他原因需要motd,但不需要motd进行备份。在sshd的配置中,不能仅根据用户设置全局设置。因此,您需要在客户端解决motd抑制。但是motd的文本和备份软件的错误消息之间没有区别。两者都是终端中的文本。我看到的唯一使这两个消息有所不同的解决方案,然后过滤掉motd的消息。由于软件的消息很难修改,因此建议修改motd的文本。例如,在周围放置一个框架:

*** BEGIN message from the machine room ***

motd message

*** END message from the machine room ***

然后,您应该过滤掉框架之间的文本并将其放下。

1
Saabi

您是否尝试过删除motd文件中的文本?只是一个想法。

Hint: /etc/motd
0
Joseph Kern

您正在尝试做什么,为什么MoTD会打扰您?我正在猜测执行远程命令并解析输出?如果是这样,则可以以多种方式完成此操作而无需调用交互式Shell(这会导致显示motd)。

0
Marie Fischer

您是否尝试过使用ssh子系统配置?您可以在 http://www.hell.org.ua/Docs/oreilly/tcpip2/ssh/ch05_07.htm 中找到一个示例,该示例甚至包括备份文件。

0
David