如何使用Zimbra OSE日志

记录所有发生的事件是任何公司系统中最重要的功能之一。日志使您能够解决新出现的问题,审核信息系统的运行以及调查信息安全事件。 Zimbra OSE还保留其工作的详细日志。它们包含从服务器性能到用户发送和接收电子邮件的所有数据。但是,读取Zimbra OSE生成的日志并非易事。在本文中,我们将通过一个特定示例向您介绍如何读取Zimbra OSE日志,以及如何使其集中化。



图片

Zimbra OSE将所有本地日志存储在/ opt / zimbra / log文件夹中,并且还可以在/var/log/zimbra.log文件中找到日志。其中最重要的是mailbox.log。它记录了邮件服务器上发生的所有动作。其中包括信件的传输,有关用户验证的数据,失败的登录尝试等。 mailbox.log中的条目是一个文本字符串,其中包含事件发生的时间,事件的级别,事件发生的流的编号,用户名和其ip地址以及事件的文本描述。







日志级别指示事件影响服务器的程度。默认情况下,使用4级事件:INFO,WARN,ERROR和FATAL。让我们按严重性增加的顺序分析所有级别。



  • INFO — Zimbra OSE.
  • WARN — , , . WARN .
  • ERROR — , . , .
  • FATAL — , - . FATAL .


邮件服务器日志文件每天更新​​。该文件的最新版本始终称为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命令,以便您可以每天收到有关失败登录尝试的信息。





audit.log中如何显示两次错误输入密码和成功登录尝试的示例



Zimbra OSE中的日志对于确定各种严重故障的原因非常有用。在发生严重错误时,管理员通常没有时间读取日志。需要尽快恢复服务器操作。但是,稍后,当服务器再次运行并生成许多日志时,可能很难在大文件中找到所需的条目。为了快速找到错误记录,知道服务器重新启动的时间并在此日期之前的日志中找到一个条目就足够了。先前的记录将是发生的错误的记录。您也可以通过搜索FATAL关键字来找到错误消息。



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



此外,日志可以帮助调查信息安全事件。让我们考虑一个具体的例子。 9月20日,其中一名员工向客户发送了一封病毒感染的信件。结果,客户端计算机上的数据被加密。但是,该员工发誓他没有发送任何东西。作为事件调查的一部分,企业安全服务向系统管理员请求与受调查用户关联的9月20日邮件服务器日志。借助时间戳,系统管理员可以找到带有日志的必要文件,提取必要的信息并将其传输给安全人员。那些人依次浏览,发现发送此信件的IP地址与用户计算机的IP地址匹配。闭路电视录像证实,这封信被发送时,该雇员正在他的工作场所。这些数据足以指控他违反了信息安全规则并解雇了他。 





将有关其中一个帐户的记录从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 zimbraLogHostname。执行该命令后,应显示收集日志的主机的名称。为了对其进行更改,必须输入命令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管理员控制台中,其中包含有关服务器状态的信息,正在运行的Logger服务将仅显示在mailstore01服务器上。







管理员的另一个麻烦是跟踪特定的电子邮件。由于Zimbra OSE中的电子邮件会同时经历几个不同的事件:在接收或发送之前,通过防病毒,反垃圾邮件等检查,对于管理员来说,如果电子邮件没有到达,则在丢失的哪个阶段进行跟踪可能会很成问题。 ...



为了解决此问题,您可以使用由信息安全专家Viktor Dukhovny开发的特殊脚本,建议Postfix开发人员使用。该脚本将特定过程的日志记录串联起来,因此,您可以根据其标识符快速显示与发送特定字母相关的所有记录。从8.7版开始,其工作已在所有版本的Zimbra OSE上进行了测试。这是脚本的文本。



#! /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编写的,要运行该脚本,需要将其保存到collat​​e.pl文件 ,使其可执行,然后运行该文件以指定日志文件,并使用pgrep突出显示所需字母的标识信息 collat​​e.pl /var/log/zimbra.log | pgrep'<20200929164500 \ .user @ mail \ .company \ .ru>'结果将是行的顺序输出,其中包含有关服务器上字母移动的信息。



# collate.pl /var/log/zimbra.log | pgrep '<20200929101700\.user@mail\.company\.ru>'
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的所有问题,您可以通过电子邮件katerina@zextras.com与Zextras公司Ekaterina Triandafilidi的代表联系。



All Articles