仅使用Bash和Sendmail发送多个输入文件和/或管道作为电子邮件中的附件

本文介绍如何仅使用Bash和Sendmail在加固的DMZ服务器上发送多个文件或管道内容作为邮件附件,包括纯文本MIME编码的详细步骤。

Over the years I've spent many an hour playing on hardened, DMZ'd servers, with only a sub-set of the usual GNU toy's to keep me company; frequently I've needed to save and send log or data extracts from these server back to my PC, or to others, and more often than not, to do this on a regular basis.

多年来,我花了一个多小时在加固的DMZ服务器上玩游戏,但只有一小部分常用的GNU玩具可以让我陪伴。 经常,我需要将这些服务器的日志或数据摘录保存并发送回我的PC或其他人,并且经常(经常)这样做。

Simple enough on an open box, just cron a script to extract and format the necessary data and either send it as a uuencoded / base 64 mmencoded attachment in an email, or simply copy / scp's the file to somewhere you can get at it e.g. a NFS or SMB mount. BUT if the server is in a DMZ you'll likely find access to any shared internal file systems and / or permission to store a private key to scp / ssh into your network not available to you, leaving email as the only practical method to send data to yourself or others being.

在一个打开的盒子上足够简单,只需cron一个脚本以提取和格式化必要的数据,然后将其作为uuencoded / base 64 mmencoded附件发送到电子邮件中,或者简单地将文件复制/ scp到您可以获取的位置,例如NFS或SMB安装。 但是,如果服务器位于DMZ中,则您可能会发现无法访问任何共享的内部文件系统和/或将私钥存储到scp / ssh到网络中的权限不可用,因此电子邮件是唯一实用的发送方法数据给自己或他人。

If the box is performing a non trivial function in the DMZ it's more than likely been hardened to some extent, and all non essential toys removed, so you'll probably find your lacking the likes of uuencode, mmencode, and perl, leaving you none of the standard mechanism to encode and to attach files to email.

如果盒子在DMZ中执行非琐碎的功能,那么它一定程度上已经变硬了,并且删除了所有非必需的玩具,所以您可能会发现自己缺少uuencode,mmencode和perl之类的东西,却一无所获编码和将文件附加到电子邮件的标准机制。

You could take the quick and dirty option of just piping the data / log into an email body an hoping Outlook will treat your data kindly, and not assume it's a malicious script, or part of the email header, or in need of some character-set conversion. This approach kept me happy for a number of years, but while working with Rockroads several  year back, I was made aware of plain text mime attachments, and haven't looked back.

您可以选择快速而肮脏的选择,只是将数据/登录到电子邮件正文中,希望Outlook会友好地对待您的数据,而不是假定它是恶意脚本,电子邮件标头的一部分或需要某些字符,设定转换。 这种方法使我开心了很多年,但是几年前在与Rockroads一起工作时,我意识到了纯文本的mime附件,并且没有回头。

Plain text mime encoding attachments offer you the ability to:

纯文本mime编码附件使您能够:

Attach CSV, XML or TXT files to a mail,.

将CSV,XML或TXT文件附加到邮件。

To Name the attachments, as they are appear to the recipient.

命名附件,因为它们在收件人中显示。

Allows you to add a BODY to the email, explaining the attachments

允许您向电子邮件中添加正文,解释附件

Offer a mechanism to specify the encoding bits and character set

提供一种机制来指定编码位和字符集

Support multiple attachments in a single mail (multi-part mime)

在单个邮件中支持多个附件( 多部分 mime)

Allow the recipient to simply save an attachments, rather than having to cut-n-paste the data out of the email.

允许收件人简单地保存附件,而不必从电子邮件中剪切粘贴数据。

Requires only shell and sendmail to be available to you on the box.

仅要求外壳程序和sendmail可供您在包装盒上使用。

Anyway per the Wikipedia article, all you need to convert a plain old smtp email in to a mime encoded one is a few content type entries, in your message body, define a unique boundary separator (a string that won't appear in your data), and to add a separator and a few more content type entries between your message body and the attachments data, another separator and finally a couple of -- to mark the end of the mail.

无论如何,按照Wikipedia的文章,将普通的旧smtp电子邮件转换为mime编码后,您需要做的就是在邮件正文中定义一些内容类型条目,并定义一个唯一的边界分隔符(一个不会出现在数据中的字符串) ),并在邮件正文和附件数据之间添加分隔符和其他一些内容类型条目,再添加一个分隔符,最后再加上几个-以标记邮件的结尾。

So in a few minutes you can replace your boring old mail line in your existing script with something a bit more sophisticated, but as I've found I regularly need to send output to myself I have knocked out a few generic scripts over the years that provide a mechanism to send myself one or more file, or the output from a command.

因此,几分钟后,您可以用更复杂的东西替换现有脚本中无聊的旧邮件行,但是正如我发现的那样,我经常需要将输出发送给自己,多年来我淘汰了一些通用脚本,提供一种向自己发送一个或多个文件或命令输出的机制。

Basically the script assumes all the command line argument along with any input piped or redirected in are files you want attached to a predefined email, to be sent to a predefined user. If you have a look through the script you'll obviously spot and realise you'll need to tweak some of the entries in the ---Tweak to suit--- block. Other than that the script is much ready to run.

基本上,脚本假定所有命令行参数以及通过管道或重定向到其中的任何输入都是您想要附加到预定义电子邮件的文件,然后发送给预定义用户。 如果您仔细看一下脚本,您会发现并意识到您需要对--- Tweak中的某些条目进行调整以适应---块。 除此之外,脚本已经可以运行了。

One line possibly worth noting is the following line:

以下一行可能是值得注意的一行:

inputMethod=`stat -L -c %F /proc/$$/fd/0`

The output from the stat call, on the current processes standard input [/prod/$$/fd/0], will indicate if a file [regular file] or stream [fifo] have been piped / redirected into the script, then via a couple of additional if, then, fi blocks that input is ALSO attached to the email, permitting the script to be used in-line, anyway the script:

在当前进程的标准输入[/ prod / $$ / fd / 0]上,stat调用的输出将指示文件[常规文件]或流[fifo]是否已通过管道/重定向到脚本,然后通过然后,如果还阻止了另外两个输入附加到电子邮件中,则允许该脚本以内联方式使用,无论如何该脚本:

#!/bin/sh
# Purpose: email the parametrised list of files to a set user along with any content piped XOR redirected in.

# ========================
DT=`date '+%Y-%m-%d'`
TMP_FL="/tmp/$0.$$"
MAIL_FL=""
ATTACHMENT=""
MIMETYPE="text/plain"
BOUNDARY=`date +%s|md5sum`
BOUNDARY=${BOUNDARY:0:32}
#----- Tweak to suit -----
MAILTO="To: arober11@somehostorother.com"
FROM="doNotReply@somehostorother.com"
REPLY_TO="doNotReply@somehostorother.com"
SUBJECT_LINE="Files from `uname -a` on $DT"
MSGBODY="Files from `uname -a` on $DT"
#----- CMD locations  -----
sendmail="/usr/sbin/sendmail"
sendmailParms=""
readlinkCMD="/usr/bin/readlink"
statCMD="/usr/bin/stat"
basenameCMD="/usr/bin/basename"
#----- Tweak to suit ends-----

#----- Test if anything has been piped or directed at us -----
inputMethod=`$statCMD -L -c %F /proc/$$/fd/0`

# ========================
# Attach file to msg
# ========================
attach_file() {

  cat >> $TMP_FL << EOF

--$BOUNDARY
Content-Type: $MIMETYPE; name="$MAIL_FL"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="$MAIL_FL"

`cat $ATTACHMENT`
EOF
}

# ========================
# Create tmp msg file
# ========================
create_msg() {

  cat > $TMP_FL <<EOF
From: $FROM
`echo -e $MAILTO`
Reply-To: $REPLY_TO
Subject: $SUBJECT_LINE
Content-Type: multipart/mixed; boundary="$BOUNDARY"

This is a MIME formatted message.  If you see this text it means that your
email software does not support MIME formatted messages, but as plain text
encoded you should be ok, with a plain text file.

--$BOUNDARY
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit
Content-Disposition: inline

$MSGBODY

EOF

  while [ $# -gt 0 ]
  do
    if [ -r $1 -a -f $1 -a -s $1 ]
    then
        MAIL_FL="`$basenameCMD $1`"
        ATTACHMENT="$1"
        attach_file
    fi
    shift
  done

  #See if anything has been piped in via STDIN, if it has add it as another attachment
  if [ "$inputMethod" = "fifo" ]
  then
    cat > "${TMP_FL}.from_pipe.stdin"
    MAIL_FL="STDIN_from_PIPE.txt"
    ATTACHMENT="${TMP_FL}.from_pipe.stdin"
    attach_file
  fi

  if [ "$inputMethod" = "regular file" ]
  then
    cat > "${TMP_FL}.from_fl.stdin"
    flName="`$readlinkCMD \`$statCMD  -L -c %n /proc/$$/fd/0\``"
    MAIL_FL="`$basenameCMD $flName`"
    ATTACHMENT="${TMP_FL}.from_fl.stdin"
    attach_file
  fi

  echo -e "\n--$BOUNDARY--\n" >> $TMP_FL
}

# ====
# Main
# ====
if [ $# -gt 0 -a -f "$1" -a -r "$1" ]
then
  create_msg $@
elif echo $inputMethod | egrep -q "character special"
then
  thisCMD=`$basenameCMD $0`
  echo
  echo "Error: No files passed as arguments, piped in, or re-directed in :("
  echo
  echo "usage:    [|]$thisCMD [<file1.txt> [<file2.txt>*]] [<]"
  echo "Purpose:  email the paramertised list of files, to a set user, along with any content piped XOR redirected in"
  echo "examples: cat file1.txt | $thisCMD"
  echo "                          $thisCMD file1.txt file2.txt"
  echo "                          $thisCMD                     < file1.txt"
  echo "          cat file1.txt | $thisCMD file2.txt"
  echo "                          $thisCMD file1.txt file2.txt < file3.txt"
  exit 1
else
  create_msg
fi

# =================
# Email the file(s)
# =================
$sendmail $sendmailParms -t <$TMP_FL
rm -f $TMP_FL*

Andrew Roberts, Oct 2011

安德鲁·罗伯茨,2011年10月

翻译自: https://www.experts-exchange.com/articles/8396/Using-just-Bash-and-Sendmail-to-send-multiple-input-files-and-or-a-pipe-as-attachments-in-an-email.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值