如何使用 Zimbra OSE 日志

记录所有发生的事件是任何公司系统最重要的功能之一。 日志允许您解决新出现的问题、审计信息系统的运行情况以及调查信息安全事件。 Zimbra OSE 还保留其操作的详细日志。 它们包括从服务器性能到用户发送和接收电子邮件的所有数据。 然而,读取 Zimbra OSE 生成的日志是一项相当重要的任务。 在本文中,我们将通过一个具体示例告诉您如何读取 Zimbra OSE 日志,以及如何将其集中化。

如何使用 Zimbra OSE 日志
Zimbra OSE 将所有本地日志存储在 /opt/zimbra/log 文件夹中,日志也可以在 /var/log/zimbra.log 文件中找到。 其中最重要的是mailbox.log。 它记录了邮件服务器上发生的所有操作。 其中包括电子邮件传输、用户身份验证数据、失败的登录尝试等。 Mailbox.log 中的条目是一个文本字符串,其中包含事件发生的时间、事件的级别、事件发生的线程号、用户名和 IP 地址以及事件的文本描述。

如何使用 Zimbra OSE 日志

日志级别表示事件对服务器运行的影响程度。 默认情况下有 4 个事件级别:INFO、WARN、ERROR 和 FATAL。 让我们按照严重性递增的顺序来看看所有级别。

  • 信息 - 此级别的事件通常旨在通报 Zimbra OSE 的进展情况。 此级别的消息包括有关创建或删除邮箱的报告等。
  • 警告 - 此级别的事件通知存在潜在危险的情况,但不会影响服务器的操作。 例如,WARN 级别标记有关用户登录尝试失败的消息。
  • 错误 - 日志中的此事件级别通知发生的错误,该错误本质上是本地错误,不会干扰服务器的操作。 此级别可以标记单个用户的索引数据已损坏的错误。
  • FATAL - 此级别表示导致服务器无法继续正常运行的错误。 例如,FATAL 级别将用于指示无法连接到 DBMS 的记录。

邮件服务器日志文件每天都会更新。 文件的最新版本始终具有名称 Mailbox.log,而特定日期的日志的名称中包含日期并包含在存档中。 例如mailbox.log.2020-09-29.tar.gz。 这使得备份活动日志和搜索日志变得更加容易。

为了方便系统管理员,/opt/zimbra/log/ 文件夹包含其他日志。 它们仅包含与特定 Zimbra OSE 元素相关的条目。 例如,audit.log 仅包含有关用户身份验证的记录,clamd.log 包含有关防病毒操作的数据,等等。 顺便说一句,保护 Zimbra OSE 服务器免受入侵者侵害的一个极好方法是 使用 Fail2Ban 保护服务器,它仅基于audit.log工作。 添加 cron 任务来执行命令也是一个很好的做法 grep -ir “无效密码” /opt/zimbra/log/audit.log接收每日登录失败信息。

如何使用 Zimbra OSE 日志
示例:audit.log 如何显示两次错误输入的密码和一次成功的登录尝试。

Zimbra OSE 中的日志对于识别各种严重故障的原因非常有用。 当发生严重错误时,管理员通常没有时间阅读日志。 需要尽快恢复服务器。 但是,稍后,当服务器备份并生成大量日志时,可能很难在大文件中找到所需的条目。 为了快速找到错误记录,只要知道服务器重新启动的时间并在日志中找到从该时间开始的条目就足够了。 先前的条目将记录所发生的错误。 您还可以通过搜索关键字 FATAL 来查找错误消息。

Zimbra OSE 日志还允许您识别非严重故障。 例如,要查找处理程序异常,您可以搜索处理程序异常。 通常,处理程序生成的错误都伴随着堆栈跟踪,该堆栈跟踪解释了导致异常的原因。 如果邮件传送出现错误,您应该使用 LmtpServer 关键字开始搜索,要搜索与 POP 或 IMAP 协议相关的错误,您可以使用 ImapServer 和 Pop3Server 关键字。

日志还可以在调查信息安全事件时提供帮助。 我们来看一个具体的例子。 20月20日,一名员工向客户发送了一封感染病毒的信件。 结果,客户计算机上的数据被加密。 然而,该员工发誓说他没有寄过任何东西。 作为事件调查的一部分,企业安全服务要求系统管理员提供与被调查用户相关的 XNUMX 月 XNUMX 日邮件服务器日志。 借助时间戳,系统管理员可以找到必要的日志文件,提取必要的信息并将其传输给安全专家。 然后,这些人再查看该信件,发现发送这封信的 IP 地址与用户计算机的 IP 地址相对应。 闭路电视录像证实,这封信发出时,该员工正在工作场所。 这些数据足以指控他违反信息安全规则并解雇他。 

如何使用 Zimbra OSE 日志
将有关某个帐户的记录从 Mailbox.log 日志提取到单独文件的示例

当涉及多服务器基础设施时,一切都变得更加复杂。 由于日志是在本地收集的,因此在多服务器基础设施中使用它们非常不方便,因此需要集中收集日志。 这可以通过设置主机来收集日志来完成。 没有特别需要向基础设施添加专用主机。 任何邮件服务器都可以作为收集日志的节点。 在我们的例子中,这将是 Mailstore01 节点。

在此服务器上我们需要输入以下命令:

sudo su – zimbra 
zmcontrol stop
exit
sudo /opt/zimbra/libexec/zmfixperms -e -v

编辑 /etc/sysconfig/rsyslog 文件,并设置 SYSLOGD_OPTIONS=”-r -c 2″

编辑 /etc/rsyslog.conf 并取消注释以下行:
$ModLoad imudp
$UDPServerRun 514

输入以下命令:

sudo /etc/init.d/rsyslog stop
sudo /etc/init.d/rsyslog start
sudo su – zimbra
zmcontrol start
exit
sudo /opt/zimbra/libexec/zmloggerinit
sudo /opt/zimbra/bin/zmsshkeygen
sudo /opt/zimbra/bin/zmupdateauthkeys

您可以使用命令 zmprov gacf | 检查一切是否正常工作。 grep zimbraLog主机名。 执行该命令后,应显示收集日志的主机名称。 为了更改它,您必须输入命令 zmprov mcf zimbraLogHostname mailstore01.company.ru。

在所有其他基础架构服务器(LDAP、MTA 和其他邮件存储)上,运行命令 zmprov gacf |grep zimbraLogHostname 以查看日志发送到的主机的名称。 要更改它,您还可以输入命令 zmprov mcf zimbraLogHostname mailstore01.company.ru

您还必须在每台服务器上输入以下命令:

sudo su - zimbra
/opt/zimbra/bin/zmsshkeygen
/opt/zimbra/bin/zmupdateauthkeys
exit
sudo /opt/zimbra/libexec/zmsyslogsetup
sudo service rsyslog restart
sudo su - zimbra
zmcontrol restart

此后,所有日志都会记录在您指定的服务器上,可以方便地查看。 此外,在 Zimbra OSE 管理员控制台中,在有关服务器状态信息的屏幕上,将仅显示 mailstore01 服务器正在运行的 Logger 服务。

如何使用 Zimbra OSE 日志

管理员另一个头疼的问题是跟踪特定的电子邮件。 由于 Zimbra OSE 中的电子邮件在被接受或发送之前会同时经历多个不同的事件:通过防病毒、反垃圾邮件等扫描,对于管理员来说,如果电子邮件未到达,则追踪到哪个阶段可能会很成问题它丢失了。

为了解决这个问题,您可以使用一个特殊的脚本,该脚本由信息安全专家 Viktor Dukhovny 开发,并推荐 Postfix 开发人员使用。 该脚本连接特定进程日志中的条目,因此,您可以根据其标识符快速显示与发送特定信件相关的所有条目。 它的工作已经在 Zimbra OSE 从 8.7 开始的所有版本上进行了测试。 这是脚本的文本。

#! /usr/bin/perl

use strict;
use warnings;

# Postfix delivery agents
my @agents = qw(discard error lmtp local pipe smtp virtual);

my $instre = qr{(?x)
	A			# Absolute line start
	(?:S+ s+){3} 		# Timestamp, adjust for other time formats
	S+ s+ 		# Hostname
	(postfix(?:-[^/s]+)?)	# Capture instance name stopping before first '/'
	(?:/S+)*		# Optional non-captured '/'-delimited qualifiers
	/			# Final '/' before the daemon program name
	};

my $cmdpidre = qr{(?x)
	G			# Continue from previous match
	(S+)[(d+)]:s+	# command[pid]:
};

my %smtpd;
my %smtp;
my %transaction;
my $i = 0;
my %seqno;

my %isagent = map { ($_, 1) } @agents;

while (<>) {
	next unless m{$instre}ogc; my $inst = $1;
	next unless m{$cmdpidre}ogc; my $command = $1; my $pid = $2;

	if ($command eq "smtpd") {
		if (m{Gconnect from }gc) {
			# Start new log
			$smtpd{$pid}->{"log"} = $_; next;
		}

		$smtpd{$pid}->{"log"} .= $_;

		if (m{G(w+): client=}gc) {
			# Fresh transaction 
			my $qid = "$inst/$1";
			$smtpd{$pid}->{"qid"} = $qid;
			$transaction{$qid} = $smtpd{$pid}->{"log"};
			$seqno{$qid} = ++$i;
			next;
		}

		my $qid = $smtpd{$pid}->{"qid"};
		$transaction{$qid} .= $_
			if (defined($qid) && exists $transaction{$qid});
		delete $smtpd{$pid} if (m{Gdisconnect from}gc);
		next;
	}

	if ($command eq "pickup") {
		if (m{G(w+): uid=}gc) {
			my $qid = "$inst/$1";
			$transaction{$qid} = $_;
			$seqno{$qid} = ++$i;
		}
		next;
	}

	# bounce(8) logs transaction start after cleanup(8) already logged
	# the message-id, so the cleanup log entry may be first
	#
	if ($command eq "cleanup") {
		next unless (m{G(w+): }gc);
		my $qid = "$inst/$1";
		$transaction{$qid} .= $_;
		$seqno{$qid} = ++$i if (! exists $seqno{$qid});
		next;
	}

	if ($command eq "qmgr") {
		next unless (m{G(w+): }gc);
		my $qid = "$inst/$1";
		if (defined($transaction{$qid})) {
			$transaction{$qid} .= $_;
			if (m{Gremoved$}gc) {
				print delete $transaction{$qid}, "n";
			}
		}
		next;
	}

	# Save pre-delivery messages for smtp(8) and lmtp(8)
	#
	if ($command eq "smtp" || $command eq "lmtp") {
		$smtp{$pid} .= $_;

		if (m{G(w+): to=}gc) {
			my $qid = "$inst/$1";
			if (defined($transaction{$qid})) {
				$transaction{$qid} .= $smtp{$pid};
			}
			delete $smtp{$pid};
		}
		next;
	}

	if ($command eq "bounce") {
		if (m{G(w+): .*? notification: (w+)$}gc) {
			my $qid = "$inst/$1";
			my $newid = "$inst/$2";
			if (defined($transaction{$qid})) {
				$transaction{$qid} .= $_;
			}
			$transaction{$newid} =
				$_ . $transaction{$newid};
			$seqno{$newid} = ++$i if (! exists $seqno{$newid});
		}
		next;
	}

	if ($isagent{$command}) {
		if (m{G(w+): to=}gc) {
			my $qid = "$inst/$1";
			if (defined($transaction{$qid})) {
				$transaction{$qid} .= $_;
			}
		}
		next;
	}
}

# Dump logs of incomplete transactions.
foreach my $qid (sort {$seqno{$a} <=> $seqno{$b}} keys %transaction) {
    print $transaction{$qid}, "n";
}

该脚本是用 Perl 编写的,要运行它,您需要将其保存到文件中 整理文件,使其可执行,然后运行指定日志文件的文件并使用 pgrep 提取您要查找的字母的标识信息 collat​​e.pl /var/log/zimbra.log | pgrep '[电子邮件保护]>'。 结果将是包含有关服务器上信件移动信息的行的顺序输出。

# collate.pl /var/log/zimbra.log | pgrep '<[email protected]>'
Oct 13 10:17:00 mail postfix/pickup[4089]: 4FF14284F45: uid=1034 from=********
Oct 13 10:17:00 mail postfix/cleanup[26776]: 4FF14284F45: message-id=*******
Oct 13 10:17:00 mail postfix/qmgr[9946]: 4FF14284F45: from=********, size=1387, nrcpt=1 (queue active)
Oct 13 10:17:00 mail postfix/smtp[7516]: Anonymous TLS connection established to mail.*******[168.*.*.4]:25: TLSv1 with cipher ADH-AES256-SHA (256/256 bits)
Oct 13 10:17:00 mail postfix/smtp[7516]: 4FF14284F45: to=*********, relay=mail.*******[168.*.*.4]:25, delay=0.25, delays=0.02/0.02/0.16/0.06, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 878833424CF)
Oct 13 10:17:00 mail postfix/qmgr[9946]: 4FF14284F45: removed
Oct 13 10:17:07 mail postfix/smtpd[21777]: connect from zimbra.******[168.*.*.4]
Oct 13 10:17:07 mail postfix/smtpd[21777]: Anonymous TLS connection established from zimbra.******[168.*.*.4]: TLSv1 with cipher ADH-AES256-SHA (256/256 bits)
Oct 13 10:17:08 mail postfix/smtpd[21777]: 0CB69282F4E: client=zimbra.******[168.*.*.4]
Oct 13 10:17:08 mail postfix/cleanup[26776]: 0CB69282F4E: message-id=zimbra.******
Oct 13 10:17:08 mail postfix/qmgr[9946]: 0CB69282F4E: from=zimbra.******, size=3606, nrcpt=1 (queue active)
Oct 13 10:17:08 mail postfix/virtual[5291]: 0CB69282F4E: to=zimbra.******, orig_to=zimbra.******, relay=virtual, delay=0.03, delays=0.02/0/0/0.01, dsn=2.0.0, status=sent (delivered to maildir)
Oct 13 10:17:08 mail postfix/qmgr[9946]: 0CB69282F4E: removed

对于与 Zextras Suite 相关的所有问题,您可以通过电子邮件联系 Zextras Ekaterina Triandafilidi 的代表 [电子邮件保护]

来源: habr.com