http://www.hanguk.jp/doc/systemMonitoring_basic.pdf
리눅스 시스템 모니터링 시스템 최적화
글쓴이 : 문태준
대한매일 뉴스넷 서비스지원팀장 (http://www.kdaily.com, http://seoul.co.kr)
taejun@tunelinux.pe.kr
http://tunelinux.pe.kr, http://database.sarang.net 운영자
0. 들어가며
이글은 효율적으로 시스템을 모니터링하고 어떻게 리눅스 서버를 최적화할 수 있을까에 대해서 다룬다.
첫 번째 장에서는 현재 시스템이 어떻게 운영되고 있고 어디에서 문제가 생기고 있는지를 알기 위한 시스템 모니터링에 대해서 설명을 한다. 시스템관리의 출발은 현재의 상태를 제대로 파악하고 여기에서 시스템을 최적화하기 위해 무엇을 해야하는지 파악을 해야하는 것이다. 프로세스, 메모리, 디스크 I/O와 네트워크의 모니터링에 대해서 알아본다.
두 번째 장에서는 운영체제가 부팅을 하면서부터 시작하는 작업인 로그파일 기록에 대하여 알아본다. 현재의 시스템에서 발생하고 있는 모든 작업은 로그를 통해 기록을 남고 문제가 발생했을 경우 가장 먼저 해야 할 작업이 로그분석작업이다. 이와 더불어 계속 불어나는 로그파일을 어떻게 효율적으로 처리할 수 있는 지에 대해서 알아보겠다.
세 번째 장에서는 앞의 두 강좌를 통해 시스템의 활동을 분석하는 방법에 대해서 배운 것을 기초로 하여 시스템 모니터링을 자동화하는 방법에 대하여 설명을 할 것이다. 시스템관리자가 해야 할 역할이 많은데 언제나 사무실에 앉아서 top만 치고 있을 수는 없지 않은가. 또 시스템이 한 대라면 모르겠지만 적게는 몇 대에서 수십, 수백대가 되는 경우 시스템관리를 한다고 애인까지 만나지 못하고 더운 여름을 전산실 에어컨과 함께 밀월을 즐길 수는 없을 것이다.
네 번째 장에서는 운영체제의 설치 및 서비스를 위한 프로그램 설치과정과 관련되어 필요한 최적화 방법에 대해서 설명을 할 것이다. 효율적인 서비스를 위해서는 설치 과정부터 필요한 프로그램만 설치하고 불필요한 프로그램을 제거를 하여 시스템의 성능은 물론 보안으로부터 대처를 할 수 있을 것이다.
마지막 장에서는 커널 차원에서의 튜닝과 보안에 대해서 다루겠다. 커널은 운영체제의 핵심부분으로 메모리 관리, 프로세스 관리, 파일 시스템 관리 등 모든 작업을 배후에서 처리하고 있는 부분이다. 그러므로 커널의 작동 원리를 이해하면 현재의 시스템에 대해서 좀 더 깊은 지식을 가질 수 있고 시스템 성능과 관련한 여러 가지 옵션들을 효율적으로 조정하여 같은 하드웨어를 가지고도 더 좋은 성능을 낼 수 있다.
기본기를 다지자
전산학의 빅5는 컴퓨터 구조론, 운영체제, 자료구조와 알고리즘, 프로그래밍 언어론 및 컴파일러, 데이터베이스론이라고 흔히 이야기를 한다. 소프트웨어 개발자의 경우 단순하게 문법을 잘 외운다고 해서 프로그래밍 능력이 높은 것은 아니다. 효율적으로 프로그램을 설계하고 적절한 알고리즘을 사용하는 것이 중요하고 하드웨어와 운영체제에 대해서 더 깊이 알고 있을수록 뛰어난 프로그램을 작성할 수 있다. 시스템 관리자의 경우도 여기에서 벗어날 수 없다. 운영체제가 어떤 방식으로 작동을 하고 있는지, 어떻게 인터넷이라는 무한한 공간에서 컴퓨터가 자료를 주고 받는지에 대한 기본 지식이 풍부할수록 시스템 관리도 단순한 세팅에서 벗어나 제대로 된 시스템 관리를 할 수가 있는 것이다. 물론 여기 글을 쓴 것처럼 그 중요성을 알고 있지만 생각만큼 쉬운 작업은 아니고 많은 노력이 필요한 작업이며 이 글을 쓰는 필자도 운영체제 및 네트웍에 대해서 뛰어난 고수는 아니다. 그렇지만 계속 발전하기 위해서는 기본기가 탄탄해야 한다는 생각을 가지고 있으며 다른 사람들과 같이 노력을 해 가고자 한다.
본 글과 관련하여 궁금한 점은 본인이 운영하는 사이트 등을 통하여 같이 논의를 했으면 좋겠다. 글을 시작하기에 앞서 본인이 이러한 글을 정리할 수 있도록 수많은 자료를 제공해준 인터넷의 수많은 사람들에 대하여 감사한 마음을 전한다. 개인의 지식은 한정될 수 밖에 없지만 네트웍을 통해 공유한 지식은 전인류의 자산이 될 것이다.
1. 시스템 모니터링 하기
- 시스템이 어떻게 움직이고 있는가?
1. 시스템 모니터링 결과에 대해서 정확히 알고 있자
ㅇ 메모리가 왜 이리 모자라지? - free 에 대하여
밤에 잠을 자고 있는데 사무실에서 급하게 전화가 왔다. 웹서비스가 엄청 느려져서 도저히 웹사이트를 볼 수가 없다는 것이다. 잽싸게 일어나서 컴퓨터를 켰다. 원격으로 접속을 해서 서버를 관찰한다. 가장 먼저 무엇을 해야할까? 어디에서 시스템이 느려지고 있는지 찾아야한다. 그리고 평상시의 상태와 비교를 해야한다. 시스템 관리자라면 흔히 일어나는 경우이다. 시스템 관리의 첫 출발은 평상시에 계속 시스템의 상태를 파악하고 모니터링 결과를 비교하는 작업이다. 또한 나온 결과를 제대로 파악하고 있어야하는데 주기적으로 시스템을 모니터링해놓고도 그 결과를 엉뚱하게 해석한다면 전혀 다른 결과를 초래할 수 있다.
예를 한번 들어보자. 리눅스에서 메모리를 점검하기 위해 흔히 free를 사용한다. 그런데 free의 결과를 잘못 이해하는 경우가 상당히 많고 필자도 마찬가지였다. 아래 결과를 보자. 512M의 메모리를 가진 시스템이다.
$ free
total used free shared buffers cached
Mem: 513368 503180 10188 0 3772 332740
-/+ buffers/cache: 166668 346700
Swap: 1028152 84908 943244
이상하게 쓰는 것도 없는데 513M에서 현재 사용하는 것이 503M이다. 아무래도 시스템에 문제가 생겼나해서 재부팅을 했는데 조금 지나자 또 대부분의 메모리를 used에서 잡아먹는다. 에라 모르겠다 메모리를 512M 더 추가시키자. 농담이 아니라 실제로 충분히 발생할 수 있는 상황이다.
디스크를 읽는 일은 메모리에 비해서 아주 느리다. 수많은 사람들이 접속해서 ls 명령어를 모두 디스크에 읽어서 실행을 한다면 그 시스템의 속도가 아주 느려질 것이다. 물론 여기서는 ls라는 간단한 명령을 말했지만 시스템의 자원을 엄청 잡아먹는 프로그램이라면 문제가 또 달라질 것이다. 이런 경우 디스크에서 한번 읽어들인 정보를 메모리에 일정기간 보관하고 있다면 처음 읽을때만 속도가 느리지 이후에는 전반적으로 빨라질 것이다. 이것을 가르켜 디스크 버퍼링이라고 하며 이런 목적으로 사용되는 메모리가 위에서 나오는 버퍼 캐쉬이다.**주1 (실제로 버퍼 캐쉬는 파일을 버퍼링하는 것은 아니고 디스크 입출력의 가장 작은 단위인 블록을 버퍼링한다. 블록 디바이스 드라이버가 사용하는 데이터 버퍼를 가지고 있는 것이다) 만일 캐쉬의 크기가 고정되어 있다면 그 크기가 너무 커도 메모리 부족현상이 생길 수 있을 것이고 지나친 스와핑을 발생하게 해서 시스템이 느려질 가능성이 크다. 리눅스에서는 자동적으로 모든 램의 빈 공간을 버퍼 캐쉬로 사용하여 메모리를 효율성을 높이고 있으며 프로그램에서 많은 메모리를 필요로 하는 경우에는 자동으로 캐쉬의 크기를 줄인다. 그렇다면 위에서 실제로 사용가능한 메모리는 free+buffers+cached 이다. -/+ buffers/cache: 이 줄이 이러한 내용을 반영하고 있다. 일반적인 리눅스 시스템관리와 관련된 서적에는 이 부분에 대하여 지적을 한 곳이 거의 없으며 맨페이지에도 이런 설명은 아직 찾지 못했다. 운영체제와 커널의 원리에 대해서 모른다면 같은 결과를 놓고도 정말 엉뚱한 분석을 할 수 있는 것이다. 위의 내용을 아는 분이라면 모르겠지만 이 글을 보는 사람들중에 위의 내용을 몰랐던 사람들은 정말 모르고 있었구나 하는 생각이 들지 않을까?
2. 현재 시스템의 문제를 찾자
시스템의 성능은 현재의 시스템 자원을 여러 가지 프로그램들의 요청에 대하여 얼마나 효율적으로 적용을 하는가에 달려있다. 요즘처럼 인터넷이 보편화된 상황에서 네트워크도 중요한 부분이기는 하지만 일반적으로 성능에서 가장 중요한 시스템 자원은 CPU, 메모리, 디스크 입출력이다. 그래서 위의 부분들을 중심으로 성능에 문제가 생기기 전에 미리 시스템을 분석하는 것이 중요하다. 시스템에 문제가 생긴다면 다음을 먼저 점검해보자
ᄋ CPU 문제 점검 - top, ps, uptime, vmstat, pstree 등
ᄋ 메모리 문제 점검 - free, vmstat 등
ᄋ 메모리에 문제가 없다면 디스크 I/O 점검 - df, du, 쿼타 등
ᄋ 디스크와 메모리에 문제가 없는데도 시스템에 문제가 생기면 CPU의 오버헤드에 문제가 있을 가능성이 크다
ㅇ 네트웍 문제 점검 - netstat, ping, traceroute, tcpdump 등
3. 사전 점검 사항
시스템이 정상적으로 작동하고 있을 때 정기적으로 모니터링을 해 두어야 시스템에 문제가 생겼을 때 대처를 할 수 있다. 아래를 참고로 하여 주기적으로 시스템 모니터링 결과를 모아두자.
ᄋ 주요 사용자들한테 성능이 괜찮다는 동의를 먼저 얻어야한다. 그리고 시스템 성능을 계속 유지할 수 있도록 정기적으로 점검한다.
ᄋ 시스템 accounting 프로그램을 이용한다. 시스템에서 CPU, I/O, 메모리 집약적인 프로그램들을 알고 있어야한다. (**주2)
$ sa
75563 169479.02re 510.44cp 0avio 506k
14056 450.37re 448.85cp 0avio 497k webalizer
361 91931.12re 37.86cp 0avio 1355k httpd*
275 7.50re 5.38cp 0avio 402k gawk
14056 455.55re 4.95cp 0avio 438k weblog
14226 588.92re 2.57cp 0avio 437k sh
11 18.88re 2.45cp 0avio 332k slocate
162 670.85re 1.46cp 0avio 666k in.telnetd
2298 45.83re 1.09cp 0avio 2858k mysqld*
325 0.86re 0.76cp 0avio 642k ps
358 1185.61re 0.66cp 0avio 454k bash
1419 0.48re 0.47cp 0avio 283k rmmod
accounting 결과 예제
ᄋ vmstat 등의 프로그램을 이용 I/O연산이 얼마나 분산되어있는지, CPU가 작동하지 않고 노는 시간(idle)은 얼마인지, 정상적인 부하가 걸릴 경우 메모리를 얼마나 사용하고 있는지 확인한다.
주기적으로 시스템 상황을 자동으로 모니터링하는 방법에 대해서는 세 번째 강좌에서 설명을 할 예정이다.
4. 문제가 발생했을 경우의 대처 방법
시스템이 정상적으로 작동하고 있을때 제대로 모니터링을 하고 분석을 해 두었다면, 사용자가 불평하거나 문제가 터지기 않더라도 언제 시스템의 성능이 나빠질지 알 수 있다. 그러면 시스템에 문제가 발생하였을 경우에는 어떻게 대처를 해야 할까?
ᄋ 어떤 프로그램을 실행하고 있으며 어떻게 사용하고 있는가? 현재 시스템에서 주요하게 제공하는 서비스는 어떤 것인가? 예를 들어 NFS를 통해 파일에 접근을 한다면 네트웍 성능이 떨어지는게 문제의 한 부분이라는 것을 알 수 있다. 웹서비스를 한다면 시스템 자체의 부하가 아니라 네트웍 회선의 문제로 속도가 느려질 가능성도 있다.
ᄋ uptime을 이용하여 시스템의 부하를 확인한다. 시스템의 부하가 어떤 추세로 움직이고 있고 어느 정도 수치로 작동하는지 확인을 한다. 웹서비스의 경우 보통 낮시간대에 접속이 폭주하므로 S자 형태로 시스템 부하가 변화될 것이다. 그런데 최대 접속할 시간이 아닌데도 시스템의 부하가 높아진다면 불필요한 프로그램이 계속 돌면서 시스템의 자원을 소비할 가능성도 있고 DOS 공격 등을 받고 있을 가능성도 크다.
$ uptime
9:23pm up 61 days, 5:23, 1 user, load average: 0.02, 0.05, 0.00
ᄋ ps와 top를 활용한다.
- 디스크 액세스나 페이징을 기다리고 이는 프로세스가 있는가? 그렇다면 I/O와 메모리를 점검하자. 리눅스에서 프로세스 대기 상태는 인터럽트 허용과 인터럽트 금지의 두가지 형태가 있다. 세마포어를 기다리거나 파일을 읽을 수 있게 되길 기다리는 것처럼 자원을 기다리는 일반적인 대기상태는 대개 인터럽트로 처리가 가능하다. (인터럽트가 허용되는 sleep 상태는 ps,top 등에서 S로 나타난다.) 그렇지만 인터럽트가 금지되는 대기상태는 스왑파일에서 메모리로 페이지를 읽어들이는 것과 같이 임계지역에서 일이 끝마치기를 기다리고 있는 상태이다. 프로세스 상태에서 D 는 uninterruptible sleep로서 page fault 등을 의미하며 page fault 등을 통해 I/O중인 상태를 나타낸다. W는 has no resident pages를 의미하며 프로세스가 스왑아웃된 상태를 나타낸다. (W는 커널 프로세스에 대해서는 정확히 동작을 하지않는다.
- CPU와 메모리를 가장 많이 사용하는 프로세스를 찾으면 부하를 분산시키는데 도움이 될 것이다.
$ ps auxw
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 1120 68 ? S Jun17 0:06 init [3]
root 2 0.0 0.0 0 0 ? SW Jun17 0:00 [keventd]
root 3 0.0 0.0 0 0 ? SW Jun17 0:00 [kswapd]
root 4 0.0 0.0 0 0 ? SW Jun17 0:00 [kreclaimd]
root 5 0.0 0.0 0 0 ? SW Jun17 0:32 [bdflush]
root 6 0.0 0.0 0 0 ? SW Jun17 0:02 [kupdated]
root 351 0.0 0.0 1164 284 ? S Jun17 0:01 syslogd -m 0
root 360 0.0 0.0 1728 356 ? S Jun17 0:00 klogd
root 388 0.0 0.0 1156 220 ? S Jun17 0:00 inetd
root 402 0.0 0.2 3824 1452 ? S Jun17 3:09 /usr/sbin/snmpd
named 416 0.0 0.3 3376 1904 ? S Jun17 0:27 named -u named
$ top
7:34pm up 14:19, 3 users, load average: 1.20, 0.54, 0.20
57 processes: 53 sleeping, 4 running, 0 zombie, 0 stopped
CPU states: 94.6% user, 5.3% system, 0.0% nice, 0.0% idle
Mem: 513368K av, 321260K used, 192108K free, 0K shrd, 9208K buff
Swap: 1028152K av, 115000K used, 913152K free 270924K cached
PID USER PRI NI SIZE RSS SHARE STAT LIB %CPU %MEM TIME COMMAND
12436 root 20 0 6428 6428 1564 R 0 13.1 1.2 0:00 cc1
3570 nobody 12 0 11148 6140 5016 R 0 2.5 1.1 0:09 httpd
12435 root 8 0 1528 1528 388 S 0 1.3 0.2 0:00 cpp
4185 root 9 0 512 328 312 S 0 0.3 0.0 0:01 sshd2
11364 taejun 10 0 876 876 680 R 0 0.3 0.1 0:00 top
1 root 8 0 120 68 68 S 0 0.0 0.0 0:04 init
2 root 9 0 0 0 0 SW 0 0.0 0.0 0:00 keventd
3 root 9 0 0 0 0 SW 0 0.0 0.0 0:03 kswapd
4 root 9 0 0 0 0 SW 0 0.0 0.0 0:00 kreclaimd
5 root 9 0 0 0 0 SW 0 0.0 0.0 0:01 bdflush
6 root 9 0 0 0 0 SW 0 0.0 0.0 0:00 kupdated
348 root 9 0 208 156 156 S 0 0.0 0.0 0:00 syslogd
357 root 9 0 608 4 4 S 0 0.0 0.0 0:00 klogd
371 root 8 0 180 124 120 S 0 0.0 0.0 0:00 crond
ᄋ vmstat를 이용한다. (vmstat 5 5)
$ vmstat 5 5
procs memory swap io system cpu
r b w swpd free buff cache si so bi bo in cs us sy id
3 0 0 115000 189428 9220 272608 1 28 10 36 108 25 2 0 98
1 0 0 115000 189972 9220 272680 0 0 0 205 196 416 95 5 0
1 0 0 115000 187060 9220 272740 0 0 0 157 156 229 95 5 0
2 0 0 115000 194852 9220 272856 0 0 0 149 142 229 96 4 0
- vmstat에서 첫 번째 줄은 부팅 이후의 각 통계치에 대한 평균치를 보여주는데 이것은 무시해야 한다. 두 번째 줄부터 보면 된다.
- cpu에서 시스템에서 사용하는 cpu시간이 지나치게 높다면(50% 이상) 디스크 I/O에서 문제가 있을 가능성이 크다. 해당 프로그램의 소스코드를 구할 수 있다면 프로그램에서 얼마나 효율적으로 I/O를 사용하는지 확인해 보아야 한다. vmstat에서 sy 항목은 system time을 의미하며 커널모드로 넘어간 상태이다.
- 시스템 전체의 부하가 높은데도 cpu에서 휴지시간(idle time, id 항목)이 일반적으로 10%를 넘는다면 I/O나 메모리에 문제가 있을 가능성이 크다.
- 휴지시간이 항상 0이라면 CPU를 완전하게 100% 사용하고 있는 상태이다. CPU의 기능을 최대한 활용하는 것은 좋은 현상이다. 그런데 항상 100% 로 바쁜 상태라면 어떤 작업이 계속 축적되고 있다는 것이며 CPU의 과부하를 의미한다. CPU를 계속 사용하고 있는 프로세스를 찾아야한다.
- 디스크의 활동이 분산되지 않았다면, I/O 작업을 효율적으로 분산시켜야한다. 그런데 현재 리눅스용 vmstat에서는 이에 대한 정보는 나오지 않는다. 다른 유닉스의 경우에는 iostat나 sar을 이용하는데 인터넷에서 패키지를 받아서 설치할 수 있다. 이러한 프로그램이 sysstat 로 리눅스용 sar, iostat 패키지이다. 사이트 주소는 다음과 같다. (최근 레드햇 배포판 등에는 들어가고 있다)
http://perso.wanadoo.fr/sebastien.godard/
아래에서는 현재 두 개의 HDD가 장착되어 있는 시스템의 상태를 보여준다.
$ iostat
Linux 2.4.4 (tunelinux.pe.kr) 07/08/01
avg-cpu: %user %nice %sys %idle
5.55 0.00 1.20 93.26
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
dev8-0 6.06 9.49 102.23 50185324 540747898
dev8-1 1.99 1.51 25.05 7964700 132509976
위 사항에서 해당하는 것이 없고 메모리와 I/O 관련 튜닝을 할 필요가 없다고 분석이 되면 CPU쪽에서 과부하가 걸린 상태이다. CPU 과부하의 경우 대처할 수 있는 몇가지 방법은 있지만 CPU의 과부하는 메모리와 I/O 문제로 나누어지기 때문에 찾아내기 힘든 부분이다.
CPU의 과부하를 줄일 방법에 대해서 설명한다.
- 필요없는 데몬과 서비스를 줄인다. rwhod와 routed는 시스템의 성능을 저해하는 프로그램으로 이를 없애는 것만으로 많은 도움이 될 것이다. kudzu, portmap, nfslock, apmd, random, netfs, identd, atd, pcmcia, lpd, sendmail, gpm, xfs, linuxconf 등이 불필요하다면 사용하지 않아도 될 서비스들이다. cpu의 부하를 줄일 뿐만 아니라 보안 관점에서도 필요없으면 내리는 것이 낫다. 여기서 잘못 이해하기 쉬운 것이 sendmail 부분이다. pine등을 이용하여 메일을 발송할 때에는 센드메일 데몬을 이용하지 않는다. 센드메일을 백그라운드 작업으로 계속 작동시키는 목적은 외부로부터 메일을 받는데 있다. 그러므로 일반적인 메일서버의 기능을 하지 않고 단지 메일을 보내는 것이 목적이라면 sendmail을 가동시킬 필요가 없다. (**주3)
- at이나 cron 등을 이용 작업을 밤이나 시스템의 부하가 적을 때 실행하는 것도 좋은 방법이다. 보통 로그 로테이션, 백업, 로그분석 등은 새벽 시간을 이용하여 처리하는게 바람직하며 기본설정되어 있는 cron 작업은 대부분 새벽 4시에 가동이 된다.
- CPU 집약적인 작업은 nice를 이용 실행우선순위를 낮추면 편집작업과 갈은 상호대화적인 작업의 성능이 향상될 것이다.
- cpu 집약적인 작업의 실행우선순위를 높이면 작업 자체는 빨라지겠지만 상호대화적인 작업의 성능은 떨어질 것이다. 그런데 보통 일반적인 인터넷 서버로 운영을 한다면 CPU 집약적인 작업은 그렇게 많은 편은 아니며 꼭 서버에서 실행시켜도 되지 않는 작업이라면 다른 시스템을 이용하는 것이 좋다. 웹로그 분석도 이러한 경우에 속한다.
- nice를 이용하는것은 임시방편일 뿐이다. 부하가 계속 증가한다면 nice를 이용하는 것에도 한계가 있다. 시스템을 업그레이드하거나 부하를 분산할 시스템을 구입해야한다.
- 커널이나 프로그램의 컴파일을 하는 경우에도 nice를 이용하면 조금이나마 속도의 향상이 있다. 그렇지만 때로 nice를 잘못 사용하면 문제가 생길 수가 있으니 조심해야 한다. 예를 들어 오라클에서는 오라클 사용자 프로세스와 백그라운드 프로세스들을 같은 우선순위에 유지해야 한다. 설계가 그렇게 되어 있기 때문이다. 우선 순위를 변경할 경우 내용과 반응시간에 원치 않는 효과를 초래할 수도 있다. 예를 들어 log write process(LGWR)에 낮은 우선 순위를 부여할 경우, 이 프로세스는 충분한 횟수만큼 작동하지 못하고 LGWR은 병목현상을 일으키게 된다. 다른 한편, 만약 LGWR이 높은 우선 순위를 부여받게 되면, 사용자 프로세스는 느린 반응시간에 시달리게 될 것이다. 무엇이든 그냥 적용하는게 아니라 그 원리를 이해하고 조심스럽게 해야 한다. (**주4)
5. 메모리 문제 파악하기
시스템에 과부하가 걸려있는데도 휴지기간(idle time)이 많거나 ps에서 많은 양의 메모리를 필요로 하는 프로그램이 실행되고 있다면 메모리 문제를 생각해 볼 수 있다.
ᄋ vmstat 5 를 실행해보자.
- swap-out이 지속적으로 항상 발생한다면 메모리가 부족한 것이다. 주기적으로 swap-outs이 발생하는건 정상적인 것이다. BSD 시스템에서는 비상호대화적인 작업을 스왑아웃한다. 현재 실행하고 있는 프로그램에서 스왑아웃이 계속 발생한다면 프로그램이 죽을 수도 있으며심각하게 메모리가 부족하다는것을 가리킨다. 스왑아웃필드(so)가 항상 0에 가까워야한다. 그렇지 않다면 프로세스들간에 가상 메모리에 대하여 경쟁하고 있으며 시스템은 페이징 상태에 있다. 페이징 활동은 또한 심각한 가용 메모리(free)의 부족과 직접적인 관련을 가지고 있으며 간접적으로는 시스템의 높은 CPU 사용시간 비율(sy)과 관련이 있다. 프로세스가 시작을 할 때 항상 이미지(text)와 데이터를 page-in 해야 하므로 page-in 열에서 높은 숫자가 항상 심각한 것은 아니라는 사실은 기억하고 있어야 한다.
- ps나 accounting 시스템에서 메모리 집약적인 작업이 있는지 확인을 한다. RSS필드나 storage integral이 큰 프로그램을 찾아보자. ps나 top에서 RSS는 프로세스가 사용중인 물리적 메모리 크기로 kbytes 단위로 보여준다. ELF 프로세스에서 사용된 라이브러리 페이지도 여기에 같이 계산이 된다. storage integral은 accounting 패키지에 들어있는 sa -K 옵션을 이용해 볼수있다.
메모리 문제를 해결할 몇가지 방법을 찾아보자.
- 시스템에서 버퍼 캐쉬가 있다면 크기를 줄인다. 대신 디스크 I/O성능에 영향을 줄 수있다. 리눅스는 /proc를 이용 전체 메모리에서 버퍼 캐쉬의 사용량을 조절할 수 있다. 이에 대해서는 마지막 장 에서 다루겠다.
- 네트워크 버퍼를 줄인다. 웹서버의 응답은 클라이언트에 직접 전달되는 것이 아니라 소켓 버퍼라는 네트워크 버퍼에 저장을 한다. OS에서는 적절한 수와 크기의 네트워크 버퍼를 가지고 있어야 메모리를 낭비하지도 않고 서버에서 필요한 버퍼를 기다리는 동안 서버의 작업이 중단되지도 않는 상태로 클라이언트의 접속을 처리할 수 있다. 갑작스럽게 접속이 중단되는 클라이언트에서 차지하고 있던 네트워크 버퍼는 웹 서버에서 메모리가 낭비되는 주요한 원인중의 하나이다. 아파치에는 SendBufferSize 지시자가 있어서 운영체제에서 지정되어 있는 TCP의 전송 버퍼를 늘릴 수 있다. 그런데 아직까지 필자도 리눅스쪽에서는 이 부분에 대하여 자세히 소개된 자료를 찾지 못했다. 아직 정확히 이해하지 못하고 있는 부분이지만 도움이 될까하여 고민 끝에 관련 내용을 포함한다. (**주5)
- 커널 테이블의 크기를 줄인다. 이를 통해 시스템의 자원을 제약할 수 있다. 예를 들어 파일 개수, 프로세스 개수등이 해당한다. 운영체제에서 이와 관련된 설정을 높이면 그만큼 커널 테이블의 크기가 늘어나 메모리도 그만큼 더 사용하게 된다.
- 많은 메모리를 필요로 하는 프로그램은 밤에 돌리자.
- 많은 메모리를 필요로 하는 프로그램은 배치 큐를 이용해 작업하자. at, cron등 활용
- 자기만 사용하는 프로그램이라면 프로그램에서 메모리를 효율적으로 사용하는지 점검하자.
- 메모리 요구량을 줄이기 위해 공유 메모리를 사용하자. 공유 메모리는 다수의 프로세스 간에 데이터를 공유하고 전달하는 효과적인 방법을 제공한다. 또한 어떤 특정한 명령을 여러명이 사용하는 경우 가상 주소공간에 해당 프로그램의 여러 복사본을 갖는게 아니라 물리적 공간에 하나의 복사본을 만들고 모든 프로세스가 그것을 공유할 수 있다. 동적 라이브러리는 여러 프로세스가 실행 코드를 공유하는 대표적인 예이다. 그런데 공유 라이브러리를 사용하는 경우 메모리는 절약할 수 있겠지만 프로그램의 성능은 정적으로 컴파일하는 것이 더 빠르다. 예를 들어 Mysql의 경우는 -static을 사용하지 않고 동적으로 링크하면 대략 13%정도 속도가 느려진다고 한다. (**주6)
- sendmail은 메모리를 많이 사용하는 프로그램으로 sendmail을 실행하는데 사용되는 시간에 제한을 두자. 아니면 네트웍을 재구성해서 메일서버를 다른 시스템으로 옮길 수 있다. 위에서 설명을 했던대로 메일을 받는 경우에만 sendmail을 사용하면 된다.
- 이막스(Emacs)는 메모리를 많이 사용하는 프로그램으로 vi 등 다른 에디터를 사용하자.
- 이 모든게 안되면 메모리를 구입하자. 하드웨어의 가격이 예전에 비해 많이 저렴해졌으며 이제 1G 메모리도 그렇게 특별한 시스템은 아닌 상황이다. 대신 프로그램에서 요구하는 기본 메모리양도 커졌다.
6. 디스크 I/O 문제 파악하기
시스템에 과부하가 걸려있는데도 휴지기간(idle time)이 많다면 디스크 I/O 문제를 생각해 볼 수 있다. 보통 메모리 문제와 I/O문제는 서로 관련이 되어있다.
ᄋ vmstat 5 를 실행한다. 그리고 이것을 정상적인 시스템 상황과 비교해본다. 정상적인 경우보다 디스크 연산이 더 높은가?
ᄋ 디스크 활동이 시스템 디스크에 골고루 분산되어있는가? iostat 등을 이용하여 모니터링하면 될 것이다.
ᄋ 그렇지 않다면 가장 활동적인 디스크가 가장 빠른 디스크인가?
ᄋ 디스크 활동이 디스크의 특정 영역에 집중되어있는가? 디스크에 적당히 분포되어있는가? 아니면 서로 다른 반대방향의 지점에 있는가?
ᄋ NFS를 사용하고 있는가? 사용자들이 자신의 지역파일에 접근하는데 속도가 느리다고 보고를 하는가? 원격 파일시스템을 사용하는가? 만약 원격 파일시스템을 사용하면 네트웍 상황에 대해서 살펴보자. 이경우에는 지역 디스크 I/O문제는 아니다.
ᄋ vmstat를 이용 메모리 상황을 살펴보자. 시스템에서 페이징이나 스와핑이 계속 일어나고 있다면, 메모리에 문제가 있으며 이경우 디스크 I/O에 심각한 문제를 초래할 수 있다. 먼저 메모리 문제를 살펴보아야한다.
이에 대한 해결책을 찾아보자.
ᄋ 파일시스템을 재구성하고 가능한한 I/O작업을 분산시킨다.
ᄋ 루트 파일시스템에 가장 빠른 디스크 드라이브와 컨트롤러를 사용한다. 루트 파일 시스템이 대부분 가장 많은 I/O작업을 한다. 특정한 파일의 성능이 중요하다면 성능이 중요한 파일을 하나의 파일시스템에 넣고 이 파일시스템에 가장 빠른 드라이브를 사용한다.
ᄋ 퍼포먼스가 중요한 파일을 블락 크기가 큰 파일시스템에 넣는다. 리눅스에서 블락 크기는 블락당 1024, 2048, 4096이다. 파일시스템을 생성할 때 지정을 해야 한다. 블락 크기를 높이면 성능이 향상될 수는 있어도 불필요하게 낭비되는 하드디스크 공간이 늘어난다.
ᄋ 버퍼 캐쉬의 크기를 늘린다. 그러면 대신 메모리에 문제가 생길 수 있다.
ᄋ 단편화를 제거하기 위해 주기적으로 파일시스템을 재구성한다.
ᄋ 자주 사용하는 파일을 파일시스템의 시작부분에 집중시키는 프로그램을 사용할수 있다.
운영체제 차원의 튜닝에서 가장 많은 성능향상을 얻을 수 있는 분야가 I/O 부분이다. I/O성능은 하드디스크의 속도뿐만 아니라 시스템 버스에 물려있는 여러 구성 요소와 함께 좌우가 된다. 그런데 리눅스를 주로 사용하는 인텔x86 계열의 하드웨어는 타상용 유닉스 시스템에 비하면 I/O와 관련되어 성능이 미약한 편이다. 또 비디오 카드등은 64비트를 넘어 128비트 체계로 간지 오래되었지만 마더보드의 PCI 슬롯은 32비트 체계를 가지고 있다. PC레벨에서는 32비트 CPU가 사요되고 있고 메모리를 부분만 64비트로 동작하고 있을 뿐이다. (**주 7) 그렇지만 PC서버가 일반화되면서 예전 상용 유닉스 장비에만 있었던 여러 가지 기능들이 속속 도입되고 있으며 앞으로도 발전이 기대된다. 여기에 몇가지 이야기를 덧붙이자면 디스크 I/O의 속도향상을 위해 RAID등을 사용할 수도 있고 소프트웨어 차원에서의 소프트웨어 레이드도 현재 리눅스에서 지원이 되고 있다. 저널링 파일 시스템이 최근부터 본격적으로 지원되기 시작하여 파일시스템의 안정성과 무결성을 높임과 더불어 속도도 꾸준한 향상이 되고 있다. 현재 리눅스에서 지원하는 저널링 파일 시스템으로는 reiserfs, SGI의 XFS 등이 있다. (**주8)
디스크 용량에 문제가 생길 수도 있다. 파일시스템에 여유공간이 부족한가? 그렇다면 몇가지 방법을 생각해보자.
ㅇ 필요없는 파일을 cron 등을 이용 정기적으로 삭제하자. 오래된 코어 덤프 파일, 에디터 백업파일, auto-save 파일 등등.
ᄋ 디스크 쿼터를 이용해 사용자의 디스크 용량 사용을 제한할 수 있다.
ᄋ 매우 작은 파일이 모여있는 파일시스템에는 작은 블럭 사이즈를 사용한다. (소스 코드, 작은 데이타 파일 등등)
ㅇ /tmp, /var/tmp 등에는 계속 임시파일이 생성되고 man 페이지를 위한 임시파일도 계속 생성이 된다. 이에 대한 처리는 레드햇 리눅스 계열에서/etc/cron.daily/tmpwatch를 이용하여 처리한다. 3장에서 다시 소개할 것이다.
7. 네트웍 문제 점검
네트웍 문제 점검
ᄋ rlogin이나 NFS를 이용하여 파일에 접근하는 사용자가 성능이 느리다고 생각이 든다면 이는 네트웍 용량이나 데이터 정합성에 문제가 있을 수 있다.
ᄋ netstat -i 를 실행하자. 충돌(collison)이 크면 네트웍에 오버헤드가 걸렸다고 생각할 수 있다. 충돌률은 ifconfig -a 등을 이용해서 나온 결과중 (collisons/TX packets) X 100을 하면 나온다. input이나 output 에러가 많다면 하드웨어 문제일 수 있다. 입력에러가 많다면 네트웍의 특정한 곳에 문제가 있을 가능성이 크며 출력에러가 많다면 시스템과 네트웍 인터페이스에 문제가 있을 가능성이 크다.
ᄋ 충돌이나 네트웍 하드웨어의 문제가 아니라면, 어떤 시스템이 가장 느린지를 찾아야한다. dropped 패킷이 크다면, 원격 시스템은 아마도 들어오는 자료에 대해 충분히 빠르게 대응하지 못할 것이다. 원격 시스템에 cpu, 메모리, 디스크 I/O문제가 있는지 확인하자. 그게 아니라면 그 시스템은 네트웍의 과부하에 견디지 못할 것이다. 네트웍을 다시 재구성하고 느린 시스템을 파일 서버로 사용하지 말자.
ㅇ 기본적인 연결 테스트에는 ping 명령을 사용하며 네트워크 접속에 대한 점검을 한다면 ifconfig, arp, netsta 등을 이용하고 네트워크 하드웨어 문제를 점검해 보아야 한다.
# ifconfig -i
eth0 Link encap:Ethernet HWaddr 00:01:02:26:BD:CE
inet addr:211.111.111.111 Bcast:211.50.6.255 Mask:255.255.255.192
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:346297 errors:0 dropped:0 overruns:0 frame:0
TX packets:346683 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:10 Base address:0xd000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:7745 errors:0 dropped:0 overruns:0 frame:0
TX packets:7745 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
# netstat -i
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0 1500 0 349675 0 0 0 350447 0 0 0 BRU
lo 16436 0 7825 0 0 0 7825 0 0 0 LRU
네트웍 부하 줄이는 방법 (**주9)
ᄋ 사용자가 네트웍을 통해 I/O집약적인 프로그램을 실행하지 않도록 막자. grep 프로그램이 I/O 집약적인 프로그램중의 대표적인 예이다. 대신 네트웍을 통해 로그인해서 작업하자.
ᄋ 네트웍에 연결된 컴퓨터와 디스크를 재구성해서 가능한 많은 사용자가 지역 지역 시스템에서 작업을 하도론 만든다.
ᄋ 디스크없는 워크스테이션의 숫자를 줄인다. 가능하다면 이런 워크스테이션은 제거한다.
ᄋ 뛰어난 네트웍 성능을 가진 시스템을 파일서버로 사용한다.
ㅇ 충돌률을 줄이기 위해서는 네트워크 세그먼트 상의 트래픽양을 줄여야 하며 이 경우 이더넷을 분리할 수 있다.
데이터 정합성에 문제가 있다면 유일한 해결책은 문제가 있는 하드웨어를 찾아서 바꾸는 것이다. 네트웍 분석툴이 이러한 작업을 하는데 반드시 필요할 것이다.
8. 마치며
이번 강의에서는 시스템 최적화를 위한 준비 단계로 프로세스, 메모리, I/O 부분을 중심으로 어떻게 현재 시스템 상태를 모니터링하고 문제를 발견하여 해결을 할 수 있는지에 대하여 설명을 하였다. 중요한 것은 시스템을 모니터링하는 것과 더불어 나온 결과에 대하여 정확하게 이해를 해야 한다는 것이다. 이에 대해서는 free를 예로 들어 설명을 하였다. 가장 먼저 주기적으로 시스템을 모니터링하여 문제를 파악하고 있어야 하고 문제가 발생했을 경우 여러 가지 상황에 따라 CPU, 메모리, I/O부분을 점검해야 한다.
2장. 로그파일 관리
시스템 최적화 - 로그파일 분석 및 효율적으로 관리하기
이번 강좌에서는 운영체제가 부팅하면서 시작하는 작업인 로그파일에 대하여 알아본다. 현재의 시스템에서 일어나고 있는 모든 작업이 로그파일에 기록이 된다. 그러므로 문제가 발생하였을 경우 가장 먼저 해야 할 일이 로그분석이다. 로그파일은 서비스하고 있는 상황에 따라 하루에 몇기가씩 쌓일 수도 있다. 운영체제와 외부에 서비스하고 있는 로그파일만으로 하드디스크가 꽉 채워질 수 있고 DDOS 등의 공격을 받아서도 짧은 시간에 엄청난 속도로 늘어날 수 있다. 이에 대해서 정확하게 분석하는 작업과 함께 주기적으로 파일을 로테이션시켜 부하를 줄여야 한다.
1. 로그파일의 종류
리눅스에서 로그파일은 일반적으로 /var/log에 기록이 된다. 로그파일은 운영하는 서비스에 따라서 차이가 나며 syslog.conf 설정에 따라 다르다. (**주1**)
파일명 |
기능 |
boot.log |
부팅 및 각종 서비스 시작 및 중지에 대한 기록 |
cron.log |
크론 활동 관련 기록 |
dmesg |
시스템 부팅 관련 기록 |
lastlog |
사용자의 마지막 로그인 시간 기록 (last 명령 이용 확인) |
maillog |
메일 서비스 관련 기록 |
messages |
커널 에러, 리부팅 메시지, 로그인 실패 등 시스템 콘솔에서 출력된 결과를 기록하고 syslog에 의하여 생성된 메시지도 기록 |
secure |
로그인 인증 및 보안 관련 주요 로그 |
wtmp |
사용자 로그인, 로그아웃 시간, 시스템 종료 시간등 기록 (last 명령 이용 확인) |
xferlog |
ftp 접근 관련 기록 |
utmp |
현재 로그인한 사용자에 대한 상태 기록 (w, who 등 이용 확인) 레드햇에서는 /var/run/wtmp에 있음 |
.history |
사용자 홈디렉토리에 있으며 사용자가 쉘상에서 작업한 것을 기록 |
사용자에 따라 sulog, pacct 등이 있을 수 있으며 이외에도 여러 인터넷 서비스에 따라 로그기록을 한다. 또한 일반 텍스트 형태의 파일만 있는 것이 아니라 utmp, utmp 등 바이너리 형태로 로그 기록을 하는 경우도 있다. 로그파일은 시스템에서 발생했던 상황을 모두 기록으로 남기기 때문에 문제가 발생하였을 때 출발점이 될 수 있으며 크래킹 여부를 판단할 수 있는 중요한 근거가 된다.
utmp 파일은 현재 시스템에 로그인한 사용자에 대한 정보를 가지고 있으며 사용자 이름, 터미널 장치 이름, 원격 로그인시 원격 호스트 이름, 사용자가 로그인한 시간 등을 기록한다. 일반 텍스트 파일이 아니기 때문에 who, w 등을 이용하여 내용을 살펴볼 수 있다.
$ w
11:40pm up 18:25, 3 users, load average: 0.05, 0.05, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
taejun pts/2 211.55.2.161 10:43am 1.00s 0.14s ? -
taejun pts/5 211.52.1.151 10:53am 17:11 0.08s 0.08s -bash
wtmp 파일은 사용자의 로그인과 로그아웃 정보를 모두 가지고 있으며 시스템의 부팅이나 재부팅에 대한 내용도 포함을 하고 있는 중요한 파일이다. last를 이용하여 확인을 할 수 있다.
lastlog 파일은 사용자가 가장 최근에 로그인을 한 기록을 남기며 시스템에 다시 로그인을 할때마다 갱신이 된다. lastlog 프로그램을 이용하여 확인할 수 있다.
# lastlog
Username Port From Latest
root tty1 Sun Jul 15 02:54:21 +0900 2001
bin **Never logged in**
daemon **Never logged in**
mail **Never logged in**
nobody **Never logged in**
mylove pts/1 211.50.6.251 Sun Jul 15 14:40:53 +0900 2001
mysql **Never logged in**
named **Never logged in**
그런데 크래커가 바보가 아니라면 당연히 크래킹을 해놓고도 그 기록을 계속 남기지는 않을 것이다. 정상적인 로그인 절차를 거칠 경우 사용자의 접속 내역은 utmp, wtmp, lastlog에 기록을 하게 되지만 백도어나 rootkit 등이 설치되어 있을 경우에는 그 사실을 모를 수가 있다. 시스템 accounting 기능(**주2**) 을 이용하면 시스템에서 어떠한 프로그램이 얼마만큼 자원을 차지하고 있는지 알 수 있을 뿐만 아니라 로그인한 사용자가 어떤 프로그램을 실행했는지에 대해서 알 수 있는 단서가 된다. 그렇지만 리눅스에서 기본적으로 설치되어 있는 패키지는 아니며 별도로 설정을 해야 한다.
history 파일은 각 사용자가 접속하여 어떠한 명령을 수록했는지 기록하고 있다. 히스토리 파일을 이용하여 공격자의 행위를 파악할 수 있다.
secure 파일은 위에서 설명을 했던대로 보안과 관련한 로그를 기록하며 telnet, ftp, pop등 인중을 필요로 하는 네트워크 서비스에 대한 기록을 남긴다. 메일서버, 웹서버, 네임서버 등도 응용프로그램 차원에서 개별 로그를 남기며 특정한 서비스에 문제가 생겼을 경우 먼저 로그기록부터 확인을 하여 문제점을 찾고 그 대책을 찾아야 할 것이다.
여기서 걸리는 문제는 계속 쌓여만 가는 로그파일을 계속 주기적으로 모니터링할 수 없다는 것이다. 이런 경우에는 아주 간단하게 자신이 주로 살펴볼 필요가 있는 로그파일에 대하여 grep으로 뽑아내거나 전문적인 로그 관련 유틸리티를 활용할 필요가 있다. 이에 대해서는 swatch 나 logcheck 등을 활용하기 바란다. (**주3) 로그 모니터링툴을 활용하는 경우 제대로 필터링을 하지 않으면 엄청난 스팸 메일이 되어 돌아온다는 것을 기억하기 바란다.
2. 로그파일 설정 - syslog 에 대하여
일반적으로 로깅 기능은 syslog를 이용하여 어떻게 사용할 것인지 지정을 한다. 배포판 설치시 로그파일을 기록하는 패키지가 자동으로 설치된다. 이러한 역할을 하는 패키지가 syslogd 패키지이다.
# rpm -ql sysklogd
/etc/logrotate.d/syslog
/etc/rc.d/init.d/syslog
/etc/rc.d/rc0.d/K99syslog
/etc/rc.d/rc1.d/K99syslog
/etc/rc.d/rc2.d/S30syslog
/etc/rc.d/rc3.d/S30syslog
/etc/rc.d/rc5.d/S30syslog
/etc/rc.d/rc6.d/K99syslog
/etc/syslog.conf
/sbin/klogd
/sbin/syslogd
/usr/doc/sysklogd-1.3.31
/usr/doc/sysklogd-1.3.31/ANNOUNCE
/usr/doc/sysklogd-1.3.31/INSTALL
/usr/doc/sysklogd-1.3.31/NEWS
/usr/doc/sysklogd-1.3.31/README.1st
/usr/doc/sysklogd-1.3.31/README.linux
/usr/doc/sysklogd-1.3.31/Sysklogd-1.3.lsm
/usr/man/man5/syslog.conf.5.gz
/usr/man/man8/klogd.8.gz
/usr/man/man8/sysklogd.8.gz
/usr/man/man8/syslogd.8.gz
시스템 로깅 프로그램은 시스템의 부팅시 초창기에 실행이 된다. 이에 대한 설정은 /etc/syslog.conf를 이용한다. 아래 내용은 필자가 주석을 첨가하였다.
# cat /etc/syslog.conf
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
kern.* /dev/console
# 모든 커널 메시지를 콘솔로.
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none /var/log/messages
# 모든 info를 messages에 기록. 여기서 mail, authpriv 관련 기록은 제외
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# 모든 로그인 인증 관련 기록. su, login 등을 모두 여기 기록
# Log all the mail messages in one place.
mail.* /var/log/maillog
# 모든 메일 메시지
# Everybody gets emergency messages, plus log them on another
# machine.
*.emerg *
# 비상 메시지(emerg)는 현재 로그인한 모든 사용자에게 알림
# Save mail and news errors of level err and higher in a
# special file.
# uucp,news.crit /var/log/spooler
# uucp, news 의 crit 정보 기록
# Save boot messages also to boot.log
local7.* /var/log/boot.log
# 부트 메시지 기록
설정파일은 매우 간단하다. 빈 행과 # 으로 시작되는 행은 무시된다. (참고로 리눅스는 BSD 형식으로 로그를 구성한다)
설정행의 구조는 다음과 같다.
facility.level destination
facility는 메시지를 보내는 서브시스템의 이름이며 level(priority)은 메시지의 중요성을 나타낸다. facility는 다음과 같다.
auth, authpriv, cron, daemon, kern, lpr, mail, news, syslog, user, uucp, local0 - local7
facility에서 auth 대신 auth_priv를 사용할 것을 추천하고 있으며 나머지는 읽어보면 쉽게 이해가 갈 것이다. 크론(cron, at), 대몬, 커널 메시지, 로컬에서 사용, 프린터, 메일, 뉴스, syslog, 사용자 레벨 메시지, UUCP.
priority는 다음과 같으며 중요도에 따라 나열하고 있다.
debug, info, notice, warning, warn (warning), err, error (err), crit, alert, emerg, panic (emerg)
상세한 내용은 아래와 같다.
emerg : 시스템 패닉
alert : 에러 경고. 즉각 알려야할 내용
crit : 하드 장치 에러와 같은 임계 에러(critical error)
err : 에러
warn : 경고
notice : 비임계 메시지
info : 정보 메시지
debug :문제 추적을 돕는 특수 정보
만약 none 이라고 하면 그에 대한 모든 로그 메시지를 제외하라는 뜻이다.
모든 facility 나 priority 를 지정하려면 * 를 쓰면 되며 여러개를 지정하려면 , 를 사용하면 된다. 그런데 여기서 반드시 알아두야할것이 priority를 지정하면 그와같은 priority부터 그 위의 priority에 관련된 로그를 기록한다는 것이다. 만약 info 를 지정하면 emerg 부터 info 사이의 모든 로그를 기록한다. 만약 단일한 priority를 지정하려면 = 를 사용하면 된다. !는 priority 범위를 제한한다. 이에 대해서는 아래에서 설명하는 예를 참고하자.
(리눅스에서 syslogd는 원래 BSD 소스에 몇가지 기능이 추가되었다. =, ! 등이 이에 속한다.)
로그파일을 기록으로 남기는 방식에는 여러가지가 있다. 가장 먼저 파일형태(/var/log/messages), named pipe, 터미널과 콘솔(/dev/console), 원격 머신(@), 사용자, 로그인한 전체 사용자(*) 등이다.
보통 위의 내용이 일반적인 배포판 구성이다. 아마 kernel 메시지에는 주석이 되어있는 경우도 있다.
예를 들어 *.err /dev/tty8 를 추가해보자. 놀고있는 tty8 콘솔에서 시스템에서 발생하는 모든 에러를 볼 수 있다.
*.* @taejun
이건 모든 메시지를 taejun 이라는 원격 호스트에서 처리하도록 할 수 있다. 어떤 경우 이게 유용할까? 모든 syslog 메시지를 한 대의 시스템으로 모을 수 있기 때문에 여러대의 서버를 운영하는 경우 한곳에서 모든 로그를 처리할 수 있고 시스템에 문제가 발생하더라도 원격 시스템에 로그를 남기므로 설사 시스템이 붕괴가 되었다고 하더라도 문제를 찾을 실마리를 찾을 수 있다.
위의 기본 설정말고 몇가지 예를 더 보자.
# Store critical stuff in critical
#
*.=crit;kern.none /var/adm/critical
# 커널을 제외하고 모든 crit 에 해당하는 메시지 기록
# (여기서 = 를 지정한 차이점에 대해서 이해해야함)
# Kernel messages are first, stored in the kernel
# file, critical messages and higher ones also go
# to another host and to the console
#
kern.* /var/adm/kernel
kern.crit @finlandia
kern.crit /dev/console
kern.info;kern.!err /var/adm/kernel-info
# 커널 관련 모든 기록은 kernel 파일에,
# 커널에서 crit 이상의 메시지는는 콘솔과 원격 호스트로.
# 두번째 부분(원격 호스트)이 유용한 것은 만약 시스템이
# 붕괴해서 디스크에서 복구할 수 없는 에러가 났더라도
# 원격 호스트에서 이 문제를 해결할 수 있는 원인을
# 찾을 수 있다.
# 이제 네번째 줄. 이건 info 부터 err 이전 그러니깐
# info , notice, warn 에 대한 메시지를 기록한다.
# 로그 범위을 제한하는 것이다.
# The tcp wrapper loggs with mail.info, we display
# all the connections on tty12
#
mail.=info /dev/tty12
# mail.info에 관련된 메시지를 12번째 콘솔에 기록.
# Store all mail concerning stuff in a file
#
mail.*;mail.!=info /var/adm/mail
# mail.info 만 제외하고 모든 mail 메시지.
# Log all mail.info and news.info messages to info
#
mail,news.=info /var/adm/info
# mail 과 news의 info 만 기록
# Log info and notice messages to messages file
#
*.=info;*.=notice;\
mail.none /var/log/messages
# info 와 notice 에 해당하는 모든 메시지 기록.
# 여기서 mail의 모든 메시지만 제외.
# Log info messages to messages file
#
*.=info;\
mail,news.none /var/log/messages
# 모든 info 에 관련된 메시지.
# 단, 메일, 뉴스의 모든 메시지는 제외
# Emergency messages will be displayed using wall
#
*.=emerg *
# 모든 emergency 메세지를 현재 로그인한 모든 사용자에게.
# 이는 wall 과 같다.
# Messages of the priority alert will be directed
# to the operator
#
*.alert root,taejun
# 모든 alert 이상 메시지를 root 와 taejun 사용자에게
*.* @taejun
# 모든 메시지를 taejun 이라는 원격 호스트로
# 위에서 설명했던 것처럼 클러스터링 시스템에서
# 모른 로그 메시지를 한곳에 기록하는 경우 유용
logger 유틸리티는 쉘 스크립트에서 syslog 기능을 이용 메시지를 보낼 수 있다.
# logger -p authpriv.alert -t oh_no_login "test"
# tail -f secure
Jul 10 23:42:12 tunelinux oh_no_login: test
위에서 설명을 한 대로 특정 시스템의 로그를 다른 원격 서버로 보내어 분석할 수 있다. 이에 대해서 설명을 한다.
먼저 확인해야 할 것이 있다.
/etc/services 파일에 아래의 내용이 있는지 확인해보자.
syslog 514/udp
로그를 만드는 쪽과 받는 쪽 두군데에서 다 필요하다. 보통 기본 설정되어있을 것입니다. 메시지를 주고받는데 UDP 포트가 필요하기 때문이다.
로그를 생성하는 서버에서 설정을 하자. /etc/syslog.conf 에 아래의 내용을 추가한다.
mail.info @admin
이건 mail.info 에 해당하는 로그를 admin 이라는 호스트로 보내는 것이다. 이왕이면 admin은 DNS에 문제가 생길 수도 있으므로 /etc/hosts에 등록해두는 것이 좋을 것이다. 필요하다면 *.* 을 이용 전부를 다 보낼 수도 있다. 이런 경우에는 시스템에 아주 심각한 문제가 생긴다고 하더라도 원격 호스트에 로그 파일이 남으므로 나중에 분석을 할 수 있다는 것이다.
이제 로그를 원격에서 받아 기록하는 서버의 설정을 한다. syslogd 대몬을 시작할때 추가 옵션이 필요하다. 레드햇(또는 호환 계열) 배포판의 경우 시작파일은 다음과 같은 형태이다.
/etc/rc.d/init.d/syslog
여기서 대몬을 시작하는 옵션으로
daemon syslogd -m 0 -r -h
이렇게 설정을 한다. 세부 옵션은 아래와 같다.
-m 0 : 기본설정되어있는것으로 변경하지 않아도 된다. 이건 지정한 분동안에 MARK 라고 로그파일에 기록을 한다. 0이면 기록을 하지 않는다.
-r : 인터넷 도메인 소켓을 이용해 네트웍에서 메시지를 받는 옵션
-h : 기본적으로 syslogd는 원격 호스트에서 받은 메시지를 로그 기록으로 전송하지 않는다. 이 옵션을 사용하여 원격 호스트에서 받은 로그파일을 전송한다. (전송이란 받은 쪽의 로그 파일에 기록한다고 생각하면 된다)
3. logrotate 이용한 로그 파일 관리
보안과 시스템을 관리하고 운영하는 측면에서 로그파일이 중요하지만 계속 쌓이기만 하는 로그파일을 그대로 둔다면 시스템에 문제가 발생할 가능성이 크다. 소규모로 서버를 운영하는 경우 로그파일에 그다지 신경을 쓰는 일이 없다. 그렇지만 제공하는 서비스가 많아지고 규모가 커질 경우 예상치 못한 곳에서 문제가 생기는 일이 많다. 그중 하나가 엄청나게 증가하는 로그파일문제이다. 메일의 경우를 예로 들어보자. 전자메일이 전송된 경우 필자의 시스템에서는 maillog와 messages에 동시에 기록이 된다. pop3도 마찬가지이다. 전자메일을 전송하는 경우에는 560바이트 정도 되었고 pop3로 메일을 가져올 경우에는 500바이트 정도 되었다. 여기서 메일주소가 잘못되어 반송된 경우에 남은 로그는 1.2k 정도가 되었다. 웹서버 로그를 보자. 웹서버 로그의 경우 로그기록을 어떻게 하느냐에 따라 다른데 common이 아니라 access, agent, referer를 모두 기록하는 combined를 이용할 경우 한번 접속당 160바이트가 증가한다. common에 비해서는 두배이상 되는 규모이다. Mysql에서도 모든 sql문에 대하여 기록을 남기는 기능을 이용할 경우 db에서 진행되는 모든 sql문이 로그파일에 그냥 기록이 되므로 규모가 큰 파일을 dump하여 다시 import 하였을 경우 로그 파일의 규모가 dump 크기에 비례하여 엄청나게 늘어난다. 로그파일의 크기가 늘어나서 불필요한 하드디스크 공간이 낭비되고 심지어 서비스가 중지될 정도로 심각한 상황이 초래될 수가 있다. 더 나아가 서비스하는데 투여되어야 할 시스템 자원이 로그파일을 기록하는데 데에만 신경을 써서 정작 서비스 자체의 속도나 질이 형편없이 떨어질 가능성도 크다.
리눅스에서 로그 로테이션을 담당하는 패키지가 logrotate 이다.
# rpm -qa | grep logrotate
logrotate-3.3-1
# rpm -ql logrotate
/etc/cron.daily/logrotate
/etc/logrotate.conf
/etc/logrotate.d
/usr/man/man8/logrotate.8.gz
/usr/sbin/logrotate
logrotate는 계속 커지는 로그파일을 효율적으로 관리하기 위한 프로그램이다. 자동으로 로테이션을 시켜주고, 압축, 제거, 메일로 보내주기 등의 작업을 한다. 초기 리눅스 설치시 자동으로 cron에 추가가 된다.
# cat /etc/cron.daily/logrotate
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
위에서 보면 logrotate 가 프로그램이고 logrotate.conf가 설정파일이라는 것을 알 수 있을 것이다. 위에서 .conf 파일대신 특정 디렉토리를 지정하면 그 해당 디렉토리의 모든 파일을 사용해 작업을 한다. logrotate 에 여러가지 옵션이 있지만 그다지 사용할 일은 없을 것 같다. 혹시나 궁금하면 man 으로 확인해보면 된다.
먼저 rotate 에 대해서 설명하겠다. rotate 3 라면 cron 로그라고 했을 경우를 가정해본다.. /var/log 디렉토리에 cron이 제일 처음 생성되고 순환간격마다 예전 cron 은 cron.1 이, cron.1은 cron.2, cron.2 는 cron.3 으로 된다. 기존의 cron.3은 삭제가 될 것이다. 그러니깐 새로 생성한 메일로그외에 이전의 로그를 3개까지 기록하는 것이다.
설정파일을 살펴보자. 한글로 되어있는 부분은 필자가 주를 단 것이다.
# cat /etc/logrotate.conf
# see "man logrotate" for details
# rotate log files weekly
weekly
# 기본적으로 일주일마다 로그파일을 순환시킴
# keep 4 weeks worth of backlogs
rotate 4
# 이전 로그파일을 4주동안 간직.
# 위에서 순환간격을 1주일로 했으므로.
# send errors to root
errors root
# 에러가 생길경우 root 에게 메일로.
# create new (empty) log files after rotating old ones
create
# 예전 로그파일을 순환시킨후 새로운 로그파일 생성
# uncomment this if you want your log files compressed
#compress
# gzip 을 이용 압축한다.
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d
# /etc/logrotate.d 파일 또는 디렉토리 안에 있는 파일을 읽어들인다.
# 참고로 필자의 서버에는 다음과 같은 기본설정 파일이 있다.
# ls /etc/logrotate.d
# apache cron ftpd named syslog
# 여기서 가장 중요한 syslog는 messages, secure, maillog, spooler,
# bootlog 로 구성
# no packages own lastlog or wtmp -- we'll rotate them here
/var/log/wtmp {
monthly
create 0664 root utmp
rotate 1
}
# 매월마다 순환시킴
# create 는 순환후 즉시 (postrotate 스크립트를 실행시키기전에)
# 로그 파일을 생성한다. 뒤에서 설명할 것이지만 postrotate는
# 로그파일을 순환한후 진행할 작업을 명시한다.
# 0664 는 생성하는 파일의 허가권, root 는 소유자, utmp 는 그룹
# rotate 1 은 위에서 설명했다. 그런데 개별적으로 설정하면
# 초기에 설정한 weekly 는 무시되 개별 설정을 따른다
# 그러므로 여기에서는 이전의 로그파일이 1개만 남을것이다.
# (원본 제외)
# 참고로 기본적으로 syslog에서는 600으로 허가권을 설정한다.
# 다른 누구도 로그파일에 접근하면 안되기 때문이다.
/var/log/lastlog {
monthly
rotate 1
}
# system-specific logs may be configured here
몇가지 주요한 옵션에 대해서 설명을 하겠다.
ㅇ 순환할 기간 설정 : daily, weekly, monthly 등.
여기에 size 를 이용해 크기까지 설정할 수 있다.접속이 많아서 로그파일이 엄청나게 늘어나는 경우에는 size(기본 kilobytes)를 이용 제어해야 할 것이다.
size 100k(= size 100)
ㅇ 압축설정 : compress
gzip으로 이전 로그파일을 압축한다. 공간을 절약할 수 있다. 이 옵션을 없애려면 주석을 달든지 아니면 nocompress(기본값) 사용
ㅇ 메일설정 : error, mail
error taejun -> 에러를 taejun 이라는 사용자에게 보냄
mail taejun -> 로그파일을 순환시키고 나중에 삭제해야 할 때 삭제하지 않고 메일로 보냄
ㅇ 로그파일 생성 : create mode owner group (기본값)
create 를 지정하면 순환후 로그 파일을 생성한다. 반대는 nocreate
ㅇ 순환간격 : rotate count
이전 로그파일이 삭제되거나 메일로 보내기전에 순환을 할 횟수 지정. 여기서 0으로 지정하면 예전 로그파일은 무조건 삭제된다.
ㅇ 지정한 로그파일이 없을 경우 : missingok, nomissingok
로그파일이 없으면 기본은 에러를 낸다(nomissingok, 기본값). missingok 를 지정하면 로그파일이 없더라도 에러를 내지는 않는다.
ㅇ 로그파일의 내용이 없을 경우(비어있을경우)
기본은 ifempty로 내용이 비었어도 순환을 한다.
순환을 하지 않도록 하려면 notifempty 를 지정하면 된다.
ㅇ 순환 후 작업 : postrotate/endscript
순환하기전 작업을 하려면 prerotate/endscript 를 사용한다. 일반적으로는 순환후 작업을 할 것이다. 예를 들어 메일관련 로그를 새로 생성했으면 syslogd를 다시 가동시켜야 할 것이다. 이런것들을 지정한다.
ㅇ 파일 또는 디렉토리 포함 : include
다른 파일이나 디렉토리안의 파일을 포함할 경우
위의 내용을 토대로 메일 로그를 조정해보자.
여기서는 /etc/logrotate.d/syslog 에서 메일서버의 로그만 따로 처리를 해보겠다.
# cat /etc/logrotate.d/maillog
weekly
size 500k
rotate 4
compress
errors admin
mail admin
nomissingok
create 0600 root root
/var/log/maillog {
postrotate
/usr/bin/killall -HUP syslogd
endscript
}
/var/log/messages {
postrotate
/usr/bin/killall -HUP syslogd
endscript
}
매주마다 한번식 순환시키고 크기가 500k가 넘지 않도록 하며 순환한 파일은 압축을 한다. 에러를 admin 이라는 사용자에게 보내고 순환후 삭제할 파일을 메일로 admin 에게 보낸다. 만약 로그파일이 없으면 에러를 내며 순환후 파일을 생성시키고 이 파일의 모드는 0600 으로 소유자와 그룹은 root 로 한다.
웹서버를 여러 대 운영하고 있고 하루에 한번씩 로그파일을 로테이션시킨다면 logrotate 설정에 중앙의 로그분석 서버로 보내는 작업을 집어넣는 것도 좋은 방법이다. 이런 경우에는 ncftput등의 명령이나 rsync를 이용할 수 있는데 필자는 rsync를 즐겨 쓰는 편이다. (**주4) 알아두면 편리한 프로그램으로 시스템간의 자료 동기화에 주로 사용하며 미러 서버를 운영하는 경우에도 많이 사용하고 있다.
4. 임시파일 관리에 대하여
리눅스 및 유닉스 시스템에서는 상황에 따라 필요하면 임시파일을 생성한다. 보통 /tmp나 /var/tmp를 이용하며 이외에도 맨페이지 등에서 사용하는 임시파일이 있다. 이런 역할을 하는 프로그램이 tmpwatch 패키지이다. cron.daily에 설정이 되어 자동으로 작동을 하도록 되어 있다.
# cat /etc/cron.daily/tmpwatch
/usr/sbin/tmpwatch 240 /tmp /var/tmp
[ -d /var/cache/man ] && /usr/sbin/tmpwatch -f 240 /var/cache/man/{X11R6/cat?,cat?,local/cat?}
[ -d /var/catman ] && /usr/sbin/tmpwatch -f 240 /var/catman/{X11R6/cat?,cat?,local/cat?}
필요에 따라 임시파일을 생성하는 경우가 있는데 이것이 악용이 된다면 시스템을 공격하는데 사용될 수가 있다. 또한 불필요한 파일 때문에 하드 디스크 공간을 낭비하는 일은 없어야 할 것이다. 위의 스크립트가 아니라고 하더라도 find 명령을 이용하여 일정한 시간이 지난 파일을 주기적으로 삭제하는 것도 한가지 방법이다.
5. 마치며
여기까지 읽었다면 시스템의 로그가 어떻게 작성되고 어떻게 관리를 해야할지 감을 잡았을 것이다. 위에서는 주로 일반적인 로그에 대해 다루었지만 자신이 사용하고 있는 서비스에 따라 적절한 설정을 하여야 한다. 이에 대해서는 위의 예제나 기본 설정되어 있는 내용을 참고로 하면 그다지 어렵지 않게 설정 가능할 것이다. 최근에 필자가 데이터베이스 작업을 하면서 자꾸만 시스템에 문제가 생기는 경우가 발생하였다. 알고보니 Mysql의 로그에 sql문의 로그를 기록하는 형태로 되어 있다보니 대용량의 자료를 넣다보면 넣은 양만큼 로그파일이 꽉 차게 되는 경우였다. 웹서버 Apache를 rpm이 아니라 직접 컴파일해서 설치한 경우 자동으로 로그로테이션이 되지 않기 때문에 아파치 로그파일 때문에 하드 디스크가 꽉 차서 어려움을 겪은 시스템 엔지니어도 보았다. 이와 같이 시스템 로그가 아니라고 하더라도 많이 사용하고 있는 서비스에 대해서는 로그 파일도 신경을 써야 한다.
오늘날 대부분의 시스템 프로그램들은 중요한 이벤트를 기록하며 syslogd와 통신을 한다. 그런데 침입자가 적절한 권한을 얻는다면 로그 파일 등을 조작할 수 있다. 이같은 문제로부터 시스템을 보호하기 위해 간단한 펄 스크립트를 사용하여 ssh를 이용 기존의 syslog 데몬과 연동을 하여 처리를 할 수 있다. 이에 대한 내용은 Linux@Work 2000년 7월호 “스크립트로 하는 로그파일 보안” 강좌를 참고하기 바란다.
3. 시스템 모니터링 자동화하기
1. 시스템 모니터링
전용선을 사용하는 경우 ISP업체를 통하여 네트웍 회선에 대한 트래픽을 어느정도 사용하고 있는지에 대하여 서비스를 제공받는다. 보통 이런 경우 ISP 업체에는 MRTG를 이용하여 자료를 제공한다. MRTG(Multi Router Traffic Grapher)는 이와 같이 일반적으로 네트웍 트래픽 관리에 사용된다. 현재와 같이 인터넷 서비스와 보편화되어 있는 상황에서 네트웍 트래픽에 대한 관리에 대해서는 중요성이 더욱 더 커지고 있다. 그런데 이번 강좌에서는 네트웍 트래픽 관리가 목적이 아니라 시스템을 주기적으로 어떻게 모니터링할 것인가에 맞추어져 있다. 위에서 말을 한 대로 MRTG를 이용하여 주로 네트웍 트래픽을 모니터링하지만 시스템을 모니터링하는데 편리한 도구여서 소개를 하는 것이다. 운영하는 서비스 규모가 커지면서 시스템 관리자가 관리를 해야 할 시스템과 장비들도 늘어가고 있다. 그런데 이 모든 것을 수동으로 일일이 ps와 top의 명령을 이용하여 모니터링하기란 힘든 일이다. 여기에는 웹서버, 메일서버등의 인터넷 서버뿐만이 아니라 여러 가지 서로 다른 시스템, 네트워크 장비, 다양한 운영체제, 통신규약 등 여러 가지 고려할 분야가 많다. 그래서 네트웍으로 연결되어 있는 다양한 자원에 대하여 안정적이고 효율적으로 관리하기 위한 노력이 네트워크 관리 시스템(Network Management System, NMS)이다. 네트웍 관리 시스템이란 네트워크 상의 여러 가지 자원을 모니터링하고 제어하는 시스템이다. 예전부터 사용되었던 HP의 OpenView나 IBM의 티볼리도 이러한 제품에 속한다. 그렇지만 아직까지 필요에 비해서는 이에 대한 정보가 공개적으로 나와있는 것은 적은 편이며 MRTG라는 도구도 사람들이 사용한지는 꽤 되었지만 SNMP등을 이용하여 시스템을 모니터링하는 부분에 대한 자료는 최근에야 조금씩 늘어나고 있는 상황이다.
물론 굳이 MRTG나 SNMP가 아니라고 하더라도 주기적으로 시스템을 모니터링하는 것은 가능하다. 간단한 쉘 스크립트를 짜고 cron을 이용하여 주기적으로 보고서를 만들 수 도 있다. php나 펄등을 이용하여 결과를 웹으로 출력도 가능하다. 그런데 위에서 말을 한것처럼 다양한 자원에 대한 모니터링과 제어가 중요해지면서 발전을 해오것이 SNMP이며 대부분의 네트웍 장비에서도 표준으로 지원하고 있고 리눅스나 솔리리스, HP-UX 등 대부분의 유닉스에서도 사용이 가능하다. MRTG는 SNMP agent가 탑재된 장치의 트래픽을 모니터링하는 툴로 장치에 주기적으로 SNMP 폴링을 하여 트래픽 정보를 그래프로 보여주는 html 페이지를 생성한다. 복잡한 프로그래밍을 하지 않아도 MRTG의 원리를 조금만 이해하면 시스템 모니터링 작업을 아주 간편하게 처리할 수 있다.
2. MRTG란 무엇인가? - MRTG 소개 및 사용방법
그렇다면 MRTG란 무엇인가? The Multi Router Traffic Grapher (MRTG)는 네트워크의 부하를 감시하는 툴이다. MRTG는 현재 네트워크의 상태를 HTML로 만들어서 사용자가 쉽게 볼수록 한다. MRTG 사이트에 있는 http://www.stat.ee.ethz.ch/mrtg/ 화면이나 필자의 사이트에 있는 그래프를 본다면 쉽게 이해가 갈 것이다.
MRTG는 대부분의 운영체제에서 작동을 하며 리눅스도 지원이 된다.라우터에서 트래픽 카운터를 읽는 SNMP를 사용하는 펄 스크립트와 트래픽 데이타를 수집하고 쉽게 읽을 수 있도록 그래픽 화면으로 변환하는 C로 구성되어있다. 속도가 요구되는 부분은 C로 작성하였다.
MRTG는 매일매일의 트래픽 상황, 과거 7일간, 4주간, 1년간 트래픽 상황을 그래프로 생성한다. 로그를 효율적으로 관리하기 때문에 로그가 커질 염려는 하지 않아도 되고 2년간의 자료를 보관한다. 비교적 저스펙의 하드웨어에서도 50개 이상의 네트웍 링크를 모니터링할 수 있다.
또한 네트웍 트래픽뿐만 아니라 모든 SNMP 변수에 대해서도 모니터링이 가능하다. 외부 프로그램을 이용해서 MRTG가 모니터링할 수 있는 자료를 모을 수도 있다. 시스템 부하, 로그인세션 , 모뎀의 가용성 등도 MRTG를 이용해 모니터링할 수 있다. 2개 이상의 데이터 소스를 하나의 그래프로 나타낼 수도 있다.
MRTG의 특징은 다음과 같다.
1. 대부분의 Unix플랫폼과, WindowsNT상에서 동작한다.
2. 간단하게 커스터마이즈할 수 있도록 Perl를 사용하고 있다.
3. 이식성이 좋은 펄을 사용해 SNMP 부분을 프로그래밍했다. 그래서 별도로 SNMP 패키지를 설치할 필요가 없다.
4. 로그를 정리하기 위한 독자의 알고리즘을 채용하고 있으므로, MRTG의 로그파일의 사이즈가 커지지 않는다.
5. 반자동의 설정용 툴을 지원한다.
6. 속도가 중요한 부분은 C로 작성되었다.
7. MRTG가 생성하는 HTML파일을 상세하게 설정하는 것이 가능하다
8. MRTG는 GNU PUBLIC LICENSE 로 제공된다.
mrtg 설치하기
MRTG 사이트는 아래와 같다.
http://people.ee.ethz.ch/~oetiker/webtools/mrtg/
http://people.ee.ethz.ch/~oetiker/webtools/mrtg/pub/에서 MRTG 최신판을 다운받는다.
그래프를 그려주기 위해서는 GD 라이브러리가 필요하며 리눅스의 경우 보통 기본으로 설치가 되어 있지만 없는 경우 http://www.boutell.com/gd/에서 다운받아 설치를 하면 된다. 물론 rpm으로 설치를 하여도 된다. Perl은 v.5.005 이상이 필요하며 펄도 일반적으로는 리눅스에 설치가 되어 있다.
$ tar xvfz mrtg-2.9.17.tar.gz
$ cd mrtg-2.9.17
$ ./configure
$ make
일반적인 공개 소프트웨어 설치 방법과 비슷하다. 이제 MRTG를 컴파일하여 사용할 준비를 다 하였다. 이제 MRTG를 사용할 수 있도록 환경파일을 설정하면 된다. 처음 접하는 사람에게는 설정파일을 만드는 것이 익숙치 않을 것이다. 이런 사람을 위하여 cfgmaker라는 자동 설정툴이 있다.
cfgmaker <community>@<router-host-name or IP > mrtg.cfg
$ ./cfgmaker --global 'Workdir:/home/httpd/html/mrtg' public@router_ip > mrtg.cfg
일단 먼저 라우터 트래픽부터 모니터링을 한다고 가정하고 router_ip에는 라우터의 ip주소를 넣으면 된다. community는 장바마다 SNMP 값을 가져올 때 사용하는 고유값으로 기본적으로는 public을 사용하지만 설정에 따라 다를 수도 있으며 SNMP 기능을 꺼 두었다면 사용할 수가 없다. 라우터에서 적절한 반응이 오지 않는다면 현재 사용하는 라우터에 SNMP기능이 활성화되었는지 먼저 확인을 하거나 네트웍 관리자에게 문의해야 한다.
--global 'Workdir:/home/httpd/html/mrtg' 은 MRTG에서 모니터링한 결과가 만들어질 디렉토리를 의미하며 이외에도 여러 가지 옵션이 많다. 그렇지만 여기서는 MRTG 자체를 설명하는 것이 목적이 아니기 때문에 상세한 내용은 인터넷에서 자료를 찾아보기 바란다. 최소한 WorkDir은 적절하게 설정을 해야 하고 Language: korean 을 설정해놓으면 MRTG 결과를 한글로 볼 수 있다.
MRTG는 mrtg를 설치한 디렉토리의 하위 bin 디렉토리에 있으며 위에서 생성한 설정파일을 옵션으로 하여 실행시키면 된다.
$ ./mrtg mrtg.cfg
만약 설정파일에 에러가 있다면 에러를 내는데 에러가 없다면 이제 라우터에서 트래픽 자료를 수집한다. 처음에 실행하면 MRTG가 로그 파일이 없다고 에러 메시지가 나오는데 두세번 실행하면 없어지니 너무 놀라지 말기를 바란다. 이는 MRTG가 로그값을 비교하여 통계를 내는데 처음에는 아무런 자료가 없기 때문에 그렇다. 이제 설정이 다 되었다면 cron 등에 등록을 하고 주기적으로 시스템 모니터링을 하면 된다.
참고로 모니터링하는 장비가 여러대라면 이러한 여러개의 타겟에 대한 내용을 편리하게 볼 수 있도록 인덱스 페이지를 만들어주는 기능이 있다.
$ indexmaker mrtg.cfg > /home/httpd/html/mrtg/index.html
MRTG 설치 디렉토리의 contrib 디렉토리에는 위에서 말한 cpu부하등의 정보를 모니터링하는 툴과 문서가 있어 참고하기에 좋다. 여기에는 라우터 트래픽 모니터링, CPU 모니터링, 디스크 모니터링, TCP 관련 모니터링 등 다양한 소스가 들어있다. MRTG를 어떻게 응용할 것인지에 대한 좋은 아이디어가 생길 것이다.
$ ls
00INDEX cisco_tftp/ ircstats2/ mrtgrq/
14all/ ciscoindex/ jm/ net-hosts/
GetSNMPLinesUP/ cpuinfo/ linux_stat/ nt-services/
IxDisk/ cpumon/ meminfo/ nt_n_cisco/
NSI/ diskmon/ monitor/ ovmrtg/
PMLines/ distrib/ mrtg-archiver/ ping-probe/
TCH/ forecd/ mrtg-archiver-script/ portmasters/
TTrafic/ gentcucci-1.0.0/ mrtg-blast/ procmem/
TotalControlModem/ get-active/ mrtg-dynip/ rdlog2/
accesslistmon/ get-equi/ mrtg-ipacc/ routers/
apc_ups/ get-multiserial/ mrtg-ipget/ rumb-stat/
ascendget/ ipchainacc/ mrtg-mail/ snmpping/
atmmaker/ ipchains/ mrtg.php/ stat/
cfgmaker_ATM/ ipfilter/ mrtg_php_portal/ stfc/
cfgmaker_cisco/ iptables-accounting/ mrtgidx/ switchmaker/
cfgmaker_dlci/ iptables_acc/ mrtgindex.cgi/ whodo/
cisco_BPX_MGX/ iptables_acc_snmp/ mrtglog/ xlsummary/
cisco_ipaccounting/ ircstats/ mrtgmk/
3. SNMP에 대하여
SNMP(Simple Network Management Protocol)는 네트웍에 연결되어 있는 장치에서 네트웍에 관련된 정보를 모으고 문제점등을 보고할 수 있는 기능을 제공하는 프로토콜이다. C/S 모델을 기반으로 작동하며 각 네트웍 장비에 Agent 가 있고 중앙(클라이언트)의 Manager에서 정보를 관리한다. 1970년대 후반 네트워크 장치의 연결 정보를 얻기 위한 일종의 관리 프로토콜인 ICMP가 처음 사용되었고 그 이후로 네트워크 자원을 모니터링하기 위한 여러 가지 프로토콜이 발표되었다가 1990년 인터넷 관리 프로토콜의 표준으로 SNMP가 제정되었다. 그러고나서 대부분의 워크스테이션, 브리지, 라우터, 스위치, 허브 등 네트워크 장비에 SNMP agent가 장착되었고 시스템과 여러 응용 프로그램에서 대해서도 이를 SNMP 상에서 관리할 수 있도록 하는 MIB가 정의되었다. 현재 사용하고 있는 SNMP는 SNMPv2를 거쳐 SNMPv3로 기능이 확장되고 있고 관리 영역도 RMON(Remote MONitoring) MIB 등을 통해 확장되고 있는 추세이다. 1989년 처음 발표되어 2001년 현재 버전3까지 발표가 되었다. SNMP의 구조는 아래 그림을 참고하기 바란다. SNMP는 매니저와 에이전트 구조로 되어있다. 에이전트는 각 네트워크 장치에 내장된 형태로 존재하며 각각의 자원에 대한 정보를 수집하고 매니저는 각각의 에이전트가 관리하는 정보를 수집해서 전체 네트워크를 관리하는 역할을 하는 것이다.
위에서 MRTG와 SNMP의 결합에 대해서 이야기를 했는데 여기서 MRTG는 SNMP 에이전트가 탑재된 장치의 트래픽과 각종 시스템 정보를 편리하게 그래픽으로 그려주는 역할을 하는 것이다. SNMP에서 서로 다른 정보를 처리하기 위해 MIB(Management Information Base), OID(OBJECT-IDENTIFIED) 등을 사용한다. 이해가 쉽도록 단순화해서 말을 하면 어떤 정보를 모니터링할 것인지에 대하여 위의 MIB, OID등을 통하여 지정을 하고 지속적으로 이 정보를 수집하는 것이다. 이중 MIB-2는 SNMP 프로토콜이 만들어진 이후 첫 번째로 나온 MIB로 TCP/IP 프로토콜 상에서 관리해야 하는 객체에 대하여 정의를 하고 있으며 일반적으로 네트워크 장비들의 SNMP를 지원한다고 하면 대부분 이 MIB-II에 정의된 객체를 관리한다고 해도 무방할 정도로 가장 대중적인 MIB이다. MIB-II에 정의된 그룹에는 system, interface, ip, tcp, snmp등이 있는데 여기서 system 그룹 객체에 대하여 예를 들자면 시스템의 이름, 시스템을 제작한 회사의 OID, 시스템의 재부팅 시간, 시스템의 위치 등이 있다. 또한 각 하드웨어 벤더, 운영체제에 따라 확장된 형태의 MIB가 존재하며 이에 대해서는 각 벤더의 설명서 등을 참고하여야 한다. SNMP 자체에 대한 내용은 관련자료와 서적을 참고하기 바란다. 참고로 아직 국내에 한글로 된 SNMP 전문 서적은 거의 없다고 보아도 무방하다.
이론적인 내용을 설명하는 자리는 아니므로 실전에 들어가보자. 그러나 SNMP 자체에 대해서 어느정도 알고 있지 못하면 이해하기가 힘들다는 것을 다시 알려준다. 현재 Linux@Work 6월 및 7월호에서 NET-SNMP에 대한 연재를 진행하고 있으니 반드시 이것을 먼저 읽어보고 진행했으면 좋겠다.
리눅스에서 가장 많이 사용되는 SNMP툴은 NET-SNMP로서 UCP-SNMP가 기능을 계속 개선하고 발전해나가면서 최근에 바뀐 이름이다. 웹사이트 주소는 다음과 같다.
http://www.netsnmp.org
http://net-snmp.sourceforge.net/
사이트에 접속해서 원하는 파일을 다운받는다. rpm파일도 있으며 다운로드 페이지로 이동하면 한글로 된 페이지가 뜰 것이다. sourceforge.net는 리눅스 공개 프로젝트를 후원하는 곳이며 현재 한국에서도 참여하는 사람이 늘어나고 있다. 여기 한글페이지도 그런 작업의 일환인 듯 하다
# lynx http://prdownloads.sourceforge.net/net-snmp/ucd-snmp-4.2.1.tar.gz
# cd ucd-snmp-4.2.1
# ./configure --prefix=/usr/local/snmp (/usr/local/snmp 디렉토리에 프로그램 설치)
압축을 해제하고 압축해제한 디렉토리로 이동하여 ./configure를 실행하면 시스템 상황을 점검하고 몇가지 물어본다. System Contact Information (root@) 에서는 관리자의 이메일 주소등을 기입하면 되고 System Location (Unknown) 에서는 현재 자신의 지역을 입력하면 된다. 다음 나오는 것은 snmpd 로그파일 지정이고 snmp 라이브러리 임시 데이터 디렉토리를 지정하는데 기본값을 사용해도 무방하다.
# make
# make install
# /usr/local/snmp/sbin/snmpd (snmp agent 실행)
컴파일을 마치고 make install을 실행하면 위에서 지정한 디렉토리로 프로그램이 설치가 된다. /usr/local/snmp에 설치를 했다면 sbin 디렉토리로 이동하여 프로그램을 실행하면 된다. ps로 프로그램이 실행되었는지 확인해보고 SNMP 에이전트 프로그램인 snmpwalk 프로그램을 실행해보자. snmpwalk 프로그램은 MIB 트리의 특정한 디렉토리의 모든 정보를 보는 프로그램이다. 현재 상태에서는 아직 snmpd 환경 설정파일을 만들지 않은 상태이며 설정파일이 없다면 기본 설정으로 실행을 한다.
# cd /usr/local/snmp
# ./bin/snmpwalk localhost public system
설치가 제대로 되고 작동을 한다면 snmpd.conf 설정파일을 만들어야 한다. 이전에는 이 파일을 직접 사용자가 만들어주어야 했지만 snmpconf 라는 설정 프로그램이 추가가 되어서 예전에 비해 손쉽게 파일을 만들 수가 있다. 실습을 위해서 snmpconf 프로그램을 실행하여 System Information Setup과 Access Control Setup, Monitor Various Aspects of the Running Host 정도를 설정하여 주면 된다. 프로그램을 실행한 디렉토리에 snmpd.conf 파일이 생성되며 snmp_설치디렉토리/share/snmp 디렉토리(여기서는 /usr/local/snmp/share/snmp)로 옮기면 된다. 이 과정이 어렵다면 필자의 예제 파일을 가지고 snmpd를 실행해도 된다. 다음은 snmpconf를 사용하였을 때 나오는 설정 메뉴이다.
Select configuration section for snmpd.conf to operate on:
1: System Information Setup
2: Access Control Setup
3: Trap Destinations
4: Monitor Various Aspects of the Running Host
5: Extending the Agent
6: Agent Operating Mode
# cat snmpd.conf
###########################################################################
#
# snmpd.conf
#
# - created by the snmpconf configuration program
#
###########################################################################
# SECTION: System Information Setup
#
# This section defines some of the information reported in
# the "system" mib group in the mibII tree.
# syslocation: The [typically physical] location of the system.
# arguments: location_string
syslocation seoul/korea
# syscontact: The contact information for the administrator
# arguments: contact_string
syscontact taejun@tunelinux.pe.kr
###########################################################################
# SECTION: Access Control Setup
#
# This section defines who is allowed to talk to your running
# snmp agent.
# rocommunity: a SNMPv1/SNMPv2c read-only access community name
# arguments: community [default|hostname|network/bits] [oid]
rocommunity taejun_community
###########################################################################
# SECTION: Monitor Various Aspects of the Running Host
#
# The following check up on various aspects of a host.
# load: Check for unreasonable load average values.
# Watch the load average levels on the machine.
#
# load [1MAX=12.0] [5MAX=12.0] [15MAX=12.0]
#
# 1MAX: If the 1 minute load average is above this limit at query
# time, the errorFlag will be set.
# 5MAX: Similar, but for 5 min average.
# 15MAX: Similar, but for 15 min average.
#
# The results are reported in the laTable section of the UCD-SNMP-MIB tree
load 15 10 10
# disk: Check for disk space usage of a partition.
# The agent can check the amount of available disk space, and make
# sure it is above a set limit.
#
# disk PATH [MIN=100000]
#
# PATH: mount path to the disk in question.
# MIN: Disks with space below this value will have the Mib's errorFlag set.
# Can be a raw byte value or a percentage followed by the %
# symbol. Default value = 100000.
#
# The results are reported in the dskTable section of the UCD-SNMP-MIB tree
disk /home 10%
disk /var 10%
# proc: Check for processes that should be running.
# proc NAME [MAX=0] [MIN=0]
#
# NAME: the name of the process to check for. It must match
# exactly (ie, http will not find httpd processes).
# MAX: the maximum number allowed to be running. Defaults to 0.
# MIN: the minimum number to be running. Defaults to 0.
#
# The results are reported in the prTable section of the UCD-SNMP-MIB tree
# Special Case: When the min and max numbers are both 0, it assumes
# you want a max of infinity and a min of 1.
proc httpd 30 5
proc mysqld 20 1
위의 내용에 대해서 간단히 설명을 하겠다. syslocation는 서버의 위치를 말하며 별다른 의미는 없다. syscontact는 관리자의 이메일이나 설명을 지정하면 되며 rocommunity taejun_community 는 읽기전용의 커뮤니티를 taejun_community로 지정한 것이다. 모니터링을 하는데 있어서 community 이름은 보안상 중요한 요소이며 지정하지 않을 경우에는 보통 public으로 되어 있다. 그 다음은 시스템의 상태를 모니터링하기 위한 설정으로 load average, 디스크 사용량, 웹과 Mysql 대몬의 숫자 등을 지정하고 있다.
snmpwalk 프로그램을 이용하여 상세한 내용을 모니터링할 수 있다. 아래 프로그램을 실행했을 때 결과가 나온다면 snmpd 프로그램은 성공적으로 실행이 된 것이다.
# snmpwalk localhost taejun_community system
system.sysDescr.0 = Linux tunelinux.pe.kr 2.4.4 #1 SMP Mon Apr 30 17:14:36 KST 2001 i686
system.sysObjectID.0 = OID: ucdSnmpAgent.linux
system.sysUpTime.0 = Timeticks: (7107526) 19:44:35.26
system.sysContact.0 = taejun@tunelinux.pe.kr
system.sysName.0 = tunelinux.pe.kr
system.sysLocation.0 = seoul/korea
system.sysORLastChange.0 = Timeticks: (1) 0:00:00.01
system.sysORTable.sysOREntry.sysORID.1 = OID: ifMIB
system.sysORTable.sysOREntry.sysORID.2 = OID: .iso.org.dod.internet.snmpV2.snmpModules.snmpMIB
system.sysORTable.sysOREntry.sysORID.3 = OID: tcpMIB
system.sysORTable.sysOREntry.sysORID.4 = OID: ip
system.sysORTable.sysOREntry.sysORID.5 = OID: udpMIB
system.sysORTable.sysOREntry.sysORID.6 = OID: .iso.org.dod.internet.snmpV2.snmpModules.snmpVacmMIB.vacmMIBConformance.vacmMIBGroups.vacmBasicGroup
snmpconf 프로그램에서 시스템을 모니터링하기 위한 여러 가지 설정을 하였는데 모니터링하고자 하는 정보에 대해서 snmp 설치 디렉토리의 share/snmp/mibs/ 디렉토리에 있는 UCD-SNMP.MIB를 참고하기 바란다. 이 파일을 살펴보면 내가 어떤 부분을 모니터링하고 주로 살펴볼 것인지에 대하여 참고가 될 것이다. 프로세스, 메모리, load average, 파일 등 자신에게 필요한 것을 결정한다. 이 글에서는 설명을 하지 않겠지만 SNMP Trap을 이용하면 에이전트에서 특별한 이벤트나 사고가 발생을 했을 때 매니저가 요구하지 않더라도 에이전트 스스로 판단해서 매니저로 메시지를 전달한다. 이를 이용하면 시스템이나 또는 네트웍 장비에서 문제가 생겼을 경우 자동으로 시스템, 네트웍 관리자에게 알려서 문제 해결을 빠른 시일안에 할 수 있을 것이다. 상용 네트웍 모니터링 도구들도 이러한 기능을 활용하고 있는 것으로 안다.
4. MRTG와 SNMP 활용한 시스템 모니터링
이제 SNMP와 MRTG를 결합하여 보자. SNMP나 쉘 스크립트 등을 통하여 모니터링 자료를 얻고 이 자료를 토대로 하여 MRTG를 이용 웹페이지로 만드는 작업이다. MRTG에서 자료를 처리하기 위해서는 SNMP가 아니라 하더라도 쉘 스크립트를 이용하여 필요한 두 개의 값만 가져오면 된다.
이에 대한 예제가 web_count.sh 와 mysql_count.sh 이다. 현재 서버의 웹프로세스와 동시접속자수, Mysql 프로세스와 동시접속자수를 구하는 스크립트이다. 웹에서 동시접속자수는 tcp-ip 상태가 ESTABLISHED로 되어 있는것만 포함을 했다. SYN_SENT, TIME_WAIT 등 다른 것들은 접속시도 및 접속해제와 관련되어 있기 때문에 뺀 것이다. (**주1)
$ cat web_count.sh
#!/bin/sh
a=`ps auxw | grep http | grep -v grep | wc -l`
b=`netstat -an | grep :80 | grep -v "0.0.0.0" | grep ESTABLISHED | wc -l`
echo $a
echo $b
$ cat mysql_count.sh
#!/bin/sh
a=`ps auxw | grep mysqld | grep -v grep | wc -l`
b=`netstat -an | grep mysql.sock | wc -l`
echo $a
echo $b
첫 장에서 설명을 한 대로 free 메모리를 정확히 파악하려면 Free+Buffer+Cached를 합쳐야 한다.
아래 mrtg.cfg 파일을 참고하여 판단을 하기 바란다. Target에는 MRTG에서 모니터링할 대상을 정해주는데 SNMP를 이용하는 경우 OID는 숫자나 이름 모두 사용할 수 있다. (iso.org.dod.internet.mgm.mib-2.system =1.3.6.1.2.1.1) 참고가 될듯하여 혼합해서 설정을 했다. 위에서 만든 web_count.sh, mysql_cout.sh 스크립트도 target에 지정하면 되는데 MRTG가 실행되면서 해당 스크립트를 실행하여 그 결과값을 가져오는 것이다. 지면 사정상 모든 cfg 파일을 보여주지는 못하고 몇가지만 보여준다.
$ cat mrtg.cfg
## 작업 디렉토리
WorkDir: /home/httpd/html/mrtg
## 한글설정
Language: korean
#
## taejun.pe.kr - network traffic(eth0)
#
### Interface 2 >> Descr: 'eth0' | Name: '' | Ip: '211.111.111.111' | Eth: '00-01-02-26-bd-ce' ###
Target[tunelinux.pe.kr.eth0]: 2:taejun_community@localhost
SetEnv[tunelinux.pe.kr.eth0]: MRTG_INT_IP="211.111.111.111" MRTG_INT_DESCR="eth0"
MaxBytes[tunelinux.pe.kr.eth0]: 10000000
Options[tunelinux.pe.kr.eth0]: bits
Title[tunelinux.pe.kr.eth0]: Traffic Analysis for -- tunelinux.pe.kr
PageTop[tunelinux.pe.kr.eth0]: <H1>Traffic Analysis for -- tunelinux.pe.kr</H1>
<TABLE>
<TR><TD>System:</TD> <TD>tunelinux.pe.kr in kdaily/seoul/korea</TD></TR>
<TR><TD>Maintainer:</TD> <TD>taejun@tunelinux.pe.kr</TD></TR>
<TR><TD>Description:</TD><TD>eth0 </TD></TR>
<TR><TD>ifType:</TD> <TD>ethernetCsmacd (6)</TD></TR>
<TR><TD>ifName:</TD> <TD></TD></TR>
<TR><TD>Max Speed:</TD> <TD>10,000 kbits/s</TD></TR>
<TR><TD>Ip:</TD> <TD>211.168.2.136 ()</TD></TR>
</TABLE>
#
## tunelinux.pe.kr - memory usage
#
Target[tunelinux.pe.kr.mem]: memAvailReal.0&memAvailReal.0:taejun_community@localhost * 1024 + memBuffer.0&memBuffer.0:taejun_community@localhost * 1024 + memCached.0&memCached.0:taejun_community@localhost * 1024
MaxBytes[tunelinux.pe.kr.mem]: 527654912
Title[tunelinux.pe.kr.mem]: tunelinux.pe.kr: MEMORY USAGE
kilo[tunelinux.pe.kr.mem]: 1024
Options[tunelinux.pe.kr.mem]: gauge, nopercent
YLegend[tunelinux.pe.kr.mem]: Free Memory
LegendI[tunelinux.pe.kr.mem]: Free Mem:
LegendO[tunelinux.pe.kr.mem]:
Legend1[tunelinux.pe.kr.mem]: Free Memory
Legend2[tunelinux.pe.kr.mem]:
Legend3[tunelinux.pe.kr.mem]:
Legend4[tunelinux.pe.kr.mem]:
ShortLegend[tunelinux.pe.kr.mem]: B
PageTop[tunelinux.pe.kr.mem]: <H1>tunelinux.pe.kr: Free Memory Usage</H1>
<TABLE>
<TR><TD>Free memory (Total - 512MB) : </TD> <TD> Free + buffers + cached </TD></TR>
</TABLE>
#
## tunelinux.pe.kr - load average
#
Target[tunelinux.pe.kr.load]: .1.3.6.1.4.1.2021.10.1.3.2&.1.3.6.1.4.1.2021.10.1.3.3:taejun_community@localhost * 100
WithPeak[tunelinux.pe.kr.load]: my
MaxBytes[tunelinux.pe.kr.load]: 10000
Title[tunelinux.pe.kr.load]: tunelinux.pe.kr: LOAD AVG.
Options[tunelinux.pe.kr.load]: gauge,integer,nopercent
YLegend[tunelinux.pe.kr.load]: Load Average
LegendI[tunelinux.pe.kr.load]: 5 min:
LegendO[tunelinux.pe.kr.load]: 15 min:
Legend1[tunelinux.pe.kr.load]: Load average for 5 Min
Legend2[tunelinux.pe.kr.load]: Load average for 15 Min
Legend3[tunelinux.pe.kr.load]: Max load average for 5 Min
Legend4[tunelinux.pe.kr.load]: Max Load average for 15 Min
YTicsFactor[tunelinux.pe.kr.load]: 0.01
PageTop[tunelinux.pe.kr.load]: <H1>tunelinux.pe.kr: LOAD AVERAGE</H1>
#
# httpd daemon & httpd session
#
Target[tunelinux.pe.kr.web]: `/usr/local/mrtg/web_count.sh`
WithPeak[tunelinux.pe.kr.web]: my
MaxBytes[tunelinux.pe.kr.web]: 100
Title[tunelinux.pe.kr.web]: tunelinux.pe.kr: httpd daemon & httpd session
Options[tunelinux.pe.kr.web]: gauge,integer,nopercent
YLegend[tunelinux.pe.kr.web]: Number?LegendI[tunelinux.pe.kr.web]: httpd daemon:
LegendO[tunelinux.pe.kr.web]: httpd session:
Legend1[tunelinux.pe.kr.web]: Number of httpd
Legend2[tunelinux.pe.kr.web]: Number of session
Legend3[tunelinux.pe.kr.web]: 5 Min Max Number of httpd
Legend4[tunelinux.pe.kr.web]: 5 Min Max Number of httpd session
ShortLegend[tunelinux.pe.kr.web]: 개
PageTop[tunelinux.pe.kr.web]: <H1>tunelinux.pe.kr: httpd daemon & session</H1>
Target[tunelinux.pe.kr.mysql]: `/usr/local/mrtg/mysql_count.sh`
WithPeak[tunelinux.pe.kr.mysql]: my
MaxBytes[tunelinux.pe.kr.mysql]: 100
Title[tunelinux.pe.kr.mysql]: tunelinux.pe.kr: mysql daemon & mysql session
Options[tunelinux.pe.kr.mysql]: gauge,integer,nopercent
YLegend[tunelinux.pe.kr.mysql]: Number?LegendI[tunelinux.pe.kr.mysql]: mysql daemon:
LegendO[tunelinux.pe.kr.mysql]: mysql session:
Legend1[tunelinux.pe.kr.mysql]: Number of mysql
Legend2[tunelinux.pe.kr.mysql]: Number of session
Legend3[tunelinux.pe.kr.mysql]: 5 Min Max Number of mysql
Legend4[tunelinux.pe.kr.mysql]: 5 Min Max Number of mysql session
ShortLegend[tunelinux.pe.kr.mysql]: 개
PageTop[tunelinux.pe.kr.mysql]: <H1>tunelinux.pe.kr: mysql daemon & session</H1>
#
## tunelinux.pe.kr - disk usage
#
Target[tunelinux.pe.kr.disk]: .1.3.6.1.4.1.2021.9.1.6.1&.1.3.6.1.4.1.2021.9.1.8.1:taejun_community@localhost
Title[tunelinux.pe.kr.disk]: tunelinux.pe.kr: DISK USAGE
kilo[tunelinux.pe.kr.disk]: 1024
Options[tunelinux.pe.kr.disk]: gauge
LegendI[tunelinux.pe.kr.disk]: /home total:
LegendO[tunelinux.pe.kr.disk]: /home use:
Legend1[tunelinux.pe.kr.disk]: /home Disk usage
Legend2[tunelinux.pe.kr.disk]: use
MaxBytes[tunelinux.pe.kr.disk]: 10080520
ShortLegend[tunelinux.pe.kr.disk]: B
kMG[tunelinux.pe.kr.disk]: K,M,G,T,P
PageTop[tunelinux.pe.kr.disk]: <H1>tunelinux.pe.kr: DISK USAGE</H1>
이제 설정파일을 이용하여 MRTG를 주기적으로 실행하고 결과를 살펴보기 바란다.
위에서는 서버의 부하를 주기 위하여 일부러 커널 컴파일을 여러개 실행시키고 ftp로 큰 파일을 다운받는 작업등을 하였다. load average 가 급상승하기 시작하고 자유 메모리가 고갈되기 시작하며 스왑이 급격하게 늘어나기 시작하였다. 물론 메모리가 512M라서 그렇게 심한 부하가 걸리는 편은 아니다.
5. 마치며
공개적으로 사용할 수 있는 몇가지 툴을 이용하면 이와 같이 편리하게 시스템 모니터링 작업을 진행할 수 있다. 대부분의 네트웍 장비에서 SNMP를 이용하므로 중앙집중적으로 서버 및 장비를 모니터링하는 것이 가능하다. 여기에 LDAP서비스(디렉토리 서비스)와 자바를 이용하면 공개된 프로그램을 이용하여서도 훌륭한 네트워크 관리 시스템을 구축하는 것이 충분히 가능하지 않을까. 이러한 시도를 하고 있는 곳이 www.opennms.org 이다. 필자가 요즘 관심을 가지고 있는 쪽으로 여유가 된다면 한번 도전해보고 싶은 분야이다.
SNMP와 MRTG 모두 현재의 지면으로만 설명하기에는 방대한 양이다. 위에서는 SNMP의 간략한 기능에 대해서만 언급을 하였지만 SNMP에는 다양한 기능이 많으며 시스템 관리자라면 보안에도 신경을 써야 한다. SNMP는 인증과 접근 방침을 정하는 낮은 단계의 보안을 제공하고 있는데 community가 여기에서 사용된다. public은 공개 community 값으로 가급적 자신만이 알 수 있는 community로 바꿀 것을 권고한다. 짧은 글이지만 이 글에서 SNMP와 MRTG를 같이 소개한 이유는 시스템 모니터링을 어떻게 자동화해서 처리할 수 있을까란 문제의식이었다. 현재 Linux@Work 2001년 6월부터 SNMP에 대한 연재가 시작되었으니 이를 참고하기 바라며 네트워크 모니터링에 대한 더욱 자세한 설명은 프로그램 세계 1999년 8월부터 2000년 1월까지 같은 저자가 연재를 한 “네트워크 정복의 첫걸음”을 참고하기 바란다.
4. 운영체제 설치하기
이번 강좌에서는 운영체제를 설치하고 보안과 최적화를 위한 기본적인 시스템 세팅에 대하여 다루겠다. 자신이 제공하고자 하는 서비스에 맞게 운영체제 설치 시점부터 신경을 써야 한다. 또한 보안도 운영체제를 설치하는 과정부터 시작이 된다.
1. 랜선을 뽑자!
운영체제를 설치하면서 가장 먼저 해야 할 일은 무엇이라고 생각을 하는가. 사람마다 여러 가지 이야기를 할 수 있겠지만 가장 먼저 해야 할 일중의 하나는 시스템을 네트웍에서 분리시키는 것이다. 간단하게 랜선만 뽑으면 된다. 크래킹을 하는 프로그램이 워낙 발전해서 일부러 자신의 서비스를 목적으로 하지 않는다고 하더라도 네트웍에 연결된 순간부터 외부로부터의 침입 위험이 있다고 할 수 있다.
시스템을 네트웍에서 분리된 곳에 두었다면 이제 설치를 시작할 단계이다. 자신이 보유하고 있는 하드웨어에 대해서 자세하게 알수록 좋은데 세부적인 부분까지 알고 있어야 나중에 커널 컴파일을 할 때 불필요한 드라이버를 커널에서 제거하여 커널의 크기를 줄일 수 있다. 커널은 시스템 부팅 후 메모리에 상주하여 있는 부분이므로 불필요한 드라이버를 커널에 포함하여 메모리를 낭비할 필요가 없다.
레드햇 계열의 경우 설치시 워크스테이션, 서버, 커스텀 등으로 구분이 되어있는데 커스텀을 선택하여 자신에게 필요한 패키지만 설치를 해야 한다. 최소한의 패키지를 설치하는게 보안의 기본이다. 그렇지만 매뉴얼 페이지와 하우투 문서는 설치를 하기 바란다.
2. 파티션 나누기
가장 먼저 해야 할 일이 파티션 나누기이다. 개인적으로 테스팅을 하는 시스템이라면 루트 파티션을 크게 잡는게 편리한 일이지만 실제 서비스를 하는 경우라면 시스템을 보호하기 위해 몇가지 파티션이 필요하다. 루트 파티션에 로그나 이메일, 웹 등의 자료를 넣으면 시스템을 붕괴시킬 가능성이 있는 서비스 거부 공격에 처할 위험이 있다. 이외에도 파티션을 여러개로 나눌 경우 여러 가지 이점이 있다.
ㅇ 서비스 거부 공격 방어
ㅇ SUID 프로그램에 대한 보호
ㅇ 빠른 부팅속도
ㅇ 백업과 업그레이드 등 관리의 편리성
ㅇ 마운팅된 파일 시스템에 대한 제어 가능성의 증대
ㅇ 각 파일 시스템에 대한 효율적인 제한
/var는 시스템의 모든 로그가 남는 파티션으로 반드시 분리를 해야 위에서 말을 한 대로 서비스 거부 공격 등에 대해 방어를 할 수 있다. 웹과 계정 서비스를 제공하는 경우에는 /home, /tmp를 반드시 분리해야 한다. 메모리가 16메가 이하라면 모르겠지만 요즘에는 이런 시스템이 거의 없을 것이다. 일반적으로 앞쪽 실린더부터 많이 쓰는 파티션으로 지정하는게 좋다. 디스크 플래터에 엑세스할 때 바깥쪽부터 액세스하므로 플래터 바깥쪽에 있는 파티션이 보다 더 좋은 I/O 성능을 낼 수 있기 때문이다. 그렇지만 시스템의 성능에 대해서 더 고민을 하고 투자를 할 생각이 있다면 RAID를 사용하거나 각 파티션별로 별도의 하드디스크를 사용하는 것이 좋다. 하다못해 남는 IDE 디스크 하나를 스왑으로 별도 할당하는것도 좋은 방법일 것이다. 그렇지만 서버로 사용한다면 가급적 SCSI를 사용할 것을 권장한다. 최근에 IDE 하드디스크의 속도가 예전에 비하여 많이 향상되기는 하였지만 여러 가지 면에서 SCSI와 직접 비교하는 것은 힘들고 SCSI의 경우 입출력 작업을 위한 별도의 CPU가 존재한다는 것을 잊어서는 안된다. 이와 더불어 설치하고 나서 reiserfs 등 저널링 파일 시스템을 사용하여 파일의 무결성 및 속도를 향상시킬 수 있을 것이다.
3. 패키지 설치
패키지를 설치할 경우 위에서 말을 한 대로 반드시 필요한 패키지만 설치를 해야 한다. 또 가급적 서버별로 서비스를 분리하는 것이 관리, 유지보수 및 보안 측면에서 우수하다. 서비스별로 필요로 하는 하드웨어의 성능과 자원이 다르기 때문이다. 그런데 패키지를 선택하면서 엄청나게 나오는 패키지 때문에 어느정도 익숙해있는 관리자라도 혼란을 느낄 것이다. 이에 대해서 간단하게 설명을 하기는 힘들며 시스템을 운영하면서 꾸준히 조금씩 패키지에 대해서 알아갈 수 밖에 없는 듯 하다.
ㅇ 보안상 이유로 불필요한 프로그램 (이번 배포판에 따라 다르며 여기서는 레드햇 6.2를 기준으로 한다)
- Applications/File : GIT
- Applications/Internet : finger, ftp, fwhois, ncftp, rsh, ntalk, telnet
- Applications/Publishing : GhostScript, groff-perl, mpage, pnm2ppa, rhs-printfilters
- Applications/System : arpwatch, bind-utils, knfsd-clients, procinfo, rdate, rdis, screen, ucd-snmp-utils
- System Enviroment/Base : chkfontpath, Network Information Server(NIS)
- System Enviroment/Daemons : XFree86-xfs, finger-server, lpr,nfs-utils, pidentd,portmapper, rsh-server, routed, rusers, rusers-server,rwall-server,rwho,talk-server,tftp,telnet-server,tftp-server,ucd-snmp,ypserv
- System Enviroment/Libraries : XFree86-libs, libpng
- User Inferface/X : XFree86-75dpi-fonts, urw-fonts
자신에 상황에 따라 패키지는 조정할 수 있다. 예를 들어 ftp, telnet 클라이언트 프로그램은 ssh 패키지 등을 이용할 수 있다. rdate는 시간 동기화에 사용이 되어 필요할 수가 있다. rdist는 원격 호스트간 자료 전송에 사용하는데 rsync로 대체할 수 있다. libpng 패키지는 PNG 이미지 포맷의 파일을 생성하고 관리하기 위해 필요할 수 있다. 이러한 패키지로는 mrtg, webalizer 등이 있다.
ㅇ 설치후 삭제해야 할 프로그램
pump, mt-st, eject, mailcap, apmd, kernel-pcmcia-cs, linuxconf, getty_ps, isapnptools,setserial, kudzu, raidtools, gnupg, redhat-logos, redhat-release, gd, pciutils, rmt, sendmail
mt-st는 테잎 드라이브가 있을 경우에는 필요할 수 있다. rmt 패키지는 원격으로 백업을 할 수 있는 기능을 제공하는데 보안상 취약하며 전문적인 백업 솔루션을 사용하는 경우에는 내장되어 있는 백업 솔루션을 사용하기 바란다. 일반적으로 원격 백업 솔루션의 경우 백업을 하면서 자체적인 암호화 알고리즘을 사용한다. (필자가 주로 사용한 것은 Arkeia이다) gd 패키지는 gif 파일을 생성하는 패키지로 mrtg, webalizer 등에서도 사용하고 웹서비스를 제공하는 경우 동적으로 이미지 생성을 위하여 필요로 하는 경우가 많이 있다. kbdconfig, mouseconfig, timeconfig, authconfig, ntsysv, setuptool 은 모든 설정을 마치고 나서 없애도 된다. 센드메일은 앞의 강좌에서도 설명을 하였듯이 메일 수신 기능이 필요없으면 구동을 할 필요가 없다. 메일 서비스는 항상 주요한 크래킹 서비스 대상의 하나이며 불필요하게 위협에 노출을 시킬 필요가 없다.
ㅇ 컴파일과 관련된 패키지
autoconf, m4, automake,dev86, bison, byacc,cdecl, cpp, cproto,ctags, egcs, ElectricFence, flex, gdb, kernel-headers, glbic-devel, make, patch
컴파일과 관련된 패키지는 서비스를 하고 있는 서버에 굳이 둘 필요가 없다. 내부 서버 등에서 컴파일을 하고 필요한 서버로 옮기면 된다. 크래커가 불법적으로 권한을 획득했다고 하더라도 새로운 프로그램을 컴파일하거나 바이너리를 바꾸는 작업은 막을 수 있다.
최소한도로 필요한 패키지만 설치를 하고나서 바로 현재까지 나와있는 보안패치를 설치해야 한다. 레드햇 사용자의 경우 아래 사이트를 참고한다.
http://www.redhat.com/apps/support/updates.html
필자가 생각하기로는 레드햇의 경우 공식적으로 보안버그가 발표되고 패치가 나오기까지는 약간의 시간이 걸린다. 그래서 필수적으로 보안관련 메일링리스트(**주1)에 가입을 하고 http://www.linuxsecurity.com/ 나 http://www.securityfocus.com/ 등을 참고하기 바란다.
설치를 다 마쳤다고 하더라도 혹시나 불필요한 데몬이 뜨는지 다시 한번 확인을 해본다. 레드햇의 경우에는 /etc/rc.d/rc3.d 디렉토리에 가면 부팅시 구동되는 프로그램들이 있다. 레드햇에서는 ntsysv로 볼수 있다.
4. 주요 서비스
아래는 주요하게 운영되고 있는 서비스에 대한 설명이다. (**주2)
S05apmd (랩탑에서만 필요)
S10xntpd (Network time protocol)
S11portmap (NIS나 NFS와 같은 rpc 서비스에 필요)
S15sound (사운드 카드 설정 저장)
S15netfs (nfs 클라이언트로 nfs 서버에서 파일시스템 마운팅에 필요)
S20rstatd (모든 r 서비스를 실행하지 않는 것이 좋다. 원격 사용자에게 너무 많은 정보를 주기 때문이다)
S20rusersd
S20rwhod
S20rwalld
S20bootparamd (디스크없는 클라이언트에서 사용하며 이런 취약한 서비스가 필요하지는 않을 것이다)
S25squid (Proxy server)
S34yppasswdd (NIS 서버에서 필요하며 매우 취약한 서비스이다)
S35ypserv (NIS 서버에서 필요하며 매우 취약한 서비스이다)
S35dhcpd (dhcp server daemon)
S40atd (cron과 비슷하며 at 서비스에 사용하며 필요하지 않다)
S45pcmcia (랩탑에서만 필요)
S50snmpd (SNMP 대몬으로 원격 사용자에게 시스템의 상세한 정보를 줄 수 있다)
S55named (DNS server. DNS를 설정한다면 BIND의 가장 최신 버전으로 업데이트해야한다. http://www.isc.org/bind.html)
S55routed (RIP, 정말로 필요하지 않으면 운영하지 말자)
S60lpd (Printing services)
S60mars-nwe (Netware file and print server)
S60nfs (NFS 서버에 사용하며 절대적으로 필요한게 아니라면 돌리지 말자)
S72amd (AutoMount daemon, 원격 파일 시스템 마운트에 사용)
S75gated (OSPF와 같은 다른 라우팅 프로토콜을 운영하는데 필요)
S80sendmail (없어도 이메일을 보낼 수 있으며 메일을 받거라 릴레이를 못할 뿐이다)
S85httpd (Apache webserver, 최신 버전으로 업데이트 할 것을 추천. http://www.apache.org/)
S87ypbind (NIS 클라이언트라면 필요)
S90xfs (X font server)
S95innd (News server)
S99linuxconf (브라우저를 이용 원격으로 리눅스 시스템 설청하는데 필요)
위에서 자신이 설치한 프로그램만 나올 것이다.
5. 보안관련팁
보안과 관련한 몇가지 주요 내용을 정리해보자.
ㅇ 불필요한 서비스를 제거한다
ㅇ inetd.conf 파일에서 불필요한 서비스를 제거한다
ㅇ tcp 래퍼를 활용한다
ㅇ ipchains(커널 2.2) 나 iptables(커널 2.4)을 활용하여 불필요한 패킷을 막는다
ㅇ 쉐도우 비밀번호를 활용한다
ㅇ 원격에서 root 로의 로그인을 차단한다
ㅇ su 권한을 특정한 그룹만 사용할 수 있도록 한다 (FreeBSD 등에서는 기본으로 되어있다)
ㅇ tripwire 등의 파일 무결성 툴을 이용한다
ㅇ 로그 파일을 분석한다
ㅇ 로그를 백업한다
6. 마치며
보안과 관련해서는 수많은 문서들이 나와있고 시중에 책도 많기에 더 세부적으로 다루지는 않겠다. 그런데 가장 중요한 것은 아무리 보안을 완벽히 한다고 해도 100% 안전한 시스템은 있을 수 없다는 것이다. 시스템을 운영하면서 백업의 중요성은 아무리 강조해도 지나침이 없다. 필자가 알고 있는 한 사이트에서는 한번 크래킹을 당하여 홈페이지가 뒤집혀진 적이 있다. 다행히 우리 회사 내부에 보관하고 있던 자료가 있어서 복구를 하였다. 그런데 조금 있다가 다시 한번 크래킹을 당했는데 자료가 없어서 완전히 새롭게 홈페이지를 만들었다고 한다. 크래킹 당하는 것이 문제가 아니라 크래킹 당하고나서 얼마나 빨리 복구를 하는 것이 더 중요하다. 쉽게 말을 해서 뚫을 놈은 어떻게든 뚫는다. 최근에 안정성, 가용성, 부하분산을 위해 서버 클러스터링(**주3)을 도입하는 경우가 많은데 서버를 이중, 삼중으로 하는 것은 보안 측면에서도 유리하다.
5. 운영체제와 커널 차원에서의 튜닝 및 보안
운영체제와 커널 차원에서의 튜닝과 보안에 대해서 중요한 부분을 설명하겠다. 보안도 다루기는 하지만 일반적인 차원에서의 보안에 대한 내용은 뺐다. 일반적인 보안에 대해서는 잘 다룬 서적이나 자료들이 많기 때문에 중복된 내용을 설명하기보다는 다른 곳에서는 자세히 다루지 않았지만 중요한 부분들을 설명하는게 나을 것 같다. 먼저 파일시스템 설정과 관련된 부분에 대해서 설명을 하고 운영체제 및 커널 차원의 튜닝과 보안에 대해서 설명을 하겠다.
1. 파일 시스템 관련
/etc/fstab에는 파일 시스템 관련된 정보가 들어있다.
$ cat /etc/fstab
/dev/sda2 /home ext2 defaults,rw,nosuid,nodev,noexec 1 2
/dev/sda3 /var ext2 defaults,rw,nosuid,nodev,noexec,noatime 1 2
/dev/sda4 /tmp ext2 defaults,rw,nosuid,nodev,noexec 1 2
여기서 세 번째 줄은 해당 파티션에 대한 제어정보가 들어있는데 의미는 다음과 같다.
default : quota, read-write, suid, async
noquota : 쿼터 사용하지 않음
nosuid : SUID/SGID 설정을 할 수 없음
nodev : 문자나 블락 특수 디바이스 설정을 할 수 없음
noexec : 바이너리 파일의 실행 권한을 주지 않음
quota : 쿼터 설정
ro : 읽기 전용 파일시스템
rw : 읽기/쓰기 파일시스템
suid : SUIG/SGID 설정 허용
noatime : atime(파일 접근 시간)을 업데이트하지 않음
리눅스 및 유닉스에서는 파일 생성 시간 및 마지막 변경시간과 함께 마지막 접근시간을 계속 기록한다. 그렇지만 자주 접근하고 변경이 되는 파일에 대해서는 파일 접근시간이 필요하지 않다면 굳이 마지막 파일 접근시간을 기록하지 않아도 된다. 웹서버, 캐쉬파일, 로그파일 등 주로 읽기전용 파일이 이에 해당할 것이다. 이 설정만으로 성능 병목현상의 가장 큰 주범인 디스크 I/O를 줄이는 데에 도움이 될 수 있다. 그렇지만 파일이 변경된 경우에는 업데이트가 되니 걱정하지 말기 바란다. (chattr 프로그램을 이용하여 개별 파일에 대해서도 지정할 수 있다)
nosuid는 SUID,SGID를 하지 못하도록 막는다. SET-UID 프로그램은 보안상 문제가 생길 여지가 많으며 루트 계정으로 접근할 수 있는 지름길이 되는 경우가 많다. 불가피하게 사용해야 할 경우가 있지만 그 외에는 nosuid 설정을 통해 보안을 강화하는게 좋다. 레드햇 계열에서 SET-UID root 프로그램은 다음과 같은 것들이 있다.
# find / -type f \( -perm -04000 -o -perm -02000 \) \-exec ls -alF {} \;
-rwsr-xr-x 1 root root 14188 Mar 7 2000 /bin/su*
-rwsr-xr-x 1 root root 86690 Oct 20 2000 /bin/ping*
-rwsr-xr-x 1 root root 62192 May 4 09:45 /bin/mount*
-rwsr-xr-x 1 root root 28432 May 4 09:45 /bin/umount*
-r-sr-xr-x 1 root root 15688 Dec 1 2000 /sbin/pwdb_chkpwd*
-r-sr-xr-x 1 root root 16312 Dec 1 2000 /sbin/unix_chkpwd*
-rwsr-xr-x 1 root root 22232 Feb 22 10:21 /usr/bin/crontab*
-rws--x--x 1 root root 14056 Jan 11 2001 /usr/bin/chfn*
-rws--x--x 1 root root 13800 Jan 11 2001 /usr/bin/chsh*
-rws--x--x 2 root root 563164 Aug 9 2000 /usr/bin/suidperl*
-rws--x--x 2 root root 563164 Aug 9 2000 /usr/bin/sperl5.00503*
-rwxr-sr-x 1 root man 36368 May 23 13:25 /usr/bin/man*
-r-s--x--x 1 root root 12244 Feb 8 2000 /usr/bin/passwd*
-rwxr-sr-x 1 root mail 11620 Feb 8 2000 /usr/bin/lockfile*
-rwsr-sr-x 1 root mail 76432 Feb 8 2000 /usr/bin/procmail*
-rwxr-sr-x 1 root slocate 23024 Dec 21 2000 /usr/bin/slocate*
-rwsr-xr-x 1 root root 198312 Nov 10 2000 /usr/bin/ssh1*
-rws--x--x 1 root root 5640 Jan 11 2001 /usr/bin/newgrp*
-rwxr-sr-x 1 root tty 8332 Jan 11 2001 /usr/bin/write*
-rwxr-sr-x 1 root utmp 6096 Feb 25 2000 /usr/sbin/utempter*
-rws--x--x 1 root root 9568 Mar 29 18:30 /usr/sbin/suexec*
-rwsr-sr-x 1 root mail 369340 Jun 19 14:31 /usr/sbin/sendmail*
-rwsr-xr-x 1 root root 17704 Oct 7 2000 /usr/sbin/traceroute*
-rwsr-xr-x 1 root root 34751 Jan 16 00:50 /usr/libexec/pt_chown*
여기서 불필요한 파일은 chmod를 이용 설정을 바꾸어야 한다. chage, gpasswd, wall, chfn, chsh, newgrp, write, usernetctl, traceroute, mount, umount, ping, netreport 등이 여기에 해당한다.
그런데 위의 프로그램은 서비스를 제공하기 위해 어쩔 수 없는 경우이지만 그러한 경우가 아니라면 특정한 파티선에 nosuid를 사용해서 계정 등의 사용자가 장난을 치는 경우를 막을 수 있다. 여기에 noexec까지 주면 바이너리 파일을 실행하지 못하기 때문에 더 안전하게 시스템을 유지할 수 있다. noexec를 준 파티션은 루트도 바이너리 파일을 실행하지 못한다. quota를 이용해서 사용자가 제한되어 있는 하드 디스크 공간을 모두 차지하는 일을 막을 수 있다. 쿼터 설정은 여기서는 생략을 하겠다. async 옵션은 파일시스템에 대한 I/O를 비동기적으로 메모리에 버퍼링하는 것인데 기본값으로 되어 있다. 디스크 접근 시간을 최소화하기 위한 부분이므로 바꿀 필요가 없다. 이것을 sync로 바꾸면 메모리에서 변경된 자료가 바로 디스크 I/O에 반영이 되므로 속도가 얼마나 느려질지 장담할 수 없다.
2. 보안관련 커널 설정
커널과 관련된 옵션은 /proc에서 직접 값을 써 줄 수도 있고 /etc/sysctl.conf 파일을 이용하여 바꿀 수도 있다. 커널과 관련된 옵션은 그냥 무조건 사용하는게 아니라 자신의 환경을 생각해야하고 그 원리를 제대로 이해했을 때 사용하는 것이 좋다. 그런데 이 작업이 그렇게 만만한 작업은 아니고 운영체제와 네트웍에 대해서 많은 지식이 있어야 이해가 가능하다. 여기서는 주로 많이 사용되는 커널 옵션에 대해서 살펴보겠다. 커널과 관련된 설정은 sysctl 프로그램을 이용하여 편리하게 설정할 수 있다. sysctl -a 하면 현재 설정된 값이 나오고 -w 옵션을 이용하여 특정값을 저장할 수 있다. 재부팅후에도 계속 사용하려면 /etc/sysctl.conf 파일에 저장하여 사용하면 된다.
ㅇ ping 요청에 반응하기 막기 : ping 요청에 반응하는 것을 막을 수 있다. 외부에서 누구도 서버에 핑을 보낼 수도 없고 보내도 반응을 하지 않기에 보안상으로 도움이 될 수 있고 네트웍 보안을 향상시킬 수 있다. 그러나 원격에서 서비스를 관리하는 경우 간단하게 시스템의 상태를 확인할 수 있는 수단을 막는 결과를 초래할 수도 있다.
net.ipv4.icmp_echo_ignore_all = 1
ㅇ Broadcast 로 오는 핑을 차단하기 : 브로드캐스트 주소에 ping을 쏘는 것을 막는다. smurf 공격 방지용이다. 스머프 공격은 에코 리퀘스트 패킷을 어떤 네트웍의 브로드캐스트 주소로 보내면 해당 네트워크의 모든 호스트가 request 패킷에 응답하느라 다른 일은 하지 못하는 것을 말한다. 그렇지만 정작 문제는 해당 네트워크의 호스트가 아니다. 이 엄청난 개수의 컴퓨터들에서 일시에 어느 한 곳으로 ICMP echo replay 패킷을 보내면 패킷을 보냈던 시스템은 마비상태로 가기 싶다. 하지만 이미 출발지 주소 자체가 실제 패킷을 보낸 시스템이 아니라 공격을 할 호스트로 바뀌어있는 상태일 것이다. (IP 스푸핑)
net.ipv4.icmp_echo_ignore_broadcasts = 1
ㅇ IP 소스 라우팅 막기 : 라우팅과 라우팅 프로토콜은 몇가지 문제를 생성해낸다. RFC 1122에 따르면 목적지의 경로에 대한 세부적인 내용을 담고 있는 IP 소스 라우팅은 목적지 호스트에서도 같은 경로를 따라 반응을 해야 하다는 문제점이 있다. 크래커가 특정 네트웍에 소스 라우팅 패킷을 보낼 수 있다면 돌아오는 반응을 가로채서 상대방의 호스트와 신뢰받은 호스트처럼 속일 수 있다. 기본값이 1이므로 0으로 바꾼다.
net.ipv4.conf.all.accept_source_route = 0
ㅇ backlog 늘리기와 syncookie 기능 사용하기 : SYN Attack 은 서비스 거부 공격(DOS)의 하나로 공격할 시스템의 모든 자원을 소비하게 해서 재부팅하게 만든다. 두 호스트 사이에 TCP 연결이 이루어지는 것은 클라이언트 호스트가 TCP 헤더에 SYN 플래그를 on한 상태로 서버 호스트로 연결 요청을 하면서 시작된다. 그러면 요청을 받은 서버는 클라이언트로 SYN/ACK를 보내고 이를 받은 클라이언트는 서버에게 ACK를 보낸다. 그런데 클라이언트에서 ACK를 보내지 않고 있으면 어떻게 될까? 문제는 TCP에서 한 소켓에서 동시에 SYN 요청을 처리하기에는 한계가 있으며 이 한계가 백로그(backlog)라고 한다. 백로그는 연결 요청이 아직 완전히 처리되지 아니한 대기상태에 있는 큐의 길이이다. 이 백로그 큐가 꽉 차게 되면 이후 들어오는 SYN 요청은 무시되며 이러한 공격을 SYN 플러딩이라고 한다. 다른 유닉스 중에서는 들어오는 소켓 요청에 대하여 두 개의 큐를 만드는 경우도 있다. 이 경우 하나는 half-open 소켓(SYN을 받고 SYN/ACK를 보낸 상태)을 위한 큐이고 또하나는 완전히 연결이 되었지만 애플리케이션에서 accept() 콜을 기다리는 큐이다. (솔라리스의 경우 tcp_conn_req_max_q0, tcp_conn_req_max_q가 이에 해당한다) backlog도 무조건 늘리는 것이 좋은 것은 아니라는 보고가 있으며 1024 이상으로 설정시에는 커널 소스를 수정해야 한다. syncookie는 SYN Flood 공격에 대응하기 위해 나온 것이지만 large windows에서는 성능에 문제가 발생할 가능성이 있다고 한다. syncookie를 사용하려면 커널에서 지정이 되어 있어야 한다.
net.ipv4.tcp_max_syn_backlog=1024
net.ipv4.tcp_syncookies = 1
ㅇ ICMP redirect를 막는다 : 호스트에서 특정 목적지로 최적화되지 않은 라우팅을 한다고 할때 ICMP redirect 패킷은 호스트에게 정확한 라우팅 경로를 알려주는 역할을 한다. 그런데 크래커가 ICMP redirect 패킷을 위조할 수 있게 된다면 호스트의 라우팅 테이블을 변경할 수 있게 되고 원하지 않는 경로로 트래픽을 보내 호스트의 보안을 해칠 수 있다. 잘 디자인된 네트웍에서는 최종 목적지로의 redirect가 필요하지 않다. redirect 보내고 받는 것을 모두 없애야 한다. (**주1)
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.all.accept_redirects=0
ㅇ bad icmp 패킷 차단 : 어떤 router 들은 broadcast frame들로 거짓 응답을 보냄으로서 RFC 1122를 위반한다. 이러한 것들은 보통 커널 경고를 통해 로깅이 된다. 이것을 TRUE로 설정을 할경우 커널은 이러한 경고를 하지 않을 것이며, 로그 파일이 지저분해 지는 것을 피할 수 있다. 기본값은 FALSE 이다. 1로 설정하여 활성화를 하면 IP나 TCP 헤더가 깨진 bad icmp packet을 무시한다.
net.ipv4.icmp_ignore_bogus_error_responses = 1
ㅇ IP 스푸핑 방지하기 : DOS 공격에서 자신의 네트워크가 스푸핑된 공격지의 소스로 쓰이는 것을 차단한다. RFC182에 따른 IP spoof 방지를 위한 설정이다.
net.ipv4.conf.all.rp_filter = 1
ㅇ IP 스푸핑된 패킷 로그에 기록하기 : 스푸핑된 패킷, 소스 라우팅 패킷, redirect 패킷에 대하여 로그파일에 기록을 남긴다.
net.ipv4.conf.all.log_martians = 1
참고로 /etc/host.conf 파일에 nospoof 옵션을 주어 IP 스푸핑 방지를 위한 설정을 추가하기 바란다.
# cat /etc/host.conf
order bind, hosts
multi on
nospoof on
3. 최적화 관련 커널 및 운영체제 설정
커널과 운영체제에서의 최적화는 네트웍, 가상 메모리, 디스크 I/O, 각종 자원 제한 등으로 나눌 수 있다. TCP-IP에서 네트웍 최적화는 TCP/IP의 기본값을 줄여서 TCP/IP에서 더 많은 연결을 처리할 수 있도록 하는게 목적이다. TCP의 연결 해제 시간을 줄이고 불필요한 IP 확장기능을 사용하지 않는다.
ㅇ 연결종료시간을 줄인다 : tcp_fin_timeout은 close되었을 때 FIN-WAIT-2 상태로 얼마나 오랫동안 소켓을 유지하고 있는가를 지정한다. 상대 호스트에 문제가 생겨서 close를 못할 수도 있고 예상치 않게 죽을 수도 있다. 커널 2.4에서 기본값은 60초인데 커널 2.2에서는 180초였다. 커널 2.2와 같이 더 늘릴 수는 있지만 시스템이 웹서버의 용도라면 수많은 소켓들 때문에 메모리에 문제가 생길 수 있다. FIN-WAIT-2 소켓은 최대 1.5K의 메모리를 사용하기 때문에 FIN-WAIT-1보다는 위험이 덜하지만 더 오래 가는 경향이 있다.
net.ipv4.tcp_fin_timeout = 30
ㅇ keepalive 시간 줄이기 : tcp_keepalive_time은 keepalive가 활성화되어 있을 때 얼마나 자주 keepalive 메시지를 보내줄지 정한다. 이는 HTTP 1.1의 연결지속 옵션과 관계없이 TCP 자체에 있는 기능이다. TCP 접속은 한쪽에서 다른 쪽으로 데이터를 전송할 필요가 없는 경우에는 트래픽이 전혀 발생하지 않으므로 휴지 상태인 접속의 경우에는 폴링이나 네트워크 부하가 없다. 그런데 더 이상 사용하지 않는 네트워크 접속을 위해 서버에서는 메모리 버퍼를 유지하고 있는 것으로 자원을 낭비하는 것이다. 사용자가 모뎀을 꺼버리거나 컴퓨터의 전원을 끄는 경우도 이에 해당한다. 기본값은 2시간(7200초)인데 처리량이 많은 웹서버인 경우에는 사용자가 페이지를 읽고 얼마나 오래 머무는지를 판단하여 이 대기시간을 최대 시간 간격으로 설정하면 되며 보통 30분정도면 적당하다.
net.ipv4.tcp_keepalive_time = 1800
ㅇ 열수 있는 포트 늘리기 : ip_local_port_range 옵션은 TCP와 UDP에서 사용할 수 있는 로컬 포트의 범위를 지정한다. 두가지 숫자로 이루어져 있는데 앞의 번호는 시작포트이고 뒤의 번호는 마지막 로컬 포트 번호이다. 메모리양에 따라 기본값이 조정되는데 128M 이하일 경우에는 1024-4999, 128M 이상일 경우에는 32768-61000 이다.
net.ipv4.ip_local_port_range = 32768 61000
ㅇ 컴파일 옵션 변경
x86 프로그램에서 최대의 성능을 내기 위해서는 컴파일 옵션에 -O9 플래그를 지정할 수 있다. 대부분의 프로그램은 Makefile에 -O2를 지정하는데 -O9는 코드를 가장 최고로 최적화하는 것이다. 프로그램의 크기는 커지지만 속도가 빨라진다. 그렇지만 CPU가 686이상에서만 성능 향상이 있다. -mcpu=cpu_type -march=cpu_type을 사용하면 각 CPU에 최적화된 코드가 생성된다. 이럴 경우에는 프로그램이 해당 CPU에서만 돈다는 단점이 있다. gcc에서 -S 옵션을 이용하면 어셈블리어로 번역되어 결과가 출력되는데 최적화를 할수록 어셈블리 코드가 짧게 변하는 것을 볼 수 있다. 이외에도 gcc를 egcs로 바꾸어서 사용할 수 있다. 이외에도 최적화된 컴파일을 하기 위해 몇가지 추천하는 옵션이 있었지만 커널 컴파일 등에서 제대로 부팅이 되지 않는 경우가 있어 여기서는 일반적인 옵션에 대해서만 소개를 하였다.
ㅇ bdflush 제어 : bdflush는 가상 메모리(VM) 서브시스템의 활동과 관련이 되어있는데 bdflush 커널 대몬에 대한 제어를 한다. bdflush는 블럭 디바이스 입출력 버퍼를 관리하는 커널 대몬으로 주로 버퍼를 비우는 역할을 맡고 있다. 하드 디스크에 쓰여질 데이터는 바로 하드 디스크로 저장되는 것이 아니라 중간에 버퍼를 통한다고 앞부분에서 설명을 하였다. 주기적으로 버퍼의 내용을 하드 디스크에 기록하는 형태로 하드 디스크 접근을 최대로 줄여서 파일 시스템의 성능을 높이기 위한 것이다. bdflush는 9개의 값으로 구성이 되어있으며 기본값은 커널 2.2에서는 40 500 64 256 500 3000 500 1884 2 이었다가 커널 2.4에서는 구성이 약간 바뀌었다. 기본값만 바뀐 것이 아니라 순서도 바뀌었다. 순서가 nfract, ndirty, nrefill, dummy1, interval, age_buffer, nfract_sync, dummy2, dummy3 이며 기본값은 “30 64 64 256 500 3000 60 0 0” 이다.
커널 소스는 /usr/src/linux/fs/buffer.c이다. 여기에서 중요한 부분은 앞의 세가지이다. nfract는 전체 버퍼 캐쉬중에서 더티 버퍼의 비율을 나타낸다. 여기서 더티는 프로세스에서 변경이 되어 하드 디스크에 쓰여질 데이터를 나타낸다. (반대는 clean 버퍼이다) 수치를 높이면 디스크에 쓰는 동작은 최대한 지연이 되지만 메모리가 부족할 경우 I/O부하가 걸릴 수 있다. 또 어느 책에서는 이 수치를 100%로 지정하는 것을 추천하고 있는데 메모리와 관련하여 "do_try_to_free_pages failed for ...." 등의 문제가 발생한 경우가 생기고 있다. ndirty는 한번에 기록될 더티 블락의 최대 숫자이다. 수치를 높이면 I/O작업을 지연시킬 수 있는데 수치가 너무 낮으면 bdflush가 오랫동안 작동을 하지 않아 메모리 부족 현상이 생길 수 있다. nrefill은 refill을 호출할 때마다 가져올 클린 버퍼 개수이다. 때로는 버퍼가 메모리 페이지에 비해 다른 크기가 될 수 있기 때문에 미리 free 버퍼를 할당하는 것이 필요하다. 수치가 클수록 메모리가 낭비될 확률은 높지만 refill_freelist()를 실행할 필요는 적어진다.
vm.bdflush = 30 64 64 256 500 3000 60 0 0
ㅇ 버퍼 메모리 사용량 조절 : buffermem 은 전체 메모리에서 버퍼 메모리 사용량을 % 비율로 조절한다. 기본값은 2 10 60으로 되어 있다. 여기서 실제 사용하는 값은 제일 앞의 한 개만 사용하며 전체 메모리에서 버퍼로 사용할 수 있는 최소량을 %로 나타낸다.
vm.buffermem = 2 10 60
위에서 말을 한 대로 가상 메모리와 관련한 설정은 시스템의 성능에 큰 영향을 미치지만 잘못 바꾸었을 경우에는 아예 시스템이 멎어버리는 현상이 생길 수가 있다. 테스팅 서버에서 조금씩 값을 바꾸어가면서 자신에게 맞는 설정을 찾아야 할 듯하다. 절대 현재 서비스되고 있는 시스템에서 테스팅을 하지는 말자.
ㅇ 스와핑 조절 : 가상 메모리와 관련된 설정 중 시스템의 성능과 연관이 깊은 것으로는 freepages(vm.freepages)가 있다. freepages는 커널에서 스와핑을 언제 어떻게 할지에 대한 동작을 제어한다. 첫 번째 값은 min으로 free pages가 이 숫자 이하로 넘어갈 때만 커널에서 더 많은 메모리를 할당한다. 두 번째 값은 low로 free pages가 이 숫자 이하로 넘어갈 때 커널에서 스와핑을 시작한다. 세 번째 값은 high로 시스템에서 스와핑을 원활하게 하기 시작하기 위해서 최소한 가지고 있어야 할 free 메모리 페이지를 지정한다. 그러므로 항상 시스템에서 여기에 해당하는 페이지를 free로 가지고 있으려 한다. 아래는 기본 설정값이다.
vm.freepages = 383 766 1149
ㅇ 열 수 있는 파일 핸들 조정 : file-max는 리눅스 커널에서 할당할 수 있는 최대 파일 핸들을 지정한다. “running out of file handles” 라는 에러 메시지가 나오는 경우에는 적절히 늘려주어야 한다. 이는 파일 오픈이 많은 사이트에서 나타나는 현상이다. 웹호스팅 업체의 경우 웹로그파일, 메일서버 관련파일 등을 제대로 관리하지 않으면 이런 경우가 생긴다. 불필요한 파일을 없애고 로그파일을 통합하여 처리한 후 이후에 별도로 도메인별로 분리하는 방법을 생각해 볼 수 있다. 4M당 256개의 파일을 할당해주면 된다. 메모리에 맞추어 설정해주면 된다.
fs.file-max = 8192
/proc/sys/fs에서 file-nr을 보면 현재 할당되어 있는 파일 개수를 알 수 있다.
# cat /proc/sys/fs/file-nr
696 158 32768
첫 번째 숫자는 현재 할당된 파일핸들, 두 번째 숫자는 그중 사용된 파일핸들이고 제일 뒤의 숫자는 파일핸들의 최대 숫자이다. 위에서 지정한 file-max 값이다.
시스템에서 현재 할당되어 있는 inode 개수는 inode-state 나 inode-nr의 제일 앞의 숫자를 보면 된다.
# cat /proc/sys/fs/inode-state
3457 6 0 0 0 0 0
ㅇ 프로세스 개수와 파일 개수 조정 : ulimit -a를 이용하여 사용자별 프로세스 숫자와 열수 있는 파일 개수를 제한할 수 있다. 커널 2.2에서는 동시에 생성 가능한 프로세스 수에 대한 제한이 있었는데 커널 2.4로 넘어오면서 이에 대한 제한이 없어졌다. (task.h에서 지정했는데 커널 2.4에는 파일이 없어졌다) 이제 유일한 제약은 메모리 한계이며 많은 수의 프로세스를 지원하기 위해 스케쥴러도 향상이 되었다. max user processes는 16383이며 open files는 1024이다. 슈퍼유저인 root에게는 max user processes 제한을 ulimit -n unlimited 라는 명령을 통하여 없앤다. 이후에도 계속 적용을 하려면 .bashrc 등에 지정을 하면 된다.
# ulimit -a
core file size (blocks) 0
data seg size (kbytes) unlimited
file size (blocks) unlimited
max memory size (kbytes) unlimited
stack size (kbytes) 8192
cpu time (seconds) unlimited
max user processes 16383
pipe size (512 bytes) 8
open files 1024
virtual memory (kbytes) 2105343
그런데 자원 한도를 변경한다고 하더라도 사용자가 소프트 한도를 변경할 수 있다. 또한 위의 모든 제한은 프로세스별로 되어 있는데 실제 작업은 여러개의 프로세스로 구성이 되어 있다. 그렇지만 코어 파일 크기의 한도를 제한하는 것은 유용한 일이다. 이를 보완할 수 있는 것이 PAM(Pluggable Authentication Module)을 이용한 limit.conf 파일의 활용이다. /etc/security 디렉토리에 있다. 이 파일을 이용하여 로그인한 사용자의 시스템 자원을 제한할 수 있다.
먼저 /etc/pam./login 파일에 아래 내용이 없으면 추가한다. limit.conf를 사용할 수 있도록 설정하는 것이다.
session required /lib/security/pam_limits.so
이제 /etc/security/limit.conf 파일을 필요에 따라 수정한다. 간단한 예를 들어 설명해보겠다.
* hard core 0
* hard rss 5000
* hard nproc 20
* hard cpu 5
* hard data 10000
코어 파일은 생성하지 못하고 최대 resident set size는 5M로, 프로세스는 최대 20개로 제한을 하였고 CPU 선점 시간은 최대 5분이며 최대 데이터는 10M이다. 계정을 가진 사용자가 아무런 제한없이 접속하여 메모리를 엄청나게 잡아먹는 프로그램을 만들었다고 해보자. (**주2)
$ cat memdown.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *memory;
int size=1024;
int m=0;
int i=0;
while(1)
{
for(i=0;i<1024;i++)
{
memory = (char *)malloc(size);
if(memory == NULL) exit(-1);
sprintf(memory, "메모리를 사랑해~\n");
}
m++;
printf("현재 %d M 소비\n",m);
}
exit(0);
}
$ gcc -o memdown memdown.c
그러면 memdown을 실행해보자. 절대 서버에서는 하지 말기 바란다.
아무런 제한이 없는 경우에는 메모리가 부족한 시스템에서는 현재 있는 메모리를 모두 잡아먹고 나중에는 스왑까지 전부 소비할 수가 있다. 이렇게 메모리 고갈, 프로세스 고갈 등을 막는데 유용하다.
여기서 제한을 걸 수 있는 사항은 다음과 같다.
- core : 코어파일 크기(KB)
- data : 최대 데이터 크기(KB)
- fsize : 최대 파일크기(KB)
- memlock - 최대 메모리잠김(locked-in-memory) 주소 공간(KB)
- nofile : 최대 열수 있는 파일수
- rss : 최대 상주셋(resident set) 크기(KB)
- stack : 최대 스택 크기(KB)
- cpu : 최대 CPU 시간(MIN)
- nproc : 최대 프로세스 개수
- as - 주소 공간 제한
- maxlogins - 최대 로그인 숫자
- priority - 사용자 프로세스 실행 우선순위
위에서 보았던 간단한 프로그램은 “username hard data 10000” 이렇게 간단한 한줄로 충분히 막을 수 있다. 다시 위의 프로그램을 실행해보면 9M까지 메모리를 사용한후 멈춘다.
$ ./memdown
현재 1 M 소비
현재 2 M 소비
현재 3 M 소비
현재 4 M 소비
현재 5 M 소비
현재 6 M 소비
현재 7 M 소비
현재 8 M 소비
현재 9 M 소비
maxlogin은 웹호스팅 업체에서 사용자들의 접속을 제한하는데 유용하다. 계정을 주고 몇십명이서 접속을 하도록 내버려두어서는 안되기 때문이다.
ㅇ 프로세스당 열 수 있는 파일 개수 : 위에서 설정을 바꾼다고 하더라도 프로세스당 열 수 있는 파일 개수는 1024로 되어 있다. 이를 수정하려면 커널 소스를 고쳐야하는데 커널 소스 디렉토리의 include/linux 디렉토리로 이동하여 fs.h 와 limits.h를 수정하면 된다. fs.h에서는 INR_OEPN 과 NR_OEPN을 원하는 수치로 조정하고 새로 컴파일을 하면 된다. 그런데 시스템에서 동시에 열 수 있는 파일수 이상으로 이 수치를 높이는 것은 불필요한 일이다. 그리고 굳이 수정하지 않더라도 일반적인 환경에서 하나의 프로세스가 1024개 이상의 파일을 여는 일은 드물다고 생각이 된다.
4. 마치며
지금까지 운영체제와 커널 차원에서 해 줄 수 있는 최적화 및 보안에 대해서 다루었다. 그러나 무조건 수치를 크게 한다고 좋은 것은 아니다. 불필요한 자원을 낭비할 가능성도 생기며 커널 차원에서 수치를 조정한다면 내부 매커니즘에 대해여 그만큼 이해를 하고 있어야 불행한 일이 발생하지 않을 것이다. 그리고 운영체제와 커널에서의 최적화는 일반적인 상황에서 필요하다기보다는 다른 부분에서의 최적화를 진행하고나서 진행할 부분이지 무조건 처음부터 최적화를 할 부분은 아니라고 생각이 든다. 예를 들어 웹서버가 폭주하고 있을 경우 먼저 해야 할 일은 좀더 효율적으로 웹서비스를 개선하고 불필요한 DB쿼리를 줄여 시스템의 부하를 줄이는 일이 우선이다. 동시접속자수가 무조건 늘어난다고 좋은 것이 아니라 그만큼 처리시간을 빠르게 하여 동시접속자를 더 줄이는 것이 올바른 방법이다. 또한 운영체제 차원에서의 최적화라는게 그렇게 쉽게 차이가 느껴지기는 힘든 부분이고 최근에 와서 하드웨어의 급격한 발전으로 그 필요성은 그만큼 줄어든다고 할 수 있다. 그러나 물론 개발자든 시스템 엔지니어든 운영체제의 내부 구조에 대해 이해가 깊을수록 업무에 도움이 되는 것은 분명한 사실이다.
6. 시스템 엔지니어로 발전하기 위하여...
시스템 모니터링부터 시작하여 로그파일처리, 모니터링 자동화, 운영체제의 설치 및 보안, 커널과 운영체제 차원에서의 튜닝에 대하여 살펴보았다. 짧은 글안에 많은 내용을 담다보니 이해하기에 좀 부담스럽지 않은가 고민도 되지만 나름대로 필요한 내용을 정리하기 위해 노력을 하였다.
정보통신관련 분야가 엄청나게 발전을 하면서 시스템 엔지니어도 많이 필요하게 되었지만 개인적인 생각으로는 아직까지 국내에서 개발에 시간과 자금과 인력을 투입하는 만큼 시스템 운영 및 관리에는 투자를 하지 않는 것 같다. 이것은 어느 정도 규모가 있는 사이트를 가도 마찬가지라는 생각이 든다. 위 글에서도 나타나듯이 시스템 엔지니어는 여러 가지 분야에 대해 고른 지식을 필요로 한다. 단순하게 웹서버 세팅을 할 줄 안다고 시스템 엔지니어라고 할 수는 없을 것이다. 운영체제, 하드웨어, TCP-IP 네트웍, 여러 가지 인터넷 서비스, 보안 등. 그렇다고 하루아침에 이 모든 것에 대한 지식을 가질 수 있는 것은 아니지만 끊임없은 재투자와 교육이 필요하다고 생각이 된다. 또한 단순하게 서비스만 잘 되고 있으면 모든 것이 다 된 것처럼 생각하는 것도 바뀌어야 할 것이다. 처음에 언급을 했듯이 무엇이든 단순하게 어떻게 세팅을 한다를 아는게 아니라 내부 원리에 대한 이해가 있어야 발전을 할 수 있다. 그런 면에서 운영체제와 네트웍에 대한 지식은 가장 기본이 되지 않을까 생각한다. 물론 필자도 이에 대해서 끊임없이 관심을 가지고 노력을 하려고 한다.
본문에서 이야기했던 내용에 대한 관련자료와 참고서적을 함께 첨부하였으니 본 내용을 기반으로 해서 더 심도깊게 나아가는데 도움이 되었으면 좋겠다. 여기 정리한 내용은 필자의 사이트에 관련내용이 있는 것이 많으므로 참고가 되기를 바란다. 마지막으로 항상 낮이나 밤이나 컴퓨터만 붙들고 있지 말고 가끔은 영화도 보고 철학책 한권 읽을 수 있는 마음의 여유를 가지고 살았으면 한다.
## 전체 참고자료 및 서적
System Performance Tunning (O'REILLY 출판사, 영문판)
시스템 관리의 핵심 (한빛미디어,, 장훈역)
Securing and Optimizing Linux : Redhat Editioin (http://www.ibiblio.org/mdw/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/index.html)
리눅스 커널 옵션 문서 : 커널 소스 디렉토리/Documentation/filesystems/proc.txt
인터넷 프로토콜 핵심 가이드(한빛 미디어, 정중기 역)
W.Richard Stevens, TCP/IP Illustrated Volume I, Addison-Wesley
웹 성능 최적화 (한빛미디어, 권원상 역)
TCP/IP 네트워크 관리 (한빛미디어, 박창민 역)
UNIX의 내부 구조(홍릉과학출판사, 조유근 역편)
각장 밑의 내용은 참고 자료이며 1), 2)는 주석을 나타낸다.
1장
월간 프로그램 세계 2001년 3월-7월 최고의 시스템 관리자가 되자
1) UNIX의 내부 구조 (홍릉과학출판사 조유근 역편) 제3장 버퍼 캐쉬 참고
2) accounting 강좌(문태준) - http://tunelinux.pe.kr/bbs/read.php?table=linuxinfo&no=16
3) 본 강좌의 4장을 참고한다
4) Oracle Administrator's Reference for Linux Release 8.0.5 (오라클) 3장 Tunning Oralce 8 on Linux 참고
5) 웹 성능 최적화 (한빛미디어, 권원상 역) 13장 네트워크 프로토콜 참고
6) Mysql 영문 매뉴얼 13장 Getting Maximum Performance from MySQL 참고
7) 월간프로그램세계 2001년 4월호 스토리지 대역폭 향상시키는 어댑터 강좌 참고
월간프로그램세계 1999년 5월호 Surrounding UNIX 특집 기사 참고
8) 월간 Linux@Work 2000년 7월 시스템 안정성 200% 끌어올리기 -reiserfs 강좌
9) TCP/IP 네트워크 관리(한빛미디어, 박창민 역) 11장 TCP/IP 문제점 진단과 해결 참고
2장
1) security.kaist 강좌 - 시스템의 로그 관리 및 분석법
http://mgt.kaist.ac.kr/~sakai/Docs/Security_document/Part3.html
한국정보보호진흥원 기술문서 - 유닉스 로그분석을 통한 침입자추적 및 로그관리 Part1
http://www.certcc.or.kr/paper/tr2001/tr2001-05/unix_log_analysis.pdf
한국정보보호진흥원 기술문서 - UNIX 피해 시스템 분석 및 침입자 모니터링 : Part I v1.0
http://www.certcc.or.kr/paper/tr2001/tr2001-03/Scene-of-the-Crime.pdf
2) Accounting 관련내용
http://mgt.kaist.ac.kr/~sakai/Docs/Security_document/Part5.html
accounting 강좌(문태준) - http://tunelinux.pe.kr/bbs/read.php?table=linuxinfo&no=16
3) 로그 필터링 자동화하기 강좌 번역판(문태준) : swatch 사용방법 참고
http://tunelinux.pe.kr/bbs/read.php?table=security&no=32
원출처 http://www.enteract.com/~lspitz/swatch.html
4) rsync 강좌 (문태준)
http://tunelinux.pe.kr/bbs/read.php?table=linuxinfo&no=30&o[at]=s&o[sc]=t&o[ss]=rsync&o[st]=a
3장
월간 Linux@Work 2001년 6월-7월 NET-SNMP 연재글(노정민님)
월간 프로그램 세계 1999년 8월-2000년 1월 네트워크 정복의 첫걸음(노정민님)
William Stallings, SNMP, SNMPv2, SNMPv3 and RMON, RMON2 Addison-Wesley
David Perkins, Evan Mcginnis, Understanding SNMP MIBs, Prentice Hall
W.Richard Stevens, TCP/IP Illustrated Volume I, Addison-Wesley
노정민, About Network 구축과 활용, 영진.com
http://net-snmp.sourceforge.net
http://www.ieft.org/rfc
http://www.simple-times.org
http://www.mrtg.co.kr
http://www.opennms.org
MRTG 설치 및 사용법
http://tunelinux.pe.kr/bbs/read.php?table=linuxinfo&no=18&o[at]=s&o[sc]=t&o[ss]=MRTG&o[st]=a
1) 인터넷 프로토콜 핵심 가이드(한빛 미디어, 정중기 역) - 7장 전송 제어 프로토콜 참고
4장
월간 프로그램 세계 2001년 3월호 100% 해킹방지 서버 보안 올가이드
월간 Linux@Work 2000년 12월호 리눅스로 꾸미는 보안 안전지대
한국정보보호진흥원 - 리눅스 시스템 관리자를 위한 보안 지침Ⅰ
http://www.certcc.or.kr/paper/tr2001/tr2001-03/guide%20for%20Linux%20system%20admin.html
1)국내에서는 한국정보보호진흥원에서 운영하는 보안 메일링리스트가 가장 활발하게 보인다. LinuxSecurity.com에서도 매주 리눅스 등의 보안 버그 패치 소식과 보안 관련 다양한 정보를 보내준다. 이외에도 다양한 곳에서 메일링리스트를 운영하니 보안관련 사이트에서 참고하기 바란다.
2) 리눅스 시스템 보호하기 번역판(문태준)
http://tunelinux.pe.kr/bbs/read.php?table=security&no=25&page=1
원출처 http://www.enteract.com/~lspitz/linux.html
3) 리눅스 가상 서버 프로젝트 홈페이지를 참고한다. http://www.linuxvirtualserver.org/
리눅스 가상 서버 프로젝트는 리눅스에서 가용성을 높이고 대규모의 서비스를 하기 위한 클러스터링을 연구하는 프로젝트로 현재 리눅스 기반의 상용 클러스터링 소프트웨어가 주로 이에 많이 기반하고 있다. 주요한 내용은 본 필자가 번역한 자료가 있는데 http://tunelinux.pe.kr/virtual/ 에서 볼 수 있다. 최근 국내에서는 http://linux.clusterkorea.org/ 사이트에서 서버 클러스터링 및 병렬 클러스터링에 대해서 활발하게 논의를 진행하고 있다.
5장.
<TCP-IP>
Building blocks of Linux packet filtering in the 2.2 kernel
http://industrial-linux.org/mlug/2000-11-11/
UNIX IP Stack Tuning Guide
http://www.cymru.com/~robt/Docs/Articles/ip-stack-tuning.html
월간 프로그램 세계 2001년 7월호 TCP SYN_Flooding 공격의 원인과 해결책
<리눅스 커널 관련 국내 웹사이트 >
http://linuxkernel.to/
http://kernelkorea.org/
http://kernel.pe.kr/ (The Linux Kernel 이라는 문서의 번역본이 있음)
<최적화>
Tuning Linux For Maximum Performance
http://www.byte.com/documents/s=429/BYT20000829S0006/index.htm
Linux In The Big League
http://www.byte.com/documents/s=501/BYT20001129S0001/
월간 프로그램 세계 1999년 7월 아파치 서버와 웹 서비스 성능 최적화
월간 프로그램 세계 2001년 5월 유닉스로 하는 고성능 인터넷 서버 프로그래밍
1)네트워크 스니핑 기술 및 방지대책
http://www.certcc.or.kr/paper/tr2000/2000-07/tr2000-07.htm
2) 이국현님(errai@hitel.net) 의 “리눅스, 최소한의 보안”이라는 강좌에서 쓰였던 간단한 소스
'학습자료(~2017) > 리눅스' 카테고리의 다른 글
[리눅스] [/etc/rc.d/init.d/*] 데몬 실행 스크립트의 이해 - 펌 (0) | 2012.03.21 |
---|---|
[리눅스] 리눅스 프로그래머를 위한 가이드 (1) | 2012.03.19 |
[리눅스] 블록 디바이스 장치별 UUID 알아내는 법 , fstab UUID로 관리법(링크) (0) | 2012.03.15 |
[리눅스] 32bit 에서 64bit 로 소스 호환을 위한 고려사항 (0) | 2012.03.13 |
[리눅스] Linux Direct IO의 이해 (Synchronous IO와의 차이를 기반으로) - 펌 (0) | 2012.03.13 |