web-dev-qa-db-ja.com

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

SSHで制御されているかどうかをシェルスクリプト(より具体的には.zshrc)から検出したい。私はホスト変数を試しましたが、それは常にシェルを実行しているコンピューターの名前です。 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

つまり、サーバーにはこの情報があります。

72
stribika

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

  • 変数SSH_CLIENTまたはSSH_TTYの1つが定義されている場合、それはsshセッションです。
  • ログインシェルの親プロセス名が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

(なぜ、セッションの起動ではなく、シェル構成でこれをテストしたいのですか?)

SSH_TTYSSH_CONNECTION、またはSSH_CLIENT変数を使用して確認できるはずです。

23
Cakemox

LinuxでもBashを使用して同じ問題が発生しました。私は最初に環境変数SSH_CONNECTIONを使用しましたが、su -の場合は設定されていないことに気付きました。

上記のlastlogソリューションは、suまたはsu -の後でも機能しませんでした。

最後に、who am iを使用しています。これは、SSH接続の場合、最後にリモート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 ...として使用できます

10
mivk

まず、環境を見て、適切なオプションを見つける

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

これらの環境変数の多くにフックして、それらの存在に基づいて特定のアクションをトリガーできます。

2
lfender6445