Python & Netmiko:ネットワークエンジニアを3時間にわたるスイッチの手動設定から救う

Python tutorial - IT technology blog
Python tutorial - IT technology blog

午前2時の電話と「手動SSH」という名の悪夢

スマホの画面が明るく光り、デスクの上で激しく振動する。午前2時。電話の向こうで上司が声を荒らげる。「南部支社のVLANが全滅だ。すぐに入って修正してくれ、顧客からのクレームが鳴り止ないんだ!」。私は飛び起き、眠い目をこすりながらVPNにログインした。目の前には、即座に設定変更が必要な50台のCiscoスイッチと10台のJuniperルーターが待ち構えていた。

手動で作業するということは、一台ずつSSHでログインし、conf tを入力し、コマンドを貼り付けてwrite memすることを意味する。1台あたり約3分。60台あれば、機械のように180分間ひたすらキーボードを叩き続けることになる。その間、サービスは停止したままだ。この時、私は痛感した。Pythonによる自動化を知らなければ、昇進する前に力尽きてしまうだろう。

私が最初に書いたスクリプトは、かろうじて動作するわずか200行程度のものだった。あの夜のような「手痛い経験」を何度か経て、今ではエラー処理モジュールを完備した2000行以上のコードへと成長した。今日は、皆さんが単純作業の繰り返しで徹夜する日々から抜け出すための方法を共有したい。

なぜParamikoではなくNetmikoを選ぶのか?

Pythonを学び始めたばかりのエンジニアは、まずParamikoから使い始めることが多い。しかし、Paramikoは純粋なSSHライブラリに過ぎない。ネットワーク機器特有の動作を全く理解していないのだ。例えば、長いログを表示する際の--More--プロンプトや、Ciscoでenableを入力した際に二度目のパスワード入力を求められる挙動などだ。

Netmikoは、Paramikoをベースに構築された強力なツールだ。プロンプト処理のメカニズムが組み込まれており、Cisco IOS、Arista EOSからJuniper Junosまで、100以上のベンダーをサポートしている。Netmikoを使えば、デバイスを定義してコマンドを送るだけでいい。残りの処理はすべてライブラリが引き受けてくれる。

30秒で環境構築

クリーンなPython環境を用意し、pipでインストールコマンドを実行するだけだ:

pip install netmiko

実践:初めての一括設定スクリプト

例えば、enableパスワードの変更や、デバイスリストへの新規VLAN作成が必要だとしよう。手入力の代わりに、IPアドレスを記述したdevices.txtファイルを使用し、Pythonに処理を任せる。

1. デバイス情報の定義

まずはPythonの辞書形式(Dictionary)でパラメータを定義することから始めよう。これがコードを整理するための最も基本的な構造だ:

from netmiko import ConnectHandler

cisco_device = {
    'device_type': 'cisco_ios',
    'host': '192.168.1.10',
    'username': 'admin',
    'password': 'your_password',
    'secret': 'enable_password', # enableパスワード
    'port': 22,
}

2. 接続とコマンドの実行

Netmikoの最大の利点は、send_config_set()メソッドだ。自動的にconfigure terminalモードに入り、コマンドリストを実行してから終了してくれる。非常に快適だ!

def deploy_config(device_info, config_commands):
    try:
        # SSH接続の初期化
        net_connect = ConnectHandler(**device_info)
        
        # enableモードへ移行
        net_connect.enable()
        
        # 設定コマンドリストの送信
        output = net_connect.send_config_set(config_commands)
        
        # 設定をNVRAMに保存
        net_connect.send_command("write memory")
        
        print(f"[OK] {device_info['host']} の設定が完了しました")
        
        # 接続解除
        net_connect.disconnect()
        
    except Exception as e:
        print(f"[Error] {device_info['host']} でエラーが発生しました: {str(e)}")

# 実際のコマンド:VLAN 100を追加し、ポート1に割り当てる
commands = [
    'vlan 100',
    'name ITFROMZERO_NETWORK',
    'interface FastEthernet0/1',
    'switchport access vlan 100'
]

deploy_config(cisco_device, commands)

教訓:未熟なコードを本番環境(Production)に持ち込むな

スクリプトを200行から2000行に拡張した際、実際に動作するコードは全体の30%に過ぎないことに気づいた。残りの70%はエラー処理に費やされている。現実として、ネットワーク機器は頻繁に「機嫌を損ねる」。SSHがフリーズしたり、パスワードが間違っていたり、別の誰かが設定権限を握っていたりする。

苦労を避けるために、スクリプトに必ず追加すべき3つの要素を挙げる:

  • Timeout: 待ち時間に制限を設ける(例:10秒)。スイッチからの応答がない時に、スクリプトが永久に停止しないようにする。
  • Logging: 常にログをファイルに記録する。翌朝、上司から「昨夜どんなコマンドを打ってネットワークを落としたんだ?」と聞かれた際、照合できる証拠になる。
  • Try-Except: すべての接続を例外処理ブロックで囲む。これにより、1台目のデバイスでエラーが発生しても、スクリプトが2台目の処理を続行できるようになる。

大規模なデバイスリストの管理方法

コード内にIPアドレスをハードコーディングするのではなく、外部ファイルから読み込もう。getpassライブラリを使用すれば、パスワードの安全性を高めることができる:

import getpass

# ターミナルからパスワードを入力し、コード内での漏洩を防ぐ
password = getpass.getpass("SSHパスワードを入力してください: ")

with open('switch_list.txt') as f:
    for ip in f:
        current_device = {
            'device_type': 'cisco_ios',
            'host': ip.strip(),
            'username': 'admin',
            'password': password,
        }
        deploy_config(current_device, commands)

ネットワークエンジニアの皆さんへ

純粋にネットワーク機器の設定だけをしてきた人にとって、Pythonの学習は最初は挫折しそうになるかもしれない。しかし、信じてほしい。Enterキーを押し、コーヒーを飲みながら50台のスイッチが自動でコマンドを実行していくのを眺める気分は最高だ。自動化は作業を楽にするだけでなく、ネットワークシステム全体の標準化(Standardization)にも貢献する。

午前2時にトラブルが発生してから慌てて勉強し始めるのはやめよう。今日、Eve-NGやGNS3などのシミュレーション環境でNetmikoをインストールして、その違いを体感してみてほしい。自動化は単なる効率化ではなく、プロフェッショナルなインフラ運用の第一歩だ。

Share: