記錄所有 SQL Server 登入帳號與時間,防範竄改 sa 密碼等安全事件。原生審計僅記錄失敗登入,需自建全量審計。
LOGON、ALTER_LOGIN 事件。xp_cmdshell)。ECHO login_time >> D:\Logondata.txt。-- 1. 清理舊觸發器
USE master;
IF EXISTS (SELECT * FROM sys.server_triggers WHERE name = 'trg_logon_audit')
DROP TRIGGER trg_logon_audit ON ALL SERVER;
GO
-- 2. 確保日誌文件存在(首次手動建立或用腳本)
-- 3. 啟用 xp_cmdshell(若未啟用)
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
GO
-- 4. 建立觸發器
CREATE TRIGGER trg_logon_audit
ON ALL SERVER
WITH EXECUTE AS 'sa'
FOR LOGON, ALTER_LOGIN
AS
BEGIN
SET NOCOUNT ON;
DECLARE @cmd NVARCHAR(4000) = N'ECHO '
+ ORIGINAL_LOGIN() + NCHAR(9)
+ CONVERT(NVARCHAR(30), GETDATE(), 121)
+ N' >> D:\Logondata.txt';
DECLARE @tbl TABLE (out_line NVARCHAR(4000));
INSERT @tbl EXEC master..xp_cmdshell @cmd;
END;
GO
NT AUTHORITY\SYSTEM 2024-05-18 10:12:04.140
JOE\Administrator 2024-05-18 10:12:31.753
sa 2024-05-18 10:15:39.930
| 限制 | 現狀 | 建議對策 |
|---|---|---|
| 無法區分 Windows / SQL 驗證 | ORIGINAL_LOGIN() 返回 NT 帳號或 SQL 帳號,但無驗證類型欄位 | 配合 EVENTDATA() 解析 <EventType>LOGON</EventType> 下的 <LoginType>(需 XML 處理) |
| ALTER_LOGIN 事件無法捕獲具體動作(改密/解鎖/重命名) | 事件資料不含詳細子操作 | 啟用 SQL Server Audit (Server Audit Specification → DATABASE_PRINCIPAL_CHANGE_GROUP) 並寫入檔案/Windows Security Log |
若觸發器邏輯錯誤導致所有登入失敗(含 sa),啟用 專用管理員連接 (DAC):
-- 命令列
sqlcmd -S admin:localhost -U sa -P -Q "DROP TRIGGER trg_logon_audit ON ALL SERVER;"
-- 或 SSMS 連線時在伺服器名輸入 admin:localhost
DAC 保留專用排程器與連線配額,觸發器不攔截 DAC 連線,是最後一道防線。
| 方案 | 優點 | 缺點 | 推薦場景 |
|---|---|---|---|
| Logon Trigger + 文本 | 零成本、即時、可自訂格式 | 維護成本高、易鎖死、無結構化查詢 | 小型環境、臨時審計 |
| SQL Server Audit (內建) | 效能極佳、支援多目標(文件/WinLog)、不可竄改、合規認證 | Enterprise Edition 才支援細粒度過濾 | 生產環境標配 |
| Extended Events | 輕量、可過濾、可環狀緩衝區 | 學習曲線陡、需手動持久化 | 深度診斷、效能分析 |
SERVER_PRINCIPAL_CHANGE_GROUP、FAILED_LOGIN_GROUP、SUCCESSFUL_LOGIN_GROUP。BEGIN 後立即 SET NOCOUNT ON、TRY...CATCH 包裹 xp_cmdshell、避免觸發器內做耗時操作。sa 密碼與 xp_cmdshell 權限,原則最小化。審計不僅是合規勾選,更是事後溯源的「黑盒子」。