Linux操作系统常规的分析SSH登录日志需要使用的命令和记录

  • 常用的日志文件
  • access-log 记录HTTP日志
  • acc/pacct 记录用户命令
  • aculog 记录MODEM的活动
  • btmp  记录失败的记录
  • lastlog  记录最近几次成功登录的事件和最后一次不成功的登录事件
  • messages 从syslog中记录信息
  • sudolog  记录使用sudo发出的命令
  • sulog  记录使用su命令的记录
  • syslog  从syslog中记录信息
  • utmp  记录当前登录的每个用户
  • wtmp 一个用户每次登录进入和退出事件的永久记录
  • xferlog  记录FTP会话
  • ===========================================================================================================================================================================================
  • 查看日志的具体命令
  • wtmp和utmp文件都是二进制文件,她们是不能被more,cat,tail等命令打开查看,剪切合并的,需要用户通过who,w,users,last等来使用这两个文件包含的信息
  • who命令:查询utmp文件并报告当前登录的每个用户,who默认输出包括用户名,终端类型,登录日期,及远程主机,如果who命令指明了wtmp文件名,则可以通过who命令查询所有以前的记录,who /var/log/wtmp将报告自从wtmp文件创建或删除,修改以来的每一次登录
  • w命令:查询utmp文件并显示当前系统中每个用户和它允许的进程信息
  • users命令:单独的一行打印当前登录的用户,每个显示的用户名对应一个登录会话,如果一个用户有不止一个登录会话,那么其他的用户名将显示相同的次数
  • last命令:往回搜索wtmp来显示自从文件第一次创建以来登录过的用户
  • ===========================================================================================================================================================================================
  • Linux SSH Log日志文件
  • 不同的操作系统其SSH记录日志文件和位置都有所差别,但是常见的目录默认位置是一样的,有secure,auth.log,messages等
  • Centos,Fedora  --> /var/log/secure
  • last命令显示用户最近登录信息
  • last命令用于显示当前操作系统中用户最近登录信息,单独执行last命令,将会读取/var/log/wtmp 文件,并把该文件记录的登录系统的用户名全部显示出来
  • 参数如下:
<number> 设置显示多少行
-a  --hostslast 把从何处登录的主机名称或IP地址,显示在最后一行
-d  --dns 将IP地址转换成主机名
-f  --file 指定记录文件取代/var/log/wtmp
-F  --fulltimes  打印所有的登录,注销时间和日期
-i  --ip  显示IP地址信息
-n  --limit 设置显示列数
-R  --nohostname 不显示系统的主机名称或IP地址
-s  --since  显示特定时间的行
-t  --until   显示知道特定时间的行
-p  --present 显示指定时间仍在登录的用户
-w  --fullnames  显示所有用户及域名名称
-x  --system  显示系统关机,重新开机,及执行等级的改变等信息
-h  --help  显示帮助信息并退出
-V  --version显示版本信息及退出 
  • 查看当前登录的用户信息last
  • 使用脚本分析
  • anyalizeslogs.py /var/log/secure
  • 分析脚本代码
#/usr/bin/env python3.4  
#Anyalize the /etc/auth.log files to get  
#   1) how many failed login trials  
#   2) how many succeeded login trials  
#   3) how many IP's where the login trials comes from and what they are  
#   4) how many invalid usernames are tested and what they are  
#  
#   usage:  
#       anyalyze <filename>  
#   note: - for standard input stream  
import sys  
import re  
  
  
# # of trials  
DEBUG_FLAG = 0  
INFO_FLAG = 0  
  
def debug(msg):  
    if DEBUG_FLAG:  
        print("[DEBUG] ", msg)  
  
def info(msg):  
    if INFO_FLAG:  
        print("[INFO] ", msg)  
  
def openLog( source ):  
    if( source == "-"):  
        return sys.stdin;  
    else:  
        debug("opening file:" + source)  
        f = open(source,'r')  
        return f  
  
# failed login  
ptnFailed = re.compile(r'Failed password for (?P<user>w+) from (?P<ip>d+.d+.d+.d+)')  
# invalid user trail  
ptnInvalid = re.compile(r'Failed password for invalid user (?P<user>w+) from (?P<ip>d+.d+.d+.d+)')  
# login succeeded  
ptnSuccess = re.compile(r'Accepted password for (?P<user>w+) from (?P<ip>d+.d+.d+.d+)')  
# sudo  
ptnSudo = re.compile(r'session opened for user (?P<user>w+) by (?P<ip>w+)')  
  
# >0: valid user & incorreck password  
# <0: invalid user  
nFailed = {}  
nSuccess = {}  
nSuccess_records = {}  
ipFailed={}  
ipSuccess={}  
  
if(len(sys.argv) < 2):  
    print("Usage:")  
    print("	"+sys.argv[0]+" <filename>")  
    print("Note: <filename> can be - for standard input stream")  
    exit(0)  
  
log = openLog(sys.argv[1])  
for line in log:  
    m = ptnFailed.search(line)  
    debug(m)  
    if not m:  
        m = ptnInvalid.search(line)  
        debug(m)  
    if m:  
        user =  m.group(ptnInvalid.groupindex['user'])  
        if user not in nFailed:  
            info("[FAILED] Found a new user <" + user + ">");  
            nFailed[user] = 0  
        nFailed[user] = nFailed[user]+1  
        ip = m.group(ptnInvalid.groupindex['ip'])  
        if ip not in ipFailed:  
            ipFailed[ip] = 0  
            info("[FAILED] Found a new ip <" + ip + ">");  
        ipFailed[ip] = ipFailed[ip] + 1  
    else:  
        m = ptnSuccess.search(line)  
        if not m:  
            m = ptnSudo.search(line)  
        debug(m)  
        if m:  
            print(line)  
            user =  m.group(ptnSuccess.groupindex['user'])  
            if user not in nSuccess:  
                nSuccess[user] = 0  
                info("[SUCCESS] Found a new user <" + user + ">");  
            nSuccess[user] = nSuccess[user]+1  
            ip = m.group(ptnSuccess.groupindex['ip'])  
            if ip not in ipSuccess:  
                ipSuccess[ip] = 0  
                info("[SUCCESS] Found a new ip <" + ip + ">");  
            ipSuccess[ip] = ipSuccess[ip] + 1  
        else:  
            debug("*** Unknown:" + line)  
# TODO: close(log)  
      
print("nFailed:" )  
print(nFailed)  
print("nSuccess:" )  
print(nSuccess)  
  
# a key-value list  
# it assure that the order is the same to the coming order  
class KeyValue:  
    def __init__(self, key, value):  
        self.key = key  
        self.value = value  
  
    def __repr__(self):  
        return repr((self.key, self.value))  
  
# return a KeyValue list because of the order of the keys in a dictionary  
# is unexpected, not same to the order as they are put in  
def sortDict(adict):  
    result=[]  
    keys = sorted(adict.keys(),key=adict.__getitem__, reverse = True)  
  
    for k in keys:  
        result.append(KeyValue(k,adict[k]))  
    return result  
  
# convert a KeyValue list to html table  
# @return a html string  
def KeyValueList2Html(kvlist, headerMap):  
    html ="<table>
"  
      
    hkey = 'Key'  
    hvalue = 'Value'  
    if headerMap:  
        hkey = headerMap['key'];  
        hvalue = headerMap['value'];  
        debug(hkey)  
        debug(hvalue)  
    html+= "<th>"+"<td>"+hkey+'</td>'+'<td>'+hvalue+'</td>'+ '</th>
'  
    for kv in kvlist:  
        html += "<tr>"+"<td>"+kv.key+'</td>'+'<td>'+str(kv.value)+'</td>'+ '</tr>
'  
    html += "</table>
"  
    return html  
  
print("------------ Tested user list *Failed* -------------", sortDict(nFailed))  
print("------------ Source IP *Failed* ------------------",sortDict(ipFailed))  
print("------------ Login Success  -------------", sortDict(nSuccess))  
print("------------ Source IP *Success* -----------------", sortDict(ipSuccess))  
  
# writing result to a HTML report  
print("Wring result to result.html ...")  
reportFilename = 'auth.log-analysis.html'  
report = open(reportFilename, 'w')  
if report:  
    title = 'Auth Log Analysis'  
    report.write('<html>
')  
    report.write('<head>'+title+'</head>
')  
    report.write('<style>'  
                 + 'table {border:black 1px solid}'  
                 +'</style>')  
                   
  
    report.write("------------ Tested user list *Failed* -------------
")  
    report.write(KeyValueList2Html(sortDict(nFailed),{'key':'username','value':'# of trial'}))  
    report.write("------------ Source IP *Failed* ------------------")  
    report.write(KeyValueList2Html(sortDict(ipFailed),{'key':'source IP','value':'# of trial'}))  
      
    report.write("------------ Login Success  -------------")  
    report.write(KeyValueList2Html(sortDict(nSuccess),{'key':'username','value':'# of trial'}))      
    report.write("------------ Source IP *Success* -----------------")  
    report.write(KeyValueList2Html(sortDict(ipSuccess),{'key':'source IP','value':'# of login'}))  
  
      
    report.write('<body>
')  
    report.write('</body>
')  
    report.write('</html>
')  
#    close(report)  
    print('OK')  
else:  
    print('Failed to open file:', reportFilename)  
迷茫的人生,需要不断努力,才能看清远方模糊的志向!
原文地址:https://www.cnblogs.com/autopwn/p/13665692.html