我想为我的服务器编写一些脚本来读取和解析电子邮件[电子邮件保护]例如,调整 iptables 防火墙白名单或黑名单。随着我扩展家庭自动化,我将更多地使用此功能。
我还需要电子邮件客户端吗?我想知道,仅仅在我的服务器上安装 MTA 是否就可以将收到的电子邮件放在文件系统的某个位置,然后脚本可以读取并解析它。我确实安装了 postfix,它为我提供了电子邮件发送功能(我相信也为我提供了 MTA)。
系统将使用的电子邮件帐户是附近 ISP(Walnut Communications)提供的电子邮件帐户。目前,我既不使用该电子邮件帐户做任何事情,也不使用我的服务器阅读电子邮件。我在这方面有一个附带问题:为什么我甚至无需通过 Walnutel.net 电子邮件帐户进行身份验证就可以发送电子邮件,而无需为其提供我认为互联网电子邮件基础设施所要求的凭证或可信度?‘
如果我能理解这两件事,我就能取得更大的进步。请注意,该服务器是无头的、CLI 的和无人值守的,所以我不需要通过它浏览电子邮件收件箱。
编辑于 2015 年 12 月 25 日:我了解到我寻求的电子邮件方法称为“bash 套接字”。在我的研究中,我尚不清楚我是否一定需要使用我的本地电子邮件帐户凭据进行身份验证才能可靠地将电子邮件发送到我的非本地 gmail 帐户,以及我是否需要使用 SSL(TLS 等)。如果需要使用 SSL/TLS 与电子邮件服务器通信,恐怕很难找到 bash 脚本示例。
答案1
我还需要电子邮件客户端吗?
是的,从远程邮件服务器检索电子邮件从定义上来说就是邮件客户端的工作。它不需要像 Thunderbird 这样的功能齐全的桌面程序,但它fetchmail
应该可以为您完成这项工作。
为什么我甚至无需通过 Walnutel.net 电子邮件帐户进行身份验证就可以发送电子邮件,而无需为其提供我认为互联网电子邮件基础设施所要求的凭证或可信度?
出于同样的原因,您可以在将信封放入邮箱之前在信封的左上角写上任何地址,而不必证明您确实住在那里:证明发件人的身份不是该系统的目标。
答案2
我成功地使用 bash-socket-scripting 获取和解析了电子邮件,而完全没有使用任何电子邮件客户端。这很容易实现,因为我的 ISP(Walnut Communications)不需要 SSL 来从他们的邮件服务器下载电子邮件。如果我需要在 Cox Communications 网络内执行此操作(他们口头声明他们需要 SSL 才能执行相同操作),那么这会更加困难,因为必要的openssl s_client -connect pop.cox.net:995 -CApath /etc/ssl/certs
命令似乎只是交互式的。
这是用于登录本地 ISP 提供的电子邮件帐户(不需要 SSL)的 bash 脚本。请注意,此示例脚本中的密码是纯文本,因此您可能需要在这些命令中添加密码隐藏措施。
#!/bin/bash
# interactive use enabled by [ ! -z $PS1 ] && echo...
exec 5<>/dev/tcp/pop3.walnutel.net/110
read -t 2 -u 5 HELO;[ ! -z $PS1 ] && echo "$HELO"
echo -e "user email_account_name_here\r" >&5 #prepend account name with "user "
read -t 2 -u 5 sendyourpassword;[ ! -z $PS1 ] && echo $sendyourpassword
echo -e "pass password_here\r" >&5 #prepend password with "pass "
read -t 2 -u 5 maildroplockedandready;[ ! -z $PS1 ] && echo -e $maildroplockedandready
echo -e "list\r" >&5
echo "" > ~/mailcontent;numofemails=-1;echo "" > ~/email_fetch_parse.log
while read -t 2 -u 5 emailtitle; do
[ ! -z $PS1 ] && echo "$emailtitle"
[ $(( ${#emailtitle} )) -lt 3 ] && break
if [ $(( ${#emailtitle} )) -lt 20 ]; then
#add to array of emailtitlnums
numofemails=$(( $numofemails + 1 ))
emailtitlenums[ $((numofemails)) ]=${emailtitle% *}
fi
done
if [ $((numofemails)) -gt -1 ]; then
for i in `seq 0 $((numofemails))`;do
echo -e "RETR ${emailtitlenums[i]}\r" >&5
boundary=""
while read -t 2 -u 5 mailcontentline;do
[ ! -z $PS1 ] && echo "$mailcontentline"
mailcontentline="${mailcontentline:: -1} " #strip the linefeed and put space there instead
if [ -z "$boundary" ];then [ $(echo "$mailcontentline"|grep -e "^Content-Type: "|grep -c "; boundary=") -gt 0 ] && boundary="$(echo "$mailcontentline"|grep -e "^Content-Type: " -e "; boundary="|/usr/bin/awk -F= '{print $2}')"
else
echo "$(grep -e "search string 1" -e "search string 2,etc" <(echo "$mailcontentline"))" >> ~/mailcontent #save lines of interest
[ $(bc <<<"${#mailcontentline} - ${#boundary}") -eq 4 ] && [ "${mailcontentline:2: -3}" == "${boundary:: -1}" ] && (for i in `seq 1 4`; do read -t 2 -u 5 mailcontentline;done) && break #
fi
done
done
for i in `seq 0 $((numofemails))`;do # to delete emails immediately
echo -e "dele ${emailtitlenums[i]}\r" >&5
while read -t 2 -u 5 deleteresponse;do [ ! -z $PS1 ] && echo "$deleteresponse";[ $(( ${#deleteresponse} )) -lt 1 ] && break;done
done
# parse ~/mailcontent here if you want. It now contains lines of interest from all emails read
else
[ ! -z $PS1 ] && echo "Inbox is empty" # >> ~/email_fetch_parse.log
fi
echo -e "QUIT\r" >&5
exec 5>&-
关于第二个问题,我了解到我的手机提供商短信服务最近停止接受来自我 [未认证] 家庭系统的直接电子邮件。这意味着我的系统无法再向我发送家庭安全事件的短信,直到我完成脚本以验证我的一个认证电子邮件帐户,是仍然可以给我发短信。因此,使用 shell 脚本,我不再需要电子邮件客户端来获取电子邮件,一旦我让脚本可以用于发送电子邮件,我的安全系统就不再需要任何第三方邮件工具,无论是 mailutils、procmail、sendmail 还是其他。对我来说,好处是我不会遇到我不知道的配置设置,而且很难/不方便确定我的应用程序所需的适当值。