分散型ネットワーク管理が抱える課題
次のようなシナリオを想像してみてください。2つのオフィス拠点にまたがり、20台のエンタープライズ向けアクセススイッチと5台のエッジルーターを管理しているとします。エンジニアがチームに参加または離脱するたびに、25台すべての機器に個別にログインしてユーザーアカウントを作成・削除しなければなりません。
また、誰かが誤ってインターフェース設定を変更したり、業務時間中に不意な機器の再起動を実行してしまったりした際、誰が原因かを突き止めるのは極めて困難です。ローカルコンソールのリングバッファが100行の履歴制限で上書きされてしまう前に、必死でログを漁る羽目になります。
個々のネットワーク機器上にローカルアカウントを直接保持することは、深刻なセキュリティ上の盲点を生み出します。
- 認証情報の形骸化(クレデンシャルドリフト): 従業員の退職後も、サブのスイッチ上に古いアカウントが数か月、あるいは数年間も放置され続けるリスクがあります。
- 大雑把なアクセス権限レベル: Cisco IOSの特権レベル(0、1、15)には柔軟性がありません。基本的なインターフェース診断を実行するためだけに、エンジニアへ過剰な特権レベル15のフル権限が付与されがちです。
- 監査性の欠如: 不正なVLAN変更によってコアトラフィックが切断された場合、巡回型のsyslogバッファからリンク切断直前に入力された正確なコマンドシーケンスを特定することは極めて困難です。
AAA(認証・認可・アカウンティング)の一元化は、こうした状況を一変させます。すべてのネットワーク機器をAAAクライアントへと変え、単一のID認証基盤に対してすべてのセッションを検証できるようになります。
基本概念:なぜTACACS+とtac_plusなのか?
ネットワーク機器の保護においては、RADIUSとTACACS+(Terminal Access Controller Access-Control System Plus)の2つのプロトコルが広く使われています。どちらもAAAを担いますが、その内部アーキテクチャは大きく異なります。
TACACS+ と RADIUS の比較
- トランスポート層と暗号化: RADIUSはUDP(ポート1812/1813)を使用し、ペイロード内のユーザーパスワードのみを暗号化します。一方、TACACS+は信頼性の高いTCP(ポート49)を使用し、ネットワーク上には最小限の12バイトヘッダーのみを公開してペイロード本文全体を暗号化します。
- AAA機能の分離: RADIUSは初回のアクセス時に認証と認可をまとめて処理します。TACACS+は認証、認可、アカウンティングを独立したトランザクションとして分離しています。この分離構造により、アクティブなセッションの実行中であってもサーバー側で動的に認可チェックを適用できます。
- コマンド単位の認可制御: ジュニアオペレーターが
reloadやconfigure terminalと入力すると、スイッチは実行を数ミリ秒間保留します。TACACS+デーモンへ認可クエリを送信し、許可(permit)または拒否(deny)の応答を待ってから、未許可の構文をその場でブロックします。
コマンドレベルのフィルタリングは、本番環境において非常に有用です。ジュニアスタッフには日常のトラブルシューティングに必要な読み取り専用アクセスのみを与えつつ、危険な構成変更は確実に制限できます。
tac_plusデーモンについて
Linux環境では、Ciscoが開発し現在はShrubbery Networksによって保守されているtac_plusが、オープンソースデーモンのデファクトスタンダードとなっています。直感的な設定ファイルを読み込み、ローカルまたはPAM/LDAPの認証情報を検証し、正規表現ベースの認可ルールを適用した上で、プレーンテキスト形式の分かりやすい監査ログを出力します。
実践ガイド:TACACS+サーバーの構築手順
Ubuntu 22.04/24.04またはDebian 12上でtac_plusをセットアップし、Cisco IOSスイッチと連携させる手順を説明します。
ステップ1:tac_plusのインストール
公式ディストリビューションのリポジトリからパッケージを取得します。
sudo apt update
sudo apt install -y tacacs+
インストーラーにより、メイン設定ファイルが/etc/tacacs+/tac_plus.confに配置され、サービスがtacacs_plusとして登録されます。
ステップ2:暗号化パスワードの生成
設定ファイル内に平文の認証情報を保存してはなりません。OpenSSLを使用して、ソルト付きのMD5またはSHA-512パスワードハッシュを生成します。
openssl passwd -1 "JuniorSecretPass123"
OpenSSLによって$1$v3rY$s0m3h4sh3dv4lu3h3r3のようなMD5暗号化文字列が出力されます。このハッシュ値をコピーして、ユーザー定義ブロックで使用します。
ステップ3:サーバー設定の定義
任意のエディタで/etc/tacacs+/tac_plus.confを開きます。
sudo nano /etc/tacacs+/tac_plus.conf
ひな形の内容を、以下の本番向け設定に置き換えます。ここではnetadmin(完全な管理者権限)とoperator(ping、traceroute、showのみに制限)の2つの特権階層を設定します。
# Linuxとネットワーク機器間で共有するグローバル暗号化キー
key = "SuperSecretTacacsKey2026"
# アカウンティングログの出力先
accounting file = /var/log/tac_plus.acct
# グループ: 上級管理者(フルアクセス権限)
group = netadmin {
default service = permit
service = exec {
priv-lvl = 15
}
}
# グループ: ジュニアオペレーター(読み取り専用 / 診断コマンドのみ)
group = operator {
default service = deny
service = exec {
priv-lvl = 1
}
# 安全な読み取り専用コマンドおよび診断コマンドを許可
cmd = show {
permit .*
}
cmd = ping {
permit .*
}
cmd = traceroute {
permit .*
}
cmd = exit {
permit .*
}
# 設定変更やシステム操作コマンドを明示的に拒否
cmd = reload {
deny .*
}
cmd = configure {
deny .*
}
}
# ユーザーアカウント
user = alex {
member = netadmin
login = des $1$v3rY$adminHashExampleString123
}
user = sam {
member = operator
login = des $1$v3rY$s0m3h4sh3dv4lu3h3r3
}
ステップ4:構文チェックとサービスの起動
本番でデーモンを起動する前に、入力ミスがないか検証します。
sudo tac_plus -P /etc/tacacs+/tac_plus.conf
構文エラーがなくコマンドが正常終了したら、systemdユニットを起動および有効化します。
sudo systemctl restart tacacs_plus
sudo systemctl enable tacacs_plus
sudo systemctl status tacacs_plus
ホストでUFWが稼働している場合は、管理サブネット(例:10.10.0.0/24)からのTCPポート49の受信トラフィックのみを許可します。
sudo ufw allow from 10.10.0.0/24 to any port 49 proto tcp
sudo ufw reload
ステップ5:ネットワークスイッチ/ルーター(Cisco IOS)の設定
Ciscoスイッチまたはルーターに接続し、設定モードに入ります。ここではLinuxサーバーのIPアドレスを10.10.0.50と仮定します。
Switch# configure terminal
! TACACS+サーバーのエンドポイントを定義
tacacs server TACACS-LINUX
address ipv4 10.10.0.50
key SuperSecretTacacsKey2026
timeout 5
exit
! サーバーをサーバーグループに割り当て
aaa group server tacacs+ TAC-GROUP
server name TACACS-LINUX
exit
! AAAサブシステムを有効化
aaa new-model
! 認証: TACACS+ダウン時はローカルデータベースへフォールバック
aaa authentication login default group TAC-GROUP local
aaa authentication enable default group TAC-GROUP enable
! 認可: シェル実行および特権レベル1/15のコマンドを検証
aaa authorization exec default group TAC-GROUP local
aaa authorization commands 1 default group TAC-GROUP local
aaa authorization commands 15 default group TAC-GROUP local
! アカウンティング: セッションの接続/切断と実行された全コマンドを記録
aaa accounting exec default start-stop group TAC-GROUP
aaa accounting commands 1 default start-stop group TAC-GROUP
aaa accounting commands 15 default start-stop group TAC-GROUP
! サーバー到達不能時に備えた緊急用ローカルバックドア
username emergency privilege 15 secret BackupLocalPassword!@#
end
write memory
ステップ6:権限の動作テストとアカウンティングログの確認
誤って締め出されないよう、現在の管理者セッションは開いたままにしてください。別のターミナルを開き、権限を制限したオペレーターアカウントでスイッチにSSH接続します。
ssh [email protected]
スイッチのプロンプトから権限範囲の制限をテストします。
Switch> show ip interface brief # <-- 成功
Switch> ping 8.8.8.8 # <-- 成功
Switch> configure terminal # <-- 失敗: % Command authorization failed
Switch> reload # <-- 失敗: % Command authorization failed
Linuxサーバーに戻り、アカウンティングファイルをリアルタイムで確認します。
sudo tail -f /var/log/tac_plus.acct
エンジニアがコマンドを実行するたびに、tac_plusによってタブ区切りの監査レコードが追加されます。
Mon Oct 20 10:14:22 2026 10.10.0.1 sam tty2 10.10.0.100 stop task_id=42 cmd=show ip interface brief <cr>
各エントリには、正確なタイムスタンプ、スイッチのIP(10.10.0.1)、ユーザー名(sam)、クライアント端末(tty2)、作業端末のIP(10.10.0.100)、および入力された正確なCLI文字列が記録されます。
まとめ
AAAの一元管理を導入することで、認証情報が散乱するカオスな状態を解消できます。tac_plusを活用すれば、新規エンジニアのアカウント登録を瞬時に完了できるだけでなく、最小特権の原則を徹底し、ネットワーク全体のコマンド実行履歴を改ざん困難な監査証跡として保存できます。さらに発展的な構成として、PAMを介してActive DirectoryやFreeIPAと認証を連携させたり、ネットワークメンテナンス時の冗長性を確保するためにスタンバイ用のセカンダリデーモンを展開したりすることも可能です。

