본문 바로가기
Elastic Stack

Logging every shell command to elastic stack

purpose

보안이나, 이력 관리를 위하여 bash  shell 상에서 입력되는 커맨드들을 로그로 관리 하고 , 해당 로그를  elastic stack 을 통하여 관리 

setting

/etc/profile 환경 변수에  history_to_syslog 라는 함수를 만들어 모든 커맨드들을 logger 명령어를 이용 하여 local1.notice 로 전달 한다.

/etc/profile
function history_to_syslog
{
        declare command
        command=$(fc -ln -0)
        if "$command" != "$old_command" ]; then
                who=$(whoami)
                cmd=$(history 1)
                TTY=`tty`
                HISNAME="`basename $TTY`"
                ip=`who |grep pts/${HISNAME} |cut -f 2 -d \(|cut -f 1 -d \)`
 
                #logger -p local1.notice -t bash -i ? $USER : "$command"
                logger -p local1.notice -- IP=$ip USER=$who, PID=$$, PWD=$PWD, CMD=$command
        fi
        old_command=$command
}
trap history_to_syslog DEBUG
 
 
 
..생략 ..


rsyslog 설정을 하여  /var/log/bash_history 파일로 전달 한다 

/etc/rsyslog.conf
.. 생략 ...
local1.notice     /var/log/bash_history

rsyslog 재시작 및 /etc/profile 적용 
rsyslog 재시작 및 source
# systemctl restart rsyslog
# source  /etc/profile


/var/log/bash_history 파일에 정상적으로 로그가 남는지 확인 한다.

/var/log/bash_history
2018-05-18T13:38:34.266632+09:00 controller01 root: IP=10.15.1.4 USER=root, PID=30150, PWD=/root, CMD= 240 2018-05-18 13:38:34 ls
2018-05-18T13:38:35.483794+09:00 controller01 root: IP=10.15.1.4 USER=root, PID=30150, PWD=/root, CMD= 241 2018-05-18 13:38:35 ifconfig
2018-05-18T13:38:35.512413+09:00 controller01 root: IP=10.15.1.4 USER=root, PID=30150, PWD=/root, CMD= 241 2018-05-18 13:38:35 ifconfig
2018-05-18T13:38:37.041778+09:00 controller01 root: IP=10.15.1.4 USER=root, PID=30150, PWD=/root, CMD= 241 2018-05-18 13:38:35 ifconfig


해당 /var/log/bash_history 파일 로그를 filebeat 로 전송 할 수 있도록  paths 설정 및 commands 라는 tags를 추가 하여 전송 할 수 있도록 한다.

filebeat.yml
- input_type: log
  enabled: true
  paths: /var/log/bash_history
  tags: [ "syslog""commands"]
 
 
..생략...


 logstash 에서는 해당 commands 라는 tags 설정시 아래 match 될 수 있도록 한다.

logstash.conf
if "commands" in [tags] {
        grok {
               
                match => [ "message","%{TIMESTAMP_ISO8601:logdate}%{SPACE}%{GREEDYDATA:hostname}%{SPACE}%{GREEDYDATA:hostname}:%{SPACE}IP=%{IP:client}%{SPACE}USER=%{WORD:user},%{SPACE}PID=%{WORD:pid},%{SPACE}PWD=%{GREEDYDATA:pwd},%{SPACE}CMD=%{GREEDYDATA:cmd}" ]
                add_field => [ "received_at""%{@timestamp}" ]
        add_field => [ "received_from""%{host}" ]
        remove_tag => ['_grokparsefailure']
        }
 
        if "_grokparsefailure" in [tags] {
          drop {}
        }
 
        syslog_pri { }
        }
 
output {
  elasticsearch {
      hosts => "localhost:9200"
  }
}


정상적으로 설정 될 경우 아래와 같이 해당 명령어를 어떠한 ip 에서 host  어느 디렉토리에서 수행 하였는지 확인 할 수있다



반응형