如果你服务器被入侵了,该怎么做才能让自己第一时间知晓?
答案很多,其中一个方法是ssh登陆后发送报警信息给相关人员。
ssh远程登陆自身是可以设置提示消息的,比如sshd_config的Banner,不过本文描述另外方法,通过/etc/profile设置。
/etc/profile这个文件是每个用户登录时都会运行的环境变量设置,当用户第一次登录时,该文件被执行, 并从/etc/profile.d目录的配置文件中搜集shell的设置。
依此,我们写个shell脚本在每次远程登陆终端、复制终端时报警。
环境要求:
安装jq、screen软件包: yum -y install jq screen
部署脚本,比如/data/public/LoginAlert.sh
/etc/profile追加报警脚本:
比如 screen -fa -d -m -S WL sh /data/public/LoginAlert.sh(shell版本)
比如 screen -fa -d -m -S WL python /data/public/LoginAlert.py(python版本)
shell版本,LoginAlert.sh脚本内容如下:
#!/bin/bash
# Author: www.saintic.com
# Email: staugur@saintic.com
# Date: 2017-08-11
# Docs: 登陆(新开终端或者复制终端)触发报警消息
#require jq
if [ ! -f $(which jq) ];then
yum -y install jq
fi
#Geo2IP by Legion(http://www.dwhd.org/)
eval `curl -s "http://ip.taobao.com/service/getIpInfo.php?ip=${SSH_CLIENT%% *}" | jq . | awk -F':|[ ]+|"' '{if($3~/^(country|area|region|city|isp)$/){print $3"="$7}}'`
if [ $(last $USER |grep "still logged in" |wc -l) != "0" ];then
isOnline="会话中"
else
isOnline="已离线"
fi
hostIps="$(ip addr|grep inet|grep -v 127.0.0.1 |awk '{print $2}' |awk -F / '{print $1}')"
area="${country} ${area} ${region} ${city} ${isp}"
loginTime=$(date "+%Y-%m-%d %H:%M:%S")
#html mail content
msgContent="<div>
<h3>服务器SSH登陆提示</h3>
<p>服务器主机名: `hostname`</p>
<p>服务器IP地址: ${hostIps}</p>
<p>登录用户: ${USER}</p>
<p>登陆状态: ${isOnline}</p>
<p>登录端口: ${SSH_CLIENT##* }</p>
<p>登录来源IP: ${SSH_CLIENT%% *}</p>
<p>登陆IP归属地: ${area}</p>
<p>最后登录时间: ${loginTime}</p>
</div>
"
if [ ! -z "${SSH_CLIENT%% *}" ]; then
# 执行报警任务
# 发送邮件、微信,记录日志等
:
fi
python版本,LoginAlert.py脚本内容如下:
# coding: utf8
# Author: www.saintic.com
# Email: staugur@saintic.com
# Date: 2017-08-14
# Docs: 登陆(新开终端或者复制终端)触发报警消息
import os
import sys
import json
import time
import socket
import urllib
import urllib2
reload(sys)
sys.setdefaultencoding('utf-8')
getHeader = lambda: {
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
'Authentication': "此处头部认证信息"
}
def getNowTime():
return time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
def get(url, use_header=True):
request = urllib2.Request(url, getHeader() if use_header else None)
response = urllib2.urlopen(request)
return json.loads(response.read())
def post(url, data, use_header=True):
""" POST请求 """
if isinstance(data, dict):
data = urllib.urlencode(data) # 将字典以url形式编码
request = urllib2.Request(url, data, getHeader() if use_header else None)
response = urllib2.urlopen(request)
return json.loads(response.read())
def getArea(ip):
url = "http://ip.taobao.com/service/getIpInfo.php?ip=%s" %ip
try:
data = get(url, use_header=False)
except Exception,e:
raise
else:
if data.get("code") == 0:
data = data['data']
return u"%s %s %s %s" %(data['country'], data['region'], data['city'], data['isp']), u"%s%s%s" %(data["country"], data['city'], data["isp"])
else:
raise ValueError
if __name__ == "__main__":
try:
clientIp, clientPort, serverIp, serverPort = os.getenv("SSH_CONNECTION").split()
except AttributeError,e:
raise
hostname = socket.gethostname()
username = os.getenv("USER")
loginTime = getNowTime()
EmailClientIpArea, WxClientIpArea = getArea(clientIp)
isOnline = u'会话中' if os.system('last %s |grep "still logged in" &> /dev/null' %username) == 0 else u'已离线'
# 定义发送邮件内容
EmailMsgContent = u"""<div>
<h3>服务器SSH登陆提示</h3>
<p>服务器主机名: %s</p>
<p>服务器IP地址: %s</p>
<p>登录用户: %s</p>
<p>登录来源IP: %s</p>
<p>登陆IP归属地: %s</p>
<p>当前是否在线: %s</p>
<p>最后登录时间: %s</p>
</div>""" %(hostname, serverIp, username, clientIp, EmailClientIpArea, isOnline, loginTime)
# 定义发送微信内容
WxMsgContent ='''[Server SSH Prompt]\n\tHostName: %s\n\tServerIps: %s\n\tLoginUser: %s\n\tLoginSourceIP: %s\n\tLoginSourceIpArea: %s\n\tLastLoginTime: %s''' %(hostname, serverIp, username, clientIp, WxClientIpArea, loginTime)
# 执行报警任务
# 发送邮件、微信,记录日志等