跳到主要內容
節省工具箱Jason Tools
經驗分享

Zimbra 整合 AD 認證的記錄查詢

Jason Cheng 發布 瀏覽 1 次
Zimbra 整合 AD 認證的記錄查詢
本文目錄
  1. 認證流程與記錄位置
  2. Zimbra 端的記錄
  3. AD/DC 端的記錄
  4. 在 Zimbra 主機上模擬 Bind
  5. 問題排除流程
  6. 結論
  7. 參考資料

企業導入 Zimbra 時,很多都會把帳號認證交給 AD(Active Directory),使用者只要記一組網域密碼。方便是方便,但只要有人反應「信箱登不進去」,問題可能出在 Zimbra、出在網路,也可能出在 AD 本身,沒有把記錄查清楚,就只能靠猜。

這篇把我平常處理這類問題時會看的記錄整理起來,從 Zimbra 端一路查到 AD/DC 端,最後附上我實際使用的問題排除順序。除了查登入問題,要稽核「誰在什麼時候登入過」也可以使用。

認證流程與記錄位置

先講一下流程:使用者在 Webmail、IMAP、ActiveSync 等任何一個入口輸入帳密,Zimbra 會依網域的設定(zimbraAuthMech 設為 ad 或 ldap),用 LDAP Bind 把帳密送到 DC 驗證,再把結果回給使用者。

所以一次登入會在兩邊各留下記錄:

  • Zimbra 端
    登入嘗試、協定、來源 IP、成功或失敗,以及 Bind 的細節
  • DC 端
    Security 事件記錄裡的驗證結果,帳號是不是被鎖、被停用都在這裡

查問題前,可以先確認網域的外部認證設定,後面比對記錄時會用到:

su - zimbra
zmprov gd example.com zimbraAuthMech zimbraAuthLdapURL zimbraAuthLdapSearchBase \
    zimbraAuthLdapSearchFilter zimbraAuthLdapSearchBindDn zimbraAuthLdapBindDn

Zimbra 端的記錄

記錄檔一覽

記錄檔內容重要度
/opt/zimbra/log/audit.log登入稽核記錄,只記錄認證結果高
/opt/zimbra/log/mailbox.log主要服務記錄,Web、SOAP、ActiveSync 的認證過程與錯誤高
/var/log/zimbra.logsyslog,含 Postfix 的 SMTP AUTH中
/opt/zimbra/log/nginx.access.logProxy 的連線記錄,看使用者到底有沒有連進來中
/opt/zimbra/log/zmmailboxd.outmailboxd 啟動與 JVM 錯誤低

audit.log:建議優先看

audit.log 是專門給稽核用的,只記錄認證結果,不會混雜其他服務訊息,格式也比較乾淨,查登入問題我都先看這個。

# 特定使用者最近的登入記錄
grep "user@example.com" /opt/zimbra/log/audit.log | tail -20

# 所有認證失敗
grep "cmd=Auth" /opt/zimbra/log/audit.log | grep "error="

# 統計今天各帳號的失敗次數,找出可能被暴力嘗試的帳號
grep "$(date +%Y-%m-%d)" /opt/zimbra/log/audit.log | grep "cmd=Auth" | grep "error=" | \
    grep -o 'account=[^;]*' | sort | uniq -c | sort -rn | head -20

每一筆會帶帳號、協定(protocol=soap、imap…)以及來源 IP(oip=),從這裡就能判斷是不是只有某個用戶端有問題,例如 Webmail 正常、手機 ActiveSync 失敗,那多半是手機上存的舊密碼。

mailbox.log:看錯誤原因

audit.log 告訴你「失敗了」,mailbox.log 才看得到「為什麼失敗」:

# 特定使用者的認證相關訊息
grep "user@example.com" /opt/zimbra/log/mailbox.log | grep -i "auth" | tail -50

# 所有認證失敗
grep -i "authentication failed" /opt/zimbra/log/mailbox.log | tail -50

# 最近一小時的認證活動
grep "$(date +'%Y-%m-%d %H')" /opt/zimbra/log/mailbox.log | grep -i "auth"

mailbox.log 的量很大,務必先用帳號篩選再看,不然會被其他訊息淹沒。

開啟 DEBUG 看 LDAP Bind 細節

預設的記錄等級不會寫出 LDAP Bind 的過程,要看 Zimbra 實際送了什麼到 AD,可以只針對那個帳號開 DEBUG,不用重新啟動服務,也不會讓整台的記錄量暴增:

su - zimbra

# 只對這個帳號開 DEBUG
zmprov addAccountLogger user@example.com zimbra.account debug
zmprov addAccountLogger user@example.com zimbra.ldap debug

# 確認目前開了哪些
zmprov getAccountLoggers user@example.com

開好之後請使用者再登入一次,mailbox.log 就會出現像這樣的訊息:

DEBUG [qtp...] [name=...] account - LDAP search base=DC=example,DC=com
filter=(samAccountName=user) bindDN=zimbra-svc@example.com
DEBUG [qtp...] [name=...] account - LDAP bind successful for
CN=User Name,OU=Users,DC=example,DC=com

從這兩行就能確認搜尋基底、篩選條件、用哪個帳號查詢,以及最後 Bind 的是哪一筆 DN。常見的問題像是使用者被搬到其他 OU 而不在搜尋基底底下、篩選條件寫錯,在這裡一眼就看得出來。

查完記得關掉:

zmprov removeAccountLogger user@example.com zimbra.account
zmprov removeAccountLogger user@example.com zimbra.ldap

注意:DEBUG 記錄會帶出 DN、搜尋條件等內部資訊,查完務必關閉,記錄檔要分享給別人看之前也要先遮蔽。

AD/DC 端的記錄

Zimbra 把帳密送到 DC 之後,DC 自己也會記錄這次驗證。要確認 Zimbra 真的有打到 AD、AD 回了什麼,就要到 DC 上看。

Security 事件記錄

打開 事件檢視器 → Windows 記錄 → 安全性,篩選以下事件識別碼:

事件識別碼意義說明
4624登入成功Zimbra 的 LDAP Bind 成功會出現在這裡,來源位址是 Zimbra 主機
4625登入失敗看 Status/Sub Status 判斷原因
4776認證資料驗證NTLM 驗證,失敗時也有錯誤碼
4740帳號被鎖定密碼錯太多次
4768 / 4771Kerberos TGT 申請/預先驗證失敗使用者在 Windows 登入時產生,可用來判斷帳號本身是否正常

4625 常見的錯誤碼:

錯誤碼意義
0xC000006A密碼錯誤
0xC0000064帳號不存在
0xC0000234帳號已鎖定
0xC0000072帳號已停用
0xC0000071密碼已過期
0xC0000224下次登入必須變更密碼

最後兩個很常見:AD 設了密碼期限,使用者在 Windows 上會被提示改密碼,但從 Webmail 登入就只會看到密碼錯誤。

注意:要看到這些事件,DC 的稽核原則要開啟「稽核登入」與「稽核認證資料驗證」。有多台 DC 時,Zimbra 連的是哪一台就要去哪一台看,或是把記錄集中到 Graylog 這類記錄平台一起查。

用 PowerShell 篩出 Zimbra 來源的驗證

事件檢視器一筆一筆點很慢,我習慣直接在 DC 上用 PowerShell,依來源 IP 篩出 Zimbra 主機的驗證記錄:

# 在 DC 上執行:列出最近一小時、來自 Zimbra 主機的登入成功與失敗
$zimbraIP = '192.168.1.20'

Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4624, 4625
    StartTime = (Get-Date).AddHours(-1)
} | ForEach-Object {
    $d = @{}
    ([xml]$_.ToXml()).Event.EventData.Data | ForEach-Object { $d[$_.Name] = $_.'#text' }
    if ($d.IpAddress -eq $zimbraIP) {
        [pscustomobject]@{
            Time      = $_.TimeCreated
            Id        = $_.Id
            Account   = $d.TargetUserName
            LogonType = $d.LogonType
            Status    = $d.Status
            SubStatus = $d.SubStatus
        }
    }
} | Format-Table -AutoSize

把 192.168.1.20 換成你的 Zimbra 主機 IP。用事件的 XML 欄位比對,比直接搜尋 Message 文字準確,也不受系統語系影響。

在 Zimbra 主機上模擬 Bind

前面都是「事後看記錄」,也可以直接在 Zimbra 主機上用 ldapsearch 模擬 Zimbra 的動作,Zimbra 本身就有附:

# 用服務帳號查詢使用者,確認搜尋基底與篩選條件
/opt/zimbra/common/bin/ldapsearch -x -H ldaps://dc01.example.com:636 \
    -D "zimbra-svc@example.com" -W \
    -b "DC=example,DC=com" \
    "(sAMAccountName=user)" sAMAccountName mail userPrincipalName

# 用使用者自己的帳密 Bind,確認密碼與帳號狀態
/opt/zimbra/common/bin/ldapwhoami -x -H ldaps://dc01.example.com:636 \
    -D "user@example.com" -W

這兩個都成功,代表 Zimbra 主機到 DC 的網路、憑證、帳號都沒問題,問題就要往 Zimbra 的設定或用戶端去找。要看 TLS 協商的細節,可以加上 -d 1。

更多 ldapsearch 的用法可以參考我之前整理的〈LDAPSearch 常用 CLI 指令整理〉。

問題排除流程

使用者反應登不進去時,我會照這個順序查:

  1. audit.log
    grep "user@example.com" /opt/zimbra/log/audit.log | tail -20
    先確認是認證失敗,還是根本沒有進到 Zimbra
  2. mailbox.log
    grep "user@example.com" /opt/zimbra/log/mailbox.log | tail -50
    看失敗原因:密碼錯誤、Bind 失敗、還是連不到 DC
  3. 開 DEBUG(必要時)
    zmprov addAccountLogger user@example.com zimbra.account debug
    請使用者再試一次,取得完整的 Bind 過程,查完就關掉
  4. 模擬 Bind
    ldapsearch / ldapwhoami
    確認網路、憑證、服務帳號與使用者帳密都正常
  5. DC 事件記錄
    4625 的錯誤碼、4740 帳號鎖定
    確認是不是密碼真的錯、帳號被鎖定,或密碼已過期
  6. 連線層
    nc -vz dc01.example.com 636
    openssl s_client -connect dc01.example.com:636 -showcerts
    排除防火牆封鎖、LDAPS 憑證過期

結論

Zimbra 整合 AD 之後,帳號問題就變成「兩套系統一起看」,只看任何一邊都很容易誤判。我自己的習慣是:先看 Zimbra 的 audit.log 確認有沒有進來,再看 DC 的事件記錄確認 AD 怎麼回,大部分的問題到這一步就很清楚了。

另外,這些記錄平常最好就集中到記錄平台保存,真的要稽核或追查時,才不會遇到記錄已經被輪替掉的狀況。

參考資料

Jason Cheng

Jason Cheng

企業開源技術顧問,專注架構規劃與實務導入

關於作者 →

延伸閱讀