这maldet / Rfxn Linux MalDetect 文档即使没有找到任何内容,也可以使用以下命令获取电子邮件报告:
-e, --report SCANID email View scan report of most recent scan or of a specific SCANID and optionally e-mail the report to a supplied e-mail address e.g: maldet --report e.g: maldet --report list e.g: maldet --report 050910-1534.21135 e.g: maldet --report SCANID [email protected]
一切都非常简单,但我不确定如何在此处将电子邮件地址作为第二个参数传递,同时允许第一个参数(扫描 ID)恢复为默认值,以便 maldet 将最新报告通过电子邮件发送到此自定义电子邮件地址。我希望能够使用它(例如在 cron 中)定期检查 Maldet 是否正在扫描并能够按预期发送电子邮件报告。
我已经尝试过maldet --report "" [email protected]
在 bash 中传递空变量的标准方法,但它会忽略它并在控制台中输出看起来像空报告的内容。
我也尝试过诸如和之类的东西,但它会响应。maldet --report 0 [email protected]
maldet --report " " [email protected]
{report} no report found, aborting
如果相关的话,环境是 Centos。
答案1
要么作者maldet
没有提供这种可能性,要么忽略了记录。从外部猜测是不可能的。最好的前进方式是特里姆大学:在程序源代码中查找它如何处理该-e
选项,以及是否有办法同时启动“最近扫描”分支并激活电子邮件选项。
答案2
抱歉,又提起一个老问题。每次扫描后,我都尝试让 maldet 通过电子邮件发送报告,但遇到了同样的问题。我按照 @Tilman 的建议深入研究了源代码。负责发送报告电子邮件的函数 view_report() 可以在/usr/local/maldetect/internals/functions
v1.6.4 中的第 645-706 行中找到。具体查看负责的代码(第 681-696 行),我们发现只有当 SCANID(存储为$rid
)是后缀时才会发送邮件,即190429-0343.31494
,对应于存在于/usr/local/maldetect/sess/
以下位置的报告的文件名:session.190429-0343.31494
if [ -f "$sessdir/session.$rid" ] && [ ! -z "$(echo $2 | grep '\@')" ]; then
if [ -f "$mail" ]; then
cat $sessdir/session.$rid | $mail -s "$email_subj" "$2"
elif [ -f "$sendmail" ]; then
if ! grep -q "SUBJECT: " "$sessdir/session.$rid"; then
echo -e "SUBJECT: $email_subj\n$(cat $sessdir/session.$rid)" > $sessdir/session.$rid
fi
cat $sessdir/session.$rid | $sendmail -t "$2"
else
eout "{scan} no \$mail or \$sendmail binaries found, e-mail alerts disabled."
exit
fi
eout "{report} report ID $rid sent to $2" 1
exit
fi
处理空 SCANID 的代码紧接着此代码(第 697-705 行):
if [ "$rid" == "" ] && [ -f "$sessdir/session.last" ]; then
rid=`cat $sessdir/session.last`
$EDITOR $sessdir/session.$rid
elif [ -f "$sessdir/session.$rid" ]; then
$EDITOR $sessdir/session.$rid
else
echo "{report} no report found, aborting."
exit
fi
我原本以为处理空 SCANID 的代码会简单地抓取最新的 SCANID 并通过电子邮件发送。它实际上做的是查看/usr/local/maldetect/sess/session.last
maldet 存储最新 SCANID 的位置。然后,出于某种原因,它会在终端编辑器中打开相应的报告,而不是直接将其打印出来。请注意,实际上没有任何可用的代码可以通过电子邮件发送最新的报告。
-- 更新修复 - 2019 年 5 月 5 日 --
由于阻止 LMD 执行完整性检查(如我最初的修复程序中所要求的)存在潜在的安全风险,因此我使用 LMD 的 custom.cron 创建了一个替代解决方案。这样做的好处是完整性检查仍然有效,并且电子邮件脚本应该在更新后仍然存在。您无需触碰 LMD 内部文件或 maldet daily cron。
确保$email_alert="1"
和$email_addr=
中至少设置为一个正确的电子邮件地址/usr/local/maldetect/conf.maldet
。然后将以下内容添加到/usr/local/maldetect/cron/custom.cron
,它将在 maldet 每日 cron 结束时自动运行:
##
# Please use this file for preservation of custom LMD execution code for the daily cronjob.
# NOTE: scripts in this file are called at the end of maldet daily cron as $custom_cron_exec
##
# log_cron="1" enable logging, log_cron="0" disable logging
# applies only to the code in this file
log_cron="1"
# logging function borrowed from /maldetect/internals/functions
eout() {
if [ "$log_cron" == "1" ]; then
msg="$1"
stdout="$2"
appn=maldet
if [ ! -d "$logdir" ]; then
mkdir -p $logdir ; chmod 700 $logdir
fi
if [ ! -f "$maldet_log" ]; then
touch $maldet_log
fi
log_size=`$wc -l $maldet_log | awk '{print$1}'`
if [ "$log_size" -ge "20000" ]; then
trim=1000
printf "%s\n" "$trim,${log_size}d" w | ed -s $maldet_log 2> /dev/null
fi
if [ ! "$msg" == "" ]; then
echo "$(date +"%b %d %H:%M:%S") $(hostname -s) $appn($$): $msg" >> $maldet_log
if [ ! -z "$stdout" ]; then
echo "$appn($$): $msg"
fi
fi
fi
}
eout "{cron} running $cron_custom_exec"
##
# LMD Daily Email v1.0.0
# Author: kdub Email: [email protected] Date: May 5th, 2019
# https://github.com/kdubdev/linux-malware-detect/blob/master/files/cron/custom.cron
# Script to send email of newest report after daily scan. More info:
# https://serverfault.com/questions/805158/how-to-get-an-email-report-of-whatever-the-most-recent-maldet-scan-is
# #
de_version='v1.0.0'
eout "{cron} starting LMD Cron Email $de_version"
eout "{cron} $intcnf shows email_alert=$email_alert email_addr=$email_addr"
# Default email subject defined in /usr/local/maldetect/internals/internals.conf
# is email_subj="maldet alert from $(hostname)"
# comment this line to use the default email_subj or change to what you want
printf -v email_subj '[%s] %s: Scan Report' "$(hostname)" "$appn($$)"
# uncomment email_addr below to override recipients. Separate multiple emails with ,
# use $email_addr to include recipient defined in /usr/local/maldetect/conf.maldet
# email_addr="$email_addr,[email protected],[email protected]"
# this is the email text inserted before the report
body_intro="Here are the results of the latest LMD scan:"
# this is the email text inserted after the report
printf -v body_footer "Email provided by LMD Cron Email %s\nCron file: %s\nLog file: %s" "$de_version" "$cron_custom_exec" "$maldet_log"
# this is a very weak email validation, just looking for @
if [ "$email_alert" == "1" ] && [ ! -z "$(echo $email_addr | grep '\@')" ]; then
# email_alert is true and email provided, send newest report
if [ -f "$sessdir/session.last" ]; then
# Get most recent scan id
rid=$(cat "$sessdir/session.last")
if [ ! -z "$rid" ]; then
# session.list contains something
if [ -f "$sessdir/session.$rid" ]; then
# report exists, get contents
body=$(cat "$sessdir/session.$rid")
eout "{cron} reading report $sessdir/session.$rid"
else
# report doesn't exist
body="{cron} unable to find report $sessdir/session.$rid."
fi
if [ -z "$body" ]; then
# report file exists but is empty
body="{cron} report $sessdir/session.$rid is empty."
fi
else
# session.last is empty
body="{cron} $sessdir/session.last is empty."
fi
else
# session.last doesn't exist
body="{cron} unable to find $sessdir/session.last."
fi
# log if body starts with {cron} ie there's a problem reading report
if [[ $body == '{cron}'* ]]; then
eout "$body"
fi
# add intro and footer to body
body=$(printf "%s\n\n%s\n\n%s\n\n" "$body_intro" "$body" "$body_footer")
if [ -f "$mail" ]; then
printf "%s" "$body" | $mail -s "$email_subj" "$email_addr"
eout "{cron} mail sent using $mail to $email_addr, subject: $email_subj."
elif [ -f "$sendmail" ]; then
printf "%s\n%s" "$email_subj" "$body" | $sendmail -t "$email_addr"
eout "{cron} mail sent using $sendmail to $email_addr, subject: $email_subj."
fi
fi
eout "{cron} mail latest report finished."
eout "{cron} done running $cron_custom_exec"
您也可以在此处查看更新https://github.com/kdubdev/linux-malware-detect/blob/master/files/cron/custom.cron
在脚本中,您可以禁用日志记录、覆盖电子邮件主题和/或收件人,以及自定义电子邮件正文简介和页脚。该脚本有大量注释,因此您可以跟进或进行更改。
我欢迎任何反馈或改进建议。
-- 以下是原始修复 --
为了修复这个问题并添加其他改进,我修改了 view_report() 并进行了以下更改:
- 添加选项“newest”作为别名
--report
,以--report ""
允许$ maldet --report newest [email protected]
- 使用或
$ maldet --report newest [email protected]
$ maldet --report "" [email protected]
- 不再需要使用编辑器查看报告,而是直接打印到终端
- 改进日志记录
第一的:您需要进行设置,autoupdate_version_hashed="0"
以/usr/local/maldetect/conf.maldet
防止 LMD 在运行更新检查时自动覆盖您所做的任何更改。请注意,这是一个潜在的安全问题:
# This controls validating the LMD executable MD5 hash with known
# good upstream hash value. This allows LMD to replace the the
# executable / force a reinstallation in the event the LMD executable
# is tampered with or corrupted. If you intend to make customizations
# to the LMD executable, you should disable this feature.
# [0 = disabled, 1 = enabled]
autoupdate_version_hashed="0"
第二:将当前的view_report()
/usr/local/maldetect/internals/functions
(645-706 行) 替换为:
view_report() {
# $1 is first arg passed from command line ex. $ maldet --report $1 $2
rid="$1"
# $ maldet --report list
if [ "$rid" == "list" ]; then
tmpf="$tmpdir/.areps$$"
for file in `ls $sessdir/session.[0-9]* 2> /dev/null`; do
SCANID=`cat $file | grep "SCAN ID" | sed 's/SCAN ID/SCANID/'`
FILES=`cat $file | grep "TOTAL FILES" | sed 's/TOTAL //'`
HITS=`cat $file | grep "TOTAL HITS" | sed 's/TOTAL //'`
CLEAN=`cat $file | grep "TOTAL CLEANED" | sed 's/TOTAL //'`
TIME=`cat $file | grep -E "^TIME|^STARTED" | sed -e 's/TIME: //' -e 's/STARTED: //' | awk '{print$1,$2,$3,$4}'`
TIME_U=`date -d "$TIME" "+%s" 2> /dev/null`
ETIME=`cat $file | grep "ELAPSED" | awk '{print$1,$2}' | sed 's/ELAPSED/RUNTIME/'`
if [ -z "$ETIME" ]; then
ETIME="RUNTIME: unknown"
fi
if [ ! -z "$SCANID" ] && [ ! -z "$TIME" ]; then
clean_zero=`echo $CLEAN | awk '{print$2}'`
if [ -z "$clean_zero" ]; then
CLEAN="CLEANED: 0"
fi
echo "$TIME_U | $TIME | $SCANID | $ETIME | $FILES | $HITS | $CLEAN" >> $tmpf
fi
done
if [ -f "$tmpf" ]; then
if [ "$OSTYPE" == "FreeBSD" ]; then
cat $tmpf | sort -k1 -n | cut -d'|' -f2-7 | column -t | more
else
cat $tmpf | sort -k1 -n | tac | cut -d'|' -f2-7 | column -t | more
fi
rm -f $tmpf 2> /dev/null
exit 0
else
eout "{list} unable to find report data for list, check \$sessdir"
exit 1
fi
fi
# If no SCANID is provided or "recent" then set $rid to most recent.
# $ maldet --report "" or $maldet --report newest
if { [ "$rid" == "" ] || [ "$rid" == "newest" ]; } && [ -f "$sessdir/session.last" ]; then
rid=`cat $sessdir/session.last`
fi
# make sure report exists
if [ -f "$sessdir/session.$rid" ]; then
# if email is provided, then send the report and exit
if [ ! -z "$(echo $2 | grep '\@')" ]; then
if [ -f "$mail" ]; then
cat $sessdir/session.$rid | $mail -s "$email_subj" "$2"
elif [ -f "$sendmail" ]; then
if ! grep -q "SUBJECT: " "$sessdir/session.$rid"; then
echo -e "SUBJECT: $email_subj\n$(cat $sessdir/session.$rid)" > $sessdir/session.$rid
fi
cat $sessdir/session.$rid | $sendmail -t "$2"
else
# eout is an internal function to log to maldet_log and echo
eout "{scan} no \$mail or \$sendmail binaries found, e-mail alerts disabled."
exit
fi
eout "{report} report ID $rid sent to $2" 1
exit
# no email is provided so show report and exit
else
printf '%b\n' "$(cat $sessdir/session.$rid)"
exit
fi
# can't find requested report so log & echo error
else
eout "{report} unable to find report session.\$rid, aborting."
exit
fi
}
/usr/local/maldetect/internals/functions
您也可以在此处的拉取请求中找到整个更新的文件:https://github.com/kdubdev/linux-malware-detect/blob/patch-1/files/internals/functions
最后的:/etc/cron.daily/maldet
如果您希望在每次每日扫描后收到电子邮件, 请在末尾添加以下行:$inspath/maldet --report newest [email protected]
注意:如果不清楚,可以互换使用-e
或--report
。
答案3
您应该编辑/usr/local/maldetect/conf.maldet
第 22 行并将其替换为有效地址。email_addr="[email protected]"
编辑:
我错误地阅读了原始帖子,但这个设置可以帮助其他人。
答案4
我的解决方案是查找文件中最新的扫描报告 ID/usr/local/maldetect/sess/session.last
像这样的包装脚本是从 Cron 调用的
#!/bin/bash
recipient=${recipient:[email protected]}
# Upgrade Maldet and Update the signatures
maldet -d
maldet -u
# Perform a scan on files created in the last week
maldet -r / 7
logger -t "system_scan" "Maldet Task ended with RC=$?"
# Send the last scan via email
maldet -e $(cat /usr/local/maldetect/sess/session.last) "$recipient"
请注意,“收件人”将提供默认值,但用户可以覆盖它,例如:
[email protected] ./scan.sh
一些陷阱:
- 检查 session.last 文件的位置是否有效!!我不确定这是否是一个记录在案的功能,因此它可能会改变
- 如果运行多次扫描,结果可能不可预测。
maldet -e list
可以使用解析结果来获取报告列表。 - 我没有尝试处理任何步骤的错误,也没有尝试捕获错误输出等。