모든 ssh 명령의 로컬 타임 스탬프 로깅?


12

어떻게 내가에서 사용하는 모든 원격 명령의 로컬, 타임 스탬프 기록을 유지할 수 있습니다 ssh(명령 줄에서 OpenSSH 클라이언트를 통해 시작 bash)?

요구 사항 :

  • 본질적인:

    • 서버 로깅에 의존하지 않고 100 % 클라이언트 측
    • 사용자의 홈 디렉토리에 저장된 로그를 사용하여 사용자별로 구성하거나 설치했습니다.
    • 다양한 사용자 및 호스트와의 여러 동시 세션 간 구별을 지원합니다.
    • 비침 입성 (매번 활성화 할 필요가없고 ssh 사용을 크게 방해하지 않음)
  • 우선 순위 :

    • 출력이 가능한 한 많이 기록되거나 필터링되지 않습니다
    • 비밀번호 항목이 기록되지 않거나 파일이 암호화됩니다
    • 사용 된 실제 명령을 나타냅니다 (탭 / 이력 완료, 백 스페이스, CTRL+ C등이 처리 된 후).
  • 가져서 좋다:

    • 또한 연쇄 세션 (원격 ssh또는 su <user>세션 중에 입력 된 명령)으로 명령을 기록합니다.
    • 세션 시작 및 종료가 기록되어야합니다
    • 간단한 bash루트 기반의 비 루트 솔루션이 가장 좋습니다 (어쩌면 명령에 대한 alias또는 bash래퍼 스크립트 ssh일까요?)

내 기술 수준 :

  • 저는 프로그래밍에 익숙하지 않지만 여전히 배우고 bash"리눅스 방식"이므로 간단한 설명이 포함 된 코드 샘플이 가장 높이 평가됩니다.

가능한 전략

  • keylogger- 문제 : 비밀번호를 기록하고 탭 / 기록을 기록하지 않습니다 ( glenn의 답변 참조 )
  • screendiff새로운 스크롤 백 라인을 찾기 위해 초당 한 번씩 스크롤 백 덤프 를 사용하는 것
  • 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명령을 입력하면 "upt \ t"가 아니라 "uptime"이 로그 파일에 나타납니다.
  • "원시"모드에서 문자를 가져옵니다. 사용자가 나쁜 타이피스트 인 ^?경우 로그 파일에 많은 (백 스페이스 문자)가 표시됩니다.

대답 해 주셔서 감사합니다. 이것에 대한 쉬운 대답이없는 것 같습니다. 아마도 ssh 클라이언트에 고유 한 것 같습니다. 한계를 설명해 주셔서 감사합니다. 탭 완성 / 백 스페이스 문자 로깅 / 비밀번호 로깅만으로도 자주 사용하지 못하는 것 같습니다. 또한 저의 우선 순위에 대해 더 많이 생각하게 만들었고, 질문에있는 사람들을 명확히 할 것입니다.
Oleg

생성 된 프로세스의 출력을 구문 분석하여 원하는 명령을 추출 할 수 있습니다. 더 쉽게하기 위해 사용자의 프롬프트를 알아야합니다.
glenn jackman 2016 년

탭 완성을 많이 사용합니다. 이것이 해당 명령이 기록되지 않았 음을 의미하지 않습니까?
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는 완료를 얻을 수 ssh와를alias 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")'

데비안에서는 /etc/bash.bashrc 파일을 편집하고 centos에서는 / etc / bashrc 파일을 편집해야합니다.

사용중인 세션에 대한 로깅을 시작하려면 편집 한 파일을 소싱해야합니다 (예 : 다음을 실행).


source /etc/bash.bashrc

데비안 시스템 또는


source /etc/bashrc
centos 시스템에서.

이제부터는 모든 ssh 세션의 모든 명령 이 데비안 시스템의 / 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를 구성하십시오.

예를 들어 데비안 시스템에서 /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: Epoch 이후 초 단위의 마이크로 초 스탬핑
  • -p N: pid에 첨부 N
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.