# Audit 系統介紹


## Audit 簡介

Audit 是對影響系統安全相關的事件進行紀錄，像是網路界面的設定, 密碼更動, 等事件都是相關的事件。

跟 Audit 有關的標準為 [Controlled Access Protection Profile (CAPP)](https://en.wikipedia.org/wiki/Controlled_Access_Protection_Profile) 標準。

> 要理解 CAPP，必須先提到它的前身——美國國防部的 TCSEC（橘皮書） 標準。在 80-90 年代，政府要求作業系統必須達到「C2」等級，意思是「需要有登入機制，且使用者可以控制檔案權限」。 CAPP 的誕生：當國際標準 Common Criteria (CC) 取代橘皮書後，CAPP 被制定出來，作為橘皮書 C2 等級在 CC 標準中的繼承者。
>
> CAPP 的四大核心要求，其中之一就是 Seuciry Audit，CAPP 要求必須記錄：「任何對存取控制策略的執行（如讀取檔案）、身份驗證（登入）、安全管理（改密碼）以及審計管理（開關 Log 功能）的行為」
> 每一條紀錄都必須能連結到一個特定的使用者，這就是為什麼需要 AUID（Audit UID）來防止使用者透過 sudo 隱藏身分。

在 FreeBSD 和 Linux 上的實做都有符合此標準。

另外常常可能搞混的是 Syslog，不同於 Syslog 運作於應用程式的層級上，Aydit 是建構於系統核心層級上的模組。

## FreeBSD

### FreeBSD Audit 定義

Auditable Events:

* 核心層級 (Kernel-centered)：例如讀寫檔案、網路連線。這主要是透過監控「系統呼叫 (System calls)」來達成。
* 使用者層級 (User-level)：例如登入 (login)、切換使用者 (su)。這些程式會主動呼叫 audit 系統呼叫來寫入紀錄。
* CAPP 標準要求：任何涉及存取控制、認證、修改安全設定的行為，都必須被記錄。

每一條審計紀錄 (Audit Record) 包含：

* Subject (主體)：誰做的？（使用者、Process、從哪裡登入）。
* Objects (客體)：對誰做的？（被讀取的檔案）。
* Data (細節)：具體做了什麼？（例如 chmod 把檔案權限改成了什麼數值）。

這些紀錄會被依序存成檔案，稱為 Audit trails (審計軌跡)。

在 Linux/Unix 中，如果你用 su 或 sudo 變成 root，你的 UID 就變成了 0。這時候系統只知道「root 刪了檔案」，但不知道是「哪個使用者切換成 root」的。因此系統在 Process 中增加了一個欄位叫 AUID (Audit UID)。

### FreeBSD Audit System 歷史

當時 Apple 為了讓 Mac OS X 通過 Common Criteria (CC)，需要一套強大的審計系統，於是與 FreeBSD 合作開發。

當時的 FreeBSD/Mac OS X 缺乏一個強大到足以滿足 CAPP 要求的審計系統，所以 Apple 和 FreeBSD 合作，採用當時的 Sun Solaris BSM 標準，所以他們的 Audit system 主要來自 Sun 的 OpenBSM。

> BSM, which is a system used for auditing, describes a set of system call and library interfaces for managing audit records as well as a token stream file format that permits extensible and generalized audit trail processing. - [OpenBSM Wiki](https://en.wikipedia.org/wiki/OpenBSM)

FreeBSD 產出的 BSM 格式是二進制的文件，由下列欄位組成：

1. Header token: 整條紀錄的總長度、時間戳記 (Timestamp)、以及事件類型 (Event type)（例如：這是 open() 系統呼叫，還是 login 事件）。
2. Data tokenL: 實際欄位，例如使用者的憑證資訊 (Credential)、函數的參數 (Arguments)、執行的回傳值 (Return values)。
3. Trailer Token: 表示紀錄結束了

FreeBSD 大部分的 Token 沒有紀錄「長度」欄位。優點省空間，缺點是如果解析程式遇到一個「看不懂的 Token ID」（例如新版本的格式），因為不知道這個 Token 有多長，程式就無法跳過它，導致整條紀錄（甚至後面整個檔案）都無法解析。

### FreeBSD Audit System 實做

我們可以在 `struct proc` or `struct thread` 底下的 `struct ucred` 裡面有 `struct auditinfo_addr` 欄位。

![alt text](image-1.png)

![alt text](image-2.png)

可以看到如上，有一個自己的 `audit.h`，我們可以看到最近的 commit

![alt text](image-3.png)

2017 的 5e38659 commit 合併 OpenBSM 的相關東西，它將 OpenBSM 1.2-alpha5 版本合併進了 FreeBSD 的開發分支 (-CURRENT)，主要包含：

1. 效能調校：可自訂 Queue 長度 (qsize)，在 audit_control 設定檔中新增了 qsize 參數，並提供了 API (getacqsize) 來查詢
2. 新增了大量新的審計事件識別碼 (Audit Event Identifiers)，包含:
   1. Asynchronous I/O (AIO)：非同步讀寫，資料庫常用的高效能 I/O 方式。
   2. Thread Management：執行緒的建立與管理。
   3. SCTP：一種較新的網路傳輸協定（電信業常用）。
   4. Jails：FreeBSD 的虛擬化容器技術（以前可能監控不完全，現在支援了）。
   5. Multi-FIB：多重路由表（進階網路功能）。
   6. POSIX 介面：如 posix_fallocate（預分配檔案空間），這通常跟資料庫或高效能存儲有關。

   Commit message 特別提到，這些功能超出了橘皮書 (Orange Book) 或 Common Criteria 的基本要求，是為了實務上的「細粒度 I/O 審計」而做的。
3. auditreduce（篩選日誌工具）和 praudit（讀取日誌工具）現在會在沙箱中執行（在支援 Capsicum 的系統上）。

所以我們可以看到 openbsm 有一個自己的目錄在 FreeBSD，如下

![alt text](image-4.png)

他的 commit 主要就是從主要的 [openbsm repo](https://github.com/openbsm/openbsm/commits/master/) merge feature.

---

我們可以看一下內部核心實做，它不一定跟 BSM 格式有關，大多是比較通用的結構。目前整個 Audit 流程為：

1. 由 auditd 設定全域規則，或由 login / sshd 設定使用者的 AUID 和 Audit Mask（決定這個使用者要被記錄什麼行為）
2. 當 System Call 剛開始時，核心會檢查「這需要紀錄嗎？」(Pre-selection)。如果需要，就幫這個執行緒 (Thread) 分配一個紀錄空間
3. 在執行過程中，把參數抓下來（例如檔案路徑、UID）
4. 回傳點 (Return Code)：當 System Call 結束時，根據結果（成功或失敗）再次確認是否要紀錄，然後把紀錄丟進 Global Queue (全域佇列)
5. 背景工人 (Audit Worker Thread)：有一個專門的背景執行緒，負責把 Global Queue 裡面的東西拿出來，寫入硬碟 (Audit Trail) 或送到即時監控管道 (Audit Pipes)

所以有一個全域的 `struct audit_queue` 來放所有相關的 audit record，如下，定義了一個 double linked list `audit_q` 全域變數：

![alt text](image-5.png)

每個執行緒身上最多帶著兩份「進行中」的紀錄（一份是 Kernel 產生的，一份是 User 自己送的）。System Call 結束後，紀錄被送到這個全域佇列。這個佇列是可靠的，但有長度限制 (如下圖)，防止耗盡記憶體 。Worker Thread 把資料轉成 BSM 格式，寫入硬碟或送給即時監控程式 。

![alt text](image-6.png)

Audit 在 FreeBSD 具有可靠性與不可繞過 (Reliability & Non-bypassability)，Syslog (一般日誌) 如果太忙或硬碟滿了，Syslog 會選擇丟掉日誌以保全系統運作。Audit (審計日誌) 則是強制監控 (Mandatory monitoring)。如果一個事件被設定要審計，那麼「要嘛紀錄成功，要嘛這個事件根本不准發生」。這意味著如果硬碟滿了，系統可能會阻止你開啟檔案，甚至讓系統停機，以確保沒有「未被記錄的動作」發生。這是在 TCB (Trusted Computing Base) 內實作的，無法被繞過 。

## Linux

## Reference

[Audit framework - ArchWiki](https://wiki.archlinux.org/title/Audit_framework)

[Chapter 19. Security Event Auditing](https://docs.freebsd.org/en/books/handbook/audit/)

