如何通过python实现--监控服务器是否有人远程登录(详细思路+代码)

@

目录
  • 起源
  • 思路
  • 实现
    • cmd命令netstat监控3389端口
    • python脚本实现
  • 展示
  • 思维导图

文章首发:https://mp.weixin.qq.com/s/Lliuq-2rB6SIrcfkebv7Jg

起源

当同一个远程服务器有多个人使用的时候,想知道服务器是否有人在用,我们不能直接的去登录,因为这样可能会把对方挤下来,这并不友好,所以这里提供一个监控远程服务器是否有人连接的方式

思路

遇到这个问题,想着如何去解决

刚开始的时候,我是想通过一个主动的方式,去监控到服务器是否有人连接,就是说当我想要知道服务器是否有人连接,我通过一个运行一个脚本程序,然后返回给我一个结果,事实证明,我并没有通过这样的思路解决这个问题

后来想以一个被动的方式来监控,比如在服务器上装载一个脚本,每5分钟运行一次脚本,来确定服务器上是否有人连接,不过这也比较消耗资源,后来想到一个方式,就是监控服务器连接和断开的行为,在每次服务器连接和断开的时候,运行脚本来知道服务器是否有人连接

放个流程图

这里是一整套的监控流程图,包括服务器监控和界面展示

实现

我们有了思路,接下来就是实现的问题

实现起来也比较简单

但是我们需要解决几个问题

  1. 如何知道服务器有没有人连接?
  2. 如何监控远程服务器的连接和断开?

cmd命令netstat监控3389端口

对于第一个问题,如何知道服务器有没有人连接?

这里可以了解一下3389端口远程桌面的服务端口)和netstat 命令,在windons服务器中,一般是一个远程连接的端口,就是说你可以监控这个端口,来知道服务器有没有人远程连接;而netstat (显示协议统计和当前 TCP/IP 网络连接)是一个cmd命令,我们可以通过它来监控端口情况

比如这里我们要监控3389端口

我们先连接远程连接服务器,打开cmd命令窗口,输入命令:netstat -n -p tcp | find ":3389"

我们就得到一个类似如这样的结果

TCP 10.11.174.373:55311 16.21.315.55:3389 ESTABLISHED

这里有2个ip,一个10.11.174.373,这个是你本地的ip,一个16.21.315.55,这个就是你服务器的ip

但你在服务器上运行这个命令的时候,如果有远程连接,那么就会得到这样的一个结果(当然,你自己连接的也算),当没有人连接的时候,就会得到一个空的,没有任何连接情况

python脚本实现

这里的脚本,我们要实现3个功能:

  1. 获取本地ip
  2. 获取服务器连接状态(ip)
  3. 相关数据存储到数据库

虽然我们使用netstat命令监控3389端口的时候有本地的ip,但是这只是有远程连接的时候有ip信息,但是如果无人连接,那么就获取不到,当然,你也可以自填本地ip,不过这样并不是很好

获取本地ip,这里我们是用python中的socket函数来实现

socket.getaddrinfo(socket.gethostname(),None)[-1][-1][0]

后面的服务器连接,上面有说

数据库存储,也就不多做说明了,直接上下代码(这里数据库,请自行建好)

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   server_ip.py
@Time    :   2020/04/23 10:08:15
@Author  :   吉祥鸟
@GitHub  :   https://github.com/jixn-hu
@CSDN    :   https://me.csdn.net/qq_37462361
'''

import os
import re
import pyodbc
import time
import socket

def now_time():
    """
    格式化返回当前时间
    :return:
    """
    now = int(time.time())
    local_time = time.localtime(now)
    format_now = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
    return format_now

def open_184_db(db="rreporttask"):
    """
    开启本地数据库
    :param db: 数据库(默认为rreporttask)
    :return: 创建好的数据库连接
    """
    print(now_time(), '连接184数据库%s' % db)
    driver = 'SQL Server'
    # 数据库ip
    serverName = '******'
    # 登陆用户名和密码
    userName = '******'
    passWord = '******'
    # 建立连接并获取cursor
    conn = pyodbc.connect(driver=driver, server=serverName,
                          user=userName, password=passWord, database=db, charset="gbk")
    return conn

def insert_many(conn, items, table_name):
    """
    多条数据插入到数据库(注:插入的数据包含表里的关键字)
    :param conn:数据库
    :param items:插入的数据列表字典(列表内包含字典类型)
    :param table_name:数据库表名
    :return:无
    """
    print(now_time(), "更新数据表{}...".format(table_name))
    # print(now_time(),"item:", items)
    if items:
        cursor = conn.cursor()
        sql1 = "insert into %s" % table_name
        sql2 = "("
        sql3 = ") values("
        sql4 = ")"
        for key in items[0].keys():  # 拼接sql语句
            sql2 += "%s," % key
            sql3 += "?,"
            # sql4 += "%s=values(%s)," % (key, key)
        sql = sql1 + sql2[:-1] + sql3[:-1] + sql4
        item_values = []
        for item in items:
            item_values.append(list(item.values()))
        num = len(item_values)
        # print(num)
        print(now_time(), '一共需要处理数据%s条' % num)
        # print(now_time(),"sql:", sql)

        try:
            for i in range(0, num, 1000):
                a = min(num, 1000 + i)
                # print(item_values[i:a])
                cursor.executemany(sql, item_values[i:a])
                conn.commit()
                print(now_time(), "当前已经处理%s条数据" % a)
        except Exception as e:
            print(now_time(), '更新数据失败,回滚')
            print(e)
            conn.rollback()
    conn.close()

def main():
    items = []
    item = {}
    time.sleep(1)
    cmd = 'netstat -n -p  tcp | find ":3389"'
    command = os.popen(cmd)
    r = command.read()
    print(r)
    zz = r.split("\n")[0].split()
    if r=='':
        ip = "0000"
    else:
        local_ip = zz[1]
        local_ip = re.sub(r":.*$",'',local_ip)
        ip = zz[2]
    item["server_ip"]=socket.getaddrinfo(socket.gethostname(),None)[-1][-1][0] # 本地ip
    item["sign_ip"] = ip
    item["entrytime"] = now_time()
    items.append(item)
    print(item)
    conn = open_184_db()
    insert_many(conn,items,"server_sign")

if __name__ == "__main__":
    main()

你可以把这个python脚本,打包成exe,然后放到服务器上,设置触发条件,当有人连接和断开服务器的时候,运行这个脚本

至于如何设置这个触发器,这就是第二个问题了,如何监控远程服务器的连接和断开?

这里可以百度下,windons自带的任务计划程序,通过这个我们可以设置exe服务器连接和断开的时,运行exe脚本,放个图,之后的自行摸索下

其实到这里,基本就是结束了,详细的思路和主要的实现,也都有了,我们可以直接查询数据库就能的知道服务器连接的情况

展示

不过后面为了更方便看,后面我自己又使用flask做了一个界面展示

就不多说明了

先放个成果图

直接上代码

server_sign.py:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   server_sign.py
@Time    :   2020/04/07 10:47:52
@Author  :   吉祥鸟
@GitHub  :   https://github.com/jixn-hu
@CSDN    :   https://me.csdn.net/qq_37462361
'''

import re
import pyodbc
import time
from flask import Flask,render_template

app=Flask(__name__)

def now_time():
    """
    格式化返回当前时间
    :return:
    """
    now = int(time.time())
    local_time = time.localtime(now)
    format_now = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
    return format_now

def open_184_db(db="rreporttask"):
    """
    开启本地数据库
    :param db: 数据库(默认为rreporttask)
    :return: 创建好的数据库连接
    """
    print(now_time(), '连接184数据库%s' % db)
    driver = 'SQL Server'
    serverName = '******'
    # 登陆用户名和密码
    userName = '******'
    passWord = '******'
    # 建立连接并获取cursor
    conn = pyodbc.connect(driver=driver, server=serverName,
                          user=userName, password=passWord, database=db, charset="gbk")
    return conn

def select_one(conn, sql="select ios_id from ios_main"):
    """
    查询信息
    :param time:
    :param type:
    :return:
    """
    print(now_time(), "正在查询数据库......")
    cursor = conn.cursor()
    try:
        cursor.execute(sql)
        result = cursor.fetchall()
        conn.commit()
        print(now_time(), "数据查询成功")
        return result
    except:
        print(now_time(), '更新数据失败,回滚')
        conn.rollback()
    conn.close()

@app.route('/admin/<name>') # route() 装饰器告诉 Flask 什么样的URL 能触发我们的函数
def hello_world(name):
    conn = open_184_db()
    data_back = {}
    datas = select_one(conn,"select server_ip,sign_ip,entrytime from(select *,ROW_NUMBER()over(partition by server_ip order by entrytime desc)rank from rreporttask..server_sign) as z where rank=1 order by server_ip")
    for data in datas:
        if data[1]=='0000' or '3389' in data[1]:
            data_back[data[0]]="未连接"
            data[1]="无"
        else:
            data_back[data[0]]="连接ing"
    # print(datas)
    return render_template("login.html",name=name,datas=datas,data_back=data_back)

@app.route('/hal/<name>') # route() 装饰器告诉 Flask 什么样的URL 能触发我们的函数
def hello_world1(name):
    return "hellodd {}".format(name)

if __name__ == "__main__":
    app.run(debug = True,host='0.0.0.0') # 用 run() 函数来让应用运行在本地服务器上

login.html:

<html>
   <!-- CSS goes in the document HEAD or added to your external stylesheet -->
<style type="text/css">
   table.hovertable {
   font-family: verdana,arial,sans-serif;
   font-size:11px;
   color:#333333;
   border-width: 1px;
   border-color: #999999;
   border-collapse: collapse;
   }
   table.hovertable th {
   background-color:#c3dde0;
   border-width: 1px;
   padding: 8px;
   border-style: solid;
   border-color: #a9c6c9;
   }
   table.hovertable tr {
   background-color:#d4e3e5;
   }
   table.hovertable td {
   border-width: 1px;
   padding: 8px;
   border-style: solid;
   border-color: #a9c6c9;
   }
   </style>
   <body>
      <h1>服务器登录状态查看</h1>
      <table class="hovertable">
         <tr>
            <th>服务器ip</th>
            <th>登录ip</th>
            <th>连接时间</th>
            <th>连接状态</th>
         </tr>
         {% for data in datas %}
            <tr>
               <td>{{ data[0] }}</td>
               <td>{{ data[1] }}</td>
               <td>{{ data[2] }}</td>
               <td>{{ data_back[data[0]] }}</td>
            </tr>
         {% endfor %}
      </table>

   </body>

</html>

思维导图

最后,放一个思维导图,供参考

关注我获取更多内容
注:转载还请注明出处,谢谢_

(0)

相关推荐

  • 本地数据库(SQL Server)远程连接服务器端服务器

    本地数据库(SQL Server 2012) 连接外网服务器的数据库,外网的服务器端需要做如下配置: 1. 首先是要打开 数据的配置管理工具 2. 配置相关的客户端协议,开启TCP/IP 3. 数据库 ...

  • 如何通过python实现--监控服务器是否有人远程登录

    起源 当同一个远程服务器有多个人使用的时候,想知道服务器是否有人在用,我们不能直接的去登录,因为这样可能会把对方挤下来,这并不友好,所以这里提供一个监控远程服务器是否有人连接的方式 思路 遇到这个问题 ...

  • 微软最强 Python 自动化工具开源了!不用写一行代码!

    来自AirPython 1. 前言 最近,微软开源了一款非常强大的 Python 自动化依赖库:playwright-python 它支持主流的浏览器,包含:Chrome.Firefox.Safari ...

  • 路由器方案板香橙派R1 Plus如何使用SSH远程登录

    不太了解OrangePi R1 Plus这款开发板的开发者,可以对比下NanoPi R2S,配置一样. 作为路由器方案板, R1 Plus适配有OpenWRT, 系统默认都开启了 ssh 远程登录,并 ...

  • (7条消息) Ubuntu开启SSH远程登录

    本文介绍如何在Ubuntu下开启ssh服务并能通过Xshell进行远程登录的方法.测试使用的是在虚拟机上装的Ubuntu和window10. 首先更新自己Ubuntu的源,具体自行解决. 更改IP地址 ...

  • python接口自动化4-绕过验证码登录(cookie)

    前言 有些登录的接口会有验证码:短信验证码,图形验证码等,这种登录的话验证码参数可以从后台获取的(或者查数据库最直接). 获取不到也没关系,可以通过添加cookie的方式绕过验证码. 一.抓登录coo ...

  • python测试开发django-43.session机制(登录/注销)

    前言 当我们登录访问一个网站时,服务器需要识别到你已经登录了,才有相应的权限访问登录之后的页面.用户退出登录后,将无权限访问再访问登录后的页面. 从登录到退出的一整个流程,可以看成是与服务器的一次会话 ...

  • python笔记38-使用zmail发各种邮件案例代码

    前言 本篇介绍使用zmail发各种格式的邮件,并运行成功的代码,小伙伴们只需更换自己的邮箱就可以运行起来了 content_text发送纯文本 先从最简单的发送纯文本的邮件开始,调通发送邮件的代码. ...

  • CentOS7 SSH远程登录服务器详解

    一.明文传输与加密传输 明文传输:当我们的数据包在网络上传输的时候,以数据包的原始格式进行传输,别人很容易截获我们的数据包,得到我们的信息. 加密传输:当两个主机之间传输信息或者是A主机远程控制B主机 ...

  • python你TM太皮了——区区30行代码就能记录键盘的一举一动

    目录 先看看效果 一.公共WiFi 公用电脑什么的 二.键盘记录器 三.python代码实现 1.安装pynput模块 2.脚本完整代码 3.启动脚本 4.登录126邮箱 抓取用户信息 四.安全提示 ...