Canary Workshop

Whatever is worth doing at all is worth doing well

SSH登录的邮件提醒脚本

今天看到网上的一些实现登录SSH发邮件提醒的方案,觉得都有所欠缺,于是用Python 3又造了个轮子出来
特点:

  • 同时支持IPv4和IPv6的IP归属地查询
  • IP归属地较为精确
  • 使用SendGridPython API发送邮件

于是轮子如下= =


先安装用到的依赖包:

1
pip3 install sendgrid geoip2

下载MaxMind的GeoIP数据库供IPv6地址查询用:

1
2
3
4
5
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
tar xvzf GeoLite2-City.tar.gz
rm GeoLite2-City.tar.gz
mv GeoLite2-City*/GeoLite2-City.mmdb GeoLite2-City.mmdb
rm -rf GeoLite2-City_*

然后是程序本体:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import os
import requests
import ast
import time
import sendgrid
from sendgrid.helpers.mail import *
apikey = 'SendGrid的API KEY'
to = '收件邮箱'
fr = '发件邮箱'
ip = os.popen('echo $SSH_CONNECTION | cut -d ‘ ’ -f1').read().replace('\n', '')
sg = sendgrid.SendGridAPIClient(apikey=apikey)
now = time.strftime('%X',time.localtime(time.time()))
def send(subject, data, fr, to):
from_email = Email(fr)
to_email = Email(to)
content = Content("text/plain", data)
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())
if ':' in ip:
reader = geoip2.database.Reader('GeoLite2-City.mmdb')
res = reader.city(ip)
country = res.country.name
state = res.subdivisions.most_specific.name
city = res.city.name
if type(country) == type(None):
country = '未知'
if type(state) == type(None):
state = '未知'
if type(city) == type(None):
city = '未知'
location = country+' '+state+' '+city
else:
response = requests.get('https://freeapi.ipip.net/'+ip)
data = ast.literal_eval(response.text)
location = ''
for i in data:
if not i == '':
location = location+i+' '
location = location[:-1]
subject = 'SSH登录安全提醒'
data = 'SSH登录安全提醒\n登录时间:'+now+' CST\n登录IP地址:'+ip+'\n登录地理位置:'+location
send(subject, data, fr, to)

注意事项:
由于SendGrid会自己把纯文本转换为HTML导致换行丢失,所以需要去SendGrid的后台把转换关掉,以纯文本格式发送邮件。