Techerest

Python for Network Engineers: SSH, Netmiko และ Network Automation

Python for Network Engineers ช่วยลดงานซ้ำในการดูแล Cisco Switch และ Router เช่น ตรวจสอบสถานะ Interface สำรอง Running Configuration และจัดทำ Inventory โดยใช้ SSH และไลบรารี Netmiko บทความนี้เน้นการอ่านข้อมูลโดยไม่เปลี่ยน Configuration พร้อมตัวอย่างที่นำไปฝึกใน Lab ได้จริง

1. ทำไม Network Engineer ควรใช้ Python?

การใช้ CLI ตรวจสอบอุปกรณ์ทีละตัวเหมาะกับการแก้ปัญหาเฉพาะหน้า แต่เมื่อมี Switch หลายสิบตัว การรันคำสั่งเดิมและบันทึกผลด้วยมือมีโอกาสผิดพลาด Python ช่วยให้ทำงานซ้ำอย่างสม่ำเสมอ ตรวจสอบย้อนหลังได้ และส่งผลลัพธ์ออกเป็นไฟล์สำหรับวิเคราะห์ต่อ

Device Inventory
      |
      v
Python + Netmiko
      |
      +-- SSH to SW01
      +-- SSH to SW02
      +-- SSH to R01
      |
      v
Command Outputs
      |
      +-- Config Backup
      +-- Interface Audit
      +-- CSV Report

Automation ไม่ได้แปลว่าต้องเปลี่ยน Configuration ควรเริ่มจากการอ่านสถานะและเก็บหลักฐานก่อน จึงค่อยขยายไปสู่ Configuration Management ที่มี Change Control

2. Architecture และขอบเขตการใช้งาน

ตัวอย่างนี้สมมติว่าเครื่อง Python เข้าถึง Management IP ของ Cisco IOS/IOS XE ได้ผ่านเครือข่ายที่ได้รับอนุญาต และอุปกรณ์เปิด SSH พร้อมบัญชีที่มีสิทธิ์ใช้คำสั่งตรวจสอบแล้ว

Admin Workstation
192.168.99.10
      |
Management VLAN
      |
      +-- SW01 192.168.99.11
      +-- SW02 192.168.99.12
      +-- R01  192.168.99.13

Netmiko เป็นเครื่องมือ SSH Automation ไม่ใช่ Network Monitoring Platform แบบ Real-Time และไม่ได้รับประกันว่าคำสั่งหรือรูปแบบ Output จะเหมือนกันทุก Cisco Platform ควรตรวจ Command Support และสิทธิ์การเข้าถึงก่อนใช้งาน

3. เตรียม Python Lab บน Windows หรือ Linux

ติดตั้ง Python และ Virtual Environment

python -m venv .venv

# Windows PowerShell
.venv\Scripts\Activate.ps1

# Linux / macOS
source .venv/bin/activate

python -m pip install --upgrade pip
python -m pip install netmiko

ตรวจสอบว่า Import ได้:

python -c "import netmiko; print(netmiko.__version__)"

ควรใช้ Virtual Environment แยกตามโปรเจกต์และบันทึกเวอร์ชัน Dependency ที่ทดสอบผ่าน เพื่อให้ผลการทำงานทำซ้ำได้

ทดสอบ SSH ก่อนเขียนสคริปต์

ssh netadmin@192.168.99.11

ยืนยัน Host Key ของอุปกรณ์ผ่านช่องทางที่เชื่อถือได้ก่อนใช้งานจริง หาก SSH ด้วยมือยังเชื่อมต่อไม่ได้ ให้แก้ Network Reachability, AAA, ACL หรือ SSH Configuration ก่อน

4. สร้าง Device Inventory

สร้างไฟล์ devices.csv โดยไม่เก็บ Password ลงในไฟล์

name,host,device_type
SW01,192.168.99.11,cisco_ios
SW02,192.168.99.12,cisco_ios
R01,192.168.99.13,cisco_ios

ชื่อ device_type ต้องตรงกับ Platform Driver ที่ Netmiko รองรับ สำหรับอุปกรณ์ Cisco IOS/IOS XE หลายรุ่นสามารถเริ่มจาก cisco_ios ได้ แต่ควรตรวจรุ่นจริงเสมอ

5. เชื่อมต่อ SSH ด้วย Netmiko

ตัวอย่างแรกอ่าน show version จากอุปกรณ์หนึ่งตัว ใช้ getpass เพื่อไม่แสดง Password ขณะพิมพ์ และใช้ finally เพื่อปิด Connection

from getpass import getpass
from netmiko import ConnectHandler

username = input("SSH username: ").strip()
password = getpass("SSH password: ")

connection = None
try:
    connection = ConnectHandler(
        device_type="cisco_ios",
        host="192.168.99.11",
        username=username,
        password=password,
        conn_timeout=10,
        auth_timeout=15,
    )
    output = connection.send_command("show version")
    print(output)
finally:
    if connection is not None:
        connection.disconnect()

ข้อควรระวัง: ตัวอย่างพื้นฐานนี้ไม่แสดงขั้นตอนการตรวจ SSH Host Key แบบบังคับ สำหรับ Production ควรใช้ SSH Client/Library และกระบวนการจัดการ Known Hosts ที่ตรวจสอบ Host Key ได้อย่างชัดเจน ไม่ควรปิดการตรวจสอบ Host Key เพียงเพื่อให้ Automation เชื่อมต่อสำเร็จ

6. สำรอง Running Configuration หลายอุปกรณ์

ตัวอย่างนี้อ่าน Inventory จาก CSV รับ Credential ตอนรัน เชื่อมต่อทีละอุปกรณ์ และบันทึก Output แยกไฟล์พร้อม Timestamp โดยไม่แสดง Configuration ใน Console และไม่ใช้คำสั่งเปลี่ยนค่าอุปกรณ์

import csv
import re
from datetime import datetime, timezone
from getpass import getpass
from pathlib import Path
from netmiko import ConnectHandler

INVENTORY = Path("devices.csv")
BACKUP_DIR = Path("backups")
BACKUP_DIR.mkdir(mode=0o700, exist_ok=True)

username = input("SSH username: ").strip()
password = getpass("SSH password: ")

def safe_name(value):
    return re.sub(r"[^A-Za-z0-9_-]", "_", value)

with INVENTORY.open(newline="", encoding="utf-8") as file:
    devices = list(csv.DictReader(file))

for device in devices:
    connection = None
    name = safe_name(device["name"])
    try:
        connection = ConnectHandler(
            device_type=device["device_type"],
            host=device["host"],
            username=username,
            password=password,
            conn_timeout=10,
            auth_timeout=15,
        )
        output = connection.send_command(
            "show running-config", read_timeout=60
        )
        timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
        path = BACKUP_DIR / f"{name}_{timestamp}.txt"
        path.write_text(output, encoding="utf-8")
        path.chmod(0o600)
        print(f"{name}: backup saved")
    except Exception as exc:
        print(f"{name}: backup failed ({type(exc).__name__})")
    finally:
        if connection is not None:
            connection.disconnect()

Output ของ show running-config อาจมีข้อมูลอ่อนไหว เช่น IP Address, Topology, Usernames, Hashes หรือ Key Material จึงต้องเก็บไฟล์ไว้ในพื้นที่จำกัดสิทธิ์และเข้ารหัสเมื่อเหมาะสม การกำหนด Permission ในตัวอย่างอาจมีผลต่างกันตามระบบปฏิบัติการ โดยเฉพาะ Windows ควรตรวจ NTFS ACL เพิ่มเติม

Backup ไม่เท่ากับ Restore ที่ผ่านการทดสอบ ต้องตรวจว่าไฟล์ครบถ้วน ไม่ถูกตัด Output และมีขั้นตอนกู้คืนที่ทดสอบใน Lab ก่อนใช้เป็นแผน Disaster Recovery

7. ตรวจสอบ Interface และสร้าง Network Audit Report

การ Audit ขั้นต้นสามารถใช้ show interfaces status บน Switch รุ่นที่รองรับ เพื่อสำรวจ Port ที่ Connected, Notconnect หรือ Disabled โดยไม่เปลี่ยน Configuration

import csv
from datetime import datetime, timezone
from getpass import getpass
from pathlib import Path
from netmiko import ConnectHandler

username = input("SSH username: ").strip()
password = getpass("SSH password: ")
rows = []

with open("devices.csv", newline="", encoding="utf-8") as file:
    devices = list(csv.DictReader(file))

for device in devices:
    connection = None
    try:
        connection = ConnectHandler(
            device_type=device["device_type"],
            host=device["host"],
            username=username,
            password=password,
        )
        output = connection.send_command(
            "show interfaces status", read_timeout=30
        )
        rows.append({
            "timestamp_utc": datetime.now(timezone.utc).isoformat(),
            "device": device["name"],
            "host": device["host"],
            "status": "collected",
            "raw_output": output,
        })
    except Exception as exc:
        rows.append({
            "timestamp_utc": datetime.now(timezone.utc).isoformat(),
            "device": device["name"],
            "host": device["host"],
            "status": type(exc).__name__,
            "raw_output": "",
        })
    finally:
        if connection is not None:
            connection.disconnect()

with Path("interface_audit.csv").open(
    "w", newline="", encoding="utf-8"
) as file:
    writer = csv.DictWriter(file, fieldnames=[
        "timestamp_utc", "device", "host", "status", "raw_output"
    ])
    writer.writeheader()
    writer.writerows(rows)

print("Audit completed: interface_audit.csv")

ไฟล์นี้เป็น Raw Output Audit ยังไม่ได้ Parse แต่ละ Port เป็นแถวข้อมูล เนื่องจากรูปแบบ CLI Output ต่างกันตาม Platform หากต้องการสร้าง Structured Interface Inventory ควรใช้ TextFSM, Genie/pyATS หรือ API ที่รองรับ แล้วตรวจผลกับ Output จริงก่อนใช้งาน Production

ตัวอย่างข้อมูลที่ควรนำไปวิเคราะห์ต่อ

  • Port ที่มีสถานะ Connected และความเร็วที่ Negotiated
  • Port ที่ Administratively Disabled
  • VLAN Assignment และ Trunk Configuration
  • Interface Errors, CRC, Drops และ Utilization
  • ความเปลี่ยนแปลงของ Port Status ระหว่างรอบ Audit

8. Verification และ Troubleshooting

ตรวจบน Cisco CLI

show ip ssh
show users
show interfaces status
show interfaces counters errors
show running-config | include hostname

คำสั่งบางรายการขึ้นกับ Platform และสิทธิ์บัญชี หากคำสั่งไม่รองรับ ให้ตรวจ Command Reference ของรุ่นนั้น

ปัญหา SSH Timeout

ตรวจ Management IP, Routing, ACL, Firewall, TCP Port 22 และ VRF ที่ใช้บริหารอุปกรณ์ หากเครื่องอยู่คนละ Management VRF ต้องตรวจเส้นทางให้ครบ

ปัญหา Authentication Failed

ตรวจ Username, AAA Server, Local Fallback, Account Lockout และ Privilege Level โดยไม่พิมพ์ Password ลง Log

ปัญหา Command Output ไม่ครบ

ตรวจ Read Timeout, Command Privilege, Pagination และ Prompt Detection หลีกเลี่ยงการเพิ่ม Timeout อย่างเดียวโดยไม่หาสาเหตุ

ปัญหา Backup บางเครื่องสำเร็จ บางเครื่องล้มเหลว

บันทึกผลเป็นรายอุปกรณ์ ตรวจ Driver, Software Version, Command Support และ Network Path แยกกัน ไม่ควรให้ความล้มเหลวของอุปกรณ์หนึ่งหยุดทั้งงาน

9. Security และ Production Best Practices

  • Least Privilege: ใช้บัญชี Read-Only หรือ Role ที่จำกัดคำสั่งเท่าที่จำเป็น
  • Credential Management: ไม่ฝัง Password ใน Source Code, CSV หรือ Git Repository; ใช้ Secret Manager เมื่อขยายระบบ
  • SSH Host Verification: ตรวจ Host Key ด้วยกระบวนการที่เชื่อถือได้ก่อนเชื่อมต่อ
  • Change Control: แยก Script อ่านข้อมูลออกจาก Script เปลี่ยน Configuration
  • Rate Limiting: ไม่เปิด SSH Session พร้อมกันจำนวนมากจนกระทบ Control Plane
  • Logging: บันทึกเวลา ชื่ออุปกรณ์ ผลสำเร็จ/ล้มเหลว แต่ไม่บันทึก Password หรือ Secrets
  • Backup Protection: จำกัดสิทธิ์เข้าถึงไฟล์และกำหนด Retention Policy
  • Verification: เปรียบเทียบข้อมูลจาก Automation กับ CLI ด้วยมือก่อนเชื่อถือรายงาน

สำหรับงาน Production ควรเพิ่ม Unit Tests, Inventory Validation, Retry แบบจำกัด, Structured Logging, Host Key Enforcement และระบบแจ้งเตือนเมื่อ Backup ไม่สำเร็จ

10. คำถามที่พบบ่อย (FAQ)

Python ใช้แทน Cisco CLI ได้ทั้งหมดหรือไม่?

ไม่ได้ Python ช่วยเรียกใช้ CLI หรือ API โดยอัตโนมัติ แต่ยังต้องเข้าใจ Networking, Platform Behavior และการตรวจสอบผลลัพธ์

Netmiko กับ Paramiko ต่างกันอย่างไร?

Paramiko เป็นไลบรารี SSH ระดับทั่วไป ส่วน Netmiko เพิ่มความสะดวกสำหรับการโต้ตอบกับ CLI ของอุปกรณ์ Network หลายยี่ห้อ

สามารถ Backup Switch 100 ตัวได้หรือไม่?

ทำได้หากมีสิทธิ์และทรัพยากรเพียงพอ แต่ต้องออกแบบ Concurrency, Timeout, Error Handling และ Load ต่ออุปกรณ์อย่างรอบคอบ

ทำไมไม่เก็บ Password ใน devices.csv?

เพื่อลดความเสี่ยงจากการเผยแพร่ Credential ผ่าน File Sharing, Backup หรือ Source Control

ควรใช้ CLI Parsing หรือ API?

หากอุปกรณ์รองรับ Structured API เช่น NETCONF/RESTCONF มักเหมาะกับข้อมูลที่ต้องการ Schema ชัดเจน ส่วน CLI Automation ยังมีประโยชน์กับอุปกรณ์เดิมและคำสั่งที่ไม่มี API เทียบเท่า

11. บทสรุป

Python + Netmiko เป็นจุดเริ่มต้นที่เหมาะสำหรับ Network Engineer ที่ต้องการพัฒนางาน Automation อย่างปลอดภัย โดยเริ่มจาก SSH Read-Only, Device Inventory, Configuration Backup และ Interface Audit ก่อนขยายไปสู่ Structured Data และ Configuration Deployment

Inventory
   |
   v
SSH Authentication
   |
   v
Read-Only Commands
   |
   +-- Config Backup
   +-- Interface Audit
   |
   v
Verification + Report
   |
   v
Operational Improvement

บทความถัดไป: Ansible for Cisco Network Automation — Inventory, Playbook, Configuration Backup, Compliance และ Change Control

Share this
Facebook Share X
TECHEREST COMMUNITY

Share your thoughts here

Join the conversation and share your perspective on this article.

Comments will load when you reach this section.