美文网首页
使用 prometheus_client 和 Flask 实现端

使用 prometheus_client 和 Flask 实现端

作者: awker | 来源:发表于2019-06-04 09:20 被阅读0次

    安装 pyyaml prometheus_client flask scapy

    # pip install pyyaml prometheus_client flask scapy
    

    编写 active_check_exporter.py

    # coding: utf-8
    from scapy.all import *
    import yaml
    import os
    from prometheus_client.core import CollectorRegistry
    from prometheus_client import Gauge, generate_latest
    from flask import Flask, Response
    
    
    def get_config(filename):
        with open(filename, "r") as ymlfile:
            cfg = yaml.safe_load(ymlfile)
        return cfg
    
    
    def tcp_connect_scan(dst_ip, dst_port, dst_timeout):
        """
        Open: 1
        Closed: 0
        CHECK: 0
        """
        src_port = RandShort()
        # 发送 SYN 数据包
        tcp_connect_scan_resp = sr1(IP(dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags="S"), timeout=dst_timeout,
                                    verbose=0)
        # 无法连接目标时,tcp_connect_scan_resp 为 None,str(type(res)) --> "<type 'NoneType'>"
        if (str(type(tcp_connect_scan_resp)) == "<type 'NoneType'>"):
            return 0
        # 判断是否有TCP包返回
        elif (tcp_connect_scan_resp.haslayer(TCP)):
            # flags == 0x12,即 A 0x10 Ack + S 0x02 Syn --> 0x10 + 0x02 = 0x12
            # 判断返回的TCP包是否为 SA(tcp_connect_scan_resp.getlayer(TCP).flags == "SA")
            if (tcp_connect_scan_resp.getlayer(TCP).flags == 0x12):
                # 发送 A Ack + R Reset 数据包,断开连接
                send_rst = sr(IP(dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags="AR"), timeout=dst_timeout,
                              verbose=0)
                return 1
            # flags == 0x14,即 A 0x10 Ack + R 0x04 Reset --> 0x10 + 0x 04 = 0x14
            # 目标端口不存在时,判断返回的TCP包是否为 RA(tcp_connect_scan_resp.getlayer(TCP).flags == 'RA')
            elif (tcp_connect_scan_resp.getlayer(TCP).flags == 0x14):
                return 0
        else:
            return 0
    
    
    # 设置 metrics
    registry = CollectorRegistry(auto_describe=False)
    active_num = Gauge('active', 'active port num', ['service'], registry=registry)
    app = Flask(__name__)
    
    
    @app.route("/metrics")
    def main():
        filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config.yml")
        config = get_config(filename)
        status = {}
        for key, value in config.iteritems():
            for ip_port in value:
                ip, port = ip_port.split(':')[0], int(ip_port.split(':')[1]),
                active = tcp_connect_scan(ip, port, 1)
                if key in status:
                    status[key] += active
                else:
                    status[key] = active
            active_num.labels(service=key).set(float(status[key]))
        return Response(generate_latest(registry), mimetype="text/plain")
    
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5001)
    
    

    要探测的端口加到 config.yml 即可,格式:

    服务名称:
      - IP1:PORT
      - IP2:PORT
    
    # cat config.yml
    fdfs_storaged:
      - 10.1.29.222:23000
      - 10.1.32.251:23000
      - 10.1.29.223:23000
      - 10.1.32.252:23000
    
    fdfs_trackerd:
      - 10.1.29.221:22122
      - 10.1.32.242:22122
    

    最终采集到的的数据

    # python active_check_exporter.py
    

    参考:

    1. https://resources.infosecinstitute.com/port-scanning-using-scapy/
    2. https://github.com/interference-security/Multiport/blob/master/multiport.py
    3. https://github.com/prometheus/client_python

    相关文章

      网友评论

          本文标题:使用 prometheus_client 和 Flask 实现端

          本文链接:https://www.haomeiwen.com/subject/mbekxctx.html