稽核記錄
稽核記錄是 Apache Cassandra 4.0 中的新功能 (CASSANDRA-12151)。此新功能適用於生產環境,並可設定堆積記憶體和磁碟空間的限制,以防止記憶體不足錯誤。所有資料庫活動都會以檔案為基礎的記錄記錄到指定的本機檔案系統目錄中,並依據可設定的值定期更新稽核記錄檔案。
稽核記錄的一些功能包括
-
不需要額外的資料庫容量來儲存稽核記錄。
-
不需要任何查詢工具來儲存稽核記錄。
-
不會影響資料庫操作的延遲,因此不會造成效能影響。
-
堆積記憶體使用量受到加權佇列的限制,可設定的最大權重位於記錄執行緒之前。
-
磁碟使用量受到可設定大小的限制,一旦達到限制就會刪除舊的記錄區段。
-
可以在啟動時使用
cassandra.yaml
啟用或停用,或在執行時使用 JMX 工具nodetool
啟用或停用。 -
可以在
cassandra.yaml
檔案中設定設定,或使用nodetool
。
稽核記錄包含所有 CQL 要求,無論成功或失敗。它也會擷取所有成功的和失敗的驗證和授權事件,例如登入嘗試。完整查詢記錄 (FQL) 和稽核記錄之間的差異在於,FQL 只擷取成功的 CQL 要求,允許重播或比較記錄。稽核記錄對於合規和除錯很有用,而 FQL 對於除錯、效能基準測試、測試和稽核 CQL 查詢很有用。
已記錄的稽核資訊
稽核記錄包含
-
要包含的所有設定鍵空間中的事件
-
要包含的所有設定類別中的事件
-
要包含的所有由設定使用者執行的事件
稽核記錄不包含
-
在
cassandra.yaml
檔案中進行的設定變更 -
nodetool
指令 -
作為 DCL 陳述式一部分提到的密碼:密碼將模糊處理為 *\**\**\*\*。
-
無法剖析的陳述式會在出現密碼一詞後模糊處理為 *\**\**\*\*。
-
拼寫錯誤的「密碼」一詞的陳述式會在沒有模糊處理的情況下記錄。請務必在重試時使用不同的密碼。
-
稽核記錄是一系列的記錄條目。稽核記錄條目包含
-
鍵空間 (字串) - 提出要求的鍵空間
-
操作 (字串) - 資料庫操作,例如 CQL 指令
-
使用者 (字串) - 使用者名稱
-
範圍 (字串) - 要求的範圍,例如資料表/函式/聚合名稱
-
類型 (AuditLogEntryType) - 要求類型
-
CQL 稽核記錄條目類型
-
常見稽核記錄條目類型
-
-
來源 (InetAddressAndPort) - 提出要求的來源 IP 位址
-
時間戳記 (長整數) - 要求的時間戳記
-
批次 (UUID) - 要求批次
-
選項 (QueryOptions) - CQL 查詢選項
-
狀態 (QueryState) - 與特定查詢相關的狀態
每個條目都包含給定事件的所有適用屬性,並以管線 (|) 串接。
CQL 稽核記錄條目類型是下列 CQL 指令。每個指令都指定到要記錄的特定類別
類別 | CQL 指令 |
---|---|
DDL |
ALTER_KEYSPACE、CREATE_KEYSPACE、DROP_KEYSPACE、ALTER_TABLE、CREATE_TABLE、DROP_TABLE、CREATE_FUNCTION、DROP_FUNCTION、CREATE_AGGREGATE、DROP_AGGREGATE、CREATE_INDEX、DROP_INDEX、ALTER_TYPE、CREATE_TYPE、DROP_TYPE、CREATE_TRIGGER、DROP_TRIGGER、ALTER_VIEW、CREATE_VIEW、DROP_VIEW、TRUNCATE |
DML |
批次處理、刪除、更新 |
DCL |
授予、撤銷、變更角色、建立角色、刪除角色、列出角色、列出權限、列出使用者 |
其他 |
使用鍵值空間 |
查詢 |
選取 |
準備 |
準備陳述式 |
常見的稽核記錄輸入類型為下列其中一種
類別 | CQL 指令 |
---|---|
驗證 |
登入成功、登入錯誤、未授權嘗試 |
錯誤 |
要求失敗 |
可用性和耐用性
與資料不同,稽核記錄輸入不會複製 |
對於特定查詢,對應的稽核輸入只會儲存在協調器節點上。例如,在複製因子為 3 的鍵值空間中執行 `INSERT`,會在一個節點(處理要求的協調器)上產生稽核輸入,而不會在其他兩個節點上產生。基於此原因,且視您必須符合的法規要求而定,請務必確保將稽核記錄儲存在非暫存的儲存空間中。
您可以使用 archive_command 選項來達成自訂需求。
在 cassandra.yaml 中設定稽核記錄
可以使用 `cassandra.yaml` 檔案來設定和啟用稽核記錄。設定和啟用在每個節點上可能相同或不同,視 `cassandra.yaml` 檔案設定而定。
啟用此功能時,也可以使用 `nodetool` 設定稽核記錄,且會覆寫 `cassandra.yaml` 檔案中設定的任何值,如 使用 nodetool 啟用稽核記錄 中所述。
稽核記錄會在每個已啟用的節點上產生,因此每個節點上的記錄都會有該節點的查詢。稽核記錄的所有選項都可以在 `cassandra.yaml` 檔案中的 `audit_logging_options:` 下設定。
檔案包含可以取消註解以供使用的下列選項
# Audit logging - Logs every incoming CQL command request, authentication to a node. See the docs
# on audit_logging for full details about the various configuration options.
audit_logging_options:
enabled: false
logger:
- class_name: BinAuditLogger
# audit_logs_dir:
# included_keyspaces:
# excluded_keyspaces: system, system_schema, system_virtual_schema
# included_categories:
# excluded_categories:
# included_users:
# excluded_users:
# roll_cycle: HOURLY
# block: true
# max_queue_weight: 268435456 # 256 MiB
# max_log_size: 17179869184 # 16 GiB
## archive command is "/path/to/script.sh %path" where %path is replaced with the file being rolled:
# archive_command:
# max_archive_retries: 10
已啟用
控制稽核記錄是否已啟用或已停用(預設值)。
若要啟用稽核記錄,請設定 `enabled: true`。
如果啟用此選項,稽核記錄會在 Cassandra 啟動時啟動。之後可以在執行階段使用 nodetool 將其停用。
您可以使用 JMX MBean `org.apache.cassandra.db:type=StorageService` 的 `AuditLogEnabled` 屬性來監控稽核記錄是否已啟用。 |
記錄器
稽核記錄器的類型是使用 `logger` 選項設定的。支援的值為
-
BinAuditLogger
(預設值) -
FileAuditLogger
-
NoOpAuditLogger
BinAuditLogger
會將事件記錄到二進位格式的檔案中。FileAuditLogger
使用標準記錄機制 `slf4j` 將事件記錄到 `audit/audit.log` 檔案中。它是一個同步的、基於檔案的稽核記錄器。roll_cycle 會在 `logback.xml` 檔案中設定。NoOpAuditLogger
是稽核記錄器的無操作實作,應在稽核記錄已停用時指定。
例如
logger:
- class_name: FileAuditLogger
BinAuditLogger 在幕後使用開源 Chronicle Queue。如果您考慮使用稽核記錄來符合法規,那麼熟悉此函式庫會很有幫助。請參閱 archive_command 和 roll_cycle 以取得影響範例。
|
audit_logs_dir
若要撰寫稽核記錄,必須在 audit_logs_dir
中設定現有目錄。
目錄必須設定適當的權限,以允許讀取、寫入和執行。記錄會視需要遞迴刪除目錄內容。請勿將連結放置在此目錄中,以連結到檔案系統的其他區段。例如,audit_logs_dir: /non_ephemeral_storage/audit/logs/hourly
。
也可以使用系統屬性 cassandra.logdir.audit
來設定稽核記錄目錄,預設設定為 cassandra.logdir + /audit/
。
included_keyspaces 和 excluded_keyspaces
設定要包含在 included_keyspaces
選項中的鍵空間,以及要排除在 excluded_keyspaces
選項中的鍵空間。預設情況下,會排除 system
、system_schema
和 system_virtual_schema
,並包含所有其他鍵空間。
例如
included_keyspaces: test, demo
excluded_keyspaces: system, system_schema, system_virtual_schema
included_categories 和 excluded_categories
要包含的資料庫操作類別會指定為 included_categories
選項,以逗號分隔的清單表示。要排除的資料庫操作類別會指定為 excluded_categories
選項,以逗號分隔的清單表示。稽核記錄支援的類別為:AUTH
、DCL
、DDL
、DML
、ERROR
、OTHER
、PREPARE
和 QUERY
。預設情況下,會包含所有支援的類別,且不會排除任何類別。
included_categories: AUTH, ERROR, DCL
excluded_categories: DDL, DML, QUERY, PREPARE
included_users 和 excluded_users
要稽核記錄的使用者會設定為 included_users
和 excluded_users
選項。included_users
選項會指定要明確包含的使用者,以逗號分隔的清單表示。excluded_users
選項會指定要明確排除的使用者,以逗號分隔的清單表示。預設情況下,會包含所有使用者,且不會排除任何使用者。
included_users:
excluded_users: john, mary
roll_cycle
roll_cycle
定義稽核記錄區段滾動的頻率。支援的值為
-
MINUTELY
-
FIVE_MINUTELY
-
TEN_MINUTELY
-
TWENTY_MINUTELY
-
HALF_HOURLY
-
HOURLY
(預設) -
TWO_HOURLY
-
FOUR_HOURLY
-
SIX_HOURLY
-
DAILY
例如:roll_cycle: DAILY
在生產節點上變更 roll_cycle 時,請閱讀以下段落。
|
使用 BinLogger
實作時,由於 Chronicle Queue 滾動週期推論機制,任何嘗試修改先前已啟用稽核記錄的節點上的滾動週期,都將靜默失敗(即使您刪除 metadata.cq4t
檔案)。
以下是 Cassandra 記錄中可見此類覆寫的範例
INFO [main] <DATE TIME> BinLog.java:420 - Attempting to configure bin log: Path: /path/to/audit Roll cycle: TWO_HOURLY [...] WARN [main] <DATE TIME> SingleChronicleQueueBuilder.java:477 - Overriding roll cycle from TWO_HOURLY to FIVE_MINUTE
若要在節點上變更 roll_cycle
,您必須
-
停止 Cassandra
-
將所有稽核記錄移至或卸載至其他位置(安全且耐用的位置)
-
重新啟動 Cassandra。
-
檢查 Cassandra 記錄
-
確保
audit_logs_dir
下的稽核記錄檔名對應到新的滾動週期。
block
block
選項指定稽核記錄是否應封鎖寫入或捨棄記錄記錄,如果稽核記錄落後。支援的布林值為 true
(預設)或 false
。
例如:block: false
捨棄記錄(例如,如果稽核用於疑難排解)
出於法規遵循目的,建議明確設定 block: true
以防止未來預設值變更時發生任何回歸。
max_queue_weight
max_queue_weight
選項設定在封鎖或捨棄之前,等待寫入檔案的記錄的記憶體中佇列的最大權重。選項必須設定為正值。預設值為 268435456,或 256 MiB。
例如,若要變更預設值:max_queue_weight: 134217728 # 128 MiB
max_log_size
max_log_size
選項設定滾動檔案的最大大小,在刪除最舊的檔案之前保留在磁碟上。選項必須設定為正值。預設值為 17179869184,或 16 GiB。例如,若要變更預設值:max_log_size: 34359738368 # 32 GiB
如果設定 archive_command 選項,則會忽略 max_log_size 。
|
archive_command
如果 archive_command 選項為空或未設定(預設),Cassandra 會使用內建的 DeletingArchiver,如果達到 max_log_size ,則會刪除最舊的檔案。
|
archive_command
選項設定使用者定義的封存指令碼,用於執行已滾動的記錄檔。例如:archive_command: "/usr/local/bin/archiveit.sh %path"
%path
會替換為已滾動檔案的絕對檔案路徑。
使用使用者定義的指令碼時,Cassandra 不會 使用 DeletingArchiver,因此指令碼負責執行任何必要的清理作業。
記錄檔一滾動,Cassandra 便會呼叫使用者定義的指令碼。這表示 Chronicle Queue 的 QueueFileShrinkManager 無法縮小稀疏記錄檔,因為它是非同步執行的。換句話說,所有記錄檔至少會達到預設區塊大小 (80 MiB),即使只有幾 KB 的實際資料。因此,Cassandra system.log 中會出現一些警告。
WARN [main/queue~file~shrink~daemon] <DATE TIME> QueueFileShrinkManager.java:63 - Failed to shrink file as it exists no longer, file=/path/to/xxx.cq4
由於 Cassandra 不使用 Pretoucher,您可以將 Chronicle Queue 設定為同步縮小檔案,也就是在檔案一滾動時縮小,方法是使用 chronicle.queue.synchronousFileShrinking JVM 屬性。例如,您可以在 cassandra-env.sh 的結尾新增下列行:JVM_OPTS="$JVM_OPTS -Dchronicle.queue.synchronousFileShrinking=true"
|
使用 nodetool
啟用稽核記錄
稽核記錄會使用 nodetool enableauditlog
指令在每個節點上啟用。記錄目錄必須在 cassandra.yaml
檔案中使用 audit_logs_dir
定義,或使用預設值 cassandra.logdir.audit
。
nodetool enableauditlog
指令的語法具有 cassandra.yaml
檔案中可以設定的所有選項,但 audit_logs_dir
除外。此外,nodetool
具有選項,可以設定要執行指令的主機和埠,以及需要驗證時要使用的使用者名稱和密碼。
nodetool [(-h <host> | --host <host>)] [(-p <port> | --port <port>)]
[(-pp | --print-port)] [(-pw <password> | --password <password>)]
[(-pwf <passwordFilePath> | --password-file <passwordFilePath>)]
[(-u <username> | --username <username>)] enableauditlog
[--excluded-categories <excluded_categories>]
[--excluded-keyspaces <excluded_keyspaces>]
[--excluded-users <excluded_users>]
[--included-categories <included_categories>]
[--included-keyspaces <included_keyspaces>]
[--included-users <included_users>] [--logger <logger>]
OPTIONS
--excluded-categories <excluded_categories>
Comma separated list of Audit Log Categories to be excluded for
audit log. If not set the value from cassandra.yaml will be used
--excluded-keyspaces <excluded_keyspaces>
Comma separated list of keyspaces to be excluded for audit log. If
not set the value from cassandra.yaml will be used
--excluded-users <excluded_users>
Comma separated list of users to be excluded for audit log. If not
set the value from cassandra.yaml will be used
-h <host>, --host <host>
Node hostname or ip address
--included-categories <included_categories>
Comma separated list of Audit Log Categories to be included for
audit log. If not set the value from cassandra.yaml will be used
--included-keyspaces <included_keyspaces>
Comma separated list of keyspaces to be included for audit log. If
not set the value from cassandra.yaml will be used
--included-users <included_users>
Comma separated list of users to be included for audit log. If not
set the value from cassandra.yaml will be used
--logger <logger>
Logger name to be used for AuditLogging. Default BinAuditLogger. If
not set the value from cassandra.yaml will be used
-p <port>, --port <port>
Remote jmx agent port number
-pp, --print-port
Operate in 4.0 mode with hosts disambiguated by port number
-pw <password>, --password <password>
Remote jmx agent password
-pwf <passwordFilePath>, --password-file <passwordFilePath>
Path to the JMX password file
-u <username>, --username <username>
Remote jmx agent username
要啟用稽核記錄,請在叢集中您要啟用記錄的每個節點上執行下列指令
$ nodetool enableauditlog
檢視稽核記錄
如果記錄器是 BinAuditLogger
,auditlogviewer
工具用於檢視 (傾印) 稽核記錄。auditlogviewer
會將二進位記錄檔轉換為人類可讀的格式;只要在命令列選項中提供稽核記錄目錄即可。如果設定記錄器 FileAuditLogger
,記錄檔已經是人類可讀的格式,而且不需要 auditlogviewer
來讀取檔案。
auditlogviewer
的語法為
auditlogviewer
Audit log files directory path is a required argument.
usage: auditlogviewer <path1> [<path2>...<pathN>] [options]
--
View the audit log contents in human readable format
--
Options are:
-f,--follow Upon reaching the end of the log continue indefinitely
waiting for more records
-h,--help display this help message
-r,--roll_cycle How often to roll the log file was rolled. May be
necessary for Chronicle to correctly parse file names. (MINUTELY, HOURLY,
DAILY). Default HOURLY.
範例
-
若要示範稽核記錄,請先使用下列設定設定
cassandra.yaml
檔案
audit_logging_options:
enabled: true
logger: BinAuditLogger
audit_logs_dir: "/cassandra/audit/logs/hourly"
# included_keyspaces:
# excluded_keyspaces: system, system_schema, system_virtual_schema
# included_categories:
# excluded_categories:
# included_users:
# excluded_users:
roll_cycle: HOURLY
# block: true
# max_queue_weight: 268435456 # 256 MiB
# max_log_size: 17179869184 # 16 GiB
## archive command is "/path/to/script.sh %path" where %path is replaced with the file being rolled:
# archive_command:
# max_archive_retries: 10
-
建立稽核記錄目錄
/cassandra/audit/logs/hourly
,並設定目錄權限,讓所有人皆可讀取、寫入和執行。
-
現在,使用
cqlsh
建立一個示範鍵值空間和表格,並插入一些資料
cqlsh> CREATE KEYSPACE auditlogkeyspace
... WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
cqlsh> USE auditlogkeyspace;
cqlsh:auditlogkeyspace> CREATE TABLE t (
...id int,
...k int,
...v text,
...PRIMARY KEY (id)
... );
cqlsh:auditlogkeyspace> INSERT INTO t (id, k, v) VALUES (0, 0, 'val0');
cqlsh:auditlogkeyspace> INSERT INTO t (id, k, v) VALUES (0, 1, 'val1');
所有支援的 CQL 指令都會記錄到稽核記錄目錄。
-
變更目錄至稽核記錄目錄。
$ cd /cassandra/audit/logs/hourly
-
列出稽核記錄檔案和目錄。
$ ls -l
您應該會看到類似下列的結果
total 28
-rw-rw-r--. 1 ec2-user ec2-user 65536 Aug 2 03:01 directory-listing.cq4t
-rw-rw-r--. 1 ec2-user ec2-user 83886080 Aug 2 03:01 20190802-02.cq4
-rw-rw-r--. 1 ec2-user ec2-user 83886080 Aug 2 03:01 20190802-03.cq4
所有稽核記錄檔案都會列出,檔案類型為 .cq4
。稽核目錄的類型為 .cq4t
。
-
執行
auditlogviewer
工具以檢視稽核記錄。
$ auditlogviewer /cassandra/audit/logs/hourly
此指令會傳回可讀取的記錄版本。以下是此示範中指令的記錄部分範例
WARN 03:12:11,124 Using Pauser.sleepy() as not enough processors, have 2, needs 8+
Type: AuditLog
LogMessage:
user:anonymous|host:10.0.2.238:7000|source:/127.0.0.1|port:46264|timestamp:1564711427328|type :USE_KEYSPACE|category:OTHER|ks:auditlogkeyspace|operation:USE AuditLogKeyspace;
Type: AuditLog
LogMessage:
user:anonymous|host:10.0.2.238:7000|source:/127.0.0.1|port:46264|timestamp:1564711427329|type :USE_KEYSPACE|category:OTHER|ks:auditlogkeyspace|operation:USE "auditlogkeyspace"
Type: AuditLog
LogMessage:
user:anonymous|host:10.0.2.238:7000|source:/127.0.0.1|port:46264|timestamp:1564711446279|type :SELECT|category:QUERY|ks:auditlogkeyspace|scope:t|operation:SELECT * FROM t;
Type: AuditLog
LogMessage:
user:anonymous|host:10.0.2.238:7000|source:/127.0.0.1|port:46264|timestamp:1564713878834|type :DROP_TABLE|category:DDL|ks:auditlogkeyspace|scope:t|operation:DROP TABLE IF EXISTS
AuditLogKeyspace.t;
Type: AuditLog
LogMessage:
user:anonymous|host:10.0.2.238:7000|source:/3.91.56.164|port:42382|timestamp:1564714618360|ty
pe:REQUEST_FAILURE|category:ERROR|operation:CREATE KEYSPACE AuditLogKeyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};; Cannot add
existing keyspace "auditlogkeyspace"
Type: AuditLog
LogMessage:
user:anonymous|host:10.0.2.238:7000|source:/127.0.0.1|port:46264|timestamp:1564714690968|type :DROP_KEYSPACE|category:DDL|ks:auditlogkeyspace|operation:DROP KEYSPACE AuditLogKeyspace;
Type: AuditLog
LogMessage:
user:anonymous|host:10.0.2.238:7000|source:/3.91.56.164|port:42406|timestamp:1564714708329|ty pe:CREATE_KEYSPACE|category:DDL|ks:auditlogkeyspace|operation:CREATE KEYSPACE
AuditLogKeyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};
Type: AuditLog
LogMessage:
user:anonymous|host:10.0.2.238:7000|source:/127.0.0.1|port:46264|timestamp:1564714870678|type :USE_KEYSPACE|category:OTHER|ks:auditlogkeyspace|operation:USE auditlogkeyspace;
Password obfuscation examples:
LogMessage: user:cassandra|host:localhost/127.0.0.1:7000|source:/127.0.0.1|port:65282|timestamp:1622630496708|type:CREATE_ROLE|category:DCL|operation:CREATE ROLE role1 WITH PASSWORD = '*******';
Type: audit
LogMessage: user:cassandra|host:localhost/127.0.0.1:7000|source:/127.0.0.1|port:65282|timestamp:1622630634552|type:ALTER_ROLE|category:DCL|operation:ATLER ROLE role1 WITH PASSWORD = '*******';
Type: audit
LogMessage: user:cassandra|host:localhost/127.0.0.1:7000|source:/127.0.0.1|port:65282|timestamp:1622630698686|type:CREATE_ROLE|category:DCL|operation:CREATE USER user1 WITH PASSWORD '*******';
Type: audit
LogMessage: user:cassandra|host:localhost/127.0.0.1:7000|source:/127.0.0.1|port:65282|timestamp:1622630747344|type:ALTER_ROLE|category:DCL|operation:ALTER USER user1 WITH PASSWORD '*******';