STUDY · NETWORK GUIDE

5-3 Trust Boundary — 信頼境界を実機で引く

アクセス端で外来の DSCP を信頼するか、0 に付け直すかを決める信頼境界を、Cat9000v (IOS-XE) の実機で扱う。Catalyst 9000 の QoS は mls qos を持たない MQC モデルであること、既定では外来 DSCP が保たれること、untrust (set dscp default) で境界を引くと 0 に付け直されること、trust device cisco-phone による条件付き信頼、table-map による CoS↔DSCP マッピングを、CML の show 出力と受信側の tcpdump で検証しながら解説する第 5 章 QoS 編の実機節。

1. 前節の振り返りと本節の内容

前節 5-2 マーキング体系 では、DiffServ が見る「印」の中身を整理しました。L2 の CoS、L3 の古い印である IP Precedence、そして現在の標準である DSCP と、その値が指す PHB (BE・CS・AF・EF) の体系です。とりわけ、DSCP は単純な優先度の番号ではなく PHB を選ぶコードポイント であり、クラス区別の主役はエンドツーエンドで運べる DSCP であることを確認しました。

前節の最後に、その印を 誰が・どこで・信用するか、あるいはつけ直すか という問いを残しました。本節はその問いを、実機 (Cat9000v) で扱います。ここまでの 5-1・5-2 は概念に徹する節でしたが、本節は第 5 章で初めての 実機ラボ を伴う節です。末端の端末がつけた印をどこまで信じ、ネットワークのどの地点で正しい DSCP に付け直すのか。この判断の設定と、その効き目を show 出力受信側のパケット観察 で見ていきます。

なお本節は、Catalyst 9000 (IOS-XE) の 信頼境界の判断そのもの = 「信頼する / しない / 条件付きで信頼する」に焦点を絞ります。class-map / policy-map による分類とマーキングの一般的な作り込み (NBAR2 など) は、次節 5-4 で改めて掘り下げます。

2. 信頼境界とは — アクセス端で「印を信じてよいか」を決める

信頼境界 (trust boundary) とは、「ここから内側の印は信頼してよい」という線のことです。DiffServ は各ホップがパケットの DSCP を信頼して扱いを決めるため (5-1 §6)、末端の端末が自分のパケットに勝手に高い DSCP をつければ、重要でない通信を不当に優先させられてしまいます。これを防ぐため、ネットワークの入口では、信頼できる相手の印だけを信頼し、信頼できない相手の印は正しい値に付け直します

判断の主体になるのが、端末が最初に接続する アクセススイッチのアクセスポート です。ここが信頼境界の代表的な位置になります。信頼境界より内側 (上位スイッチ・ルータ間) では、境界で整えられた印を各ホップが信頼します。境界の外 (信頼できない端末) がつけた印は、境界で一度リセットするか、正しい値に付け直すのが原則です。

本節では、この信頼境界を Catalyst 9000 の実機で引きます。使う検証ラボは、端末 (PC1) がアクセススイッチ (SW1) の 1 ポートに接続し、その先に受信端末 (PC2) がいる、最小構成です。

3. Cat9000v の QoS は MQC — mls qos は無い

まず、Catalyst 9000 (IOS-XE) の QoS の土台を押さえます。古い Catalyst 3560/3750 系 (Classic IOS) では、QoS はグローバルの mls qos で有効化し、ポートで mls qos trust dscp のように信頼を設定していました。Catalyst 9000 (IOS-XE) には、この mls qos がありません

snippet
SW1# show mls qos
           ^
% Invalid input detected at '^' marker.

Catalyst 9000 の QoS は、有効化のスイッチを持たず常時オンで、分類・信頼・マーキングをすべて MQC (Modular QoS CLI) = class-map / policy-map / table-map で表現します。したがって、信頼境界も「trust コマンド一発」ではなく、入口に当てる policy-map と、ポートの設定 で組み立てます。使用した機器と IOS-XE は次のとおりです。

snippet
SW1# show version | include Cisco IOS-XE Software|C9|cat9|Version
Cisco IOS XE Software, Version 17.15.03
Cisco IOS Software [IOSXE], Catalyst L3 Switch Software (CAT9K_IOSXE), Version 17.15.3, RELEASE SOFTWARE (fc1)
Switch Ports Model              SW Version        SW Image              Mode
*    1 24    C9KV-UADP-8P       17.15.03          CAT9K_IOSXE           INSTALL

4. アクセス端で選べる 3 つの信頼モード

信頼境界に届いた印を、アクセス端でどう扱うか。Catalyst 9000 で取れる方針は、大きく 3 つに分かれます。untrust (信頼しない)・trust (信頼する)・conditional trust (条件付き信頼) です。外来の DSCP=46 (EF) を例に、それぞれが何をするかを整理すると、次のようになります。

アクセス端の 3 つの信頼モードと、外来 DSCP=46 の帰結。① untrust は入口の policy-map (set dscp default) で外来印を破棄して 0 に付け直す (46 → 0)。② trust は外来 DSCP をそのまま信頼する (46 のまま)。Cat9000v の既定はこちら。③ conditional trust (trust device cisco-phone) は CDP で電話を検出した時だけ信頼し、居なければ 0 扱い。信頼できない端末側は untrust、信じてよい相手だけ trust する、が信頼境界の引き方

この 3 モードのうち、既定の挙動は trust です。信頼できない端末が刺さるアクセス端では、既定に任せず untrust か条件付き信頼を明示的に当てて信頼境界を引きます。以下では、それぞれの挙動を実機の show 出力と受信側の観察で確かめます。

5. 既定は信頼 — 何もしなくても DSCP は保たれる

最初に、何も設定しないアクセスポートの既定の挙動 を確認します。検証ラボは次の構成です。端末 PC1 が EF (DSCP46) を付けた通信を送り、SW1 のアクセス端 Gi1/0/1 で受けて、同じ VLAN の Gi1/0/2 から受信端末 PC2 へ L2 スイッチングします。

検証ラボのトポロジ。PC1 (端末) が EF=DSCP46 を付けた UDP を送り、SW1 (Cat9000v) の Gi1/0/1 で受ける。このアクセス端が信頼境界。SW1 は同一 VLAN の Gi1/0/2 から PC2 (受信端末) へ L2 スイッチングし、PC2 は届いた ToS を tcpdump で観察して結果を検証する。SW1 Gi0/0 は Mgmt-vrf で管理網へ

PC1 は、端末側で ToS バイトに EF を書き込んだ UDP を送り続けています (iperf -S 0xb8、0xb8 = DSCP46)。この状態で、Gi1/0/1 に「入ってきた DSCP が EF かどうか」を数えるだけの入口 policy-map を当てて、スイッチが入口で何を見ているかを確認します。

snippet
SW1# show policy-map interface GigabitEthernet1/0/1

  Service-policy input: PM-CLASSIFY

    Class-map: CM-EF (match-any)
      200 packets
      Match:  dscp ef (46)

    Class-map: class-default (match-any)
      5 packets
      Match: any

match dscp ef のクラスが 200 packets ヒットしています。つまりスイッチは、アクセス端で 端末がつけた DSCP46 をそのまま見ています。では、その印は宛先まで残るのでしょうか。受信側 PC2 で、届いたパケットの ToS バイトを tcpdump で観察します。

snippet
PC2:~$ sudo timeout 6 tcpdump -n -v -c 6 -i eth0 'udp and dst 192.168.10.20' 2>/dev/null \
       | grep -o 'tos 0x[0-9a-f]*' | sort | uniq -c
      6 tos 0xb8       ← 6 パケットすべて ToS 0xb8 = DSCP 46 (EF)

ここでは届いたパケットの ToS だけを取り出して数えています (grep -otos 0x.. を抜き、uniq -c で集計)。tos 0xb8 は二進で 10111000、上位 6 ビット 101110 = 46 = EF です。何も設定しなくても、端末がつけた DSCP46 がそのまま PC2 まで運ばれています。これが Catalyst 9000 の既定挙動、すなわち 既定で外来 DSCP を信頼 (trust) する ということです。

ここに信頼境界の問題があります。既定のままでは、信頼できない端末が勝手に EF をつけても、それがそのまま通ってしまいます。だからこそ、信頼できない端末が刺さるアクセス端では、既定に任せず 明示的に信頼境界を引く 必要があります。

6. 信頼しない (untrust) — 境界で 0 に付け直す

信頼できない端末のアクセス端では、外来の印を破棄して DSCP を 0 (BE) に付け直します。これが untrust です。Catalyst 9000 では、入口に「すべての通信の DSCP を既定値 (0) に上書きする」policy-map を当てて実現します。

snippet
policy-map PM-UNTRUST
 class class-default
  set dscp default          ← すべての外来 DSCP を 0 (default=BE) に付け直す
!
interface GigabitEthernet1/0/1
 switchport mode access
 service-policy input PM-UNTRUST

この policy を当てると、show policy-map interface に「入口で DSCP を default に付け直している」ことが現れます。

snippet
SW1# show policy-map interface GigabitEthernet1/0/1

  Service-policy input: PM-UNTRUST

    Class-map: class-default (match-any)
      0 packets
      Match: any
      QoS Set
        dscp default

0 packets と出ているとおり、この検証機ではマーキングの適用カウンタが増えません (仮想機の制約。§8 で後述します)。だからこそ効き目は、カウンタでなく受信側で確かめるのが確実です。§5 と同じく PC1 は EF (DSCP46) を送り続けています。untrust を当てた状態で、PC2 に届く ToS を観察します。

snippet
PC2:~$ sudo timeout 6 tcpdump -n -v -c 6 -i eth0 'udp and dst 192.168.10.20' 2>/dev/null \
       | grep -o 'tos 0x[0-9a-f]*' | sort | uniq -c
      6 tos 0x0        ← 6 パケットすべて ToS 0x0 = DSCP 0 (BE)

既定では tos 0xb8 (DSCP46) だったものが、untrust を当てた後は tos 0x0 (DSCP0) になりました。同じ端末が同じ EF を送っているのに、アクセス端で印が 0 に付け直された のです。これが信頼境界を引くということです。端末の勝手な EF は、境界で無効化されました。既定 (trust) と untrust の違いを、同じパケットで並べると次のとおりです。

同じ EF (DSCP46) パケットの 2 つの結末。上レーン (trust・既定) は外来 DSCP をそのまま信頼し、46 のまま PC2 へ届く (tcpdump = tos 0xb8)。下レーン (untrust) は入口の set dscp default が印を破棄し、0 に付け直して PC2 へ届く (tcpdump = tos 0x0)。違うのはアクセス端の信頼設定だけで、どちらになったかは受信側の tcpdump で検証できる

7. 条件付き信頼と CoS↔DSCP マッピング

条件付き信頼 (conditional trust) は、trust と untrust の中間です。「特定の機器が接続されている時だけ信頼する」という設定で、代表例が IP 電話です。IP 電話は、その背後につないだ PC の通信と、電話自身の音声通信を、1 本のアクセスポートに混ぜて送ってきます。このとき「電話がつけた音声の印は信頼したいが、背後の PC の勝手な印は信頼したくない」という要求が生まれます。Catalyst 9000 では、trust device で表現します。

snippet
interface GigabitEthernet1/0/1
 switchport mode access
 trust device cisco-phone     ← CDP で Cisco IP 電話を検出した時だけ信頼

trust device cisco-phone は、CDP で Cisco IP 電話を検出できた時だけ その印を信頼し、電話が居なければ信頼しない (0 扱い) という条件付きの信頼です。信頼できる機器 (電話) が実際にそこに居ることを CDP で確かめてから信頼するため、電話を外して PC を直結しても、勝手な印は通りません。trust device には cisco-phone のほか ctsip-cameramedia-player が選べます。

境界では、L2 の CoS と L3 の DSCP を対応づける (マッピングする) 必要も生じます (5-2 §7)。トランクや電話の先から CoS 付きで届いた印を、内側でエンドツーエンドに運べる DSCP へ引き継ぐためです。Catalyst 9000 では table-map で対応表を作ります。

snippet
SW1# show table-map COS-TO-DSCP
 Table Map COS-TO-DSCP
 from 0 to 0
 from 1 to 8
 from 2 to 16
 from 3 to 24
 from 4 to 34
 from 5 to 46
 from 6 to 48
 from 7 to 56
 default 0

この対応表を policy-map から呼び出すと、入口で CoS を見て DSCP に写せます。

snippet
SW1# show policy-map PM-TRUST-COS
  Policy Map PM-TRUST-COS
    Class class-default
      set dscp cos table COS-TO-DSCP    ← 入力の CoS を表に従って DSCP へ

なお set dscp cos table は、Cisco の Catalyst 9300 QoS 設定ガイド (IOS-XE 17.15) の set dscp 構文一覧には明記されていません。本節の検証機 (C9KV-UADP・17.15.03) では実機の set dscp cos ? ヘルプに table Set packet ip dscp from L2 cos based on table map. と表示され、投入も通りました。公開ガイドに載っていない構文は、このように実機の ? ヘルプで裏を取ってから使うと安全です。

上の対応表は一例です (CoS5 → DSCP46=EF、CoS4 → DSCP34=AF41 など)。どの CoS をどの DSCP に写すかは運用側で決めますが、その指針として広く参照される設定ガイドライン RFC 4594 があります (5-2 §7。RFC 4594 は Informational で、規格そのものではなく推奨のまとめです)。重要なのは値を丸暗記することではなく、境界では CoS と DSCP を対応表で明示的につなぐ という点です。

8. 落とし穴・補足

信頼境界は「どの印を信じるか」の設計であり、思い込みで組むと逆の結果になります。本節の実機に関わる注意点をまとめます。

既定は「信頼」なので、放置は危険。 Catalyst 9000 は、何も設定しなければ外来 DSCP をそのまま信頼します (§5 で DSCP46 がそのまま通った)。これは便利な一方、信頼できない端末が刺さるアクセス端を放置すると、勝手な高優先度の印がそのまま網内に入ります。信頼境界は「引き忘れると穴になる」 ことを意識し、端末側のアクセス端には明示的に untrust か条件付き信頼を当てます。

再マーキングの効き目は、カウンタでなく受信側で確かめる。 今回の検証機は仮想の C9KV-UADP で、QoS のハードウェア処理が完全にはエミュレートされません。実際、入口の 分類 カウンタ (match dscp ef = 200) は動きましたが、マーキング の適用数 (QoS Set dscp default の packets) は 0 のままでした。そのため本節では、再マーキングの証拠を 受信側 PC2 の tcpdump (tos 0xb8 → 0x0) に置いています。物理の Catalyst 9000 ではマーキングのカウンタも増えますが、「印がどう変わったかは受信側で観測する」 姿勢は実機でも有効です (5-1・原則として、印は各ホップの設定しだいで変わる)。

untrust は「0 にする」であって「捨てる」ではない。 set dscp default は DSCP を 0 (BE) に 付け直す だけで、パケットを破棄するわけではありません。信頼できない端末の通信も、優先はされないものの通常転送 (BE) では流れます。破棄したいなら、それは QoS の信頼設定ではなく ACL やポリシングの仕事です。

mls qos を探さない。 Catalyst 3560/3750 の記憶で mls qosmls qos trust dscp を打つと、Catalyst 9000 では通りません (§3)。信頼も再マーキングも MQC (class-map / policy-map / table-map) で組む、と頭を切り替えます。

9. 次節

本節では、信頼境界を Cat9000v の実機で引きました。Catalyst 9000 の QoS は mls qos を持たない MQC モデルであること、既定では外来 DSCP がそのまま信頼されて宛先まで運ばれること (分類カウンタ 200・tcpdump tos 0xb8)、untrust (set dscp default) で境界を引くと DSCP が 0 に付け直されること (tcpdump tos 0x0)、trust device cisco-phone による条件付き信頼、そして table-map による CoS↔DSCP マッピングを、show 出力と受信側の観察で確かめました。信頼境界の判断が、実機で観測できる形で効いていることが分かりました。

次節 5-4 Classification と Marking の実装 では、信頼境界の内側で行う 分類とマーキングの作り込み に踏み込みます。本節では信頼するか付け直すかの判断に絞りましたが、次節では class-map で通信をどう見分け (match dscp・NBAR2 など)、policy-map で DSCP や CoS をどう設定するか (set dscp / set cos) を、実機で組み立てていきましょう。