블로그 이미지
redkite

카테고리

분류 전체보기 (291)
00.SI프로젝트 산출물 (0)
00.센터 운영 문서 (0)
01.DBMS ============.. (0)
01.오라클 (117)
01.MS-SQL (15)
01.MySQL (30)
01.PostgreSql (0)
01.DB튜닝 (28)
====================.. (0)
02.SERVER ==========.. (0)
02.서버-공통 (11)
02.서버-Linux (58)
02.서버-Unix (12)
02.서버-Windows (2)
====================.. (0)
03.APPLICATION =====.. (11)
====================.. (0)
04.ETC =============.. (0)
04.보안 (5)
====================.. (0)
05.개인자료 (1)
06.캠핑관련 (0)
07.OA관련 (1)
Total
Today
Yesterday

달력

« » 2025.2
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

공지사항

최근에 올라온 글

쉘에서 실행한 명령을 syslog로 자동 보내기

작성일 : 2008/11/18 19:53

 

 

조회수 : 3174

 

 


제 목 : 쉘에서 실행한 명령을 syslog로 자동 보내기
작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
작성일 : 2008.9.30(화)
정리일 : 2008.10.31(금)

서버에 접속한 유저가 어떤 명령을 내렸는지 실시간으로 확인하려면 어떻게 해야할까? history file을 뒤진다? 이건 너무 불편하다. 명령이 실행될 때마다 특정이벤트를 발생해서, 별도 저장해주면 효과적일 것이다. 그 것도 syslog를 통해서 명령이 저장된다면 원격지 서버에서 특정 서버의 실행 명령을 모조리 확인해볼 수 있을 것이다.

몇줄의 쉘 function으로 syslog로 실행명령을 보내는 방법을 알아보자.

1. bash로 syslog로 메시지 보내기

function logging
{
stat="$?"
cmd=$(history|tail -1)
IP=`/usr/bin/who am i|awk -F\( '{print$2}'|awk -F\) '{print$1}'`
if [ "$cmd" != "$cmd_old" ]; then
logger -p local1.notice "[2] STAT=$stat"
logger -p local1.notice "[1] IP=$IP, PID=$$, PWD=$PWD, CMD=$cmd"
fi
cmd_old=$cmd
}
trap logging DEBUG

 

 

cmd_logging.txt


1: function logging
2: {
3: stat="$?"
4: cmd=$(history|tail -1)
5: if [ "$cmd" != "$cmd_old" ]; then
6: logger -p local1.notice "[2] STAT=$stat"
7: logger -p local1.notice "[1] PID=$$, PWD=$PWD, CMD=$cmd"
8: fi
9: cmd_old=$cmd
10: }
11: trap logging DEBUG

 



위 스크립트에서 중요한 부분은 logger와 trap이다.

1) logger는 지정한 메시지를 syslog로 보내주는 명령이다.
위에서는 local1 서비스종류(facility)과 notice 레밸로 syslog로 메시지를 보내준다.
logger의 활용에 대해서는 '여러 서버의 load를 터미널에서 실시간 모니터링' (글 좋은진호, 2008.2)
중 '2. 미리 준비되어 있어야할 사항' 부분을 살펴보기 바란다.
http://coffeenix.net/board_view.php?bd_code=1571
2) trap은 bash내부 명령으로 특정시그널이 발생할 때 지정한 명령어가 실행된다.
형식) trap "명령" 시그널
위에서는 DEBUG 형태로, 명령이 실행될 때마다 logging function을 호출한다.

1번째줄 : logging function을 정의한다.
3번째줄 : 명령의 실행 결과를 stat 변수에 저장해둔다.
4번째줄 : history중에서 맨 마지막에 실행한 명령을 뽑아 cmd 변수에 저장해둔다.
5번째줄 : 이전에 실행한 명령과 방금 실행한 명령이 다를 경우에만 syslog로 보내도록 해준다.
이전에 ls 명령을 했고, 방금 ls명령을 했다면 따로따로 로그에 남을까? 그렇다.
cmd_olg는'4 ls -la'를 저장하고 있고, cmd는'5 ls -la'를 저장하고 있다. 즉, history 번호가 함께 저장되기 때문에 다른 명령으로 판단한다.
이 if문이 없을 경우에는 아무 명령도 입력하지 않고 엔터만 쳐도 이전에 실행한 명령을 반복적으로 syslog로 보내버리므로 반드시 필요하다.
6번째줄 : 이전에 실행한 명령의 실행 결과 코드를 syslog로 보낸다.
7번째줄 : 방금 실행한 명령의 실행디렉토리, 명령을 syslog로 보낸다. PID는 bash의 PID다.

위의 스크립트를 global하게 적용하려면 /etc/profile 에 추가하거나 /etc/profile.d/cmd_logging.sh 로 저장하면 된다. 유저별로 적용하려면 $HOME/.bash_profile 또는 $HOME/.bashrc에 넣어둔다. 이제 적용됐는지 로긴해보자.

2. syslog에 남기는 로그 형태

아래의 로그를 살펴보자. 시간표시를 자세히 보면 [2]가 먼저 저장되고, [1]이 그 다음에 저장된다. [2] 는 이전에 실행한 명령의 실행 결과 코드이며, [1]은 방금 실행한 명령이다. 방금 실행한 결과 코드는 다음 명령이 실행되어야 결과로 저장이 된다.
 


Sep 30 17:11:31 cnx1 coffeenix: [2] STAT=0
Sep 30 17:11:31 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 4 ls -la
Sep 30 17:11:31 cnx1 coffeenix: [2] STAT=0
Sep 30 17:11:31 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 5 w
Sep 30 17:11:32 cnx1 coffeenix: [2] STAT=126
Sep 30 17:11:32 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 6 pwd
Sep 30 17:11:32 cnx1 coffeenix: [2] STAT=0
Sep 30 17:11:32 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 7 ls -la
Sep 30 17:11:36 cnx1 coffeenix: [2] STAT=0
Sep 30 17:11:36 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 8 vi get_stat.sh
Sep 30 17:15:24 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:24 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 9 chmod 700 get_stat.sh
Sep 30 17:15:28 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:28 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 10 ./get_stat.sh
Sep 30 17:15:35 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:35 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 11 ls
Sep 30 17:16:31 cnx1 coffeenix: [2] STAT=0
Sep 30 17:16:31 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD= 12 cd /var/log
Sep 30 17:16:32 cnx1 coffeenix: [2] STAT=0
Sep 30 17:16:32 cnx1 coffeenix: [1] PID=29168, PWD=/var/log, CMD= 13 ls

 



실행명령만 별도 로그로 저장하고 싶다면 /etc/syslog.conf 에 다음을 추가하고, syslogd 데몬을 재실행해주면 된다.

 


local1.notice /var/log/cmd.log

 



원격지로 명령을 보내려면, 마찬가지 방법으로 /etc/syslog.conf 에 다음을 추가하고, 재실행하면 된다. 물론 수신받는 원격지 syslog 서버에서는 메시지 수신을 허용해둔 상태여야 한다.

 


local1.* @192.168.123.2

 

### 적용 후 service syslog restart 를 통하여 적용


아쉬운 점은 csh은 trap이 없고, 대신할 csh 내부 명령으로 onintr 이 있으나 위의 trap과 같은 효과는 얻어내기 힘들다.

3. 참고자료

* 여러 서버의 load를 터미널에서 실시간 모니터링 (글 좋은진호, 2008.2)
http://coffeenix.net/board_view.php?bd_code=1571 (logger 명령)
* bash man 페이지

               

'02.서버-Linux' 카테고리의 다른 글

[리눅스]패스워드 만료일자 변경  (0) 2012.12.19
[리눅스]부트영역 복구하기  (0) 2012.12.19
[리눅스]USB 인식  (0) 2012.12.19
[리눅스]NCFTP로 백업하기  (0) 2012.12.19
[리눅스]Core File 설정  (0) 2012.12.19
Posted by redkite
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함