シェルがSSHによって制御されているかどうかをどのように検出しますか?

シェルがSSHによって制御されているかどうかをどのように検出しますか?

SSHを介して制御されるかどうかをシェルスクリプト(より具体的には.zshrc)で検出したいと思います。 HOST変数を試しましたが、常にシェルが実行されているコンピューターの名前。 SSHセッションが開始されたホスト名にアクセスできますか? 2つを比較すると、私の問題は解決しました。

ログインするたびに、最後のログイン時間とホストを知らせるメッセージが表示されます。

Last login: Fri Mar 18 23:07:28 CET 2011 from max on pts/1
Last login: Fri Mar 18 23:11:56 2011 from max

これは、サーバーにこの情報があることを意味します。

答え1

私が使用する基準は次のとおりです~/.profile

  • 変数の1つSSH_CLIENTが定義されている場合はSSHセッションです。SSH_TTY
  • ログインシェルの親プロセス名がある場合sshdはSSHセッションです。
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
  SESSION_TYPE=remote/ssh
# many other tests omitted
else
  case $(ps -o comm= -p "$PPID") in
    sshd|*/sshd) SESSION_TYPE=remote/ssh;;
  esac
fi

(セッション開始ではなくシェル構成でこれをテストするのはなぜですか?)

答え2

SSH_TTYSSH_CONNECTIONまたは変数でSSH_CLIENT確認できる必要があります。

答え3

私はLinuxでBashを使って同じ問題に直面しました。最初は環境変数SSH_CONNECTIONを使用しましたがsu -

su上記のLastlogソリューションは前後には機能しませんsu -

最後に を使用します。who am iSSH接続の場合は、最後にリモートIP(またはホスト名)が表示されます。 su以降も有効です。

Bash正規表現を使用すると、次のような効果が得られます。

if [[ $(who am i) =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then echo SSH; else echo no; fi

zshが正規表現をサポートしていない場合は、grep、cut、sedなどを使用して、さまざまな方法で同じ結果を得ることができます。

気になるので、ルートの.bashrcで私が使用する用途は次のとおりです。

    # We don't allow root login over ssh.
    # To enable root X forwarding if we are logged in over SSH, 
    # use the .Xauthority file of the user who did su

    w=$(who am i)
    if [[ $w =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then
        olduser=${w/ .*/}
        oldhome=$(getent passwd $olduser | cut -d: -f 6)
        [ -f "$oldhome/.Xauthority" ] \
          && export XAUTHORITY=$oldhome/.Xauthority
    fi

別の可能なアプローチは、親suプロセスを介して再帰的に検索することです。sshd

#!/bin/bash

function is_ssh() {
  p=${1:-$PPID}
  read pid name x ppid y < <( cat /proc/$p/stat )
  # or: read pid name ppid < <(ps -o pid= -o comm= -o ppid= -p $p) 
  [[ "$name" =~ sshd ]] && { echo "Is SSH : $pid $name"; return 0; }
  [ "$ppid" -le 1 ]     && { echo "Adam is $pid $name";  return 1; }
  is_ssh $ppid
}

is_ssh $PPID
exit $?

.bashrcに関数を追加すると、次のように使用できます。if is_ssh; then ...

答え4

まず、あなたの環境を見て、正しい選択を見つける

printenv|grep SSH
SSH_CLIENT=192.168.1.xxx
SSH_CONNECTION=192.168.1.xxx
SSH_TTY=/dev/ttys021

これらの環境変数の多くを連結して、存在するかどうかに応じて特定のアクションをトリガーできます。

関連情報