Profile picture

[Python] 네트워크 스위치(switch) 상태를 텔레그램으로 실시간 확인하기: 파이썬으로 자동화하는 방법 (Paramiko)

JaehyoJJAng2024년 03월 01일

시나리오

  • 회사에서 관리하는 네트워크 장비들 중 스위치의 상태를 매일 확인해야 하는 상황
  • 매번 직접 접속하여 로그와 버전을 확인하는 과정은 귀찮고, 시간이 많이 소요됨.

해결 방법

  • 텔레그램 봇을 활용해 자동화된 알림을 받는 솔루션
  • 파이썬과 간단한 라이브러리들을 사용해 스위치에 SSH로 접속하고, 매일 아침 스위치 상태를 확인할 수 있는 방법 제시

image


개요

  • 네트워크 스위치에서 log, version, run 등의 정보를 텔레그램으로 받아보는 자동화된 시스템 구축
  • 사용된 기술 스택: Python, Paramiko, python-telegram-bot, schedule

사전 준비

  • 텔레그램 봇 생성 및 API 토큰
  • 스위치 SSH 접속 계정
    • Privilige 값이 15인 어드민 계정

스위치 정보 수집하기

import paramiko
import telegram
from telegram.ext import Updater
import schedule
import time
import asyncio

def get_switch_info(host :str, port :int, username :str, password :str) -> tuple:
    # SSH 클라이언트 생성 및 스위치에 연결
    with paramiko.SSHClient() as ssh:
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(
            hostname=host, port=port, username=username, password=password,
            look_for_keys=False, # SSH 키 탐색을 하지 않음
            allow_agent=False)   # SSH 에이전트 사용하지 않음
        
        # 대화형 셸 열기
        shell = ssh.invoke_shell()
        time.sleep(1)
        
        # Enable 모드로 전환
        shell.send('enable\n')
        time.sleep(1)
        shell.send(f'{password}\n')
        time.sleep(1)
        
        # 명령어 실행
        shell.send('terminal length 0\n')  # 스크롤 제한 해제 (필수 아님)
        time.sleep(1)

        shell.send('show version\n')
        time.sleep(1)
        version_output = shell.recv(65535).decode('utf-8')

        shell.send('show logging\n')
        time.sleep(1)
        log_output = shell.recv(65535).decode('utf-8')

        shell.send('show running-config\n')
        time.sleep(2)
        run_output = shell.recv(65535).decode('utf-8')
    return version_output, log_output, run_output

def save_file(message: str) -> None:
    with open('switch_info.txt', 'w') as file:
        file.write(message)

async def send_file(bot: telegram.Bot, file: str, chat_id: str) -> None:
    await bot.send_document(chat_id=chat_id, document=open(file=file, mode='rb'))

async def send_message(bot: telegram.Bot, message: str, chat_id: str) -> None:
    await bot.send_message(chat_id=chat_id, text=message)

async def main() -> None:
    # 텔레그램 봇 토큰
    TELEGRAM_TOKEN :str =''
    TELEGRAM_CHATID :str =''
    
    bot = telegram.Bot(token=TELEGRAM_TOKEN)

    # SSH 설정
    HOST :str = '' # 스위치 IP
    PORT :int = 22 # 스위치 port
    USERNAME :str = '' # 스위치 계정 id
    PASSWORD :str = '' # 스위치 계정 pw
    
    # 스위치 정보 추출
    version, log, config= get_switch_info(host=HOST, port=PORT, username=USERNAME, password=PASSWORD)
    
    # 메시지 작성
    message = f"[Switch Info]\n{version}\n\n[Switch loggging]\n{log}\n\n[Switch config]\n{config}"
    
    # 파일로 생성
    save_file(message=message)
    
    # 메시지 전송
    await send_message(bot=bot, message=f"[{HOST}] 장비 알람 도착!\n", chat_id=TELEGRAM_CHATID)
    
    # 파일 전송
    await send_file(bot=bot, file='switch_info.txt', chat_id=TELEGRAM_CHATID)
    
if __name__ == '__main__':
    asyncio.run(main())

실행 결과

python3 main.py

image


Loading script...