[Linux] Logrotate를 이용하여 로그 관리하기

들어가기에 앞서

로그란?

  • 커널, 서비스, 애플리케이션 등 시스템에 발생한 이벤트를 분류하여 기록한 파일이다.
  • 시스템에 특정 이벤트에 대한 기록이 있으면 해당 이슈가 발생한 시기와 이유를 확인할 수 있다.

로그의 필요성

운영적인 측면

  • 시스템에 장애가 발생했을 경우, 장애를 해결하기 위해 로그를 확인해야 한다.
  • 시스템의 성능을 개선하는 용도로도 사용 할 수 있다.

보안적인 관점

  • 사용자의 허가되지 않은 접근 시도에 대한 추적과 감사를 수행할 수 있다.
  • 침해사고 발생 시 침해사고의 원인과 침입경로, 피해상황 등을 파악할 수 있는 중요한 단서가 된다.

로그 관리 데몬

  • 리눅스 시스템이 init프로세스에서 systemd로 바뀌면서 로그와 관련된 데몬도 syslog에서 rsyslog에 의해서 처리되도록 변경되었다. (성능과 보안성이 향상되었음)
  • 최신 버전 리눅스에서는 systemd가 사용되면서 rsyslog에 systemd-journal이 추가되었다.
    • systemd-journal은 시스템에서 발생되는 모든 로그를 기록하며, 로그를 텍스트 형태로 저장하지 않고 바이너리 파일 형태로 저장한다.
  • System Event ➟ systemd-journald ➟ rsyslogd ➟ Log files
    • systemd 시스템에서 로그는 rsyslogd와 systemd-journald 두 데몬에 의해서 관리된다.
    • 시스템에서 이벤트가 발생하면 모두 systemd-journald로 전달된다.
    • systemd-journald는 부팅이 시작되는 순간부터 로그를 수집한다.
    • 이후, rsyslogd로 syslog를 전달하여 각 파일 별로 로그를 저장한다.

로그 파일 위치

  • 로그를 수집하는 데몬에 따라서 로그가 저장되는 위치가 다르다.
  1. Kernel Log Message, Syslog Message, Service Message ➟ systemd-journald로 전달
  2. 이후 systemd-journald 데몬은 /run/log/journal 디렉토리에 모든 로그를 저장한 파일인 저널(journal) 데이터 파일 생성하고, 저장한 로그 중에서 syslog 형태의 로그를 rsyslogd로 전달
  3. rsyslogd에 의해 수집되는 로그는 /var/log 디렉토리에 각 syslog에 해당하는 로그 파일들을 생성하고 저장

rsyslogd에 의해서 수집되는 로그의 파일 위치

  • rsyslogd에 의해 수집되는 로그는 보통 syslog라고 부른다.
  • rsyslogd는 /etc/rsyslog.conf를 참고하여 /var/log 디렉토리에 로그 종류별로 각각 텍스트파일로 저장한다.
  • 아래는 rsyslogd에 의해 처리되는 로그의 파일 위치이다.
    • /var/log/messages: 대부분의 로그 기록(인증, 메일, cron, 부팅, 디버깅과 관련된 로그 제외)
    • /var/log/secure: 인증과 관련된 로그 기록
    • /var/log/maillog: 메일과 관련된 로그 기록
    • /var/log/cron: 주기적인 작업과 관련된 로그 기록
    • /var/log/boot.log: 부팅 과정에서 발생한 로그 기록

systemd-journald에 의해서 처리되는 저널(journal) 데이터 파일 위치

  • systemd-journald에 의해 수집되는 로그를 저널 데이터라고 부른다.
  • 저널 데이터는 /run/log/journal 디렉토리에 바이너리 파일 형태로 저장된다.
  • 저널 데이터 파일이 저장되는 /run 디렉토리는 메모리 기반파일시스템인 tmpfs로 마운트 되어 있으므로 시스템 재부팅시 저널 데이터 파일은 삭제된다.

Logrotate

  • 지정된 로그 파일에 계속해서 로그를 쌓게 되면 로그 파일의 크기가 과도하게 커질 수 있다. 이럴 경우 로그 파일을 읽어오기 위해 보다 많은 메모리가 필요할 뿐 아니라 로그를 확인하고 분석하는 것도 어려워진다. 따라서 로그 파일의 크기가 커지지 않도록 제한할 필요가 있다.
  • 로그 파일이 생성된 후 일정 기간이 지나거나 로그 파일의 크기가 일정 크기게 도달할 경우 로그 파일을 백업하고, 새롭게 로그 파일을 생성하여 새롭게 로그를 저장하도록 해야한다. 또한 백업된 파일도 일정 기간이 지나거나 개수가 많아질 경우 삭제하도록 설정해야 한다. 이 과정을 로그 파일의 순환(Logrotate)라고 한다.

로그 파일의 순환 과정

  • 'logrotate'라는 유틸리티를 사용하여 이루어진다. 이 유틸리티는 사용자가 수동으로 실행하는 것이 아니라 cron 작업에 의해 하루에 한 번씩 실행하도록 등록되어 있다.
  • logrotate가 실행될 때 로그 파일의 크기가 너무 크거나 혹은 일정 기간이 지나면 현재 로그 파일 이름 뒤에 날짜가 추가 되고, 날짜가 추가되기 전의 파일 이름으로 된 새로운 빈 파일이 생성된다.

Logrotate 설정 과정

  • /etc/logrotate.conf 파일을 사용하여 설정한다. 이 파일의 내용은 아래와 같다.
    [1] 로그 파일을 순환 시킬 기간에 대한 설정(daily, weekly, monthly, yearly)
    [2] 순환된 로그 파일을 보관할 기간에 대한 설정([1]에서 설정한 기간 단위 사용)
    [3] 로그 파일 순환 후 새로운 로그 파일 생성
    [4] 순환된 파일의 파일명 변경 옵션(YYYYMMDD)
    [5] 순환된 파일을 압축하여 보관하는 옵션
    [6] 로그 순환에 대한 추가 설정 파일이 저장된 디렉토리
    [7] 사용자의 로그인/로그아웃 정보를 저장하는 wtmp 로그 파일의 순환 설정
    [8] 로그인 실패 기록을 저장하는 btmp 로그 파일의 순환 설정
  • 이 설정 파일에는 wtmp, btmp 로그 파일에 대한 설정만 포함되어 있고 기타 로그 파일에 대한 설정은 [6]번에 포함되어 있다.
  • [6]번 항목이 지정하는 디렉토리에는 logrotate에 의해 순환되는 파일들의 추가 설정 파일이 저장된다. 이 파일들은 logrotate.conf 파일의 전역 설정이 적용되고, 각 설정 파일에서 순환시킬 로그 파일의 경로와 각 로그에 해당하는 개별 설정을 적용한다.
  • 만약 전역 설정과 개별 설정이 서로 다른 설정 값을 저장할 경우, 전역 설정 대신 개별 설정이 적용된다.

실습

로그 데이터 순환 및 S3 백업

목표

  • 매일 자정에 Nginx와 wtmp 로그를 순환시키고, 어제 날짜로 새로 생성된 로그 파일을 지정된 S3 버킷에 백업하기

전제 조건

  • 사용 환경: AWS
  • EC2(Amazon Linux2), S3 버킷 준비, IAM 권한 확인
  • nginx 설치
    sudo yum update -y
    amazon-linux-extras list | grep nginx
    sudo amazon-linux-extras install -y nginx1 -y
    nginx -v
    sudo service nginx start
    service nginx status

EC2 리눅스 서버 시간대 변경(linux 2 AMI)

  • 설정상 편의를 위해 관리자 권한으로 변경
    $ sudo su

  • 서버 시간대를 서울 기준으로 변경(ZONE="Asia/Seoul")
    # vi /etc/sysconfig/clock

  • 인스턴스가 현지 시간 정보를 참조할 때 표준 시간대 파일을 찾을 수 있도록 /etc/localtime과 표준 시간대 파일 사이에 심볼 링크 생성
    # ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

  • AWS 콘솔에서 인스턴스 재부팅

AWS configure 설정

  • AWS 액세스 키가 없을 경우 생성 (참고)

    • AWS CLI 사용을 위해 필요한 절차
  • 로컬에 다운로드 받은 액세스 키 파일을 열고, 터미널에서 aws configure 설정 (참고)

    • Secret Access Key는 타인에게 노출되지 않아야 함

/nginx.conf에서 user를 nginx에서 root로 변경

  • $ sudo su
  • 위치: vi /etc/nginx/nginx.conf
    • 미변경시 /var/log/nginx/error.log에 13: Permission denied 로그가 찍힘
  • service nginx restart

Logrotate 프로세스 설정 파일 설정(NGINX)

  • vi /etc/logrotate.d/nginx
# vi /etc/logrotate.d/nginx

/var/log/nginx/*log {
    daily // 일 단위로 rotate 진행
    rotate 10 // 로그 파일을 10개만 저장하고 나머지는 삭제
    missingok // 로그 파일이 발견되지 않을 경우 에러처리 하지 않음
    create 0640 root root // 로그 파일 생성시 0644 권한, root 사용자, root 그룹으로 생성
    notifempty // 로그 내용이 없어도 rotate 진행
    dateext // 백업 파일명에 날짜가 기입되도록 함
    dateyesterday // 백업 파일명의 날짜를 어제 날짜로 지정
    dateformat -%Y%m%d // date형식 지정(YYYYMMDD 형식이 아닌 다른 형식으로 사용시 지정)
    sharedscripts // 로그 파일이 여러 개 있어도 스크립트를 공유하여 postrotate 스크립트를 한 번만 실행
    postrotate // rotate 실행 후 스크립트 파일 실행
        YESTERDAY=$(date -d yesterday '+%Y%m%d')
        LOGFILE="/var/log/nginx/access.log-${YESTERDAY}"
        ##
        echo "${LOGFILE}"
        echo "${YESTERDAY}"
        ##
        if [ -f ${LOGFILE} ]; then
                sudo /usr/bin/aws s3 cp ${LOGFILE} s3://{버킷명}/${YESTERDAY}/access-${YESTERDAY}.log
                echo "${LOGFILE} 파일이 s3에 복사되었습니다."
        else
                echo "${LOGFILE} 파일이 존재하지 않습니다."
        fi
        ##
        /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
    endscript
}

Logrotate 프로세스 설정 파일 설정(WTMP)

  • wtmp: 사용자들의 로그인, 로그아웃 정보와 시스템 관련 정보를 기록하는 로그
  • wtmp 로그는 last 명령어를 사용하여 확인
  • vi /etc/logrotate.conf
# vi /etc/logrotate.conf

# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
dateext

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp {
    daily
    dateext
    dateyesterday
    create 0664 root utmp
    rotate 10
    missingok
    notifempty
    #compress
    prerotate
        sudo rm -rf /var/log/wtmp-*.log
        sleep 1
        sudo last -f /var/log/wtmp >> /var/log/wtmp-$(date -d yesterday '+%Y%m%d').log
    endscript
    postrotate
        YESTERDAY=$(date -d yesterday '+%Y%m%d')
        LOGFILE="/var/log/wtmp-${YESTERDAY}.log"
        ##
        echo "${LOGFILE}"
        echo "${YESTERDAY}"
        ##
        if [ -f ${LOGFILE} ]; then
                sudo /usr/bin/aws s3 cp ${LOGFILE} s3://{버킷명}/${YESTERDAY}/wtmp-${YESTERDAY}.log
                echo "${LOGFILE} 파일이 s3에 복사되었습니다."
        else
                echo "${LOGFILE} 파일이 존재하지 않습니다."
        fi
    endscript
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

# system-specific logs may be also be configured here.

매일 자정(00:00)에 로그가 순환 되도록 설정

  • /etc/cron.daily의 기본 값은 이른 아침 시간에 적용 되는 것으로 보임

  • 매일 자정마다 하루치 로그가 적재되도록 관리할 것이므로, /etc/cron.daily/에 있는 logrotate를 임의 위치(나의 경우 /usr/logrotate/)에 디렉토리 생성 후 이동
    mkdir -p /usr/logrotate/
    mv /etc/cron.daily/logrotate /usr/logrotate/

  • vi /etc/crontab 아래 내용 작성하여 내가 정한 시간에 순환 되도록 적용
    0 0 * * * root /usr/logrotate/logrotate

테스트

logrotate 강제 실행

  • logrotate -f /etc/logrotate.conf

logrotate 실행 모드

-f 강제 실행
-d 디버그 모드 (실제로 실행 되진 않음)
-v 실행과정 화면에 표시

결과

참고

좋은 웹페이지 즐겨찾기