有没有办法确定远程脚本是从本地 shell 还是远程 shell 运行的?

有没有办法确定远程脚本是从本地 shell 还是远程 shell 运行的?

我有一个远程脚本,可以使用ssh user@host "bash /path/to/remote/script.sh".

如果直接从远程 shell 执行此脚本,我不希望它运行,但仅当通过 SSH 在本地执行时才运行。我考虑过向脚本传递一个类似的值ssh user@host "bash /path/to/remote/script.sh local",并且脚本退出 if $1was not local,但是有没有更可靠的方法来测试这一点?

非常感谢,史蒂夫。

答案1

您可以检查脚本的父进程 pid 的进程名称是否匹配sshd

例如,在脚本早期的某个地方(紧接该#!行之后是一个好地方):

#!/bin/bash

if [ "$(ps h -o comm -p "$PPID")" != "sshd" ] ; then 
  echo "This script can only be run directly from ssh." > /dev/stderr
  exit 1
fi

这使用 bash 的内置只读变量“$PPID”。它在 bash 的每个实例中自动定义。

请注意,这是毫无意义的,因为任何具有脚本读取权限的人都可以复制它并删除这几行。无论脚本使用什么方法来尝试执行此操作,情况都是如此。

此外,进程名称很容易伪造。sshd在运行脚本之前编写一个包装器脚本将其进程名称设置为 是很容易的。


如果您担心其他用户可能会运行您的脚本,您是否考虑过设置脚本的权限,以便仅有的脚本的所有者可以读取或执行它吗? (例如chmod 700 /path/to/script

答案2

一个相当糟糕的、低分辨率的方法是测试 SSH 会话变量是否存在:

SSH_CLIENT='10.10.11.11 48052 22'
SSH_CONNECTION='10.10.11.11 48052 10.20.30.40 22'
SSH_TTY=/dev/pts/2

但是,远程计算机上不受信任的用户可以轻松伪造此类变量,然后运行该脚本。

我能想到的确保脚本无法在远程计算机上的本机 shell 中运行的最佳方法是不在远程计算机上存储脚本。相反,请将其本地存储在您所在的计算机上ssh

ssh user@host bash < /local/path/to/script.sh

[编辑]

如果您想将远程脚本保留在调用它的本地脚本中(而不是在单独的文件中),则此处文档就足够了,例如本例中:

#/usr/bin/env bash

user='someuser'
host='remote.host.name'

ssh -T $user@$host << \EOF
printf 'The remote hostname is: '
hostname
printf 'Current time on the remote host is: '
date
EOF

您可以通过执行以下操作进一步划分远程脚本:

#/usr/bin/env bash

remote_script() {
cat << \EOF
printf 'The remote hostname is: '
hostname
printf 'Current time on the remote host is: '
date
EOF
}

user='someuser'
host='remote.host.name'

remote_script | ssh -T $user@$host

相关内容