すべてのsshコマンドのローカルのタイムスタンプ付きロギング?


12

どのように私は私が使用するすべてのリモートコマンドのローカル、タイムスタンプを記録しておくことができますssh(コマンドラインOpenSSHクライアントを経由開始しますかbash)?

要件:

  • 必須:

    • サーバーのログ記録に依存しない100%クライアント側
    • ログはユーザーのホームディレクトリに保存され、ユーザーごとに構成またはインストールされます。
    • さまざまなユーザーやホストとの複数の同時セッションを区別するためのサポート。
    • 非侵入型(毎回アクティブにする必要はなく、sshの使用を大幅に妨害しません)
  • 高優先度:

    • 出力はログに記録されないか、可能な限り除外されません。
    • パスワードエントリがログに記録されていないか、ファイルが暗号化されています
    • 使用された実際のコマンドを示します(タブ/履歴の完了、バックスペース、CTRL+ Cなど...が処理された後)
  • あった方がよい:

    • 連鎖セッションのコマンドも記録します(リモートsshまたはsu <user>セッション中に入力されたコマンド)
    • セッションの開始と終了をログに記録する必要があります
    • 単純なbashベースの非ルートソリューションが最適です(おそらく、コマンドのaliasまたはbashラッパースクリプトsshですか?)

私のスキルレベル:

  • 私はプログラミングに不慣れですが、まだbash「Linuxのやり方」を学んでいるので、簡単な説明のあるコードサンプルをいただければ幸いです。

可能な戦略

  • キーロガー -問題:パスワードをログに記録し、タブや履歴の完了をログに記録しない(glennの回答を参照)
  • screen1秒に1回、およびdiffそれらの間にスクロールバックダンプを行い、新しいスクロールバック行を見つける -問題:これを便利な自動化された方法で実装するにはどうすればよいですか?
  • ssh "$@" | tee >(some_cleaner_function >> $logfile) -問題:連鎖セッションで複数行のコマンドまたは履歴を処理できない、慎重なクリーンアップが必要(私の回答を参照)
  • 上記のいくつかの組み合わせ

次のSSHセッション:

user@local:~$ ssh user@remote
Last login: Tue Jun 17 16:34:23 2014 from local
user@remote:~$ cd test
user@remote:~/test$ ls
a  b
user@remote:~/test$ exit

次の~/logs/ssh.logようなログが出力される場合があります。

2014-06-17 16:34:50   [user@remote - start]
2014-06-17 16:34:51   [user@remote] cd test
2014-06-17 16:34:52   [user@remote] ls
2014-06-17 16:34:53   [user@remote] exit
2014-06-17 16:34:53   [user@remote - end]

または、ファイルの先頭でセッションを開始するために使用されるコマンドラインを使用して、セッションごとに個別のログが作成される可能性があります。


また、nanoやvimのようなエディタ処理する必要があります
デイジー

回答:


4

私はあなたの質問に興味をそそられました。もともと答えるつもりはなかったのですが、夢中になりました。

これは使用しexpect、それは本当にキーロガーです。

#!/usr/bin/expect -f

proc log {msg} {
    puts $::fh "[timestamp -format {%Y-%m-%d %H:%M:%S}]: $msg"
}

set ssh_host [lindex $argv 0]
set ::fh [open "sshlog.$ssh_host" a]

log "{session starts}"

spawn ssh $ssh_host

interact {
    -re "(.)" {
        set char $interact_out(1,string)
        if {$char eq "\r"} {
            log $keystrokes
            set keystrokes ""
        } else {
            append keystrokes $char
        }
        send -- $char
    }
    eof
}

log "{session ends}"

ノート:

  • 名前にsshの宛先を含むファイルに追加します
  • これはキーロガーです。sshキーを設定していない場合は、ログファイルでユーザーのパスワードを取得します
  • タブ補完により無効化されます。ユーザーがuptTabuptimeコマンドに対して)入力すると、「uptime」ではなく「upt \ t」がログファイルに記録されます。
  • 「raw」モードで文字を取得します。ユーザーがタイピストである場合^?、ログファイルに多くの(バックスペース文字)が表示されます。

ご回答どうもありがとうございました。興味深いのは、これに対する簡単な答えがないようで、おそらくsshクライアントのネイティブです。制限について説明していただきありがとうございます。タブ補完/バックスペース文字ロギング/パスワードロギングでこれを頻繁に使用しないようにするには十分だと思います。また、自分の優先事項についてもっと考えるようになりました。質問でそれらを明確にします。
Oleg

生成されたプロセスからの出力を解析して、必要なコマンドを抽出できます。それを簡単にするために、ユーザーのプロンプトを知る必要があります。
グレン・ジャックマン、2014年

タブ補完を頻繁に使用しています。これは、それらのコマンドがログに記録されないことを意味しませんか?
Oleg

ああ、あなたの言っていることがわかります。出力はどのように解析されますか?プロンプトは、構成オプションとしてどこかに入力できます。
Oleg

質問の最後に可能な解決策のリストを追加しました。ssh ... | tee -ai <logfile>は安全に入力と出力をログに記録するために適切に機能しますが、タイムスタンプを追加したり、バックグラウンドで出力を除外したりする方法がわかりません。
Oleg

2

現在、以下のbashスクリプトを使用しています。これには多くの問題がありますが、すべての要件、優先度、および「所有するのに便利」(少なくともほとんどの場合)に対処する唯一の解決策です。

この回答では、sshセッションをローカルでロギングすることが非常に難しい理由について説明します。

これまでに見つけたスクリプトの問題:

  1. 複数行コマンドは問題を引き起こします:

    • リモート履歴の複数の項目を(上/下キーで)ページを移動すると、最新のコマンドの代わりに履歴項目がログに記録されます。複数行コマンドを使用した直後にbash履歴から削除することで、これを回避できます。
    • 複数行コマンドの最初の行のみがログに記録されます。
  2. チェーンされたセッション(sshまたはsuリモートエンドのコマンドを使用)により、履歴のスクロールでは、実際に使用されたコマンドの代わりに、スクロールされて渡されたコマンドが記録されます。

  3. 正規表現は改善することができ、特定の環境では変更が必要になる場合があります。

    • 印刷cat -v前の文字をクリーニング前に変換してカンニングをします。その結果、^[[コマンドのように文字列を使用した場合、有効なコンテンツが削除される可能性があります。
    • 履歴を非常に高速でページングする場合など、コマンドの前にログに記録された入力が追加されることがあります。これには通常、実際のコマンドの前に「^ M」が続くため、必要に応じて削除できます。
    • 他の制御文字が時々発生します。どれを削除しても安全かがわかるまで、今のところはすべてそのままにしておきます。先ほど述べた^ Mは、無効なログ入力を検出するのに役立ちます。^ Cは、コマンドが中止されたかどうかを通知します。
    • プロンプトの正規表現は特定のプロンプトに合わせて変更する必要がある場合があり、リモート環境が異なると制御文字パターンが異なる場合があると想像できます。
  4. ホスト名などのsshコマンドのbash補完はありません。 あなたがこのスクリプトを別名場合は、bashの補完を得ることができるsshalias ssh="sshlog"

スクリプトソースとインストール:

インストールするには、以下を〜/ bin / sshlogに貼り付け、実行可能にします。に電話してくださいsshlog <ssh command options>。オプションで、ユーザーの.bashrcファイルの「ssh」のエイリアス。

#!/bin/bash
# A wrapper for the ssh command that produces a timestamped log of all ssh commands
declare -r logfile=~/logs/ssh.log
declare -r description="sshlog-${$} ${@}"
declare -r TAB=$'\t'

logdir=`dirname ${logfile}`
[ -d ${logdir} ] || mkdir "${logdir}";

clean_control_chars() {
    while IFS= read -r line; do
        # remove KNOWN control characters. Leave the rest for now.
        # line=$(echo "${line}" | sed 's/\^\[\[K//g')  # unkown control character: ^[[K
        # line=$(echo "${line}" | sed 's/\^\[\[[0-9]\+[P]//g')  # these are generated by up/down completion - e.g. ^[[2P
        line=$(echo "${line}" | sed 's/\^\[\[[0-9]*[A-Z]//g')  # all other ^[[..
        # replay character deletions (backspaces)
        while [[ $(echo "${line}" | grep -E --color=never '.\^H') != "" ]]; do
            line=$(echo "${line}" | sed 's/.\^H//')
        done
        # remove common control characters
        line=$(echo "${line}" | sed 's/\^M$//')  # remove end of line marker from end
        line=$(echo "${line}" | sed 's/^\^G//g')  # remove start marker from start
        # remove ^G from other locations - possibly a good idea
        # line=$(echo "${line}" | sed 's/\^G//g')
        # remove all other control characters - not recommended (many like ^C and ^M indicate which section was processed/ ignored)
        # line=$(echo "${line}" | sed 's/\^[A-Z]//g')
        echo ${line};
    done
}

filter_output() {
    while IFS= read -r line; do
        # convert nonprinting characters and filter out non-prompt (in Ubuntu 14.04 tests, ^G indicates prompt start)
        line=$(echo "${line}" | cat -v | grep -Eo '[\^][G].*[\$#].*')
        [[ ${line} != "" ]] && echo "${line}"
    done
}

format_line() {
    while IFS= read -r line; do
        raw=${line};
        line=$(echo "${line}" | clean_control_chars);
        prompt=$(echo "${line}" | grep -Po '^.*?(\$|#)[\s]*')
        command=${line:${#prompt}}
        timestamp=`date +"%Y-%m-%d %H:%M:%S %z"`
        echo -e "${timestamp}${TAB}${description}${TAB}${prompt}${TAB}${command}"
    done
}

echo "Logging ssh session: ${description}"
echo "[START]" | format_line >> ${logfile}
/usr/bin/ssh "$@" | tee >(filter_output | format_line >> ${logfile})
echo "[END]" | format_line >> ${logfile}

ログの内容の例:

2014-06-29 23:04:06 -0700   sshlog-24176 remote [START]
2014-06-29 23:04:12 -0700   sshlog-24176 remote oleg@remote:~$  cd test
2014-06-29 23:04:13 -0700   sshlog-24176 remote oleg@remote:~/test$     ls
2014-06-29 23:04:14 -0700   sshlog-24176 remote oleg@remote:~/test$     exit
2014-06-29 23:04:14 -0700   sshlog-24176 remote [END]

0

私の答えはそれほど複雑ではなく、キーロガーではありません。サーバーログから独立しているとは言えません(つまり、すべてのアクションをサーバーに対して実行する必要があり、すべてのログはサーバー側のログです)。したがって、システム全体のbashrcに渡すことをお勧めします次のようなプロンプトコマンド:


PROMPT_COMMAND='history -a >(tee -a ~/.bash_history | logger -t "$USER[$$] $SSH_CONNECTION")'

debianではファイル/etc/bash.bashrcを編集し、centosではファイル/ etc / bashrcを編集してください。

現在のセッションのロギングを開始する場合は、編集したファイルを入手する必要があります。たとえば、次のように実行します。


source /etc/bash.bashrc

debianシステムまたは


source /etc/bashrc
CentOSシステムで。

これ以降、すべてのsshセッションのすべてのコマンドは、debianシステムでは/ var / log / syslogに、centosシステムでは/ var / log / messages記録されます

別のファイルにログを記録し、他のログファイルを台無しにしたくない場合は、以下を使用できます。


PROMPT_COMMAND='history -a >(tee -a ~/.bash_history | logger -p local6.info -t "$USER[$$] $SSH_CONNECTION")'
前のPROMPT_COMMANDの例の代わりに、必要に応じてrsyslogdを構成します。

たとえば、Debianシステムで/etc/rsyslog.confファイルを編集します。次の行を変更します。


.;auth,authpriv.none           -/var/log/syslog

.;auth,authpriv.none,local6           -/var/log/syslog
次の行をファイルの最後に追加します。

local6.info                     /var/log/history.log

次に実行します:

touch /var/log/history.log && /etc/init.d/rsyslog restart


この質問は、各リモートサーバーを構成する(覚えている/許可する)必要がない、または接続しているすべてのリモートサーバーから手動でログをダウンロードする必要なしに、開始/ローカル/クライアントコンピューター側でsshセッションをログに記録する問題について具体的にですに。あなたの答えは、この質問には答えませんが、サーバーの監査の改善に関心のある人には役立つと思います。おそらく、より関連性の高い質問に移動する必要があります。
Oleg

0

いかがstrace -o /tmp/ssh_log -ff -s8192 -T -ttt -fp $(pidof sshd)ですか?これにより、すべてのsshセッションがログに記録されます。後でログを解析するためのツールが必要になる場合や、単にを使用するgrep場合awkなどがあります。

  • -f:分岐した子供をトレース
  • -ff:各子を個別に記録 ssh_log.PID
  • -s8192:文字列のログ制限を増やす(必要な場合)
  • -T -ttt:エポック以降の秒単位のマイクロ秒スタンピング
  • -p N:pidにアタッチ N
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.