Rsyslog 概述
Rsyslog 是 Linux 系統中功能強大的日誌處理系統,全名為 “Rocket-fast System for Log Processing”。它是傳統 syslog 的增強版本,提供了高效能、模組化架構和豐富的過濾功能。在 Ubuntu 22.04 中,Rsyslog 預設已安裝並與 systemd-journald 協同運作。
Rsyslog 的主要特點
- 高效能:能夠處理每秒數十萬筆日誌訊息
- 可靠傳輸:支援 TCP、TLS 加密傳輸,確保日誌不遺失
- 彈性過濾:提供屬性過濾器和表達式過濾器
- 模組化設計:輸入、輸出、解析器皆可透過模組擴充
- 範本系統:自訂日誌格式和輸出結構
為什麼需要集中日誌管理?
在多伺服器環境中,集中日誌管理帶來以下優勢:
| 優勢 | 說明 |
|---|
| 統一監控 | 從單一位置檢視所有伺服器日誌 |
| 安全備份 | 即使伺服器被入侵,日誌仍安全保存 |
| 合規要求 | 符合 PCI-DSS、ISO 27001 等規範 |
| 事件關聯 | 跨伺服器分析安全事件和效能問題 |
設定檔結構
Rsyslog 的設定檔採用模組化架構,主要位於以下位置:
1
2
3
| /etc/rsyslog.conf # 主設定檔
/etc/rsyslog.d/ # 額外設定檔目錄
/etc/rsyslog.d/*.conf # 自訂設定檔
|
主設定檔結構
查看預設設定檔:
1
| sudo cat /etc/rsyslog.conf
|
設定檔主要分為三個區塊:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 1. 模組載入區塊
module(load="imuxsock") # 本地系統日誌
module(load="imklog") # 核心日誌
# 2. 全域設定區塊
$WorkDirectory /var/spool/rsyslog
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
# 3. 規則區塊
*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure
mail.* /var/log/maillog
|
Facility 與 Priority
Rsyslog 使用 Facility(設施)和 Priority(優先等級)來分類日誌:
Facility(設施):
| 設施 | 說明 |
|---|
| kern | 核心訊息 |
| user | 使用者程式 |
| mail | 郵件系統 |
| daemon | 系統服務 |
| auth | 認證系統 |
| syslog | syslogd 內部訊息 |
| local0-7 | 自訂應用程式 |
Priority(優先等級):
| 等級 | 數值 | 說明 |
|---|
| emerg | 0 | 系統無法使用 |
| alert | 1 | 需立即處理 |
| crit | 2 | 嚴重錯誤 |
| err | 3 | 一般錯誤 |
| warning | 4 | 警告 |
| notice | 5 | 正常但重要 |
| info | 6 | 資訊性訊息 |
| debug | 7 | 除錯訊息 |
設定伺服器端
將一台 Ubuntu 22.04 伺服器設定為集中日誌伺服器。
安裝與啟用 Rsyslog
1
2
3
4
5
6
7
| # 確認 rsyslog 已安裝
sudo apt update
sudo apt install rsyslog -y
# 啟用並啟動服務
sudo systemctl enable rsyslog
sudo systemctl start rsyslog
|
設定接收日誌
編輯主設定檔,啟用 TCP 或 UDP 接收:
1
| sudo nano /etc/rsyslog.conf
|
取消註解以下行以啟用 UDP(埠號 514):
1
2
| module(load="imudp")
input(type="imudp" port="514")
|
取消註解以下行以啟用 TCP(埠號 514):
1
2
| module(load="imtcp")
input(type="imtcp" port="514")
|
設定防火牆
1
2
3
4
5
6
7
8
| # 允許 UDP 514
sudo ufw allow 514/udp
# 允許 TCP 514
sudo ufw allow 514/tcp
# 重新載入防火牆
sudo ufw reload
|
建立專屬設定檔
建立遠端日誌接收設定:
1
| sudo nano /etc/rsyslog.d/10-remote.conf
|
加入以下內容:
1
2
3
4
5
6
| # 為遠端主機建立獨立的日誌目錄
$template RemoteHost,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
# 將所有遠端日誌儲存到對應目錄
if $fromhost-ip != '127.0.0.1' then ?RemoteHost
& stop
|
建立日誌目錄並設定權限
1
2
3
| sudo mkdir -p /var/log/remote
sudo chown syslog:adm /var/log/remote
sudo chmod 750 /var/log/remote
|
重新啟動服務
1
2
3
4
5
6
7
| sudo systemctl restart rsyslog
# 驗證服務狀態
sudo systemctl status rsyslog
# 確認埠號監聽
sudo ss -tuln | grep 514
|
設定客戶端
在需要傳送日誌的客戶端伺服器上進行設定。
建立客戶端設定檔
1
| sudo nano /etc/rsyslog.d/50-remote-logging.conf
|
使用 TCP 傳送日誌(推薦):
1
2
3
4
5
| # 設定遠端日誌伺服器(使用 TCP)
*.* @@log-server.example.com:514
# 或使用 IP 位址
*.* @@192.168.1.100:514
|
使用 UDP 傳送日誌:
1
2
3
4
5
| # 設定遠端日誌伺服器(使用 UDP)
*.* @log-server.example.com:514
# 或使用 IP 位址
*.* @192.168.1.100:514
|
設定佇列以提高可靠性
1
| sudo nano /etc/rsyslog.d/50-remote-logging.conf
|
加入佇列設定:
1
2
3
4
5
6
7
8
| # 設定磁碟佇列,防止日誌遺失
$ActionQueueType LinkedList
$ActionQueueFileName remote_queue
$ActionResumeRetryCount -1
$ActionQueueSaveOnShutdown on
# 傳送所有日誌到遠端伺服器
*.* @@192.168.1.100:514
|
重新啟動客戶端服務
1
| sudo systemctl restart rsyslog
|
測試日誌傳送
1
2
3
4
5
| # 產生測試日誌
logger -t test "This is a test message from client"
# 在伺服器端驗證
sudo tail -f /var/log/remote/*/test.log
|
日誌分類與過濾
Rsyslog 提供強大的過濾功能,可根據不同條件分類日誌。
基於 Facility 過濾
1
2
3
4
5
6
7
8
| # 將認證日誌單獨儲存
auth,authpriv.* /var/log/auth.log
# 將郵件日誌單獨儲存
mail.* /var/log/mail.log
# 排除特定 facility
*.*;auth,authpriv.none /var/log/syslog
|
基於 Priority 過濾
1
2
3
4
5
| # 只記錄錯誤及以上等級
*.err /var/log/errors.log
# 記錄 info 到 warning
*.info;*.!err /var/log/info.log
|
基於屬性過濾
1
2
3
4
5
6
7
8
| # 根據主機名稱過濾
:hostname, isequal, "webserver01" /var/log/webserver01.log
# 根據程式名稱過濾
:programname, isequal, "nginx" /var/log/nginx-syslog.log
# 根據訊息內容過濾
:msg, contains, "error" /var/log/error-messages.log
|
使用表達式過濾(RainerScript)
1
2
3
4
5
6
7
8
9
| # 進階過濾範例
if $hostname == 'webserver01' and $syslogseverity <= 3 then {
action(type="omfile" file="/var/log/webserver01-errors.log")
}
# 多條件過濾
if ($programname == 'nginx' or $programname == 'apache2') then {
action(type="omfile" file="/var/log/webservers.log")
}
|
範本設定
範本允許自訂日誌的輸出格式和儲存結構。
自訂時間格式範本
1
2
3
4
5
| # 定義範本
$template CustomFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg%\n"
# 套用範本
*.* /var/log/custom.log;CustomFormat
|
JSON 格式範本
1
2
3
| $template JSONFormat,"{ \"timestamp\":\"%timegenerated:::date-rfc3339%\", \"host\":\"%HOSTNAME%\", \"severity\":\"%syslogseverity-text%\", \"facility\":\"%syslogfacility-text%\", \"program\":\"%programname%\", \"message\":\"%msg:::json%\" }\n"
*.* /var/log/json-logs.log;JSONFormat
|
動態檔案路徑範本
1
2
3
4
5
6
7
8
| # 依日期建立目錄
$template DailyLog,"/var/log/remote/%HOSTNAME%/%$year%-%$month%-%$day%.log"
# 依程式名稱分類
$template ByProgram,"/var/log/apps/%programname%.log"
# 套用範本
*.* ?DailyLog
|
TLS 加密傳輸
使用 TLS 加密確保日誌傳輸的安全性。
產生憑證
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # 建立憑證目錄
sudo mkdir -p /etc/rsyslog/ssl
cd /etc/rsyslog/ssl
# 產生 CA 私鑰和憑證
sudo openssl genrsa -out ca-key.pem 4096
sudo openssl req -new -x509 -days 3650 -key ca-key.pem -out ca-cert.pem \
-subj "/CN=Rsyslog CA"
# 產生伺服器私鑰和憑證請求
sudo openssl genrsa -out server-key.pem 4096
sudo openssl req -new -key server-key.pem -out server-req.pem \
-subj "/CN=log-server.example.com"
# 簽發伺服器憑證
sudo openssl x509 -req -days 3650 -in server-req.pem \
-CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial \
-out server-cert.pem
# 設定權限
sudo chmod 600 /etc/rsyslog/ssl/*.pem
sudo chown syslog:syslog /etc/rsyslog/ssl/*.pem
|
伺服器端 TLS 設定
1
| sudo nano /etc/rsyslog.d/10-tls.conf
|
加入以下內容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 載入 TLS 模組
module(load="imtcp" StreamDriver.Name="gtls"
StreamDriver.Mode="1"
StreamDriver.AuthMode="x509/name")
# TLS 憑證設定
global(
DefaultNetstreamDriver="gtls"
DefaultNetstreamDriverCAFile="/etc/rsyslog/ssl/ca-cert.pem"
DefaultNetstreamDriverCertFile="/etc/rsyslog/ssl/server-cert.pem"
DefaultNetstreamDriverKeyFile="/etc/rsyslog/ssl/server-key.pem"
)
# 監聽 TLS 埠號
input(type="imtcp" port="6514")
|
客戶端 TLS 設定
將 CA 憑證複製到客戶端:
1
| sudo scp log-server:/etc/rsyslog/ssl/ca-cert.pem /etc/rsyslog/ssl/
|
設定客戶端:
1
| sudo nano /etc/rsyslog.d/50-tls-remote.conf
|
1
2
3
4
5
6
7
8
9
| # 載入 TLS 驅動
$DefaultNetstreamDriver gtls
$DefaultNetstreamDriverCAFile /etc/rsyslog/ssl/ca-cert.pem
$ActionSendStreamDriverMode 1
$ActionSendStreamDriverAuthMode x509/name
$ActionSendStreamDriverPermittedPeer log-server.example.com
# 傳送日誌到 TLS 埠
*.* @@log-server.example.com:6514
|
日誌輪替
設定遠端日誌的輪替策略。
建立 logrotate 設定
1
| sudo nano /etc/logrotate.d/remote-logs
|
加入以下內容:
1
2
3
4
5
6
7
8
9
10
11
12
13
| /var/log/remote/*/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 syslog adm
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
|
測試輪替設定
1
2
3
4
5
| # 測試設定(不實際執行)
sudo logrotate -d /etc/logrotate.d/remote-logs
# 強制執行輪替
sudo logrotate -f /etc/logrotate.d/remote-logs
|
監控與除錯
檢視 Rsyslog 狀態
1
2
3
4
5
| # 服務狀態
sudo systemctl status rsyslog
# 檢視 rsyslog 自身的日誌
sudo journalctl -u rsyslog -f
|
啟用除錯模式
1
2
3
4
5
| # 以除錯模式啟動
sudo rsyslogd -dn
# 或設定除錯輸出
sudo nano /etc/rsyslog.d/99-debug.conf
|
1
2
| $DebugFile /var/log/rsyslog-debug.log
$DebugLevel 2
|
驗證設定檔語法
1
2
| # 檢查設定檔語法
sudo rsyslogd -N1
|
常見問題排查
日誌未送達:
1
2
3
4
5
6
7
8
| # 檢查網路連線
telnet log-server.example.com 514
# 檢查防火牆
sudo ufw status
# 檢查 SELinux(如適用)
sudo getenforce
|
權限問題:
1
2
3
4
5
| # 確認目錄權限
ls -la /var/log/remote/
# 修正權限
sudo chown -R syslog:adm /var/log/remote/
|
參考資料