이전 회에서 MariaDB 감사 로그를 남길 수 있도록 준비를 했습니다.

MariaDB 감사로그는 누가 언제 접속을 했는지?, 어떤 쿼리를 실행 했는지? 결과는 얼마나 나왔는지? 이런 것들을 기록하는 로그 입니다. 이것을 raw 로그로 확인 하는 것은 매우 힘들고 귀찮은 작업이 될 것 입니다.

20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,85,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'E294063AA70B23929726B1EA2D23BC84\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,88,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'4228CCA43DBE1C7148D6399C07C637AC\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,91,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'574390B9E3F452089FDEF84A70ACF529\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,94,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'FFDD2CD38F77866134050B4BC9A678FA\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,97,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'64DC6FE8845BB45D81824C21068518DB6FC555A8A4A980536A2A09A049647232\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,100,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'F513243CF5015EF6FE6D8BF05201379E\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,103,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'AB3D9B43EDFA0136540AACEA96214124\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,106,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'BFD7828505000B279FA059F46B83296B\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,109,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'FFDD2CD38F77866134050B4BC9A678FA\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,112,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'1EC6892E651F0102A94DFC97B9B0B49103C28518D82CBAA46D2E5BC90488A746\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,115,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'0018147FC4DA54DFC85BF2829FECD91E\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,118,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'F2C5BD55C9C9F8CD81A541084AA1B302\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,121,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'E74CBB65E0BDD48C00688BCAC3B24E26\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,124,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'FFDD2CD38F77866134050B4BC9A678FA\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,127,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'37C1451D9BBF334F1D509476B74464FD\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,130,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'3EBE14803C8642A5722F4DB010318D7C\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,133,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'8B2BA1D8B61C713B779E0A67FDA98BB5\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,136,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'8E2AA42EEE4C692FAF8C55E6725FEB4E\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,139,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'FFDD2CD38F77866134050B4BC9A678FA\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,142,QUERY,webservice,'SELECT CAST(AES_DECRYPT(UNHEX( NAME_CONST(\'encryptedText\',_utf8mb4\'37FD593CC84F3B6BC02EBF22359F1C1CE82489DB79BB3814E14CB21DE8AE6A23\' COLLATE \'utf8mb4_uca1400_ai_ci\')), \'***************\') AS CHAR)\r\n\tINTO returnVal',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,34,142,QUERY,webservice,'SELECT CUST_SEQ,\r\n\tAES256_DECRYPT(NAME) AS NAME,\r\n\tAES256_DECRYPT(PHONE_NO) AS PHONE_NO,\r\n\tAES256_DECRYPT(BIRTH_DT) AS BIRTH_DT,\r\n\tAES256_DECRYPT(GENDER) AS GENDER,\r\n\tAES256_DECRYPT(EMAIL) AS EMIAL,\r\n\tREG_DATE,\r\n\tREG_SEQ\r\nFROM CUSTOMER_INFO\nLIMIT 0, 200',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,33,145,QUERY,webservice,'SELECT * FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=\'webservice\' AND TABLE_NAME=\'CUSTOMER_INFO\' ORDER BY TABLE_NAME,INDEX_NAME,SEQ_IN_INDEX',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,33,146,QUERY,webservice,'SELECT kc.CONSTRAINT_NAME,kc.TABLE_NAME,kc.COLUMN_NAME,kc.ORDINAL_POSITION\nFROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kc WHERE kc.TABLE_SCHEMA=\'webservice\' AND kc.REFERENCED_TABLE_NAME IS NULL AND kc.TABLE_NAME=\'CUSTOMER_INFO\'\nORDER BY kc.CONSTRAINT_NAME,kc.ORDINAL_POSITION',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,33,147,QUERY,webservice,'SELECT cc.CONSTRAINT_NAME, cc.CHECK_CLAUSE, tc.TABLE_NAME\nFROM (SELECT CONSTRAINT_NAME, CHECK_CLAUSE\nFROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS\nWHERE CONSTRAINT_SCHEMA = \'webservice\'\nORDER BY CONSTRAINT_NAME) cc,\n(SELECT TABLE_NAME, CONSTRAINT_NAME\nFROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS\nWHERE TABLE_SCHEMA = \'webservice\' AND TABLE_NAME=\'CUSTOMER_INFO\') tc\nWHERE cc.CONSTRAINT_NAME = tc.CONSTRAINT_NAME\nORDER BY cc.CONSTRAINT_NAME',0
20250313 01:20:34,raspberrypi,developer1,192.168.45.102,33,148,QUERY,webservice,'SHOW CREATE TABLE `webservice`.`CUSTOMER_INFO`',0
20250313 01:21:00,raspberrypi,developer1,192.168.45.102,33,149,QUERY,webservice,'SHOW FULL TABLES FROM webservice WHERE Tables_in_webservice LIKE \'AES256_ENCRYPT\' AND Table_type <> \'SEQUENCE\'',0

 

여기서는 이 로그를 일 단위로 분석해서 별도의 테이블에 넣고 필요 할 때 이 테이블의 내용을 조회 해서 보고서를 작성하는 방식으로 진행 할 예정 입니다.
감사 로그 관련 테이블이 서비스와 같은 database와 분리 해서 별도의 database에 있는 것이 좋을 것 같습니다.
database와 사용 계정을 생성하고 권한을 부여하겠습니다.

 

DB 생성 및 사용자 생성, 권한 부여

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| webservice         |
+--------------------+
5 rows in set (0.003 sec)

MariaDB [(none)]> create database server_audit;
Query OK, 1 row affected (0.002 sec)

MariaDB [(none)]> grant all privileges  on server_audit.* to 'dba'@'192.168.45.102';
Query OK, 0 rows affected (0.024 sec)

MariaDB [(none)]> create user 'server_audit'@'localhost' identified via ed25519 using password('BassCraft@!5269');
Query OK, 0 rows affected (0.052 sec)

MariaDB [(none)]> grant select, insert, update, delete on server_audit.* to 'server_audit'@'localhost';
Query OK, 0 rows affected (0.003 sec)

MariaDB [none]> create user 'server_audit'@'192.168.45.102' identified via ed25519 using password('BassCraft@!5269');
Query OK, 0 rows affected (0.027 sec)

MariaDB [none]> grant select, insert, update, delete on server_audit.* to 'server_audit'@'192.168.45.102';
Query OK, 0 rows affected (0.019 sec)

MariaDB [none]> flush privileges;
Query OK, 0 rows affected (0.004 sec)

MariaDB [none]>

 

server_audit 데이터베이스를 생성하고, 해당 데이터베이스에 대해 자체 서버(localhost)에서 접속 할 수 있는 계정과 관리자(192.168.45.102)가 작업을 위해 접근할 계정을 각각 만들고 권한(읽기, 쓰기, 수정, 삭제)을 부여 했습니다.

 

필요한 테이블은 로그를 분석 하면서 만들어 보겠습니다.

 

로그 파일 분석 Processor 만들기

MariaDB 로그는 지난번 설정에서 일단위로 압축해서 보관 되도록 설정했습니다.

https://opensrc.tistory.com/261

 

[MariaDB] 보안 취약점 점검 #7 감사 정책 준비

보안 설정을 잘 하는 것도 중요 하지만 보안에 문제가 없는지 상시 모니터링을 하고 확인을 하는 것도 매우 중요한 부분입니다.하지만 규모가 작은 조직에서는 개발자가 모든 것을 다 하는 경우

opensrc.tistory.com

 

의도한 대로 로그가 잘 쌓이고 있는지 확인해 보겠습니다.

$ sudo ls -al /var/log/mysql
total 2092
drw-rw----  2 mysql mysql     4096 Mar 13 04:15 .
drwxrwxr-x 10 root  syslog    4096 Mar  9 00:04 ..
-rw-rw----  1 mysql mysql     6880 Mar 13 05:11 error.log
-rw-rw----  1 mysql mysql     1721 Mar  2 04:48 error.log-20250303.gz
-rw-rw----  1 mysql mysql      142 Mar  4 00:21 error.log-20250304.gz
-rw-rw----  1 mysql mysql     1128 Mar  4 04:21 error.log-20250305.gz
-rw-rw----  1 mysql mysql     1117 Mar 10 13:04 error.log-20250311.gz
-rw-rw----  1 mysql mysql     1123 Mar 12 00:47 error.log-20250312.gz
-rw-rw----  1 mysql mysql      435 Mar 12 23:52 error.log-20250313
-rw-rw----  1 mysql mysql  1051841 Mar 13 12:58 mysql.log
-rw-rw----  1 mysql mysql     3627 Mar  3 00:03 mysql.log-20250303.gz
-rw-rw----  1 mysql mysql     3213 Mar  4 00:46 mysql.log-20250304.gz
-rw-rw----  1 mysql mysql     2393 Mar  5 00:41 mysql.log-20250305.gz
-rw-rw----  1 mysql mysql      231 Mar  6 00:28 mysql.log-20250306.gz
-rw-rw----  1 mysql mysql     2857 Mar  7 00:43 mysql.log-20250307.gz
-rw-rw----  1 mysql mysql      232 Mar  8 00:04 mysql.log-20250308.gz
-rw-rw----  1 mysql mysql      233 Mar  9 00:04 mysql.log-20250309.gz
-rw-rw----  1 mysql mysql     3505 Mar 10 00:27 mysql.log-20250310.gz
-rw-rw----  1 mysql mysql     5654 Mar 11 00:50 mysql.log-20250311.gz
-rw-rw----  1 mysql mysql     6850 Mar 12 00:51 mysql.log-20250312.gz
-rw-rw----  1 mysql mysql   280823 Mar 13 00:36 mysql.log-20250313
-rw-rw----  1 mysql mysql   235358 Mar 13 12:58 server_audit.log
-rw-rw----  1 mysql mysql    33353 Mar 13 03:11 server_audit.log-20250304.gz
-rw-rw----  1 mysql mysql    15409 Mar 10 13:04 server_audit.log-20250305.gz
-rw-rw----  1 mysql mysql    10090 Mar 11 22:31 server_audit.log-20250311.gz
-rw-rw----  1 mysql mysql   396700 Mar 13 00:36 server_audit.log-20250312
$

 

server_audit.log 는 접근이 없으면 쌓이지 않는 것 같습니다. 중간 중간 날짜가 빠져 있습니다.

이 로그를 읽어서 DB에 적재 하기 위해 로그의 포멧을 간단히 정리해 보았습니다.

 

/**
 *  server_audit_log file format
 *  MariaDB server_audit_log format 참고
 *  https://mariadb.com/kb/en/mariadb-audit-plugin-log-format/
 *
 *  1. 각 필드는 콤마로 분리
 *  2. 파일로 저장하는 경우 필드 구성 (server_audit_output_type=file)
 *    - [0] timestamp : 이벤트 발생 시간 (기본 포멧은 YYYYMMDD HH:mm:dd)
 *    - [1] serverhost : 이벤트가 발생한 DB서버 hostname
 *    - [2] username : 사용자 ID
 *    - [3] host : 사용자 IP
 *    - [4] connectionid : 사용자 접속 ID (커넥션 별로 다른 듯)
 *    - [5] queryid : 쿼리ID
 *          테이블에 대한 여러 이벤트의 경우 다수의 로우가 생성됨
 *          operation이 CONNECT, DISCONNECT, FAILED_CONNECT인 경우 0
 *    - [6] operation : 작업유형 (CONNECT, QUERY, READ, WRITE, CREATE, ALTER, RENAME, DROP)
 *    - [7] database : 사용한 DB명
 *    - [8] object :
 *          operation이 QUERY 인경우 수행한 쿼리 (싱글 쿼테이션으로 감싸 있으며 내부에 콤마를 포함할 수 있음)
 *          테이블 변경 인경우 테이블 명
 *          operation이 CONNECT, DISCONNECT, FAILED_CONNECT인 경우 빈값
 *    - [9] retcode : 로그 실행 결과 코드
 */

 

더 상새한 내용용은 공식 문서를 참고 하시기 바랍니다.

https://mariadb.com/kb/en/mariadb-audit-plugin-log-format/

 

MariaDB Audit Plugin - Log Format

The audit log is a set of records written as a list of fields to a file in plain‐text format.

mariadb.com

 

audit log를 읽어서 누가 언제 접속, 종료 했는지를 확인하고, 개인정보 복호화 함수를 조회 하는 기록을 남기고 복호화 한 수(로우 * 컬럼) 를 누적하여 이상 징후가 있는 경우 해당자에게 소명을 하기 위한 목적입니다.

고려해야 할 것이 커넥션이 일어나고 일 단위 로그 로테이션에 걸쳐 있는 경우를 고려해야 합니다.

종료되지 않은 커넥션이 있는경우 임시 테이블에 담았다가 다음날(종료 되면 처리 하도록 구현 하였습니다.)

아래와 같이 테이블을 구성 하였습니다.

/*DROP TABLE IF EXISTS SERVER_AUDIT_MASTER;*/

CREATE TABLE SERVER_AUDIT_MASTER (
    CONNECTION_ID INT(11) UNSIGNED NOT NULL COMMENT '커넥션 ID',
    USER_NAME VARCHAR(20) NOT NULL COMMENT '사용자 ID',
    USER_HOST VARCHAR(20) NOT NULL COMMENT '사용자 IP',
    DATABASE_NAME VARCHAR(20) NULL COMMENT '데이터베이스 명',
    CONNECT_TIMESTAMP VARCHAR(17) NULL COMMENT '접속시간',
    DISCONNECT_TIMESTAMP VARCHAR(17) NULL COMMENT '종료시간',
    PRIMARY KEY (CONNECTION_ID)
) COMMENT = 'server audit log master';

/*DROP TABLE IF EXISTS PRIVATE_POLICY_HIST;*/

CREATE TABLE PRIVATE_POLICY_HIST (
    CONNECTION_ID INT(11) UNSIGNED NOT NULL COMMENT '커넥션 ID',
    QUERY_ID DECIMAL(15) NOT NULL COMMENT '쿼리 ID',
    START_TIMESTAMP VARCHAR(17) NULL COMMENT '쿼리 실행 시작 시간',
    END_TIMESTAMP VARCHAR(17) NULL COMMENT '쿼리 실행 종료 시간',
    QUERY TEXT NULL COMMENT '쿼리',
    POLICY_COUNT INT COMMENT '개인정보조회수',
    PRIMARY KEY (CONNECTION_ID, QUERY_ID),
    CONSTRAINT FOREIGN KEY (CONNECTION_ID) REFERENCES SERVER_AUDIT_MASTER (CONNECTION_ID)
) COMMENT='개인정보 조회 이력';

/*DROP TABLE IF EXISTS INCOMPLETE_QUERY;*/

CREATE TABLE INCOMPLETE_QUERY (
    CONNECTION_ID INT(11) UNSIGNED NOT NULL COMMENT '커넥션 ID',
    START_TIMESTAMP VARCHAR(17) NULL COMMENT '쿼리 실행 시작 시간',
    POLICY_COUNT INT COMMENT '개인정보조회수',
    PRIMARY KEY (CONNECTION_ID),
    CONSTRAINT FOREIGN KEY (CONNECTION_ID) REFERENCES SERVER_AUDIT_MASTER (CONNECTION_ID)
) COMMENT='미완료 쿼리 임시 저장';

 

 

자세한 내용은 소스를 참고 하시고, 원하시는 방향으로 수정 하셔서 사용하시면 될 것 같습니다.

Java 21, Spring Boot, MyBatis 기반 어플리케이션 입니다.

 

실행 방법은 README.md 파일을 참고 하시기 바랍니다.

 

https://github.com/basscraft/MariaDBAuditLogProcessor

 

GitHub - basscraft/MariaDBAuditLogProcessor: MariaDB Server Audit Log Processor

MariaDB Server Audit Log Processor. Contribute to basscraft/MariaDBAuditLogProcessor development by creating an account on GitHub.

github.com

 

이전 회차에서 설정한 로그 로테이션 주기는 매일 0시에 실행 되는 것 같습니다.

위 어플리케이션을 crontab 에 등록 해서 매일 새벽 1시에 실행 하도록 하겠습니다.

컴파일된 jar 파일을 /usr/local/MariaDBAuditLog 디렉토리에 올리고

간단한 쉘스크립트를 만들어서 /usr/local/MariaDBAuditLog/app.sh로 저장 하고 실행 퍼미션을 주었습니다.

$ vi app.sh
#!/bin/bash
nohup java -jar -Dspring.profiles.active=prod -Dspring.application.json='{\"spring.datasource.username\":\"server_audit\",\"spring.datasource.password\":\"******\"}' /usr/local/MariaDBAuditLog/MariaDBAuditLogProcessor.jar
$

 

$ sudo chmod 700 /usr/local/MariaDBAuditLog/app.sh
$ sudo ls -al /usr/local/MariaDBAuditLog/
total 18960
drwxr-xr-x  3 root root     4096 Mar 13 17:22 .
drwxr-xr-x 13 root root     4096 Mar 13 13:54 ..
-rw-rw-r--  1 root root 19395264 Mar 13 17:21 MariaDBAuditLogProcessor.jar
-rwx------  1 root root      545 Mar 13 15:18 app.sh
drwxr-xr-x  2 root root     4096 Mar 13 17:22 log
$

/var/log/mysql 아래에 있는 로그들이 mysql:mysql 소유로 되어 있기 때문에 root 권한으로 실행해야 퍼미션 문제가 없습니다.

log 디렉토리 아래는 어플리케이션이 실행되고 나면 하위에 AuditLogProcessor.log 파일과 함께 생성됩니다.

 

매일 새벽 1시에 실행 되도록 root 계정의 crontab 에 등록 하도록 하겠습니다.

$ sudo crontab -e
... 생략 ...
0 1 * * * /usr/local/MariaDBAuditLog/app.sh >/dev/null 2>&1
$

crontab 이 제대로 실행 된 것 인지 확인 하려면 /var/log/syslog 를 확인 하면 됩니다.

$ sudo cat /var/log/syslog | grep CRON

 

끝.

+ Recent posts