リモートスクリプトがローカルシェルで実行されているのか、リモートシェルで実行されているのかを確認する方法はありますか?

リモートスクリプトがローカルシェルで実行されているのか、リモートシェルで実行されているのかを確認する方法はありますか?

を使用して動作するリモートスクリプトがありますssh user@host "bash /path/to/remote/script.sh"

私はこのスクリプトがリモートシェルで直接実行されるのではなく、SSHを介してローカルで実行されている場合にのみ実行したいと思います。同様の値をスクリプトに渡し、スクリプトでssh user@host "bash /path/to/remote/script.sh local"ない$1場合は終了することを検討しましたが、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

ただし、リモートコンピュータの信頼できないユーザーはこれらの変数を簡単に偽造してスクリプトを実行できます。

スクリプトをリモートシステムのプライマリシェルで実行できないようにするために私が考える最善の方法は、リモートシステムにスクリプトを保存しないことです。代わりにコンピュータにローカルに保存してください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

関連情報