리눅스에서 사용자 명령어(history)를 rsyslog 중앙 로그 서버로 전송하는 방법
리눅스에서 사용자 명령어(history)를 rsyslog 중앙 로그 서버로 전송하는 방법
리눅스에서 사용자의 bash 명령 이력을 실시간으로 수집하여 중앙 syslog 서버로 전송하는 방법입니다.
보안 감사(audit), 사용자 행위 추적, 운영 이력 관리에 활용할 수 있다.
전체 흐름
[클라이언트 서버]
bash trap (DEBUG)
↓
logger 명령어
↓
rsyslog (local6.notice)
↓ TCP/UDP 514
[중앙 로그 서버]
rsyslog (imtcp / imudp)
↓
/var/log/clients/<HOSTNAME>/bash_history.log
1. Bash History → syslog 연동
trap 'function' DEBUG 를 이용하면 bash에서 명령어를 실행할 때마다 지정한 함수를 호출할 수 있다.
이 함수 안에서 logger로 syslog에 기록하는 방식이다.
/etc/profile.d/history.sh 작성
cat <<'EOF' > /etc/profile.d/history.sh
function history_to_syslog()
{
# 재귀 호출 방지: 함수 진입 시 trap을 먼저 해제
trap - DEBUG
local cmd="${BASH_COMMAND}"
# logger, trap 등 내부 명령어는 로깅에서 제외
case "$cmd" in
history_to_syslog*|\
logger*|\
trap*|\
local\ cmd*|\
who\ am\ i*|\
tty|\
pwd|\
return*)
trap 'history_to_syslog' DEBUG
return
;;
esac
# SSH 접속 시 IP는 "(192.168.1.100)" 형태로 반환되므로 괄호 제거
local ip
ip=$(who am i | awk '{gsub(/[()]/,""); print $5}')
ip=${ip:-"local"} # 콘솔 직접 로그인 시 fallback
logger -p local6.notice -t bash_history \
"USER=$(whoami) \
IP=${ip} \
TTY=$(tty) \
PWD=$(pwd) \
CMD=${cmd}"
# 함수 종료 시 trap 복원
trap 'history_to_syslog' DEBUG
}
trap 'history_to_syslog' DEBUG
EOF
권한 설정 및 적용
chmod 644 /etc/profile.d/history.sh
source /etc/profile.d/history.sh
2. rsyslog 클라이언트 설정
TCP vs UDP 비교
| 항목 | TCP | UDP |
| 전송 보장 | O (재전송) | X (유실 가능) |
| 서버 장애 대응 | queue 버퍼링 가능 | 불가 |
| 성능 오버헤드 | 상대적으로 높음 | 낮음 |
| 운영 환경 권장 | 권장 | 내부망 경량 수집 시 |
운영 환경에서는 TCP를 권장한다.
2-1. 로컬 저장 + 중앙 서버 전송
로컬 디스크에도 기록하면서 중앙 서버로도 전송하는 방식이다. 로컬 백업이 필요한 환경에 적합하다.
rsyslog 설정(TCP 사용 시)
sudo vim /etc/rsyslog.d/history.conf
if $programname == 'bash_history' then {
action(type="omfile"
file="/var/log/bash_history.log")
action(type="omfwd"
target="logserv.scbyun.com"
port="514"
protocol="tcp")
}
---
UDP 사용 시
sudo vim /etc/rsyslog.d/history.conf
if $programname == 'bash_history' then {
action(type="omfile"
file="/var/log/bash_history.log")
action(type="omfwd"
target="logserv.scbyun.com"
port="514"
protocol="udp")
}
---
2-2. 중앙 서버로만 전송 (로컬 저장 없음)
로컬 디스크 사용량을 줄이고 싶을 때 사용한다.
rsyslog 설정(TCP 사용 시)
sudo vim /etc/rsyslog.d/history.conf
if $programname == 'bash_history' then {
action(type="omfwd"
target="logserv.scbyun.com"
port="514"
protocol="tcp")
stop
}
---
UDP 사용 시
sudo vim /etc/rsyslog.d/history.conf
if $programname == 'bash_history' then {
action(type="omfwd"
target="logserv.scbyun.com"
port="514"
protocol="udp")
stop
}
---
stop 옵션 설정이 중요하다.
이 옵션이 있어야 /var/log/messages, /var/log/syslog 같은 로컬 로그 파일에 기록되지 않는다.
2-3. 운영 환경 권장 설정 (TCP + Disk-Assisted Queue)
linkedList(메모리 큐)는 rsyslog 재시작 시 데이터가 유실된다.
운영 환경에서는 disk-Assisted 큐를 사용하여 재시작 후에도 미전송 로그를 복구할 수 있도록 구성한다.
sudo vim /etc/rsyslog.d/history.conf
if $programname == 'bash_history' then {
action(
type="omfwd"
target="logserv.scbyun.com"
port="514"
protocol="tcp"
# 서버 장애 시 무한 재시도
action.resumeRetryCount="-1"
# 메모리+디스크 혼합 큐 (재시작 후 복구 가능)
queue.type="disk-Assisted"
queue.filename="bash_history_fwd" # 스풀 파일명 (필수)
queue.size="10000"
queue.maxDiskSpace="100m"
)
stop
}
rsyslog 재시작
sudo systemctl restart rsyslog
3. 기존 rsyslog 설정과 중복 전송 방지
기존 설정에 아래와 같이 전체 전송 룰이 있다면
*.info;mail.none;authpriv.none;cron.none @logserv.scbyun.com
local6.notice 로그도 함께 전송되어 중앙 서버에 중복으로 기록될 수 있다.
해결 방법: history.conf 에 stop을 추가하면 rsyslog의 rule 처리 흐름이 해당 시점에서 중단된다.
이후 *.info 룰까지 처리가 넘어가지 않으므로 중복 전송이 방지된다.
if $programname == 'bash_history' then {
action(type="omfwd"
target="logserv.scbyun.com"
port="514"
protocol="tcp")
stop # ← 이 줄이 있어야 이후 룰로 넘어가지 않음
}
/etc/rsyslog.d/ 디렉터리의 파일은 파일명 알파벳 순서로 로드된다.
history.conf가 기존 전송 룰보다 먼저 처리되도록 00-history.conf처럼 접두사를 붙이는 것도 좋은 방법이다.
4. 중앙 로그 서버(수신 측) 설정
중앙 서버에서 클라이언트 로그를 수신하려면 imtcp 또는 imudp 모듈을 활성화해야 한다.
sudo vim /etc/rsyslog.d/00-server.conf
# TCP 수신 활성화
module(load="imtcp")
input(type="imtcp" port="514")
# 호스트별 디렉터리로 분리 저장
if $programname == 'bash_history' then {
action(type="omfile"
file="/var/log/clients/%HOSTNAME%/bash_history.log"
dirCreateMode="0750"
fileCreateMode="0640"
dirOwner="root"
fileOwner="root")
stop
}
sudo systemctl restart rsyslog
UDP를 사용할 경우 imtcp 대신 imudp를 로드하고 protocol="udp"로 맞춰준다.
5. 로그 로테이션 (logrotate)
로컬 또는 서버에 파일로 저장하는 경우 로테이션 설정이 필요하다. 미설정 시 단일 파일이 무한정 커진다.
sudo vim /etc/logrotate.d/bash_history
/var/log/bash_history.log {
daily
rotate 90
compress
missingok
notifempty
postrotate
systemctl kill -s HUP rsyslog
endscript
}
# 중앙 서버 호스트별 로그 로테이션
/var/log/clients/*/bash_history.log {
daily
rotate 90
compress
missingok
notifempty
sharedscripts
postrotate
systemctl kill -s HUP rsyslog
endscript
}
6. 로그 확인
클라이언트 로컬
tail -f /var/log/bash_history.log
중앙 로그 서버
- 특정 호스트 로그 확인
tail -f /var/log/clients/web01/bash_history.log
- 전체 서버 로그에서 검색
grep bash_history /var/log/messages
May 10 10:23:45 web01 bash_history: USER=scbyun IP=192.168.1.100 TTY=/dev/pts/0 PWD=/home/scbyun CMD=ls -al
May 10 10:23:48 web01 bash_history: USER=scbyun IP=192.168.1.100 TTY=/dev/pts/0 PWD=/home/scbyun CMD=cat /etc/passwd