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


44

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

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

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

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


1
您能添加一些有关cron工作的详细信息吗?
Kyle Brandt

1
motd仅打印用于交互式会话。我刚刚对其进行了测试,它是这样的:> $ ssh主机→打印了MOTD> $ ssh主机ls→仅打印主目录的内容。你有没有尝试过
niXar

还应注意签入/etc/profile.d可能在此处运行的任何脚本,并在登录时将一些输出打印到控制台。
戴夫

4
是否真的有法律要求您说“禁止未经授权的访问”?我认为DMCA会破坏任何类型的电子系统(无论保护程度如何)都是违法的,因此,只要您有某种密码/ SSH密钥要求,这似乎就是纯净的橱窗装饰。
尼克T

Answers:


58

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

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

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


3
我喜欢“做得正确”。
Benoit

14
我不想将其从服务器中删除,因为出于法律原因,我需要在服务器上保留“禁止授权访问”通知。
罗里

3
首先,通知不会阻止未经授权的访问,它只是通知人们您可以(并将)采取适当的法律行动,并且可能会监视他们的使用,就像有关记录电话交谈的通知一样。
jtimberman

另外,如果您粘贴正在使用的cron作业,那将有很大帮助。
jtimberman

3
.hushlogin很好
andrewtweber '16

16

如果您希望按用户使用此功能,只需执行a,touch ~/.hushlogin然后就可以使用OpenSSH了。

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


2
我尝试过,但是没有用。正如其他人指出的那样,该模式可能是从pam印刷的
罗里(Rory)

11

@note所有示例均假设您已使用设置了connectionString类似的变量connectionString=user@server

我如何找到解决方案

使用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

我希望我对此有更多的支持。在弄清楚我们需要做的过度ssh脚本方面非常有帮助。
csexton

神奇的答案!非常感谢你!!
Scottie H

10

这个骇客如何?;-P

ssh -t user@machineName '/bin/bash'

以下是正确的:

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

ssh -T machineName 'echo foo'

3
ssh user @ machine'您的命令在这里'仍然不显示motd(它不是交互式shell)。
玛丽·菲舍尔

哦,太好了,一点....
凯尔·勃兰特

但是它的意思是“它不是交互式外壳”,因为我尝试过,并且我可以运行命令,使用这些命令我将丢失-t
Ciasto piekarz

请注意,添加“ -t”会改变行为(它会根据您的TERM设置显示,并在需要时添加控制字符,等等)。它可以更改某些命令的结果(例如,可能会在以下命令中引入错误:ssh -t somehost“ tar cf-一些文件”> local.tar#请勿在此处使用-t……尤其是如果您从ssh Unix主机Windows,但在其他情况下可能会出现许多其他问题)。看到精彩的@StephaneChazelas答案:unix.stackexchange.com/questions/151916/...
奥利维尔·杜拉克

3

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


您无法在ssh客户端中对其进行控制,但可以肯定的是在客户端上:) ..有关详细信息,请参阅我的答案
drAlberT 2009年

不,您已经提出了一个关于正在打印的motd的有趣/聪明的技巧,而不是阻止客户端打印它的解决方案,这就是问题所在。
theotherre

2

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

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

不,你不会。请参阅下面的凯尔·布兰特(Kyle Brandt)的答案。
Stobor

-1-答案不反映编辑过的问题。不再相关。
rom09年

2

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

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

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

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


2
那不是解决方案,而是一种解决方法。
niXar

对不起,我不同意你的看法。恕我直言,这是应该干净地完成的方式...如果有一种方法可以明确配置ssh客户端以忽略motd,但我同意了,但它不存在,仅仅是因为它不在sshd的控制之下!
drAlberT

2

只是一个旁注(如果可以,我会发表评论):成功登录系统,将显示motd的内容。如果我想合法地阻止人们访问盒子,我宁愿通过sshd_config中的“横幅”来做到这一点。输入用户名之后但进行身份验证之前,将显示内容。


4
是的,但是您可以在ssh客户端上使用-q禁用横幅,所以我不同意您的注释
drAlberT 2009年

1
噢,男孩,我完全可以看到它,“-q”击败了为Dynacorp Inc.工作的资深法律团队的全部辩护。他们没有看到它的到来。变得真实。如果本应看到横幅的人故意逃避了……横幅仍然具有约束力,因为您必须知道要逃避它。
niXar

2

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

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

workstation ~ $ ssh root@server
server ~ # echo "MOTD" > /etc/motd
server ~ # ^D
workstation ~ $ ssh root@server
MOTD
server ~ # ^D
workstation ~ $ ssh root@server 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

如果查看man sshd,您会看到它说:登录过程用户成功登录后,sshd将执行以下操作:1.如果登录名是tty且未指定任何命令,则显示上次登录时间和/ etc / motd(除非在配置文件或〜/ .hushlogin中禁止;请参见“文件”部分)。2. ...注意,如果在ssh登录名中输入了命令目录,则不会显示MOTD
katriel

我知道,这就是我所展示的。你想说什么?
niXar

1

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

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

motd message

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

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


1

这里的解决方案:

如果您不负责服务器,并且无法更改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“ failed_ remote_command 2>&1” 2> / dev / null || echo SSH连接失败或远程命令返回了非零退出代码
 bash:failed_remote_command:找不到命令
SSH连接或远程命令失败-他们两个都返回了非零的退出代码127

范例2:

ssh remotehost“ failed_ remote_command 2>&1; true ” 2> / dev / null || echo SSH连接失败
 bash:failed_remote_command:找不到命令

示例3a:

ssh remotehost“ failed_ remote_command 2>&1; true” 2> / dev / null || echo SSH连接失败
 #没有显示消息

示例3b:

SSH nonexistinghostfailed_ remote_command 2>&1;真” 2>的/ dev / null的|| echo SSH连接失败
 SSH连接失败

0

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

Hint: /etc/motd

4
他从客户端说,从服务器端在sshd_config中将PrintMotd设置为no可能会更好
Kyle Brandt

0

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


哦,例如?我真的宁愿使用ssh思想..
罗里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.