Netmiko SSH 자동화은(는) 무엇을 하나요?
이 스킬은 Netmiko를 사용하여 네트워크 장치에 연결하는 Python 자동화를 작성하거나 검토할 때 사용합니다. 기본 경로는 읽기 전용으로 유지하며, 설정 변경은 별도의 변경 창, 피어 리뷰 및 롤백 계획이 필요합니다.
사용 시점
- 라우터, 스위치 또는 방화벽에서
show명령어 출력 수집 - 인터페이스, 라우팅 또는 설정 증적을 위한 소규모 감사 스크립트 구축
- 네트워크 SSH 스크립트에 타임아웃 및 예외 처리 추가
- TextFSM 템플릿이 있는 경우 명령어 출력 파싱
- 프로덕션 장치에 적용 전 자동화 검토
안전 기본값
- 읽기 전용
send_command()수집으로 시작 - 인벤토리를 작고 명시적으로 유지, 전체 주소 범위 스캔 금지
- 환경 변수, 볼트 또는
getpass사용, 자격 증명 하드코딩 금지 - 연결 및 읽기 타임아웃 설정
- 오래된 장치에 과부하가 걸리지 않도록 동시성 제한
send_config_set()전에 명시적 연산자 플래그 필요- 변경 사항이 검증되고 승인될 때까지
save_config()호출 금지
읽기 전용 연결 패턴
import os
from getpass import getpass
from netmiko import ConnectHandler
from netmiko.exceptions import (
NetmikoAuthenticationException,
NetmikoTimeoutException,
ReadTimeout,
)
device = {
"device_type": "cisco_ios",
"host": "192.0.2.10",
"username": os.environ.get("NETMIKO_USERNAME") or input("사용자명: "),
"password": os.environ.get("NETMIKO_PASSWORD") or getpass("비밀번호: "),
"secret": os.environ.get("NETMIKO_ENABLE_SECRET"),
"conn_timeout": 10,
"auth_timeout": 20,
"banner_timeout": 15,
"read_timeout_override": 30,
}
try:
with ConnectHandler(**device) as conn:
if device.get("secret") and not conn.check_enable_mode():
conn.enable()
output = conn.send_command("show ip interface brief", read_timeout=30)
print(output)
except NetmikoAuthenticationException:
print("인증 실패")
except NetmikoTimeoutException:
print("SSH 연결 시간 초과")
except ReadTimeout:
print("명령어 읽기 시간 초과")
예제에서는 문서화 범위의 플레이스홀더 주소를 사용하세요. 실제 인벤토리는 무시된 로컬 파일 또는 비밀 관리 시스템에 보관하세요.
배치 수집
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Any
def collect_show(device: dict[str, Any], command: str) -> dict[str, Any]:
host = device["host"]
try:
with ConnectHandler(**device) as conn:
output = conn.send_command(command, read_timeout=45)
return {"host": host, "ok": True, "output": output}
except (NetmikoAuthenticationException, NetmikoTimeoutException, ReadTimeout) as exc:
return {"host": host, "ok": False, "error": type(exc).__name__}
results = []
with ThreadPoolExecutor(max_workers=8) as pool:
futures = [pool.submit(collect_show, device, "show version") for device in devices]
for future in as_completed(futures):
results.append(future.result())
max_workers는 장치 환경과 AAA 시스템이 더 높은 연결 볼륨을 처리할 수 있다고 알려진 경우가 아니라면 낮게 유지하세요.
구조적 파싱
Netmiko는 TextFSM, TTP 또는 Genie를 통해 지원되는 명령어 출력을 파싱할 수 있습니다. 파서 출력을 최적화 도구로 취급하고 유일한 증적 경로로 간주하지 마세요.
with ConnectHandler(**device) as conn:
parsed = conn.send_command(
"show ip interface brief",
use_textfsm=True,
raise_parsing_error=False,
read_timeout=30,
)
if isinstance(parsed, str):
print("파서 템플릿이 일치하지 않음, 검토를 위해 원시 출력 저장")
else:
for row in parsed:
print(row)
파싱이 차단 결정을 주도하는 경우, 파싱된 결과와 함께 원시 명령어 출력을 보관하여 운영자가 불일치를 검사할 수 있도록 하세요.
보호된 설정 패턴
import os
commands = [
"interface GigabitEthernet0/1",
"description CHANGE-1234 UPLINK-TO-CORE",
]
apply_changes = os.environ.get("APPLY_NETWORK_CHANGES") == "1"
if not apply_changes:
print("드라이 런 모드. 후보 명령어:")
print("\n".join(commands))
else:
with ConnectHandler(**device) as conn:
conn.enable()
before = conn.send_command("show running-config interface GigabitEthernet0/1")
output = conn.send_config_set(commands)
after = conn.send_command("show running-config interface GigabitEthernet0/1")
print(before)
print(output)
print(after)
print("시동 구성을 저장하기 전에 동작을 확인하세요.")
구성 저장은 별도의 승인 단계입니다. 프로덕션에서는 롤백 스니펫을 포함하고 변경 기록에 변경 전후 증적을 캡처하세요.
검토 체크리스트
- 스크립트가 명시적인 인벤토리 소스를 식별합니까?
- 자격 증명이 소스, 로그 및 예외 메시지에 없습니까?
conn_timeout,auth_timeout및 명령어read_timeout이 설정되었습니까?- 전체 배치를 중단하지 않고 장치별로 실패를 보고합니까?
- 스크립트가 광범위한 스캔과 무제한 동시성을 피합니까?
- 설정 변경이 드라이 런 또는 명시적 연산자 플래그 뒤에 있습니까?
save_config()가 초기 푸시와 분리되어 검증과 연결됩니까?
안티 패턴
- 소스에 비밀번호, enable 비밀 또는 개인 키를 하드코딩
- 설정 명령어를 기본 코드 경로로 전송
- 검토된 인벤토리 대신 CIDR 범위에 대해 자동화 실행
- 전체 실행 구성을 세니타이제이션 없이 공유 시스템에 로깅
- 파서 성공을 장치 상태가 올바르다는 증거로 취급
함께 보기
- 스킬:
cisco-ios-patterns - 스킬:
network-config-validation - 스킬:
network-interface-health