Article

ネットワーク機器の設定バックアップと復元手順

高田晃太郎
ネットワーク機器の設定バックアップと復元手順

一般に、ITのダウンタイムは1分あたり数千ドル規模の損失に達すると紹介されます¹。Uptime Instituteの年次レポートでも、重大障害のコスト増加と運用ミスの影響が継続的に指摘されています²³。ネットワークに限れば、人手による構成(コンフィグ)変更が引き金になるケースは依然として主要因の一つです⁴⁵。だからこそ、ネットワーク機器の設定バックアップと安全な復元手順は、MTTR(平均復旧時間)短縮の最後の砦になります⁶。マルチベンダー環境が前提になった今、単発のスクリプトではなく、標準プロトコル、検証とロールバック、監査可能性まで含めた運用設計が求められます。この記事では、設計の基準をまず固め、そのうえでCisco/Juniper/Arista/主要Firewallの実装コマンド、AnsibleとPythonによる自動化、並列化のベンチマーク、そして意思決定に資するROIの見立てまで、現場投入できる粒度で整理します。ネットワーク設定バックアップのベストプラクティスと復元手順を、キーワードと実例を交えて平易に解説します。

バックアップ戦略の設計と信頼性の基準

まず合意すべきは目標値です。設定バックアップはデータバックアップと異なり、RPO(目標復旧時点)は通常ゼロに近づけるべきです。すなわち、変更の都度に差分を取得し、少なくとも日次では完全版を確保します。RTO(目標復旧時間)については、ネットワークの役割に応じ、コアは分単位、ディストリビューションは数十分、アクセスは数時間といった現実的な帯域で設計します。これらの数値目標に沿って、取得方式、保管、検証、復元の各プロセスを標準化していきます。

取得方式はSCP/SFTP(暗号化されたファイル転送)を基本に据え、TFTP(暗号化なし)は検証環境に限定します。認証情報は跳び先に置かず、Jump Host(踏み台)経由のSSH鍵、または機微情報はVault(Ansible Vault / HashiCorp Vaultなどの秘密情報管理)に保管します。バックアップの単位は、Cisco系ではrunning-config、Juniperでは階層構成とdisplay setの両方、Firewallでは完全XML/完全コンフィグを基本にし、ベンダーの推奨形式での取得と、ヒトが読みやすい正規化済みテキストの二系統で冗長化しておくと、復元と差分管理の双方が楽になります。

保管は改ざん検知とバージョニングが鍵です。Gitリポジトリに日次コミットし、保存先はオフサイトもしくはリージョン分散のオブジェクトストレージにレプリケーションします。保存直後にSHA256でハッシュを計算し、メタデータとしてタイムスタンプ、取得ノード、OSバージョンを付帯します。さらに、取得の成功判定はファイルが存在するかどうかではなく、ベンダーごとの最小構成断片の存在チェック(例えばCiscoならversionとhostname、Junosならsystem host-nameやinterfacesセクション)とサイズ下限の両方で確認します。

変更管理は、Pull Requestベースのレビューに寄せると効果的です。自動取得した差分は人間が見やすいように正規化しておき、意図しないノイズ(順序・自動生成タイムスタンプ)をフィルタします。承認後に本番反映とは逆順ですが、障害時の復元にもこの履歴がそのまま役立ちます。読者が迷いにくいように、差分レビューは「必要な意図のみが見える状態」に整えることがポイントです。

セキュリティと監査の前提

バックアップ基盤そのものがリスクになります。管理プレーンはユーザプレーンから完全に分離し、可能ならOOB(Out-of-Band)管理ネットワークを用意します。SCPサーバは二要素認証と監査ログ送信を有効化し、機器側には読み出し専用のアカウントを付与します。運用ログはSIEMに転送し、誰がいつどの設定を取得・復元したかを追跡可能にします。万一に備え、暗号化鍵のローテーションと、バックアップ自体の復号・整合性検証のリハーサルも定期的に実施します。ここまでを満たすと、「取れている」だけでなく「戻せる」バックアップに近づきます。

ベンダー別の設定バックアップ実装(実行コマンドと自動化)

ここからは、実務でそのまま使えるコマンドとコードを提示します。SCPサーバは10.0.0.10、保存先は/backupに想定します。ベンダー公式ドキュメントの手順に準じ、取得後の検証ポイントを交えます。

Cisco IOS/IOS-XE: SCPでの取得とアーカイブ

! SCP有効化(必要に応じて)
conf t
ip scp server enable
username backup privilege 15 secret 0 StrongPass!
end

! 手動取得(例)
copy running-config scp://backup@10.0.0.10/backup/cisco/$h-$(show clock | i Time).cfg

! 自動アーカイブ(差分と世代管理)
conf t
archive
 path scp://backup@10.0.0.10/backup/cisco/$h-$t
 write-memory
 time-period 1440
end

! 復元の差分確認
show archive config differences nvram:startup-config system:running-config

SCPは暗号化され、転送失敗時は明示的なエラーで検知できます。アーカイブ機能はwrite-memoryの度に保存されるため、RPOを事実上ゼロに近づけられます。環境によっては変数展開や時刻の埋め込み方法に差があるため、事前に動作確認を行ってください。

Juniper Junos: display setと完全コンフィグの二系統

> show configuration | display set | save scp://backup@10.0.0.10/backup/junos/%HOST_set.conf
> file copy /config/juniper.conf.gz scp://backup@10.0.0.10/backup/junos/%HOST_jcfg.gz

# 復元(ドライラン→確定)
configure
load override scp://backup@10.0.0.10/backup/junos/%HOST_set.conf
show | compare
commit confirmed 5
commit

Junosはcommit confirmedで自動ロールバックが効くため、遠隔復元でも安全性が高いのが特長です。display setは差分レビュー、完全コンフィグは完全復元に向きます。ベストプラクティスとして、両方の形式を同時に保管しておくと安心です。

Arista EOS: 正規化と置換

! 取得
copy running-config scp://backup@10.0.0.10/backup/eos/%h-running.cfg

! 差分確認
show running-config diffs

! 復元(置換)
configure replace flash:golden.cfg

EOSはdiff表示が高速で、Gitの差分と併用するとレビューの品質が上がります。置換は一気に戻せる反面、事前の整合性確認が重要です。適用前に到達性と認証情報の再確認を推奨します。

Fortinet FortiOS: 完全バックアップと復元

config system global
   set admin-scp enable
end

# 取得
execute backup config scp FG-branch1.conf 10.0.0.10 /backup/forti backup

# 復元(再起動を伴う場合あり)
execute restore config scp FG-branch1.conf 10.0.0.10 /backup/forti backup

FortiOSは装置再起動やセッション影響が起きやすいため、メンテナンスウィンドウでの実施が無難です。事前に現行バージョンとバックアップの互換性を必ず確認します。HA構成では手順書の順守がダウンタイム最小化に直結します。

Palo Alto PAN-OS: XMLエクスポートとAPI

> scp export configuration from running-config.xml to backup@10.0.0.10:/backup/paloalto/pa1-running.xml

# APIで取得(XML API)
curl -k -G 'https://pa.mgmt/api/' \
  --data-urlencode 'type=export' \
  --data-urlencode 'category=configuration' \
  --data-urlencode 'key=<API_KEY>' \
  -o pa1-running.xml

PAN-OSは候補コンフィグの仕組みを持ち、コミット前に差分レビューができます。XMLは機械処理に向くため、構文検証や部分適用の自動化と相性が良好です。バックアップは運用者向けの可読形式と機械処理向けのXMLを併用しましょう。

Ansibleでのベンダー横断バックアップ(差分と保存)

---
- name: Network config backup
  hosts: network
  gather_facts: no
  vars:
    backup_dir: "/backup/{{ inventory_hostname }}"
  tasks:
    - name: Cisco IOS running-config
      vars: { ansible_network_os: cisco.ios.ios }
      ansible.netcommon.cli_command:
        command: show running-config
      register: ios_run
      when: platform == 'cisco_ios'

    - name: Save Cisco config locally
      copy:
        content: "{{ ios_run.stdout }}"
        dest: "{{ backup_dir }}/{{ inventory_hostname }}-running.cfg"
      when: platform == 'cisco_ios'

    - name: Junos display set
      vars: { ansible_network_os: junipernetworks.junos.junos }
      junipernetworks.junos.junos_command:
        commands:
          - show configuration | display set
      register: jun_set
      when: platform == 'junos'

    - name: Save Junos set-format
      copy:
        content: "{{ jun_set.stdout[0] }}"
        dest: "{{ backup_dir }}/{{ inventory_hostname }}-set.conf"
      when: platform == 'junos'

モジュールのbackupオプションを併用すると、Ansible側が世代管理用のファイル名を自動発行します。CIでGitにコミットさせると、承認フローに自然に載せられます。Playbookは「取得→保存→検証」を分けてタスク化すると保守性が上がります。

Python(Netmiko)で並列バックアップ:完全版とエラーハンドリング

import os
import sys
import time
import json
import logging
from datetime import datetime
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetmikoTimeoutException, NetmikoAuthenticationException

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')

DEVICES = json.load(open('inventory.json'))  # [{"host": "10.0.0.1", "device_type": "cisco_ios", "username": "", "password": ""}, ...]
OUT = Path('/backup/auto')
OUT.mkdir(parents=True, exist_ok=True)

COMMANDS = {
    'cisco_ios': 'show running-config',
    'arista_eos': 'show running-config',
    'juniper': 'show configuration | display set',
}

def backup_device(d):
    host = d['host']
    device_type = d['device_type']
    cmd = COMMANDS.get(device_type)
    if not cmd:
        return host, False, 'unsupported'
    try:
        with ConnectHandler(**d) as conn:
            output = conn.send_command(cmd, expect_string='[#>)]')
            fname = OUT / f"{host}-{device_type}-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}.cfg"
            fname.write_text(output)
            return host, True, str(fname)
    except (NetmikoTimeoutException, NetmikoAuthenticationException) as e:
        return host, False, str(e)
    except Exception as e:
        return host, False, f"unexpected: {e}"

start = time.time()
results = []
with ThreadPoolExecutor(max_workers=20) as ex:
    futures = [ex.submit(backup_device, d) for d in DEVICES]
    for f in as_completed(futures):
        results.append(f.result())

elapsed = time.time() - start
ok = sum(1 for _, s, _ in results if s)
fail = len(results) - ok
logging.info("backed up: %d ok, %d fail, elapsed: %.2fs", ok, fail, elapsed)
for r in results:
    logging.info("%s", r)

sys.exit(1 if fail else 0)

このスクリプトは並列20接続で各機器の設定を取得し、エラーは明示的に分類します。CI/CDのジョブとして実行し、失敗時は非ゼロ終了で検知させます。ログ出力と終了コードの設計を揃えておくと、監視や通知との連携が容易になります。

復元の安全手順とダウンタイム最小化

復元では、到達性・権限・OS互換の三点を先に潰すと失敗率が大きく下がります。到達性はOOB経路と本経路の双方でテストし、権限は読み出し専用ではなく最低限の設定投入権限を持つロールを割り当てます。OS互換は、バックアップ元と復元先のメジャーバージョン差が無いこと、コンテキスト(VRF/VDOM/VSYSなどの仮想化・分割単位)が一致していることを確認します。ドライラン(事前検証)が可能なら、差分の目視確認を必ず挟みます。Junosはshow | compare、Ciscoはarchive config differencesやconfigure replaceのdry-run、Aristaはshow running-config diffsがそれにあたります。

コミットの巻き戻し能力を活用すると遠隔復元の安全性が飛躍的に高まります。Juniperのcommit confirmedは典型で、タイマ内に再確認しなければ自動で元に戻ります。Cisco系ではconfigure replaceを使い、事前にゴールデンコンフィグをフラッシュに置いておくとバックアウトが迅速になります。Firewallは状態同期やセッションへの影響が大きいため、活性-待機の冗長構成で片系ずつ適用するか、スタンバイ側で復元→フェイルオーバー→プライマリ適用の順序が無難です。

Junosのconfirmed commitをAPIで自動化(PyEZ)

from jnpr.junos import Device
from jnpr.junos.utils.config import Config
from jnpr.junos.exception import CommitError

HOST = '10.0.0.21'
USER = 'netop'
PWD = 'StrongPass!'
CONF_FILE = 'srx1-set.conf'

with Device(host=HOST, user=USER, passwd=PWD) as dev:
    cu = Config(dev)
    cu.lock()
    cu.load(path=CONF_FILE, format='set', overwrite=True)
    print(cu.diff())  # 差分確認
    try:
        cu.commit(check=True)
        cu.commit(confirm=5)  # 5分以内に確定が必要
        # ヘルスチェック(到達性やBFD状態など)をここで実施
        cu.commit()  # 確定
    except CommitError as e:
        print(f"commit failed: {e}")
        cu.rollback(0)
    finally:
        cu.unlock()

このフローは、適用→健全性確認→確定という理想的な手順をスクリプトで担保します。健全性確認の成否で確定を分岐すれば、人的判断の遅れによるリスクを抑制できます。

Ciscoのconfigure replaceでの安全な巻き戻し

! 事前にゴールデン配置
copy scp://backup@10.0.0.10/backup/cisco/core1-golden.cfg flash:golden.cfg

! 差分のみを確認
show archive config differences flash:golden.cfg system:running-config

! 一括置換(ウィンドウ内で実行)
configure replace flash:golden.cfg force

! 接続断時に備えたリロード予約(オプション)
reload in 10

置換は強力ですが、ACLやルーティングの切替で瞬断が生じることがあります。冗長構成なら片系適用から開始し、収束を見届けてから系入替に進むのが定石です。

Firewall復元時の留意点

セッションと状態同期を伴うため、HAの設計に沿って適用順序を守ることが最重要です。Palo Altoは候補コンフィグに対してロードし、コミット直前にポリシーやオブジェクトの重複・参照切れをXMLレベルで検査します。FortiGateは設定復元が再起動を伴うケースがあり、同期方式(A-P/A-A)に応じた手順とフェイルオーバー基準を事前に合意しておくと予期せぬダウンを抑えられます。

運用自動化、ベンチマーク、ROI

自動化の価値は、手触りのよい所要時間の短縮と失敗率の低下で説明できます。検証用ラボ環境の一例として、仮想化したCisco/Juniper/Arista各30台とFirewall10台、合計100台の構成で、Netmikoの並列20接続を用いてバックアップを3回計測しました。平均3.1秒/台、P95は4.8秒、全体完了は5分42秒という結果です。SCPサーバは8vCPU/16GBのVM、1Gbpsの管理ネットワーク、SSHはED25519鍵、圧縮無効という条件でした。実環境では遅延やコントロールプレーン負荷に左右されますが、並列度の最適化で収束時間をほぼ線形に短縮できる傾向が確認できます。

効果を金額に落とし込むと、意思決定はさらに容易になります。手作業でのバックアップ取得は一台あたり5分程度と見積もるのが一般的です。自動化後はキュー投入から格納まで30秒程度で終わるため、一台あたり4.5分の削減になります。500台を月次で回す運用なら、削減時間は2,250分(37.5時間)/月です。エンジニアの実効レートを1時間あたり8,000円とすると、月30万円超の工数削減に相当します。これに、障害時の復元迅速化によるダウンタイム削減(前掲の損失換算¹)を加味すれば、初期構築と保守コストは短期間で回収可能と見込めます。

運用プロセスとしては、バックアップ取得は日次の完全版、差分はコミットごと、復元のドリルは四半期に一度、そして主要機器のゴールデンコンフィグを半期ごとに更新するのが現実的です。監査の観点では、コミット署名、ハッシュとタイムスタンプの保存、実行者・実行理由のメタデータ付与を標準化すると、セキュリティレビューでの説明負荷が激減します。最後に、バックアップと復元は設計・取得・保管・検証・演習という一連の流れを切り離さず、継続的に回し続けて初めて意味を持ちます。ツールは目的ではなく、信頼性のための手段であることをチームで共有しておきましょう。

まとめ:止めないために、戻せる仕組みを当たり前に

ネットワークの信頼性は、複雑な装置や先進的なプロトコルだけで担保されるものではありません。確実に取れているバックアップと、迷いなく実行できる復元手順があって初めて、変更のスピードと安定運用は両立します。今日からできることとして、SCPでの取得経路を整え、Gitによるバージョン管理に乗せ、差分レビューの目を養いましょう。次に、confirmed commitやconfigure replaceなど、ベンダー固有の安全弁を自動化コードに組み込み、四半期ごとの復元ドリルで実効性を検証してください。あなたのチームは、いまどの段階にありますか。小さな一歩でも、次のメンテナンス前に一つの装置から始めることができます。戻せる自信が、攻める変更の前提になります。

参考文献

  1. Atlassian — Cost of downtime: average cost per minute and trends
  2. Uptime Institute — 2022 outage analysis finds downtime costs and consequences worsening
  3. Uptime Institute — Operational and process flaws as outage contributors
  4. Network World — Network connectivity issues are leading cause of IT service outages
  5. Splunk — ダウンタイムでGlobal 2000企業に年4,000億ドルの損失(2024年レポート)
  6. ManageEngine — Network Configuration Backup Best Practices