Percona MongoDB - Audit 설정 및 Log Rotate - 감사 기능

Share

Last Updated on 4월 13, 2024 by Jade(정현호)

안녕하세요 

이번 글은 Percona Server for MongoDB를 통해서 감사 기능인 Audit 기능 활성화 및 Log Rotate에 대해서 확인해보도록 하겠습니다.

PSM Auditing

Percona Server for MongoDB는 MongoDB Community 버전을 포크(fork) 하여 만든 MongoDB로 Percona 사에서 MongoDB Community에서 새로운 기능을 추가하여 배포하는 포크 버전 MongoDB 입니다.

MongoDB Community 버전에서 Auditing 기능을 사용하기 위해서는 MongoDB Enterprise(사용)해야 하기 때문에 Community 버전을 포크하여 Audit 기능을 포함한 Percona Server for MongoDB를 사용하여 Audit 기능을 사용하였습니다.

Percona Server for MongoDB는 Auditing 외에 MongoDB Enterprise에서만 사용할 수 있는 다른 여러 기능도 포함하고 있는 포크 버전의 MongoDB 입니다.

글에서는 Percona Server for MongoDB 7.0 버전을 사용하였습니다.

Percona Server for MongoDB(이하 PSM)에서 Auditing 을 활성화하기 위해서 mongod.conf 나 mongod를 통해 인스턴스 시작시 파라미터를 지정해서 DB 인스턴스를 시작해야 합니다.


• mongod 커맨드라인으로 시작시 예시

$ mongod \
 --dbpath /data/db
 --auditDestination file \
 --auditFormat JSON \
 --auditPath /var/log/psmdb/audit.json \
 --auditFilter '{ "users.user" : "tim" }'


• mongod.conf 파일에 파라미터 설정

auditLog:
  destination: file
  format: JSON
  path: /var/log/psmdb/audit.json
  filter: '{ "users.user" : "tim" }'

                

Audit 파라미터

Auditing를 사용하기 위해서 필요 또는 가능한 파라미터는 다음과 같습니다.

Command line Configuration file Description
--auditDestination auditLog.destination 감사를 활성화하고 감사 이벤트를 보낼 위치를 지정합니다.
- console: audit event를 stout 으로 출력합니다.
- file: audit event를 destination 과 auditformat에 따라서 file에 기록합니다.
- syslog: audit event 를 syslog 에 기록합니다.
--auditFilter auditLog.filter 기록될 Audit Event에 대해서 필터를 지정하여 원하는 Audit Event만 기록할 수 있도록 합니다.
설정하지 않으면 모든 Event가 기록됩니다.
Syntax: { <field1>: <expression1>, ... }
--auditFormat auditLog.format audit log 파일을 저장할 유형을 설정하며, JSON 또는 BSON 둘 중에서 선택하며 기본값은 JSON입니다.
--auditPath auditLog.path 설정한 경로와 파일명으로 Audit Event를 기록합니다.
파라미터를 설정하지 않으면 MongoDB 서버의 log 파일 경로에 "auditLog.json' 파일명으로 생성 합니다.

                       

Audit message syntax

Auditing 활성화후에 기록되는 audit 파일의 내용은 8개 항목으로 기록됩니다.

{
  atype: <String>,
  ts : { "$date": <timestamp> },
  local: { ip: <String>, port: <int> },
  remote: { ip: <String>, port: <int> },
  users : [ { user: <String>, db: <String> }, ... ],
  roles: [ { role: <String>, db: <String> }, ... ],
  param: <document>,
  result: <int>
}


각 항목이 의미하는 내용은 다음과 같습니다.

Parameter Description
atype Event의 type
ts Event의 UTC 시간대의 date 정보
local 인스턴스의 로컬 IP 주소 및 포트 번호
remote 인스턴스에 연결된 원격(Source) IP 주소 및 포트 번호
users 유저명
role 사용자에게 부여된 역할
param 특정 유형과 관련된 이벤트의 세부정보
result Exit code(0 for success)


Audit 로그는 8가지 항목에 대해서 분류해서 기록하며, Audit Filter 정책을 설정할 때도 8개 항목에 대해서 설정할 수 있습니다.
            

Audit Filter

audit filter 기능을 통해서 원하는 로그만(또는 특정 내용은 남기지 않는) 설정을 할 수 있습니다. 몇 가지 예시를 살펴보도록 하겠습니다.

filter는 { <field1>: <expression1>, ... } 으로 설정합니다.


• 특정 유저만 기록

다음은 tim 이라는 유저만 event가 기록되도록 하는 설정합니다.

auditLog:
  ..
  ..
  filter: '{ "users.user" : "tim" }'

Audit message syntax에서 확인할 수 있는 내용처럼 users 에는 항목에는 user와 db 정보가 기록됩니다.
users : [ { user: <String>, db: <String> }, ... ]
그래서 위에서 filter 설정 시 users 항목의 user 를 지정하기 위해서 "users.user" 라고 filed명을 지정한 것입니다.


• 특정 이벤트만 기록
다음의 예제에서는 dropCollection 과 dropDatabase event만 기록하도록 설정한 것입니다.
MongoDB에서 사용할 수 있는 query selectors를 사용해서 filter 를 설정할 수 있습니다.
$eq, $in, $gt, $lt, $ne 등과 같은 query selectors를 사용하여 여러 이벤트 유형을 기록할 수 있습니다.

auditLog:
  destination: file
  filter: '{ atype: { $in: [ "dropCollection", "dropDatabase" ] } }'


event는 다음과 같은 종류가 있습니다.

"authenticate", "authCheck",
"renameCollection", "dropCollection", "dropDatabase",
"createUser", "dropUser", 
"dropAllUsersFromDatabase", "updateUser",
"grantRolesToUser", "revokeRolesFromUser", 
"createRole", "updateRole",
"dropRole", "dropAllRolesFromDatabase", 
"grantRolesToRole", "revokeRolesFromRole",
"grantPrivilegesToRole", "revokePrivilegesFromRole",
"replSetReconfig","enableSharding", "shardCollection", 
"addShard", "removeShard",
"shutdown","applicationMessage"


• 여러 항목을 지정
Filter는 1개 이상 여러 개의 항목을 지정하여 할 수 있습니다.
다음은 remote ip(source ip)가 127.0.0.1 인 즉, Local에서 접속한 세션과 IP 192.168.56.5에서 접속한 세션 중에서 유저명이 tim 인 세션에 대해서만 Event를 기록하도록 Filter를 설정하는 예시입니다.

auditLog: 
  destination: file 
  filter: '{"remote.ip" :{ $in: ["192.168.56.5","127.0.0.1"]},"users.user" : "tim"}'

 

위의 예제와 같이 여러 항목을 동시에 지정하면서 항목 별로 query selectors 를 활용하여 원하는 내용의 Event만 기록되도록 정책을 설정할 수 있습니다.
              

auditAuthorizationSuccess

auditAuthorizationSuccess는 setParameter 에서 설정 가능한 파라미터입니다.

auditAuthorizationSuccess는 인증 성공에 대한 감사를 활성화화 여부를 의미합니다. auditAuthorizationSuccess가 false인 경우 Auditing에서 authCheck에 대한 인증 실패만 기록합니다.
인증이 성공한(로그인이 성공한) 세션에 대한 Event 기록을 남기기 위해서 true로 설정이 필요합니다.


• mongod.conf
mongod.conf 에만 설정한 경우 재시작이 필요합니다.

setParameter:
  auditAuthorizationSuccess: true


• adminCommand를 사용
재기동 없이 기동중인 MongoDB 인스턴스에 바로 적용하기 위해서는 다음과 같이 adminCommand를 사용합니다.

db.adminCommand( { setParameter: 1, auditAuthorizationSuccess: true } )


• 파라미터 확인
파라미터 적용되었는지 확인은 다음과 같이 확인합니다.

> db.adminCommand( { getParameter : 1, "auditAuthorizationSuccess" : 1 } )
{ auditAuthorizationSuccess: true, ok: 1 }


추가로 MongoDB 인스턴스의 재시작에 대비하기 위해 mongod.conf에도 파라미터를 기록합니다.

setParameter:
  auditAuthorizationSuccess: true

               

Log Rotate

MongoDB에서는 남길수 있는 로그는 크게 두 종류 server log 와 audit log 입니다.(audit log는 auditing 활성화시에만)

이렇게 2 종류 로그에 대해서 Rotate 할 수 있는 방법은 OS에서 수행하는 방법과 MongoDB 에서 수행하는 방법 두가지입니다.

기본적으로 MongoDB는 logRotate 커맨드(db.adminCommand)에 대한 응답으로 또는 mongod 또는 mongos 프로세스가 운영 체제로부터 SIGUSR1 신호를 수신할 때만 Log Rotate를 수행합니다.

서버 로그와 감사 로그는 모두 logRotate 명령을 사용하여 함께 또는 각각 별도로 Rotate 할 수 있습니다.

MongoDB의 표준 로그 회전 접근 방식은 현재 로그 파일을 보관하고 새 로그 파일을 시작합니다. 이를 위해 mongod 또는 mongos 인스턴스는 ISODate 형식으로 파일 이름에 UTC 타임스탬프를 추가하여 현재 로그 파일의 이름을 바꿉니다.
그런 다음 새 로그 파일을 열고 이전 로그 파일을 닫은 다음 모든 새 로그 항목을 새 로그 파일로 보냅니다.

SIGUSR1 시그널은 리눅스에서 사용되는 시그널(signal) 중 하나입니다. 이 시그널은 프로세스에게 특정 동작을 수행하도록 알려줍니다. 여러 시그널 중 하나인 SIGUSR1은 사용자 정의 시그널로, 프로세스에게 특별한 의미를 부여할 수 있습니다.

MongoDB에서의 SIGUSR1은 Log Rotate(또는 Log 다시 열기)를 수행하도록 지정되어 있습니다.
이는 다른 서비스(또는 데몬)에서도 유사하게 사용되는 시그널로 Nginx 등에서도 SIGUSR1 시그널이 사용됩니다.
                       

SIGUSR1 사용

SIGUSR1 시그널을 통해서 Log Rotate를 수행하기 위해서는 크게 커맨드 라인에서 직접 수행과 logroate 데몬에 등록 두가지가 있습니다.


• 커맨드 라인에서 수행

# 커맨드 라인에서 직접 수행
/bin/kill -SIGUSR1 `cat /data/mongod.pid`

# 또는 PID를 직접 지정하여 수행
kill -SIGUSR1 2200

* /data/mongod.pid 경로 및 파일명은 예시입니다.
* PID 2200 는 예시입니다.


수행하여 파일이 rotate 되면 UTC 타임스탬프를 추가하여 현재 로그 파일의 이름을 바꿉니다.

SIGUSR1를 수행해서 MongoDB에 시그널을 보내면 mongod.conf의 systemLog.logRotate 설정에 따라 로그 교체 방법이 달라집니다.
                 

logRotate 파라미터

logRotate 파라미터는 서버 로그 및/또는 감사 로그를 회전할 때 logRotate 명령에 대한 동작을 결정합니다

systemLog:
  destination: file
  logRotate: <값>
  • rename: 로그파일을 ISODate 형식으로 파일 이름에 UTC 타임스탬프를 추가하여 현재 로그 파일의 이름을 바꿉니다.(기본값)
  • reopen: 로그 파일을 닫았다가 다시 엽니다. Linux/Unix logrotate 유틸리티를 사용할 때 reopen 으로 설정합니다.
    reopen을 설정하면 logAppend : true 로 설정이 필요합니다.


이와 같이 systemLog.logRotate 설정에 따라 새로운 파일이 생성되면서 교체되거나, 기존 파일을 닫고 열어서 새로운 내용을 기록합니다.


OS에서 SIGUSR1를 사용하는 두번째 방법으로 logrotate 데몬을 이용하는 것입니다. logrotate 데몬은 리눅스에서 로그파일의 회전(rotate)하고 관리하는 역할을 하는 데몬입니다.

리눅스의 logrotate를 통해 파일을 새로 생성하고 기존파일을 삭제할 때 이전 MongoDB에서는 logrotate의 copytruncate 파라미터를 사용하였지만, MongoDB에서 SIGUSR1 시그널을 지원함에 따라 SIGUSR1을 통해서 파일 닫고 열기를 수행하면 됩니다.

logrotate의 copytruncate 파라미터를 사용하지 않고 SIGUSR1 시그널을 사용한다면 MongoDB에서 파일 rename이 되지 않고 닫고 열기만 되도록 systemLog.logRotate 파리미터를 reopen 으로 지정하면 됩니다.

systemLog.logRotate 파리미터의 기본값은 rename 입니다.

logrotate 데몬을 사용하기 위해서는 /etc/logrotate.d 디렉토리 아래 파일을 생성하고 다음과 같이 내용을 입력하여 파일을 생성합니다.


• /etc/logrotate.d/mongodb 파일 생성

/data/audit.json
/data/mongod.log {
    daily
    rotate 7
    missingok
    dateext
    sharedscripts
    postrotate
        /bin/kill -SIGUSR1 `cat /data/mongod.pid`
    endscript
}

* 경로 및 파일명은 예시입니다.


위의 내용은 서버 로그인 mongod.log 과 감사 로그인 audit.json 파일에 대해서 rotate를 수행하는 내용입니다.
postrotate 에서 SIGUSR1 시그널을 통해서 기존 로그 파일을 닫고 열게 됩니다.

이렇게 설정하면 rotate 될 때마다 dateext 옵션에 의해서 *.log-YYYYmmdd 포맷으로 파일이 생성됩니다.
                  

logRotate command

MongoDB내에서 logRotate command를 통해서 MongoDB 서버 로그와 Audit 로그를 rotate 할 수 있습니다.

Server Log와 Audit Log 둘 다 생성되는 환경에서 예를 들어 Server Log는 하루에 한번 Rotate 하려고 하는데, Audit Log는 그와 다르게 1시간에 한 번씩 Rotate 하고 싶을 경우가 있을 수 있습니다.

또는 2개의 로그파일 중에서 특정 파일만 빠르게 용량이 증가해서 특정 파일만 Rotate 하고 싶은 경우도 있을 수 있습니다.

SIGUSR1 시그널을 통해 수행하면 2개의 로그 파일이 모두 Rotate가 수행되기 때문에 이와 같은 요구사항이 있을 경우 logRotate command를 사용하는 것도 한가지 방법입니다.


• 명령어 Syntax

db.adminCommand(
   {
     logRotate: <integer or string>,
     comment: <string>
   }
)

logRotate 명령은 admin 데이터베이스(스키마)에서 실행해야 합니다.


• Command Field 설명

Field Description
logRotate Rotate를 수행할 Log를 선택
1: MongoDB server 와 audit logs 모두를 수행
server: MongoDB server log만 rotate 수행
audit: audit log만 rotate 수행
comment (Optional) 로그 순환 수행시 서버가 로그 파일 및 감사 파일에 기록한 메시지


systemLog.logRotate 파라미터에서 rename(기본값)으로 설정되어있을 경우 ISODate 형식으로 파일 이름에 UTC 타임스탬프를 추가합니다.

Format: <YYYY>-<mm>-<DD>T<HH>-<MM>-<SS>


• Examples
Rotate 명령어 수행의 예시입니다.

서버 로그와 Audit 로그를 순환하고 로그 파일에 사용자 정의 메시지를 기록합니다.

db.adminCommand( { 
    logRotate: 1, 
    comment: "Rotating server/audit log" 
    } )


서버 로그만 순환하고 로그 파일에 사용자 정의 메시지를 기록합니다.

db.adminCommand( { 
    logRotate: "server", 
    comment: "Rotating server log" 
    } )


감사 로그만 순환하고 로그 파일에 사용자 정의 메시지를 기록합니다.

db.adminCommand( { 
    logRotate: "audit", 
    comment: "Rotating audit log" 
    } )

 

이번 글에서는 PSM에서의 Auditing 기능과 Log Rotate 기능에 대해서 확인해 보았으며, 여기서 마무리하도록 하겠습니다.
               

Reference

Reference URL
docs.percona.com/psm/audit-logging
Rotate Log Files — MongoDB Manual


연관된 다른 글

 

 

 

              

0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x