当前位置:首页>python>一学一实践:通过Python监控路由器配置变更+ORM存储

一学一实践:通过Python监控路由器配置变更+ORM存储

  • 2026-09-27 12:54:24
一学一实践:通过Python监控路由器配置变更+ORM存储

1.路由器配置变更监控 + ORM 存储

综合运用 paramiko、hashlib、SQLAlchemy ORM,每隔 5 秒从路由器采集一次 show running-config, 计算配置的 SHA256 哈希值并存入 SQLite 数据库,与上一次哈希比较,若发现配置变化则打印告警。

数据库模型字段:

id:主键,自动递增

router_ip:路由器 IP(带索引)

router_config:完整配置文本

config_hash:SHA256 哈希值(64位十六进制字符串)

record_time:采集时间,自动填写当前时间

脚本:

import sys, os, hashlib, time, datetime, re# ---- 1. 复用python12下的的 qytang_multicmd ----sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'python12'))from qytang_multicmd import qytang_multicmd  # noqa: E402# ---- 2. SQLAlchemy ORM ----from sqlalchemy import create_engine, Column, Integer, String, DateTimefrom sqlalchemy.orm import declarative_base, sessionmakerengine = create_engine('sqlite:///router_config.db',                       connect_args={'check_same_thread': False})Base = declarative_base()Session = sessionmaker(bind=engine)class RouterConfig(Base):    """路由器配置备份模型"""    __tablename__ = 'router_config'    id            = Column(Integer, primary_key=True)    router_ip     = Column(String(64),    nullable=False, index=True)    router_config = Column(String(99999), nullable=False)    config_hash   = Column(String(500),   nullable=False)    record_time   = Column(DateTime, default=datetime.datetime.now)    def __repr__(self):        return f"{self.__class__.__name__}(路由器IP地址: {self.router_ip} | 配置Hash: {self.config_hash} | 记录时间: {self.record_time})"Base.metadata.create_all(engine, checkfirst=True)# ---- 3. 工具函数 ----def get_show_run(host, username, password):    """获取配置并计算 hash"""    raw = qytang_multicmd(host, username, password,                          ['terminal length 0', 'show running-config'],                          verbose=False)    match = re.search(r'(hostname[\s\S]+end)', raw)    if match:        config = match.group(1)                       # 从 match 中取出配置文本        config_hash = hashlib.sha256(config.encode('utf-8')).hexdigest()   # 对配置文本做 SHA256        return config, config_hash    else:        return None, Nonedef save_config(host, config, config_hash):    """写入数据库(使用独立 session,避免事务残留)"""    with Session() as session:        record = RouterConfig(router_ip=host, router_config=config, config_hash=config_hash)        session.add(record)        session.commit()def get_latest_two_hashes(host):    """查询最近两条记录"""    with Session() as session:        results = (session.query(RouterConfig)                   .filter(RouterConfig.router_ip == host)            # 按 router_ip 过滤                   .order_by(RouterConfig.id.desc())                   .limit(2)                   .all())        return results# ---- 4. 主循环 ----if __name__ == '__main__':    host     = '10.10.1.1'       # 换成自己的路由器    username = 'xxx'    password = 'xxx'    print(f"[*] 开始监控 {host} 的配置变化,每 5 秒采集一次...\n")    while True:        config, config_hash = get_show_run(host, username, password)        if config and config_hash:            save_config(host, config, config_hash)            records = get_latest_two_hashes(host)            if len(records) < 2:                print(f"本次采集的HASH:{config_hash}")            elif records[0].config_hash == records[1].config_hash:                print(f"本次采集的HASH:{config_hash}")    # 配置无变化,打印本次 hash            else:                print("==========配置发生变化==========")                print(f"  THE MOST RECENT HASH  {records[0].config_hash}")                print(f"  THE LAST HASH         {records[1].config_hash}")        else:            print("[!] 无法获取有效的配置")        time.sleep(5)

效果:

最新文章

随机文章