Ubuntu 22.04 Rsyslog 集中日誌管理

Ubuntu 22.04 Rsyslog Centralized Log Management

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認證系統
syslogsyslogd 內部訊息
local0-7自訂應用程式

Priority(優先等級):

等級數值說明
emerg0系統無法使用
alert1需立即處理
crit2嚴重錯誤
err3一般錯誤
warning4警告
notice5正常但重要
info6資訊性訊息
debug7除錯訊息

設定伺服器端

將一台 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/

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy