如图示:
目标:通过邮箱获取服务器公网地址
发送端:sendmail + msmtp
接收端:fetchmail
原始邮件过滤:awk, sed
*将接收工作置于Linux平台下将有机会获得好的体验,譬如一键ssh连接,无需手动将地址复制粘贴至putty中。
I.探测与发送
msmtp配置文件参照: OpenWrt发送邮件(支持TLS)
定时任务如下:
#!/bin/bash
# Code by Soundtrack9407
# blog.youkuaiyun.com/ke515041
ADDR=`curl -s icanhazip.com`
ADDR_OLD="/var/addr_old"
WAN_LOG="/etc/diy/wan_history"
#---------------------------------
send_mail(){
echo -e "Subject: Data\r\n\r\n$1" | msmtp --from=xxx@126.com -t xxx@126.com
}
write_ADDR(){
echo $1 > /var/addr_old
}
#---------------------------------
if [ -n "$ADDR" ] ; then
if [ -f "$ADDR_OLD" ] ; then
if [ "$ADDR" != "$ADDR_OLD" ] ; then
send_mail $ADDR
write_ADDR $ADDR
echo $ADDR >> $WAN_LOG
fi
else
send_mail $ADDR
write_ADDR $ADDR
echo $ADDR >> /etc/diy/wan_history
fi
fi
脚本流程图
II.接收与解析
Windows平台:使用网易邮箱客户端Chrome插件,登录密码为客户端授权码,新邮件数量提示功能(有延时)。
Linux平台,以Ubuntu 16.04 LTS 为例:
sudo apt-get install fetchmail
fetchmail将根据配置文件来检查邮箱:
poll pop3.126.com proto pop3
uidl
auth password
user xxxxx@126.com
password 第三方客户端授权码
options
keep
ssl
keep,从邮箱中复制邮件内容而不是剪切;
ssl,开启TLS,提高传输安全性;
fetchmail -f ~/.fetchmail
收取后的邮件将置于/var/mail/目录下
III. 过滤
收取后的邮件充斥着原始信息,从中提取服务器公网地址:
示例:
From sendmail@126.com Wed Jan 4 22:18:35 2017
Return-Path: <sendmail@126.com>
Received: from Inspiron (localhost [127.0.0.1])
by Inspiron (8.15.2/8.15.2/Debian-3) with ESMTP id v04EIYwU002366
for <helloworld@localhost>; Wed, 4 Jan 2017 22:18:35 +0800
Received: from pop3.126.idns.yeah.net [220.181.15.128]
by Inspiron with POP3 (fetchmail-6.3.26)
for <helloworld@localhost> (single-drop); Wed, 04 Jan 2017 22:18:35 +0800 (CST)
Received: from localhost (unknown [113.84.191.99])
by smtp7 (Coremail) with SMTP id DsmowAD3aajjNmxYXgBIDw--.62687S3;
Wed, 04 Jan 2017 07:42:28 +0800 (CST)
Subject: Data
X-CM-TRANSID:DsmowAD3aajjNmxYXgBIDw--.62687S3
Message-Id:<586C36E4.A43509.22999@m15-114.126.com>
X-Coremail-Antispam: 1Uf129KBjDAr29KB7ZKAUJBBBBB549EdanIXcx71AAAAAA7v73
VFW2AGmfu7bjvjm3AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxUvG-eUUUUU
X-Originating-IP: [113.84.191.99]
Date: Wed, 4 Jan 2017 07:42:28 +0800 (CST)
From: sendmail@126.com
X-CM-SenderInfo: xsxezudrp/1tbicwRAGlUw3+XZSAUEAsz
113.84.191.99
提取关键字”X-Originating-IP”(发件人ip),过滤
awk '/X-Originating-IP/{print $2}' /var/mail/soundtrack | sed 's/\[*]*//g;N;D'
使用keep关键字,fetchmail会将邮件全部复制下来(有待改进之处,只复制最新邮件并删除旧邮件,可有效减少数据处理量),但只需要最新的地址。
操作:先按关键字过滤并打印有ip地址的列,再去方括号取最后一行(最新):
helloworld@Inspiron:~/vps$ awk '/X-Originating-IP/{print $2}'
[123.84.108.108]
[123.84.191.99]
[123.84.186.217]
[123.84.191.213]
[123.84.190.22]
[123.84.108.144]
[123.84.187.226]
[123.84.109.167]
[123.84.189.45]
[12.124.188.125]
[163.46.192.61]
[12.124.189.74]
[12.148.124.254]
helloworld@Inspiron:~/vps$ awk '/X-Originating-IP/{print $2}' | sed 's/\[*]*//g;N;D'
12.148.124.254
Ⅳ.调用自动化
在Ubuntu平台下,创建到远程服务器的ssh、OpenVPN连接,用脚本取代重复操作:
#!/bin/bash
# Mutli-VPS SSH Connect Controller
ras_vps=(game "" "22" key/key_vps)
canada_vps=(game "192.169.12.1" "22" key/key_vps)
action(){
ssh $1@$2 -p $3 -i $4
}
echo "VPS Secure Connect"
echo "->1 RAS"
echo "->2 Canada"
read -p "[1-2] " num
if [ "$num" -eq "1" ];then
fetchmail -f ~/.fetchmail
ras_vps[1]="`awk '/X-Originating-IP/{print $2}' /var/mail/soundtrack | sed 's/\[*]*//g;N;D'`"
fi
case $num in
1)action ${ras_vps[0]} ${ras_vps[1]} ${ras_vps[2]} ${ras_vps[3]} ;;&
2)action ${canada_vps[0]} ${canada_vps[1]} ${canada_vps[2]} ${canada_vps[3]} ;;&
esac
V.改进
A.在Linux平台下已经能获取到发件人地址,便没有必要将服务器地址作为正文进行发送。
B.不使用icanhazip.com获取公网地址,更改为向主路由查询Router Automatic Controller “curl”。
C.报错:收取带有附件的邮件,因为只需要收取带有服务器IP的邮件,使用 -l参数,只收取size小于指定字节数的邮件(实测每封约600-605字节)。
fetchmail -f .fetchmail -l 630
鸣谢
Google
使用 fetchmail
Fetchmail使用简介(转)
shell脚本检测网络是否畅通
Manual Reference Pages - fetchmail