Ubuntu 22.04 系統日誌管理與分析

Complete guide to managing and analyzing system logs on Ubuntu 22.04

日誌系統簡介

在 Linux 系統中,日誌(Log)是記錄系統運作狀態、應用程式行為和安全事件的重要資訊來源。Ubuntu 22.04 使用 systemd 作為系統管理工具,其內建的日誌服務 journald 已成為現代 Linux 發行版的標準日誌管理系統。

為什麼日誌管理很重要?

  • 故障排除:當系統或服務發生問題時,日誌是診斷問題的第一線資訊
  • 安全監控:日誌記錄了登入嘗試、權限變更等安全相關事件
  • 效能分析:透過日誌可以了解系統資源使用情況和瓶頸
  • 合規性要求:許多安全標準要求保留系統日誌一定時間

Ubuntu 22.04 的日誌架構

Ubuntu 22.04 採用雙軌日誌系統:

系統說明
systemd-journald現代的二進制日誌系統,由 systemd 管理
rsyslog傳統的文字日誌系統,將日誌寫入 /var/log/

這兩個系統並行運作,journald 會將日誌轉發給 rsyslog,因此您可以選擇使用任一方式查看日誌。


journalctl 使用

journalctl 是 systemd 提供的日誌查詢工具,用於存取 journald 收集的日誌資料。它提供了強大的過濾和搜尋功能。

基本查詢

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 查看所有日誌(從最舊開始)
sudo journalctl

# 查看所有日誌(從最新開始,分頁顯示)
sudo journalctl -r

# 查看最近的日誌(類似 tail -f)
sudo journalctl -f

# 查看最近 100 行日誌
sudo journalctl -n 100

按時間過濾

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看今天的日誌
sudo journalctl --since today

# 查看昨天的日誌
sudo journalctl --since yesterday --until today

# 查看特定時間範圍的日誌
sudo journalctl --since "2023-07-01 00:00:00" --until "2023-07-31 23:59:59"

# 查看過去一小時的日誌
sudo journalctl --since "1 hour ago"

# 查看過去 30 分鐘的日誌
sudo journalctl --since "30 minutes ago"

按服務過濾

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 查看特定服務的日誌
sudo journalctl -u nginx.service

# 查看多個服務的日誌
sudo journalctl -u nginx.service -u mysql.service

# 即時追蹤服務日誌
sudo journalctl -u ssh.service -f

# 查看服務最近的日誌
sudo journalctl -u apache2.service -n 50

按優先等級過濾

journald 使用與 syslog 相同的優先等級:

等級數值說明
emerg0系統無法使用
alert1必須立即採取行動
crit2嚴重錯誤
err3一般錯誤
warning4警告訊息
notice5正常但值得注意
info6資訊性訊息
debug7除錯訊息
1
2
3
4
5
6
7
8
# 只顯示錯誤及以上等級
sudo journalctl -p err

# 顯示警告及以上等級
sudo journalctl -p warning

# 顯示特定等級範圍
sudo journalctl -p warning..err

按程序過濾

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 按 PID 過濾
sudo journalctl _PID=1234

# 按執行檔路徑過濾
sudo journalctl _EXE=/usr/sbin/sshd

# 按使用者 ID 過濾
sudo journalctl _UID=1000

# 按群組 ID 過濾
sudo journalctl _GID=1000

按啟動次數過濾

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 列出所有啟動記錄
sudo journalctl --list-boots

# 查看當前啟動的日誌
sudo journalctl -b

# 查看上一次啟動的日誌
sudo journalctl -b -1

# 查看特定啟動 ID 的日誌
sudo journalctl -b <boot-id>

輸出格式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# JSON 格式輸出
sudo journalctl -o json

# JSON 格式(美化)
sudo journalctl -o json-pretty

# 簡短格式(預設)
sudo journalctl -o short

# 詳細格式
sudo journalctl -o verbose

# 只顯示訊息內容
sudo journalctl -o cat

核心日誌

1
2
3
4
5
# 查看核心訊息(類似 dmesg)
sudo journalctl -k

# 查看當前啟動的核心訊息
sudo journalctl -k -b

日誌統計

1
2
3
4
5
# 查看日誌磁碟使用量
sudo journalctl --disk-usage

# 驗證日誌完整性
sudo journalctl --verify

重要日誌檔位置

除了 journald 的二進制日誌外,Ubuntu 22.04 也在 /var/log/ 目錄下保存傳統的文字日誌檔。

系統日誌

檔案路徑說明
/var/log/syslog主要系統日誌,記錄大部分系統活動
/var/log/kern.log核心訊息日誌
/var/log/dmesg開機時的核心訊息
/var/log/boot.log系統啟動日誌

認證與安全日誌

檔案路徑說明
/var/log/auth.log認證相關日誌(登入、sudo、SSH)
/var/log/faillog登入失敗記錄
/var/log/lastlog最後登入記錄
/var/log/wtmp登入/登出歷史記錄
/var/log/btmp登入失敗歷史記錄

應用程式日誌

檔案路徑說明
/var/log/apache2/Apache 網頁伺服器日誌
/var/log/nginx/Nginx 網頁伺服器日誌
/var/log/mysql/MySQL 資料庫日誌
/var/log/postgresql/PostgreSQL 資料庫日誌
/var/log/mail.log郵件伺服器日誌

套件管理日誌

檔案路徑說明
/var/log/apt/history.logAPT 套件安裝歷史
/var/log/apt/term.logAPT 操作終端輸出
/var/log/dpkg.logdpkg 套件管理記錄

常用查看指令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 查看系統日誌最後 50 行
sudo tail -50 /var/log/syslog

# 即時追蹤認證日誌
sudo tail -f /var/log/auth.log

# 搜尋特定關鍵字
sudo grep "error" /var/log/syslog

# 查看登入失敗記錄
sudo lastb

# 查看最近登入記錄
last

# 查看最後登入時間
lastlog

日誌輪替設定

日誌輪替(Log Rotation)是自動管理日誌檔大小的機制,防止日誌檔無限增長佔用磁碟空間。Ubuntu 使用 logrotate 工具來管理傳統日誌檔的輪替。

logrotate 設定檔

主要設定檔位置:

  • /etc/logrotate.conf:主設定檔
  • /etc/logrotate.d/:各服務的個別設定檔

查看主設定檔

1
cat /etc/logrotate.conf

典型的主設定內容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 每週輪替
weekly

# 保留 4 個舊檔案
rotate 4

# 輪替後建立新檔案
create

# 壓縮舊日誌
compress

# 延遲壓縮(保留最近一個不壓縮)
delaycompress

# 包含其他設定檔
include /etc/logrotate.d

設定選項說明

選項說明
daily每天輪替
weekly每週輪替
monthly每月輪替
yearly每年輪替
rotate n保留 n 個舊檔案
compress使用 gzip 壓縮舊檔案
delaycompress延遲壓縮到下次輪替
missingok如果日誌檔不存在,不報錯
notifempty如果日誌檔為空,不輪替
create mode owner group輪替後建立新檔案並設定權限
size n當檔案超過 n 大小時輪替
maxsize n限制最大檔案大小
postrotate/endscript輪替後執行的腳本

自訂日誌輪替設定

建立自訂應用程式的日誌輪替設定:

1
sudo nano /etc/logrotate.d/myapp

範例設定:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data www-data
    sharedscripts
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}

手動執行日誌輪替

1
2
3
4
5
6
7
8
# 測試設定(不實際執行)
sudo logrotate -d /etc/logrotate.conf

# 強制執行輪替
sudo logrotate -f /etc/logrotate.conf

# 執行特定設定檔
sudo logrotate -f /etc/logrotate.d/nginx

journald 日誌大小管理

journald 有自己的日誌大小管理機制,設定檔位於 /etc/systemd/journald.conf

1
sudo nano /etc/systemd/journald.conf

常用設定選項:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[Journal]
# 持久化儲存(預設為 auto)
Storage=persistent

# 日誌最大使用磁碟空間
SystemMaxUse=500M

# 保留最少可用空間
SystemKeepFree=1G

# 單一日誌檔最大大小
SystemMaxFileSize=100M

# 日誌最長保留時間
MaxRetentionSec=1month

# 壓縮日誌
Compress=yes

修改後重新載入設定:

1
sudo systemctl restart systemd-journald

清理舊日誌:

1
2
3
4
5
6
7
8
# 只保留最近 7 天的日誌
sudo journalctl --vacuum-time=7d

# 限制日誌大小為 500MB
sudo journalctl --vacuum-size=500M

# 只保留最近 5 個日誌檔
sudo journalctl --vacuum-files=5

分析技巧

有效的日誌分析可以幫助您快速找出問題根源和潛在的安全威脅。

常見問題排查

系統啟動問題

1
2
3
4
5
6
7
8
# 查看啟動失敗的服務
systemctl --failed

# 查看特定服務的啟動日誌
sudo journalctl -u <service-name> -b

# 查看啟動過程的錯誤
sudo journalctl -b -p err

SSH 登入問題

1
2
3
4
5
6
7
8
# 查看 SSH 登入失敗記錄
sudo grep "Failed password" /var/log/auth.log

# 統計失敗登入的 IP
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20

# 查看成功登入記錄
sudo grep "Accepted" /var/log/auth.log

磁碟問題

1
2
3
4
5
# 查看磁碟相關錯誤
sudo journalctl -k | grep -i "error\|fail\|warning"

# 查看特定磁碟的訊息
sudo journalctl -k | grep sda

使用 grep 和 awk 分析

1
2
3
4
5
6
7
8
# 統計每小時的日誌數量
sudo cat /var/log/syslog | awk '{print $1, $2, $3}' | cut -d: -f1 | uniq -c

# 找出最常見的錯誤訊息
sudo grep -i error /var/log/syslog | awk '{for(i=6;i<=NF;i++) printf $i" "; print ""}' | sort | uniq -c | sort -rn | head -10

# 分析特定時間段的日誌
sudo awk '/Jul 31 10:00/,/Jul 31 11:00/' /var/log/syslog

使用 journalctl 進階分析

1
2
3
4
5
6
7
8
9
# 統計每個服務的錯誤數量
sudo journalctl -p err -o json | jq -r '._SYSTEMD_UNIT' | sort | uniq -c | sort -rn

# 查看佔用最多日誌空間的服務
sudo journalctl --disk-usage
sudo du -sh /var/log/journal/*

# 匯出日誌供進一步分析
sudo journalctl --since "2023-07-01" --until "2023-07-31" -o json > july_logs.json

安全事件分析

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 檢查 sudo 使用記錄
sudo grep "sudo" /var/log/auth.log

# 檢查可疑的 cron 活動
sudo grep CRON /var/log/syslog

# 檢查使用者新增/刪除記錄
sudo grep -E "useradd|userdel|usermod" /var/log/auth.log

# 檢查套件安裝記錄
sudo grep "install" /var/log/dpkg.log

建立日誌監控腳本

建立簡單的日誌監控腳本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/bash
# 檔案:/usr/local/bin/log-monitor.sh

LOG_FILE="/var/log/syslog"
ALERT_EMAIL="admin@example.com"
KEYWORDS="error|critical|failed|denied"

# 檢查最近 5 分鐘的日誌
RECENT_ERRORS=$(sudo journalctl --since "5 minutes ago" -p err --no-pager)

if [ -n "$RECENT_ERRORS" ]; then
    echo "發現錯誤日誌:"
    echo "$RECENT_ERRORS"
    # 可選:發送郵件通知
    # echo "$RECENT_ERRORS" | mail -s "系統錯誤警報" $ALERT_EMAIL
fi

設定定期執行:

1
2
# 每 5 分鐘檢查一次
echo "*/5 * * * * root /usr/local/bin/log-monitor.sh" | sudo tee /etc/cron.d/log-monitor

推薦的日誌分析工具

對於更進階的日誌分析需求,可以考慮以下工具:

工具說明
Logwatch自動分析日誌並產生報告
GoAccess即時網頁伺服器日誌分析
Fail2ban自動封鎖惡意 IP
ELK Stack企業級日誌收集與分析平台
Graylog集中式日誌管理系統

總結

有效的日誌管理是 Linux 系統管理的重要技能。透過本文介紹的內容,您應該能夠:

  1. 理解 Ubuntu 22.04 的日誌架構,包括 journald 和傳統 syslog 的運作方式
  2. 熟練使用 journalctl,進行各種條件的日誌查詢和過濾
  3. 了解重要日誌檔位置,快速找到需要的日誌資訊
  4. 設定日誌輪替,有效管理磁碟空間
  5. 應用分析技巧,快速診斷系統問題和安全事件

最佳實踐建議

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 1. 設定 journald 持久化儲存
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald

# 2. 設定合理的日誌保留策略
sudo nano /etc/systemd/journald.conf
# SystemMaxUse=1G
# MaxRetentionSec=3month

# 3. 定期檢查磁碟使用量
sudo journalctl --disk-usage
df -h /var/log

# 4. 設定日誌監控和告警
# 使用 Fail2ban 自動封鎖惡意 IP
sudo apt install fail2ban

# 5. 定期審查安全日誌
sudo grep -E "Failed|Invalid|error" /var/log/auth.log | tail -50

記得定期檢視系統日誌,及早發現潛在問題!

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