使用 prometheus_client 和 flask 实现端口探测 exporter

安装 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()
    tcp_connect_scan_resp = sr1(IP(dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags="S"), timeout=dst_timeout,
                                verbose=0)
    if (str(type(tcp_connect_scan_resp)) == "<type 'NoneType'>"):
        return 0
    elif (tcp_connect_scan_resp.haslayer(TCP)):
        if (tcp_connect_scan_resp.getlayer(TCP).flags == 0x12):
            send_rst = sr(IP(dst=dst_ip) / TCP(sport=src_port, dport=dst_port, flags="AR"), timeout=dst_timeout,
                          verbose=0)
            return 1
        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
12475671-21db176dacd1e11f.png

参考:

  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

转载于:https://www.jianshu.com/p/c35c0e7df301

猜你喜欢

转载自blog.csdn.net/weixin_34197488/article/details/91267507