4-2 AAA — 認証・認可・アカウンティングとRADIUS / TACACS+
認証 / 認可 / アカウンティングという AAA の 3 本柱、method-list と local fallback、RADIUS と TACACS+ の違いを整理する。RADIUS の単一往復と TACACS+ の多段往復を、外部認証サーバとの debug 出力で対照して実機検証する。
1. 前節の振り返りと本節の内容
前節 4-1 ACL では、ルータを通過するパケットを送信元・宛先・プロトコル・ポートで選別する パケットフィルタリング (Packet Filtering) を扱いました。ACL が制御するのは「どの通信を通すか」であり、対象はネットワークを流れるパケットそのものでした。
本節で扱う AAA (Authentication, Authorization, Accounting) は、視点をパケットから 利用者 (ユーザ) へ移します。AAA が制御するのは「誰がログインでき、何を実行でき、何をしたかを記録するか」であり、ネットワーク機器そのものへのアクセスを管理する仕組みです。ルータやスイッチに SSH / コンソールでログインしてくる管理者を、どう認証し、どこまでの操作を許し、その操作をどう記録するかを扱います。
本節では AAA の 3 本柱 (認証 / 認可 / アカウンティング) を整理し、aaa new-model による AAA の有効化、ローカルユーザ DB を使う ローカル AAA、外部サーバを使う RADIUS と TACACS+ の違いを扱います。CML 上の csr1000v (NAS) と外部 AAA サーバ (FreeRADIUS / tac_plus) で、RADIUS 認証・local fallback・アカウンティング・TACACS+ の認可 (exec の特権レベル) の粒度差を実機検証します。
2. AAA の 3 本柱 — 認証・認可・アカウンティング
AAA は、ネットワーク機器へのアクセス制御を 3 つの独立した機能に分けて扱う枠組みです。3 つの機能は以下のとおりです。
- Authentication (認証) — 「誰か」を確かめる 機能。ログインしてきた利用者が、名乗ったとおりの本人であるかを、ユーザ名とパスワード (または証明書・トークン) で検証します。
- Authorization (認可) — 「何ができるか」を決める 機能。認証を通った利用者に対し、どの特権レベルでログインさせるか、どのコマンドを実行させるかを制御します。
- Accounting (アカウンティング) — 「何をしたか」を記録する 機能。利用者がいつログインし、いつログアウトし、どのコマンドを実行したかをログとして残します。
3 つは独立した機能であり、認証だけを使い認可・アカウンティングを使わない構成も成立します。認証で「本人確認」、認可で「権限付与」、アカウンティングで「行動記録」という流れで、機器へのアクセスを段階的に管理します。
AAA を使う前のルータは、コンソールや vty に設定したパスワード 1 つで「ログインできるかどうか」だけを判断していました。この方式では利用者ごとの区別がなく、誰がログインしたかも記録されません。AAA はこの単純なパスワード認証と違い、利用者単位で認証し、利用者ごとに権限を変え、利用者ごとに行動を記録する ことを可能にします。
IOS / IOS-XE で AAA を使うには、グローバル設定モードで aaa new-model を投入します。このコマンドが AAA 機能全体を有効化するスイッチであり、これを入れて初めて認証・認可・アカウンティングの各設定 (aaa authentication / aaa authorization / aaa accounting) が利用できます。
3. ローカル AAA と method-list
AAA の認証先には、機器自身の ローカルユーザ DB を使う方法と、外部の AAA サーバ に問い合わせる方法があります。まず外部サーバを使わず、機器内の username で定義したユーザ DB を認証先にする ローカル AAA から確認します。
aaa new-model を投入し、ログイン認証をローカル DB に向ける設定は以下のとおりです。
aaa new-model
aaa authentication login default local
aaa authorization exec default localaaa authentication login default local は「login (端末ログイン) の認証に、ローカルユーザ DB (local) を使う」という宣言です。この default の部分が method-list (メソッドリスト) の名前にあたります。
method-list は、認証 / 認可 / アカウンティングを「どの方法で、どの順に試すか」を並べた名前付きのリストです。method-list には 2 種類あります。
- default リスト — 名前が
defaultのリスト。明示的に別のリストを当てない限り、すべての回線 (コンソール / vty) に自動的に適用されます。 - 名前付きリスト —
VTY_RADIUSのように任意の名前を付けたリスト。回線にlogin authentication <名前>で明示的に当てたときだけ適用されます。
method-list の核心は、複数のメソッドを順に並べ、前のメソッドが使えないとき次のメソッドへ移る (フォールバックする) 点です。たとえば group RAD-GRP local と書くと「まず RADIUS サーバ群 (RAD-GRP) で認証を試み、それが使えなければローカル DB で認証する」という 2 段構えになります (§7 で実機確認します)。
aaa new-model を投入した直後の認証 method-list の状態は、show aaa method-lists authentication で確認できます。
show aaa method-lists authentication
authen queue=AAA_ML_AUTHEN_LOGIN
name=default valid=TRUE id=0 :state=ALIVE : LOCAL
name=CONSOLE_LOCAL valid=TRUE id=AC000003 :state=ALIVE : LOCAL
authen queue=AAA_ML_AUTHEN_ENABLE
authen queue=AAA_ML_AUTHEN_PPP
...
permanent lists
name= Permanent Enable None valid=TRUE id=0 :state=ALIVE : ENABLE NONE
name= Permanent Enable valid=TRUE id=0 :state=ALIVE : ENABLE
name= Permanent None valid=TRUE id=0 :state=ALIVE : NONE
name= Permanent Local valid=TRUE id=0 :state=ALIVE : LOCAL
name= Permanent rcmd valid=TRUE id=0 :state=ALIVE : RCMD
R1#name=default valid=TRUE id=0 :state=ALIVE : LOCAL の行が、aaa authentication login default local で作られた default リストです。末尾の LOCAL が「このリストはローカルユーザ DB を使う」ことを示します。state=ALIVE は、このリストが有効に動作していることを表します。ローカル AAA では、認証メソッドが LOCAL 1 つだけなので、機器内の username に一致すれば認証成功、一致しなければ失敗となります。
4. 外部 AAA サーバ — RADIUS と TACACS+
ローカル AAA は機器単体では完結しますが、管理対象の機器が増えると問題が生じます。10 台のルータがあれば 10 台それぞれにユーザ DB を持たせることになり、パスワード変更や利用者追加のたびに全台を個別に設定し直す必要があります。
外部 AAA サーバ は、ユーザ DB と認証ポリシーを 1 か所のサーバに集約し、機器側はそのサーバへ問い合わせるだけにする方式です。利用者の追加・削除・パスワード変更はサーバ側だけで済み、機器側の設定は変わりません。この構成では、利用者が直接ログインするネットワーク機器 (ルータ / スイッチ) を NAS (Network Access Server)、認証要求を受けて可否を判定するサーバを AAA サーバ と呼びます。
外部 AAA サーバとの通信プロトコルには RADIUS (Remote Authentication Dial-In User Service) と TACACS+ (Terminal Access Controller Access-Control System Plus) の 2 つが広く使われます。両者は役割が似ていますが、トランスポート・暗号化範囲・機能分割に違いがあります。比較は以下のとおりです。
| 観点 | RADIUS | TACACS+ |
|---|---|---|
| トランスポート | UDP (認証 1812 / 課金 1813) | TCP 49 |
| 保護範囲 | パスワード部分のみを保護 | ヘッダ以外のボディ全体を保護 |
| 認証と認可 | 結合 (Access-Accept に属性を同梱) | 分離 (認証と認可が別トランザクション) |
| 実機の往復 (debug) | 単一 Access-Request → Access-Accept | start → GET_PASSWORD → continue → PASS の多段 |
| コマンド認可の粒度 | 粗い (priv-lvl 属性が中心) | 細かい (コマンド単位の認可が可能) |
| 由来 | IETF 標準 (RFC 2865 / 2866) | Cisco 由来 |
最大の構造的な違いは、RADIUS が認証 (AuthN) と認可 (AuthZ) を 1 つのやりとりに結合している のに対し、TACACS+ がこの 2 つを分離している 点です。RADIUS では認証成功の応答 (Access-Accept) に特権レベルなどの認可情報が属性として同梱されて返ります。TACACS+ では認証が成功した後、別のトランザクションとして認可を問い合わせます。この違いは実機の debug で「往復回数の差」として観測でき (§6・§9)、TACACS+ の分離設計は コマンド単位の細かい認可 を可能にします。
保護範囲も異なります。RADIUS は Access-Request 内のパスワード部分だけを共有鍵で保護し、ユーザ名などその他の属性は平文です。TACACS+ は、ヘッダを平文に残しつつ、共有鍵に基づく方式でボディ全体を保護します (この保護は標準 RFC 8907 では現代的な意味の暗号化ではなく難読化 (obfuscation) と位置づけられており、機密性・完全性・リプレイ保護を完全に保証するものではありません)。トランスポートも、RADIUS が UDP なのに対し、TACACS+ は TCP を使い、コネクションの確立と切断を伴います。
5. ラボトポロジ — NAS が外部 AAA サーバに認証を問い合わせる
本ラボは csr1000v 1 台を NAS とし、外部に RADIUS サーバ (FreeRADIUS) と TACACS+ サーバ (tac_plus) を 1 台用意した構成です。R1 が AAA クライアント (NAS) として、自身の vty ログイン認証を外部サーバへ問い合わせます。
- R1 = NAS (AAA クライアント) — 利用者が SSH でログインしてくるネットワーク機器です。
aaa new-modelと method-list を設定し、認証要求を外部サーバへ転送します。AAA の問い合わせは、AAA 専用のインターフェース (Gi2) を source-interface に指定して送出します。 - RADIUS サーバ (FreeRADIUS) — UDP の認証ポート 1812・課金ポート 1813 で待ち受けます。利用者
netadmin(特権レベル 15) とnetoper(特権レベル 1) を登録してあります。 - TACACS+ サーバ (tac_plus) — TCP ポート 49 で待ち受けます。利用者
tacadmin(グループ netadmin / 特権レベル 15) とtacoper(グループ netoper / 特権レベル 1) を登録してあります。
AAA サーバは R1 の AAA source-interface と同一セグメントに置くため、ルーティングは不要です。検証では R1 から AAA サーバへ到達できることを ping で確認してから各フェーズに入ります。
ping 172.16.1.130 source GigabitEthernet2 repeat 3
Type escape sequence to abort.
Sending 3, 100-byte ICMP Echos to 172.16.1.130, timeout is 2 seconds:
Packet sent with a source address of 172.16.1.231
.!!
Success rate is 66 percent (2/3), round-trip min/avg/max = 1/1/2 ms
R1#R1 が Gi2 (172.16.1.231) を送信元に AAA サーバ (172.16.1.130) へ到達できています。初回の . は ARP 解決待ちのタイムアウトで、解決後の !! で到達しています (前節 4-1 と同じく、初回 ping の . は ARP 解決の所要時間によるものです)。以降の show / debug 出力には検証環境の実アドレス (NAS = 172.16.1.231 / AAA サーバ = 172.16.1.130) がそのまま現れます。
上の図では教材の一般化のため、RADIUS (
10.0.50.10) と TACACS+ (10.0.50.20) を別アドレス・別ノードとして描いています。一方、本検証環境では FreeRADIUS と tac_plus を同一ホスト (172.16.1.130) に同居させているため、後続の §6show aaa servers・§9show tacacsではいずれの宛先も172.16.1.130として現れます。実運用では、RADIUS / TACACS+ サーバを用意し、NAS から IP 到達できればよく、サーバの配置 (別ホストか同居か) や製品は問いません。教材の主題は IOS-XE 側の AAA 設定であり、サーバ構築の詳細には立ち入りません。
6. RADIUS 認証の実機検証 — Access-Request から Access-Accept へ
RADIUS で外部認証を行う設定を確認します。R1 に RADIUS サーバ・サーバグループ・送信元インターフェース・method-list を設定します。
radius server RAD1
address ipv4 172.16.1.130 auth-port 1812 acct-port 1813
key radlab123
!
aaa group server radius RAD-GRP
server name RAD1
!
ip radius source-interface GigabitEthernet2
!
aaa authentication login VTY_RADIUS group RAD-GRP local設定の各行の意味は以下のとおりです。
radius server RAD1— RADIUS サーバ 1 台を定義します。address ipv4で IP と認証ポート (1812) / 課金ポート (1813) を、keyで NAS とサーバが共有する秘密鍵を指定します。aaa group server radius RAD-GRP— RADIUS サーバを束ねるサーバグループを作り、server name RAD1で先のサーバを所属させます。method-list はこのグループ名 (RAD-GRP) を参照します。ip radius source-interface GigabitEthernet2— RADIUS パケットの送信元アドレスを Gi2 に固定します。サーバ側は送信元 IP で NAS を識別するため、送信元を固定することが重要です。aaa authentication login VTY_RADIUS group RAD-GRP local—VTY_RADIUSという名前付き method-list を作り、認証を「まずgroup RAD-GRP(RADIUS)、使えなければlocal(ローカル DB)」の順に試すよう定義します。
認証フローの実体を確認します。本ラボのようなユーザ名・パスワード認証では、RADIUS の認証は、NAS が利用者の資格情報を Access-Request で問い合わせ、サーバが Access-Accept (成功) または Access-Reject (失敗) で応答する、単一の往復です (RADIUS には追加情報を要求する Access-Challenge もあり、チャレンジ応答方式では往復が複数になりますが、本節の単純なログイン認証では単一往復です)。
test aaa group コマンドで、サーバグループに対する認証を試験できます。正しいパスワードを与えると認証が成功します。
test aaa group RAD-GRP netadmin radadmin123 new-code
User successfully authenticated
USER ATTRIBUTES
Message-Authenticato 0 <hidden>
service-type 0 6 [Administrative]
priv-lvl 0 15 (0xF)
priv-lvl 0 15 (0xF)
R1#User successfully authenticated で認証が成功しています。注目箇所は、認証成功と同時に service-type 6 [Administrative] と priv-lvl 15 (0xF) という属性が返っている点です。RADIUS は認証成功の応答に認可情報 (特権レベル 15) を 同梱 して返します。これが §4 で述べた「RADIUS は認証と認可が結合している」ことの実機での現れです。
誤ったパスワードを与えると、サーバは明示的に拒否します。
test aaa group RAD-GRP netadmin wrongpass new-code
User rejected
R1#User rejected で認証が失敗したことが分かります。この test では §6 冒頭の成功例と先ほどの ping (§5) でサーバが到達可能であることを確認済みのため、この失敗は「サーバが到達可能なまま資格情報の不一致で 明示的に拒否 (Access-Reject) した」ケースです (この「到達可能なサーバによる明示的な拒否」は §7 の local fallback で重要になります。なお test aaa group の User rejected という文言自体は、サーバが無応答 (dead) のときにも同じく表示されるため、両者の区別はサーバの到達可否で判断します)。
実際の RADIUS パケットの往復は debug radius で観察できます。debug の核心部分は以下のとおりです。
RADIUS(00000000): Send Access-Request to 172.16.1.130:1812 id 1645/1, len 54
RADIUS: User-Password [2] 18 *
RADIUS: User-Name [1] 10 "netadmin"
RADIUS: NAS-IP-Address [4] 6 172.16.1.231
RADIUS: Received from id 1645/1 172.16.1.130:1812, Access-Accept, len 69
RADIUS: Service-Type [6] 6 Administrative [6]
RADIUS: Cisco AVpair [1] 19 "shell:priv-lvl=15"Send Access-Request to 172.16.1.130:1812 で、NAS が認証ポート 1812 へ Access-Request を送出しています。User-Name (netadmin) は平文で、User-Password (* で伏字) は共有鍵で保護されて含まれています。サーバは Access-Accept を返し、その中に Service-Type Administrative と Cisco AVpair "shell:priv-lvl=15" が乗っています。この AVpair が、認証成功した利用者の特権レベルを 15 に決定します。NAS が Access-Request を送り、RADIUS が priv-lvl 属性を含む Access-Accept を 1 回で返す —— この単一往復が RADIUS 認証フローの実体です。
この一連のメッセージの往復を、成功・誤パスワード時の拒否・サーバ無応答時の local fallback まで含めて時間で追うと、次のようになります。
サーバの状態は show aaa servers で確認できます。
show aaa servers | include RADIUS|host|State|Authen
RADIUS: id 1, priority 1, host 172.16.1.130, auth-port 1812, acct-port 1813, hostname RAD1
State: current UP, duration 46s, previous duration 0s
...
Authen: request 0, timeouts 0, failover 0, retransmission 0
R1#host 172.16.1.130, auth-port 1812, acct-port 1813 で、RADIUS の既定ポート (認証 1812 / 課金 1813) が確認できます。State: current UP はサーバが応答可能な状態であることを示します。
7. method-list と local fallback — サーバ無応答時の 2 番目のメソッド
§6 の method-list VTY_RADIUS は group RAD-GRP local と定義しました。この 2 番目の local が、どういうときに効くのかを実機で確認します。
method-list のフォールバックは、前のメソッドが「使えない」ときに次のメソッドへ移る 仕組みです。ここで「使えない」とは、サーバが無応答 (dead) であること を指します。RADIUS サーバが到達不能で応答が返ってこない状況を作り、ローカル DB へフォールバックするかを確認します。
検証では、RADIUS の宛先を到達不能なアドレス (172.16.1.199) に向けてサーバを dead 状態にし、ローカル admin で SSH ログインを試みます。VTY_RADIUS が当たった回線でのログイン時の debug は以下のとおりです。
*Jun 26 01:15:18.604: AAA/BIND(00000038): Bind i/f
*Jun 26 01:15:18.604: AAA/AUTHEN/LOGIN (00000038): Pick method list 'VTY_RADIUS'
*Jun 26 01:15:18.989: %RADIUS-4-RADIUS_DEAD: RADIUS server 172.16.1.199:1812,1813 is not responding.
*Jun 26 01:15:18.999: %RADIUS-4-RADIUS_ALIVE: RADIUS server 172.16.1.199:1812,1813 is being marked alive.
*Jun 26 01:15:22.687: %SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: admin] [Source: 192.168.1.26] [localport: 22] at 01:15:22 UTC Fri Jun 26 20263 つの段階が読み取れます。第一に、Pick method list 'VTY_RADIUS' で VTY_RADIUS リストが選ばれています。第二に、%RADIUS-4-RADIUS_DEAD: ... is not responding で、1 番目のメソッドである RADIUS サーバが応答しないことが検出されています (直後の %RADIUS-4-RADIUS_ALIVE は、IOS-XE が dead とマークしたサーバを所定のデッドタイム経過後に再び試行可能としてマークし直すもので、本環境ではデッドタイムが既定の 0 のため即時に戻りますが、この回のローカル認証には影響しません)。第三に、%SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: admin] で、ローカル DB の admin によるログインが成功しています。RADIUS が無応答 (dead) のため、method-list の 2 番目に置いた local がローカル DB で認証を引き受けた —— これが local fallback です。
サーバが無応答であった証跡は、show aaa servers のタイムアウトカウンタにも現れます。
show aaa servers | include RADIUS|host|State|Dead|timeouts|Authen
RADIUS: id 1, priority 1, host 172.16.1.199, auth-port 1812, acct-port 1813, hostname RAD1
...
Authen: request 4, timeouts 4, failover 0, retransmission 2
R1#Authen: request 4, timeouts 4 のとおり、認証要求 4 件すべてがタイムアウトしています。サーバが応答を返さないため、要求数とタイムアウト数が一致して積み上がります。
ここで誤解しやすい点を強調します。local fallback が効くのは サーバが無応答 (dead) のときだけ です。サーバが到達可能で、かつ認証を 明示的に拒否 (Access-Reject) した場合は、ローカル DB へフォールバック しません。§6 で見た User rejected のように、サーバが「このパスワードは間違っている」と応答した場合は、それが最終的な判定となり、認証は失敗で確定します。「RADIUS が落ちたらローカルで入れる」が「RADIUS でパスワードを間違えてもローカルで入れる」ではない点に注意します (§10 で改めて整理します)。
8. アカウンティングの実機検証 — 誰が何をしたかを記録する
AAA の 3 本目、アカウンティング (Accounting) を確認します。アカウンティングは利用者の行動を記録する機能で、exec セッション (端末ログイン) の開始・終了を記録する設定は以下のとおりです。
aaa accounting exec default start-stop group RAD-GRPaaa accounting exec default start-stop group RAD-GRP は「exec セッションの開始時 (start) と終了時 (stop) の両方を、RADIUS サーバグループ (RAD-GRP) へ記録する」という宣言です。start-stop は、セッション開始時に START レコードを、終了時に STOP レコードを送る方式を意味します。
ログイン時にアカウンティングのレコードが送られる様子は、debug aaa accounting で観察できます。
*Jun 25 23:54:12.388: %SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: admin] [Source: 192.168.1.26] [localport: 22] at 23:54:12 UTC Thu Jun 25 2026
*Jun 25 23:54:12.405: AAA/ACCT/EXEC(00000024): Pick method list 'default'
*Jun 25 23:54:12.406: AAA/ACCT/EXEC(00000024): Queueing record is START
*Jun 25 23:54:12.408: AAA/ACCT(00000024): Accounting method=RAD-GRP (RADIUS)
*Jun 25 23:54:12.410: AAA/ACCT/EXEC(00000024): START protocol reply PASS
*Jun 25 23:54:12.410: AAA/ACCT(00000024): Accounting response status = SUCCESS
R1#ログイン成功 (LOGIN_SUCCESS) の直後に、Queueing record is START で START レコードが作られ、Accounting method=RAD-GRP (RADIUS) で RADIUS サーバグループ宛に送られています。START protocol reply PASS と Accounting response status = SUCCESS は、サーバがこのレコードを受領した (ACK を返した) ことを示します。
start-stop を指定しているため、利用者がログアウトすると STOP レコードも送られます。同じ debug の後半には、ログアウト時に STOP レコードが送られ、同じく SUCCESS で受領される様子も記録されます。アカウンティングにより、「いつ・誰が・どのセッションを開始し、いつ終了したか」がサーバ側に蓄積され、後から監査できる記録となります。これが AAA の「何をしたか」を担う機能です。
9. TACACS+ の実機検証 — 認証の多段往復と認可 (exec) の粒度差
外部 AAA サーバのもう一方、TACACS+ を確認します。設定は RADIUS と同じ構造で、tacacs server / aaa group server tacacs+ / ip tacacs source-interface で構成します。
tacacs server TAC1
address ipv4 172.16.1.130
key taclab123
!
aaa group server tacacs+ TAC-GRP
server name TAC1
!
ip tacacs source-interface GigabitEthernet2サーバの状態は show tacacs で確認できます。
show tacacs | include TACACS|Server|Socket|State
Tacacs+ Server - public :
Server name: TAC1
Server address: 172.16.1.130
Server port: 49
Socket opens: 0
Socket closes: 0
...
Server Status: Alive
R1#Server port: 49 のとおり、TACACS+ は TCP ポート 49 を使います (RADIUS の UDP 1812/1813 との違い)。Server Status: Alive でサーバが応答可能であることが確認できます。
認証の往復の違い
TACACS+ の認証フローは RADIUS と構造が異なります。RADIUS が単一の Access-Request / Access-Accept だったのに対し、TACACS+ は認証フェーズが複数の往復に分かれます。debug tacacs の核心部分は以下のとおりです。
TPLUS: Authentication start packet created for 0(tacadmin)
TPLUS: Using server 172.16.1.130
TPLUS: Received authen response status GET_PASSWORD (8)
TPLUS: processing authentication continue request id 0
TPLUS: Authentication continue packet generated for 0
TPLUS: Received authen response status PASS (2)往復の流れが読み取れます。まず NAS が Authentication start packet を送り、サーバが GET_PASSWORD (8) を返してパスワードを要求します。NAS はそれを受けて Authentication continue packet でパスワードを送り、サーバが PASS (2) で認証成功を返します。start → GET_PASSWORD → continue → PASS の多段往復 であり、RADIUS の単一往復とは明確に異なります。この多段往復は、TACACS+ の 認証フェーズ がパスワード要求を含む複数のやりとりで構成されることの現れです。なお、TACACS+ が認証 (AuthN) と認可 (AuthZ) を分離するのは、この認証フェーズの後に、認可を 別のトランザクション として問い合わせる点であり、認証フェーズが多段になること自体とは別の仕組みです (認可のトランザクションは次の「認可 (exec) の粒度差」で扱います)。
この多段往復を時間で追うと、RADIUS の単一往復との違いがはっきりします。
認可 (exec) の粒度差 — 特権レベルの出し分け
TACACS+ の特徴が現れるのが 認可の粒度 です。同じ TACACS+ サーバが、利用者ごとに異なる特権レベルを出し分ける様子を、実際のログインで確認します。本ラボでは、TACACS+ に向けた認証 method-list と exec 認可の method-list を vty に当て、tacadmin と tacoper でそれぞれログインして show privilege を実行します。
aaa authentication login VTY_TAC group TAC-GRP local
aaa authorization exec VTY_TAC group TAC-GRP localaaa authentication login VTY_TAC group TAC-GRP local で TACACS+ 認証の method-list を、aaa authorization exec VTY_TAC group TAC-GRP local で exec 認可 (ログイン時の特権レベルをサーバに問い合わせる) の method-list を定義し、これを運用の vty に当てます。exec 認可では、サーバが利用者ごとに返す特権レベルがそのままログイン後の特権レベルになります。
特権レベル 15 のグループに属する tacadmin でログインした場合は以下のとおりです。
show privilege
Current privilege level is 15
R1#Current privilege level is 15 で、特権レベル 15 (全コマンド実行可能) でログインしています。プロンプトも特権モードを示す R1# です。一方、特権レベル 1 のグループに属する tacoper でログインした場合は以下のとおりです。
show privilege
Current privilege level is 1
R1>Current privilege level is 1 で、特権レベル 1 (限定されたコマンドのみ) でのログインです。プロンプトもユーザモードを示す R1> です。同じ TACACS+ サーバが、tacadmin には特権レベル 15 を、tacoper には特権レベル 1 を出し分けている —— これが exec 認可による特権レベルの出し分けです。本ラボで実機確認したのは、この exec 認可 (ログイン時の特権レベル) の粒度差までです。
RADIUS でも priv-lvl 属性で特権レベルを渡せます (§6) が、TACACS+ は認可を独立したトランザクションとして扱う設計のため、exec 認可に加えて コマンド単位の認可 (aaa authorization commands) —— 利用者ごとに実行可能なコマンドそのものを許可・拒否する制御 —— まで構成できます (本ラボでは exec 認可までを実演し、コマンド単位の認可は TACACS+ の設計能力として説明に留めます)。「認証中心で認可は属性で粗く渡す RADIUS」と「認証と認可を分離し、コマンド単位まで細かく認可できる TACACS+」という違いが、ネットワーク機器の管理者アクセス制御で TACACS+ が選ばれる理由となります。
10. 落とし穴・補足
実機検証で確認した、教科書の記述と実機挙動の対応や運用上の注意点を記録します。
RADIUS の既定ポートは認証 1812 / 課金 1813 — 現行の RADIUS は認証に UDP 1812、課金に UDP 1813 を使います。古い実装では認証 1645 / 課金 1646 が使われていましたが、これは現在の既定ではありません。なお §6 の
debug radiusに現れるid 1645/1はトランザクションの内部識別表示であって、ポート番号ではありません (RADIUS パケットの Identifier フィールド自体は 1 オクテット = 0〜255 の範囲なので、1645という値は Identifier そのものでもありません)。実際の宛先ポートは、同じ debug 行にSend Access-Request to 172.16.1.130:1812と明示されているとおり 1812 です。TACACS+ は TCP ポート 49 を使います。local fallback はサーバ無応答 (dead) 時のみ効く — method-list の
group ... localのlocalは、前のメソッド (RADIUS / TACACS+ サーバ) が 無応答 のときだけ働きます (§7)。サーバが到達可能で、かつ認証を 明示的に拒否 (Access-Reject) した場合は、ローカル DB へフォールバックせず、認証はそのまま失敗で確定します。「サーバが落ちたときの保険」としてローカルアカウントを 2 番目に置く設計は有効ですが、「サーバでパスワードを間違えてもローカルアカウントで入れる」わけではない点に注意します。ローカルアカウントに頼った復旧を想定するなら、サーバを意図的に到達不能にできる経路を運用設計に含めておく必要があります。RADIUS は認証と認可が結合、TACACS+ は分離 — RADIUS は認証成功の応答 (Access-Accept) に priv-lvl などの認可属性を同梱します (§6)。TACACS+ は認証と認可を別トランザクションで扱います (§9)。この設計差は debug の往復回数の違いとして実機に現れ、RADIUS は単一往復、TACACS+ は start → GET_PASSWORD → continue → PASS の多段往復となります。コマンド単位の細かい認可を必要とする機器管理では、分離設計の TACACS+ が向きます。
aaa new-model投入後のログイン既定特権は 1 —aaa new-modelを入れると、認証を通っただけのログインは既定で特権レベル 1 (ユーザモード) になります。特権レベル 15 を得るには、認可で priv-lvl 15 を渡す (RADIUS ならshell:priv-lvl=15属性、TACACS+ なら認可で特権レベルを返す。ローカルならusername ... privilege 15)、または enable で昇格する必要があります。§9 でtacadminがR1#(特権 15) に、tacoperがR1>(特権 1) になったのは、認可で渡された特権レベルの差です。アカウンティングの
start-stopは開始と終了の両方を記録 —aaa accounting exec default start-stopは、exec セッションの開始時に START、終了時に STOP のレコードを送ります (§8)。START protocol reply PASS/Accounting response status = SUCCESSがサーバの受領 ACK です。記録のタイミングにはstart-stopのほかstop-only(終了時のみ) もあり、監査要件に応じて選びます。検証環境固有の事情 — 本ラボの AAA サーバは、検証環境の都合で外部に構築した FreeRADIUS / tac_plus を使い、NAS と同一の管理セグメント上に置いています (§5)。実運用では RADIUS / TACACS+ サーバを 1 台用意し、NAS から IP 到達できればサーバの配置や製品は問いません。本節の主題は IOS-XE 側の AAA 設定 (method-list・source-interface・サーバグループ) であり、サーバ構築の詳細は扱いません。
11. 次節
本節では、AAA の 3 本柱 (認証 / 認可 / アカウンティング) を整理し、aaa new-model による有効化、ローカル AAA と method-list、外部サーバ RADIUS / TACACS+ の違いを実機で確認しました。RADIUS が認証と認可を結合した単一往復で priv-lvl を返すのに対し、TACACS+ は認証と認可を分離した多段往復で、利用者ごとに特権レベルを出し分ける exec 認可の粒度 (priv-lvl の出し分け) を持つことを debug と show privilege で対照しました。TACACS+ はさらにコマンド単位の認可も構成できますが、本ラボで実機検証したのは exec 認可の特権レベル差までです。method-list の local fallback がサーバ無応答時のみ効くという、運用で誤解しやすい挙動も実機で確認しました。
ACL が「どの通信を通すか」を制御するのに対し、AAA は「誰がログインでき、何をできるか」という利用者を制御する仕組みでした。次節 4-3 802.1X では、この利用者制御を ポート単位 に拡張します。スイッチのポートに機器を接続した瞬間、その機器が正規の利用者かを認証してからネットワークへの参加を許す ポートベース認証 (Port-Based Authentication) を見ていきます。AAA で扱った認証の枠組みが、スイッチポートと連動してどう動くかを確認していきましょう。
Authentication・Authorization・Accounting の頭文字だ。日本語だと認証・認可・アカウンティング。それぞれ役割がきっぱり分かれてる。
- 認証(Authentication) = 「誰か」を確かめる。名乗ったとおりの本人か、ユーザ名とパスワードで検証する。
- 認可(Authorization) = 「何ができるか」を決める。どの特権レベルで入れるか、どのコマンドを許すか。
- アカウンティング(Accounting) = 「何をしたか」を記録する。いつログインして、いつ抜けて、何を打ったか。
aaa new-model を打つ。これが AAA 全体を有効化するスイッチで、これを入れて初めて aaa authentication みたいな各設定が使えるようになる。両方ある。機器自身の ローカルユーザ DB(username で定義したやつ)を使う「ローカル AAA」と、外部の AAA サーバに問い合わせる方式だ。まずローカルから見よう。
aaa new-model
aaa authentication login default local
aaa authorization exec default localaaa authentication login default local は「端末ログインの認証にローカル DB を使う」宣言。この default の部分が method-list の名前なんだ。
「認証や認可を、どの方法で・どの順に試すか」を並べた名前付きのリストだ。2 種類ある。
- default リスト = 名前が
default。明示的に別のを当てない限り、全部の回線(コンソール/vty)に自動で当たる。 - 名前付きリスト =
VTY_RADIUSみたいに任意の名前を付けたやつ。回線にlogin authentication <名前>で明示的に当てた時だけ効く。
そして method-list の核心は、複数のメソッドを並べて、前が使えないと次へ移る(フォールバックする)ことだ。
group RAD-GRP local と書くと「まず RADIUS サーバ群で認証を試して、それが使えなければローカル DB で認証」の 2 段構えになる。この「使えなければ」の意味があとで大事になるから、頭の隅に置いといてくれ。2 つ広く使われてる。RADIUS と TACACS+ だ。役割は似てるけど、中身がけっこう違う。
| 観点 | RADIUS | TACACS+ |
|---|---|---|
| トランスポート | UDP(認証 1812 / 課金 1813) | TCP 49 |
| 保護範囲 | パスワード部分のみ | ヘッダ以外のボディ全体 |
| 認証と認可 | 結合(Accept に属性同梱) | 分離(別トランザクション) |
| debug の往復 | 単一 Request → Accept | start→GET_PASSWORD→continue→PASS の多段 |
| コマンド認可の粒度 | 粗い(priv-lvl 中心) | 細かい(コマンド単位可) |
| 由来 | IETF 標準 | Cisco 由来 |
test aaa group で試験できる。正しいパスワードを与えると ──
test aaa group RAD-GRP netadmin radadmin123 new-code
User successfully authenticated
USER ATTRIBUTES
service-type 0 6 [Administrative]
priv-lvl 0 15 (0xF)User successfully authenticated で成功。注目は、認証成功と同時に service-type 6 [Administrative] と priv-lvl 15 っていう属性が返ってること。RADIUS は認証成功の応答に認可情報(特権レベル 15)を同梱して返す。これがさっきの「RADIUS は認証と認可が結合してる」の実機での姿だよ。
User rejected が返る。ここで大事なのは、これが「サーバは到達できてるのに、資格情報が違うから明示的に拒否した(Access-Reject)」ケースだってこと。この「到達可能なサーバによる明示的な拒否」が、次の local fallback の話で効いてくる。……ちなみに User rejected って文言は、サーバが無応答(dead)のときにも同じく出るから、両者はサーバの到達可否で区別する。文言だけでは見分けられない罠だ。debug radius で往復が見える。
RADIUS: Send Access-Request to 172.16.1.130:1812 id 1645/1, len 54
RADIUS: User-Name [1] 10 "netadmin"
RADIUS: Received ... Access-Accept, len 69
RADIUS: Cisco AVpair [1] 19 "shell:priv-lvl=15"Access-Request を 1812 へ送って、User-Name は平文、User-Password は伏字(鍵で保護)。サーバが Access-Accept を返して、その中に shell:priv-lvl=15 の AVpair が乗ってる。この AVpair が特権レベルを 15 に決める。Request を送って、priv-lvl 入りの Accept が 1 回で返る ── これが RADIUS 認証の実体だ。
id 1645/1 って書いてあるりん。1645 ってポート番号りん? さっき RADIUS は 1812 って言ってたのに。1645 はポート番号じゃない。トランザクションの内部識別表示だ。実は昔の RADIUS 実装は認証 1645/課金 1646 を使っていた時代があって紛らわしいんだけど、現行の既定は認証 1812/課金 1813。しかもこの 1645 は RADIUS パケットの Identifier フィールドそのものでもない(Identifier は 1 オクテット=0〜255 の範囲だから 1645 は入らない)。実際の宛先ポートは、同じ debug 行の Send Access-Request to 172.16.1.130:1812 の方だよ。local ── これがいつ効くかを見よう。ここが AAA で一番誤解されるところだ。フォールバックの「使えない」は、サーバが無応答(dead)であることを指す。RADIUS の宛先を到達不能なアドレスに向けてサーバを dead にして、ローカル admin で SSH ログインを試すと ──
AAA/AUTHEN/LOGIN: Pick method list 'VTY_RADIUS'
%RADIUS-4-RADIUS_DEAD: RADIUS server 172.16.1.199 is not responding.
%SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: admin]VTY_RADIUS が選ばれ → RADIUS が「応答しない」と検出され → ローカル DB の admin でログイン成功。これが local fallback だ。RADIUS が無応答だから、2 番目の local が認証を引き受けた。
そこに気づけたら完璧だ。local fallback が効くのはサーバが無応答(dead)のときだけ。サーバが到達可能で、かつ認証を明示的に拒否(Access-Reject)した場合は、ローカル DB へフォールバックしない。つまり ──
- 「RADIUS が落ちたらローカルで入れる」→ 正しい(dead → fallback する)
- 「RADIUS でパスワードを間違えてもローカルで入れる」→ 間違い(reject は最終判定、失敗で確定)
この 2 つを混同すると、「サーバが生きてる状態でローカルパスワードで入れるはず」と思い込んで詰まる。ローカルアカウントに頼った復旧を想定するなら、サーバを意図的に到達不能にできる経路を運用設計に入れておく必要があるんだ。
「何をしたか」を記録する機能だ。exec セッション(端末ログイン)の開始・終了を記録する設定はこう。
aaa accounting exec default start-stop group RAD-GRPstart-stop は「開始時に START レコード、終了時に STOP レコードを送る」方式。ログインすると ──
AAA/ACCT/EXEC: Queueing record is START
AAA/ACCT: Accounting method=RAD-GRP (RADIUS)
AAA/ACCT/EXEC: START protocol reply PASS
AAA/ACCT: Accounting response status = SUCCESSログイン成功の直後に START レコードが作られ、RADIUS へ送られ、SUCCESS でサーバが受領(ACK)した、と読める。ログアウトすると STOP も同じく送られる。
stop-only(終了時だけ)もある。監査要件に応じて選ぶ。ちなみに start-stop は開始と終了の両方を記録するから、セッションが今も続いてるか、いつ始まったかまで追える。tacacs server / aaa group server tacacs+ / ip tacacs source-interface)。違うのはポートと認証の往復だ。まずポートは TCP 49。show tacacs で Server port: 49 Server Status: Alive が見える。RADIUS の UDP 1812/1813 とは違うだろ。debug tacacs を見ると ──
TPLUS: Authentication start packet created for 0(tacadmin)
TPLUS: Received authen response status GET_PASSWORD (8)
TPLUS: Authentication continue packet generated for 0
TPLUS: Received authen response status PASS (2)NAS が Authentication start を送る → サーバが GET_PASSWORD でパスワードを要求 → NAS が continue でパスワードを送る → サーバが PASS で成功。start → GET_PASSWORD → continue → PASS の多段往復だ。RADIUS の単一往復とは明確に違う。
認可の粒度だ。同じ TACACS+ サーバが利用者ごとに違う特権レベルを出し分ける。運用の vty に認証と exec 認可の method-list を当てて、tacadmin と tacoper でログインして show privilege すると ──
(tacadmin)Current privilege level is 15 → R1#
(tacoper) Current privilege level is 1 → R1>同じサーバが tacadmin には 15、tacoper には 1 を出し分けてる。これが exec 認可による特権レベルの出し分けだ。
aaa authorization commands)── 利用者ごとに「実行できるコマンドそのもの」を許可・拒否する制御 ── まで組める。「認証中心で認可は属性で粗く渡す RADIUS」と「認証と認可を分離してコマンド単位まで細かく認可できる TACACS+」── この差が、機器管理者のアクセス制御で TACACS+ が選ばれる理由だ。ただ、このラボで実機検証したのは exec 認可(特権レベルの出し分け)までで、コマンド単位の認可は TACACS+ の設計能力としての説明に留めてる。今日の勘所を並べておく。
- ポート:RADIUS は認証 UDP 1812/課金 1813、TACACS+ は TCP 49。debug の
id 1645はポートでも Identifier でもなく内部識別表示。 - local fallback は無応答時のみ:「サーバが落ちたら入れる」は正しいが「パスワード間違えても入れる」は間違い。
- RADIUS=結合/TACACS+=分離:分離とは「認証の後に認可を別トランザクションで問い合わせる」こと。これとは別に、実機の認証フェーズの往復は RADIUS が単一・TACACS+ が多段(start→GET_PASSWORD→continue→PASS)で見える。「多段」は認証フェーズ内の話、「分離」は認証後の別問い合わせで、混ぜない。
aaa new-model後の既定特権は 1:認証を通っただけでは特権 1(ユーザモード)。15 が要るなら認可で priv-lvl 15 を渡すか enable で昇格する。tacadmin がR1#、tacoper がR1>になったのは認可で渡された特権差だ。