tag:crieit.net,2005:https://crieit.net/tags/Network/feed 「Network」の記事 - Crieit Crieitでタグ「Network」に投稿された最近の記事 2023-09-25T00:26:04+09:00 https://crieit.net/tags/Network/feed tag:crieit.net,2005:PublicArticle/18573 2023-09-23T02:32:08+09:00 2023-09-25T00:26:04+09:00 https://crieit.net/posts/NEC-IX-VLAN-VLAN NEC IXシリーズルーターでポートVLANとタグVLANをVLANスイッチ的に併用する <p>この記事では、 GE0, GE1 の 2つの "デバイス" を持つ NEC の IX2105 ルーターを例に、1カ所のスイッチングハブ用のデバイスの中で ポートVLAN と タグVLAN を併用し、スイッチングハブのトランクポートやアクセスポートのように使う方法について説明する。</p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>国内の中規模オフィス向けのルーターとして、 Yamaha や Cisco がよく知られているが、 NEC も <a target="_blank" rel="nofollow noopener" href="https://jpn.nec.com/univerge/ix/Info/ix2106.html">UNIVERGE IXシリーズ</a> を提供している。</p> <p>Yamaha の RTXシリーズ と価格帯が近いものの、 NEC の IXシリーズ には、 Yamaha と比べてもわりと柔軟な構成を行える利点がある。</p> <p>一方で Yamaha と比べた場合、 NEC の IXシリーズ の設定方法を調べるのは少し…いや、だいぶ難しい。<br /> 書籍や Web 記事、公式マニュアルなど、ドキュメントや設定例の全てに於いて、 Yamaha と比べて著しく情報が少ないためだ。</p> <p>そんな IXシリーズ を使って、ポートVLAN と タグVLAN を併用する方法について紹介しよう。<br /> (この併用も、Yamaha の RTX で同一ポート内で実現するのは難しい機能のひとつだ)</p> <p>なお、同じ UNIVERGE でも LTE や Wi-Fi などのワイヤレス機能を持った WAシリーズ では、 VLAN 周りのコマンド体系が異なるため、このページの方法は使えない。</p> <p>設定例として挙げている IX2105 は <a target="_blank" rel="nofollow noopener" href="https://www.necplatforms.co.jp/product/ix/product/ix2105.html">2019年9月30日をもって販売を終了</a> しているが、マイナーバージョンこそ <a target="_blank" rel="nofollow noopener" href="https://www.nw-meister.jp/service/resources/common/products/ix/relnotes/ix2105-release-10.2.42.txt">Ver.10.2 までに留まるものの不具合修正は続いて</a>いる。<br /> (例えば後継の IX2106 だと 10.2系 は <a target="_blank" rel="nofollow noopener" href="https://www.nw-meister.jp/service/resources/common/products/ix/relnotes/ix2106-release-10.2.26.txt">Ver.10.2.26</a> までで終了し、最新版は <a target="_blank" rel="nofollow noopener" href="https://www.nw-meister.jp/service/resources/common/products/ix/relnotes/ix2106-release-10.8.21.txt">Ver.10.8.21</a> となっている)<br /> 中古なら<a target="_blank" rel="nofollow noopener" href="https://auctions.yahoo.co.jp/search/search?ei=utf-8&p=IX2105">ヤフオク等で二束三文で手に入る</a>し、最新 FW (ソフトウェア) も NEC に "UNIVERGE IXシリーズ ソフトウェアダウンロードサイトへの接続申請書" を出せば手に入るので、練習機としてはもってこいだ。</p> <h2 id="ゴール"><a href="#%E3%82%B4%E3%83%BC%E3%83%AB">ゴール</a></h2> <p>以下のような構成を行う。</p> <ul> <li>既定ではスイッチングハブとなっている、 <code>GE1</code> デバイスの4つの物理ポートを、以下の3つに分割する <ul> <li>タグ付き通信を行う(即ちトランクポートとなる)1番ポート <ul> <li>但し、管理VLAN 的に使うため、 untag のフレームも受け付ける</li> </ul></li> <li>VLAN100 の通信を untag で行う(即ちアクセスポートとなる)2番ポート</li> <li>VLAN200 の通信を untag で行う(即ちアクセスポートとなる)3, 4番ポート</li> </ul></li> <li>各 VLAN それぞれで DHCP サーバによる異なるセグメントの IP アドレスの割り当てを行う</li> <li><code>GE0</code> デバイスでは NAT (NAPT) を行い、 <code>GE1</code> デバイスの各セグメントからのルーティングも受け付ける</li> </ul> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2023/09/use-port-and-tag-vlans-together-on-nec-ix-00.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2023/09/use-port-and-tag-vlans-together-on-nec-ix-00-1024x576.png" alt="" /></a></p> <p>先に最終的な構成を載せておくと、以下のようになる。</p> <pre><code class="text">ip ufs-cache enable ip dhcp enable ip access-list web-http-acl permit ip src any dest 192.168.99.1/32 ! ! ! ! ! ブリッジの有効化 bridge irb enable ! ! ! ! GE0 から DNS サーバーを自動取得し DNSプロキシー を実行 proxy-dns ip enable proxy-dns interface GigaEthernet0.0 priority 254 ! Webコンソールを管理ポートの 192.168.99.1 として開始 http-server ip access-list web-http-acl http-server ip enable ! ! ! ! 各サブネットごとに、自身をDNSサーバーと通知するDHCPプロファイルを作成 ip dhcp profile dhcp-profile-99 dns-server 192.168.99.1 ! ip dhcp profile dhcp-profile-120 dns-server 192.168.120.1 ! ip dhcp profile dhcp-profile-130 dns-server 192.168.130.1 ! device GigaEthernet0 ! GE1 ポートに ポートベース VLAN グループを設定 device GigaEthernet1 vlan-group 2 port 2 vlan-group 3 port 3 4 ! GE0 は WAN 側として、 IPアドレスを DHCP から自動取得し、 NAPT を有効化 interface GigaEthernet0.0 description WAN1 ip address dhcp receive-default ip napt enable ip napt hairpinning no shutdown ! GE0 の グループ N/A (ポート1番) のアドレスと DHCP の設定 interface GigaEthernet1.0 description LAN1 ip address 192.168.99.1/24 ip dhcp binding dhcp-profile-99 no shutdown ! GE0 の グループ N/A (ポート1番) の VLANID 222 の VLAN タグ付きの設定 (BVI20とブリッジ) interface GigaEthernet1.2 description VLAN222 encapsulation dot1q 222 tpid 8100 auto-connect no ip address bridge-group 200 no shutdown ! GE0 の グループ N/A (ポート1番) の VLANID 333 の VLAN タグ付きの設定 (BVI30とブリッジ) interface GigaEthernet1.3 description VLAN333 encapsulation dot1q 333 tpid 8100 auto-connect no ip address bridge-group 300 no shutdown ! GE0 の グループ 2 (ポート2番) の untag の設定 (BVI20とブリッジ) interface GigaEthernet1:2.0 no ip address bridge-group 200 no shutdown ! GE0 の グループ 3 (ポート3番&4番) の untag の設定 (BVI30とブリッジ) interface GigaEthernet1:3.0 no ip address bridge-group 300 no shutdown ! VLANID 222 向けのブリッジインタフェースのアドレスと DHCP の設定 interface BVI20 ip address 192.168.120.1/24 ip dhcp binding dhcp-profile-120 bridge-group 200 no shutdown ! VLANID 333 向けのブリッジインタフェースのアドレスと DHCP の設定 interface BVI30 ip address 192.168.130.1/24 ip dhcp binding dhcp-profile-130 bridge-group 300 no shutdown ! interface Loopback0.0 no ip address ! interface Null0.0 no ip address ! </code></pre> <p>メモ:</p> <p>なお、このページのコンフィグ例では、 IX2105 や IX2106, IX2107 のように GigaEthernet1 デバイスがスイッチングハブであることを前提としている。<br /> IX2215 や IX2235 のように GigaEthernet2 デバイスなどがスイッチングハブとなっている場合、適宜読み替えて設定して欲しい。</p> <h2 id="前提知識"><a href="#%E5%89%8D%E6%8F%90%E7%9F%A5%E8%AD%98">前提知識</a></h2> <p>ひとつひとつ、細かく解説していこう。</p> <p>まず前提として理解しておかなくてはならないのは、 IXシリーズの設定の考え方に於いて <strong>タグVLAN と ポートVLAN は全く異なる機能</strong> であり、独立した設定となっている、という点だ。</p> <h3 id="タグVLAN"><a href="#%E3%82%BF%E3%82%B0VLAN">タグVLAN</a></h3> <p><strong>タグVLAN</strong> は、</p> <ol> <li>ある GigaEthernet1.0 といった <strong>"基本インタフェース"</strong> に対して、 GigaEthernet1<strong>.2</strong> のような <strong>"サブインタフェース"</strong> を作成し… <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></li> <li><strong>各サブインタフェースに VLAN ID を割り当て</strong>ると…</li> <li><strong>基本インタフェース側</strong>では IEEE 802.1Q <strong>VLANタギング でカプセル化</strong>されたフレームが流れる</li> </ol> <p>という仕組みだ。</p> <p>すなわち、基本インタフェース GigaEthernet1<strong>.0</strong> 内にて、各サブインタフェース GigaEthernet1<strong>.1</strong>, GigaEthernet1<strong>.2</strong> が、 VLANタギング によってトンネリングされていると見做せる。</p> <p>基本インタフェースも各サブインタフェースも、それぞれに IP アドレスを割り当てれば、各々がルーティングの対象となる。</p> <p>メモ:</p> <p>IXルーター上でトンネリングを行う仕組みとしては、似たようなもので他にも Tunnelインタフェース が存在する。</p> <p>Tunnelインタフェース では、カプセル化後が (L3 の) IP パケットとなるようなモノを対象とするため、カプセル化後のパケットはルーティングされる。</p> <p>一方、サブインタフェースでは、 VLANタギング や PPPoE といった、カプセル化後が (L2 の) Ethernet フレームとなるようなモノを対象としているため、カプセル化後のフレームは親となる基本インタフェース(と後述するブリッジ先)にしか流れない、といった仕組みの違いがある。</p> <h3 id="ポートVLAN"><a href="#%E3%83%9D%E3%83%BC%E3%83%88VLAN">ポートVLAN</a></h3> <p>一方で <strong>ポートVLAN</strong> は、</p> <ol> <li>スイッチハブ機能を持つデバイス (IX2105 なら GigaEthernet1) を</li> <li>複数のサブネット (グローバルキャストドメイン) に分割&グループ化し</li> <li>GigaEthernet1<strong>:2</strong>.0, GigaEthernet1<strong>:3</strong>.0 のような「ポートベース VLAN グループ番号」が異なる独立したインタフェースを作成する <sup id="fnref2:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></li> </ol> <p>という仕組みだ。</p> <p>すなわち、 グループなし GigaEthernet1.0 や、ポートベース VLAN でグループ化された GigaEthernet1<strong>:2</strong>.0, GigaEthernet1<strong>:3</strong>.0 などは、それぞれ L2 (レイヤー2) 的に互いに独立していると見做せる。</p> <p>もちろん、各ポートVLANグループにそれぞれ IP アドレスを割り当てれば、各々がルーティングの対象となる。</p> <h3 id="ブリッジ"><a href="#%E3%83%96%E3%83%AA%E3%83%83%E3%82%B8">ブリッジ</a></h3> <p>独立した タグVLAN と ポートVLAN を紐づけるためには、複数のインタフェースをひとつのサブネット(グローバルキャストドメイン)にまとめる <strong>ブリッジ機能</strong> を活用する。</p> <p>インタフェースにブリッジ機能を割り当てると、そのインタフェースでは L3 のネットワーク層の情報が機能しなくなるため、IPアドレスや DHCP の設定など L3 に関する機能が使用できなくなる。 <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p> <p>このため、ブリッジしたインタフェース上でルーティングや IPアドレスの設定などを行う場合、 <strong>BVIインタフェース</strong> という仮想インタフェースを作成してブリッジに加え、これに IPアドレス などの L3 に関する機能を割り当てる必要がある。</p> <blockquote> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2023/09/use-port-and-tag-vlans-together-on-nec-ix-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2023/09/use-port-and-tag-vlans-together-on-nec-ix-01.png" alt="" /></a></p> </blockquote> <h2 id="具体的なコンフィグの解説"><a href="#%E5%85%B7%E4%BD%93%E7%9A%84%E3%81%AA%E3%82%B3%E3%83%B3%E3%83%95%E3%82%A3%E3%82%B0%E3%81%AE%E8%A7%A3%E8%AA%AC">具体的なコンフィグの解説</a></h2> <p>まず、 GE0 を NAPT する WAN側、 GE1 を DHCP と Webコンソールを有効にした LAN側 と見立てた、以下のようなコンフィグを入れてある状態とする。</p> <pre><code class="text">ip ufs-cache enable ip dhcp enable ip access-list web-http-acl permit ip src any dest 192.168.99.1/32 ! proxy-dns ip enable proxy-dns interface GigaEthernet0.0 priority 254 ! http-server ip access-list web-http-acl http-server ip enable ! ip dhcp profile dhcp-profile-99 dns-server 192.168.99.1 ! interface GigaEthernet0.0 description WAN1 ip address dhcp receive-default ip napt enable ip napt hairpinning no shutdown ! interface GigaEthernet1.0 description LAN1 ip address 192.168.99.1/24 ip dhcp binding dhcp-profile-99 no shutdown ! </code></pre> <h3 id="タグVLANの構成"><a href="#%E3%82%BF%E3%82%B0VLAN%E3%81%AE%E6%A7%8B%E6%88%90">タグVLANの構成</a></h3> <p>タグVLAN のトランクポートを扱うには、前述の「サブインタフェース」を作成する必要がある。</p> <p>以下のように、 GigaEthernet1.0 に対応する各サブインタフェースにも IP アドレスや DHCP の設定を行うと、 GE1 の各ポートでは</p> <ul> <li>タグなし: 192.168.99.1/24 の基本インタフェース</li> <li>VLAN ID 222: 192.168.120.1/24 のサブインタフェース番号2</li> <li>VLAN ID 333: 192.168.130.1/24 のサブインタフェース番号3</li> </ul> <p>に割当たるようになる。</p> <p><code>encapsulation dot1q</code> コマンドを実行した場合は、その反映には端末の再起動が必要な点には注意。</p> <pre><code class="text">ip dhcp profile dhcp-profile-120 dns-server 192.168.120.1 ! ip dhcp profile dhcp-profile-130 dns-server 192.168.130.1 ! interface GigaEthernet1.2 description VLAN222 encapsulation dot1q 222 tpid 8100 auto-connect ip address 192.168.120.1/24 ip dhcp binding dhcp-profile-120 no shutdown ! interface GigaEthernet1.3 description VLAN333 encapsulation dot1q 333 tpid 8100 auto-connect ip address 192.168.130.1/24 ip dhcp binding dhcp-profile-130 no shutdown </code></pre> <p><code>encapsulation dot1q</code> コマンドで tpid の値を省略してもデフォルト値 0x8100 が設定されるのだが、省略したか否かにかかわらず <code>show running-config</code> や <code>show startup-config</code> のダンプ結果には表示されるため、最初からコマンドに含めている。</p> <p>上記の例では、説明のために敢えて サブインタフェース番号 2 に VLAN ID 222、等と異なる番号を割り当てているが、実際に設定するときはある程度揃えておいた方が分かりやすいだろう。<br /> サブインタフェース番号の上限は 32 等と少なめ(機種による)なので、 VLAN ID と完全に一致させるのはなかなか難しいだろうが。</p> <h2 id="ポートVLANとブリッジの追加構成"><a href="#%E3%83%9D%E3%83%BC%E3%83%88VLAN%E3%81%A8%E3%83%96%E3%83%AA%E3%83%83%E3%82%B8%E3%81%AE%E8%BF%BD%E5%8A%A0%E6%A7%8B%E6%88%90">ポートVLANとブリッジの追加構成</a></h2> <p>前項の タグVLAN の構成だけでは、 GE1 のどの番号のポートもトランクポートへのアクセスとなるため、 untagged なフレームを VLAN 用のサブネットにスイッチングできない。</p> <p>GE1 の 2番~4番ポートをアクセスポートのように扱うために、これらのポートにポートVLANのグループ設定を構成し、トランクポートとネットワークを分割する以下のコードを実行する。</p> <pre><code class="text">device GigaEthernet1 vlan-group 2 port 2 vlan-group 3 port 3 4 </code></pre> <p>"ポートベース VLAN グループ番号" 2 に、 GE1 の 2番ポートを、 グループ番号 3 に、 GE1 の 2番 & 4番 ポートを、それぞれ割り当てている。</p> <p>なお、グループ番号は 1 からスイッチングハブスロット上のポート数以下の整数値 (IX2105 なら 4) を設定できる。</p> <p>GE1 の 1番ポートをグループ化の対象としないことにより、1番ポートには GigaEthernet0.0 の タグVLAN トランクポートのフレームが引き続き流れ続ける。</p> <p>一方で、単にポートVLANグループに分割しただけでは、2番~4番ポートに untagged のフレームはスイッチングされてこない。</p> <p>そこで、 untagged なフレームが流れている タグVLAN の各サブインタフェースと、 <strong>ブリッジ</strong> させてしまおう。</p> <pre><code class="text">configure bridge irb enable ! ! interface GigaEthernet1.2 description VLAN222 encapsulation dot1q 222 tpid 8100 no ip address no ip dhcp binding dhcp-profile-120 bridge-group 200 no shutdown ! interface GigaEthernet1:2.0 no ip address bridge-group 200 no shutdown ! interface BVI20 ip address 192.168.120.1/24 ip dhcp binding dhcp-profile-120 bridge-group 200 no shutdown ! ! interface GigaEthernet1.3 description VLAN333 encapsulation dot1q 333 tpid 8100 no ip address no ip dhcp binding dhcp-profile-130 bridge-group 300 no shutdown ! interface GigaEthernet1:3.0 no ip address bridge-group 300 no shutdown ! interface BVI30 ip address 192.168.130.1/24 ip dhcp binding dhcp-profile-130 bridge-group 300 no shutdown ! </code></pre> <p>まず、ブリッジ機能を有効にするために <code>bridge irb enable</code> コマンドの実行が必要だ。<br /> (このコマンドはグローバルコンフィグモードで実行する必要があるため、手前で <code>configure</code> コマンドを実行している)</p> <p>ここで タグVLAN の サブインタフェース と、 グループ化したポートを ブリッジするのだが、 前述の通りブリッジ機能を使うと サブインタフェースに設定していた L3 の IP 関連の構成が機能しなくなる。<br /> このため、 VLAN 毎に BVI インタフェースを作成してブリッジに加えたうえで、そちらに <code>ip address</code> や <code>ip dhcp binding</code> の構成を移植する。</p> <p>なお、タグVLAN で使用している "サブインタフェース番号" GigaEthernet1<strong>.2</strong> と、ポートベース VLAN で使用している "グループ番号" GigaEthernet1<strong>:2</strong>.0 (、そして BVI インタフェース番号 BVI<strong>20</strong> や bridge-group <strong>200</strong>、 VLANID VLAN<strong>222</strong>) をある程度数字揃えてブリッジしているが、必ずしもこれら番号は揃えておく必要は無い。<br /> 見やすさやわかりやすさを重視しつつ、指定できる範囲内で設定するのが良いだろう。</p> <h2 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h2> <p>ここまでの設定が完了すると、4つのサブネット間でルーティングされ、GE1 デバイスの各ポートでは以下のような組み合わせで VLAN のイーサネットフレームが流れるようになる。</p> <p><a href="https://crieit.now.sh/upload_images/65977e5c680bdc1e3b81a85057afc4fb650f11784d39a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/65977e5c680bdc1e3b81a85057afc4fb650f11784d39a.png?mw=700" alt="image.png" /></a></p> <p>試しに、GE1 の 2番ポート に繋いだ PC (192.168.120.2) から、 GE1 の 1番ポート に繋いだ PC (192.168.99.2) に、 ping を打ってみた所を、 GE1 の 1番ポート に繋いだ PC 側でパケットキャプチャしてみる。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2023/09/use-port-and-tag-vlans-together-on-nec-ix-11.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2023/09/use-port-and-tag-vlans-together-on-nec-ix-11.png" alt="" /></a></p> <p>192.168.120.1/24 のサブネットで ARP のブロードキャストされたフレームが、送信元 PC に繋いだ NIC の MACアドレス (Buffalo_f0:1X:XX) より <strong>VLANID 222 のタグ付き</strong>で 1番ポート へ届いていることがわかる。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2023/09/use-port-and-tag-vlans-together-on-nec-ix-12.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2023/09/use-port-and-tag-vlans-together-on-nec-ix-12.png" alt="" /></a></p> <p>一方、 ICMP の通信はルーティングされた上で 192.168.99.2/24 のサブネットへ届いているため、 IXルーター の MACアドレス (NECPlatf_4f:XX:XX) より<strong>タグなし</strong>で 1番ポート へ届いていることがわかる。</p> <h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2> <p>上記の設定では、VLANグループ間でスイッチングはされないが、サブネット同士で自由にルーティングされる。このため、L3スイッチで VLAN を分割しただけの場合とは異なり、 VLAN 間でも IPレイヤー の通信は行われる。実運用で VLAN 間の通信を制限したい場合は、適宜フィルタなどを追加して使う事になるだろう。<br /> また、パスワードが設定されていないので、実運用では設定しておこう。</p> <p>以上のように、VLAN スイッチなどでは単純にできるような設定でも、ルーターで実現するにはまぁまぁ大変であることがわかると思う。</p> <p>とはいえ、ブリッジなどを駆使すれば、このような複雑な構成であってもルーターだけで構成できるのが IXルーター の強みとも言える。</p> <p>上記の例では使用しなかったが、 GigaEthernet1<strong>:2****.3</strong> のように、"ポートベース VLAN グループ番号" に "サブインタフェース番号" をつけることもできるため、ポートベース VLAN グループに割り当てたポートに VLAN タグがついたフレームを流すことも可能だ。 <sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p> <p>参考: <a target="_blank" rel="nofollow noopener" href="https://www.labohyt.net/blog/lan/post-7008">NEC IX2207 の VLAN 設定備忘録 | hyt adversaria</a></p> <div class="footnotes" role="doc-endnotes"> <hr /> <ol> <li id="fn:1" role="doc-endnote"> <p><a target="_blank" rel="nofollow noopener" href="https://www.support.nec.co.jp/View.aspx?id=3170102588">IX2000シリーズ取扱説明書</a> の 【3 基本操作と各種説明 → モードについて → インタフェース表示の意味】 あたりを参照 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a> <a href="#fnref2:1" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> <li id="fn:2" role="doc-endnote"> <p><a target="_blank" rel="nofollow noopener" href="https://www.support.nec.co.jp/View.aspx?id=3170102598">IX2000/IX3000 シリーズ 機能説明書</a> の【■2.9 ブリッジの設定】より <a href="#fnref:2" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> <li id="fn:3" role="doc-endnote"> <p><a target="_blank" rel="nofollow noopener" href="https://www.support.nec.co.jp/View.aspx?id=3170102600">UNIVERGE IXシリーズ 設定事例集</a> の 【19.2 ポートベース VLAN とタグ VLAN の併用】 あたりを参照 <a href="#fnref:3" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> </ol> </div> advanceboy tag:crieit.net,2005:PublicArticle/18356 2022-12-28T23:48:38+09:00 2022-12-28T23:48:38+09:00 https://crieit.net/posts/GNS3-VyOS-63ac5746e74c7 GNS3 に VyOS 仮想ルーターを追加する長い道のり④ 応用編 <p>本記事は <a target="_blank" rel="nofollow noopener" href="https://qiita.com/advent-calendar/2022/nw-engineering-are-core-output">【アットホームな現場です】🎄★☆ネットワーク系エンジニア★☆アレコレアウトプット★☆🎄 Advent Calendar 2022</a> 25日目の記事だ。<br /> ごめんなさい、色々書いてたら結局分量が多くなって期限内に書き切れなかった。</p> <p><a target="_blank" rel="nofollow noopener" href="https://gns3.com/">GNS3</a> という OSS のネットワークエミュレータを、 Cisco の IOS などの取得なしに、無料のライセンス内で利用できるようにしようという話。</p> <p>今回は最終回の応用編。<br /> 以前の投稿はこちら。<br /> <a href="https://crieit.net/posts/GNS3-VyOS">https://crieit.net/posts/GNS3-VyOS</a> (① 環境導入編)<br /> <a href="https://crieit.net/posts/GNS3-VyOS-63ac561ed5a75">https://crieit.net/posts/GNS3-VyOS-63ac561ed5a75</a> (② イメージ準備編)<br /> <a href="https://crieit.net/posts/GNS3-VyOS-63ac5693838af">https://crieit.net/posts/GNS3-VyOS-63ac5693838af</a> (③ 実践編)</p> <h2 id="目指すゴール"><a href="#%E7%9B%AE%E6%8C%87%E3%81%99%E3%82%B4%E3%83%BC%E3%83%AB">目指すゴール</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-00.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-00.png" alt="" /></a><br /> 今回は、上記の図のように、 ルーターを 2台 置いて、 ルーターを跨いだ端末間 (<code>tmp-net-tools-1</code>, <code>-2</code>) で通信ができるように構成していく。</p> <h2 id="相互通信するコンテナの準備"><a href="#%E7%9B%B8%E4%BA%92%E9%80%9A%E4%BF%A1%E3%81%99%E3%82%8B%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E6%BA%96%E5%82%99">相互通信するコンテナの準備</a></h2> <p>ルーターを跨いだ通信を実際に行うことになるコンテナを準備する。</p> <p>通信の確認を行う最低限のモジュール(パッケージ)をインストールしたイメージを用意する。</p> <p>(リスクを自分で評価しつつ)第三者が用意したイメージを使っても良いのだが、今回は自分でビルドしてみよう。</p> <ol> <li>まず、 VM管理ツールや ssh で GNS3 VM の管理画面に入る</li> <li>メニューから Shell を選択する<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-03.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-03.png" alt="" /></a></li> <li><p>以下のコマンドで、 <code>tmp-net-tools</code> という名前をつけた Docker イメージをビルドする<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-01.png" alt="" /></a></p> <ul> <li> <br /> <code>shell gns3@gns3vm:~$ docker build -t tmp-net-tools - FROM alpine:latest RUN apk add --no-cache curl iperf3 net-tools EOF</code></li> </ul></li> <li><p>GNS3 (GUI) の Preferences を開き、 Docker コンテナテンプレートで上記のビルド済み <code>tmp-net-tools</code> でテンプレートを作成する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-02.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-02.png" alt="" /></a></p> <ul> <li>Console type は telnet で OK.</li> </ul></li> </ol> <p>ここでポイントとなるのは、 GNS3 で動かすコンテナは基本的に(明示的に接続市内限り)外部ネットワークに繋がっていないが、 GNS3 VM で Docker をビルドする際は、外部ネットワークに繋がると言う点だ。<br /> このため、コンテナ内にて追加で必要なパッケージがある場合、このように予めコンテナの build 段階でインストールしておく必要がある。</p> <h2 id="ネットワークの構成 1"><a href="#%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E6%A7%8B%E6%88%90+1">ネットワークの構成 1</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-00.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-00.png" alt="" /></a><br /> コンテナテンプレートの準備ができたら、ペタペタとデバイスを貼って結線していく。<br /> 2つの VyOS とも、 eth0 を端末のコンテナ側に、 eth1 をルーター同士を繋ぐ Switch に繋いでいこう。</p> <p>本来 VyControl は、 1サービスで複数の VyOS を管理できるはずなのだが、 試した感じどうも管理対象の切り替えでエラーになってしまうので、 素直に VyOS と VyControl を 1対1 で作成している。<br /> ただ、そうするとホストPCからそれぞれの VyControl にアクセスする際に同じ IP アドレスとなって Cookie が衝突するため、片方にログインするともう一方からログアウトされてしまう問題があるので注意。</p> <p>また、 vycontrol-host や tmp-net-tools の各コンテナにて、 Edit config からの <code>/etc/network/interfaces</code> の編集で、 eth0 を DHCP から IP アドレスを取得するよう設定することを忘れずに。</p> <p>VyOS は前回の設定に加えて eth1 の IP アドレスを静的に決めるため、それぞれ以下のように設定する。</p> <p><code>VyOS1.3.2-1</code>:</p> <pre><code class="shell">vyos@vyos:~$ configure vyos@vyos# set interfaces ethernet eth0 address '192.168.11.254/24' vyos@vyos# set interfaces ethernet eth1 address '192.168.1.1/24' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.11.0/24' default-router '192.168.11.254' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.11.0/24' name-server '192.168.11.254' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.11.0/24' range 0 start '192.168.11.17' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.11.0/24' range 0 stop '192.168.11.126' vyos@vyos# set service https api keys id my_id key 'my_secret_key' vyos@vyos# set service https certificates system-generated-certificate lifetime '65535' vyos@vyos# set service https virtual-host vyos1 listen-address '192.168.11.254' vyos@vyos# set service https virtual-host vyos1 listen-port '6443' vyos@vyos# set service https virtual-host vyos1 server-name 'vyos1.example.com' vyos@vyos# commit vyos@vyos# save vyos@vyos# exit </code></pre> <p><code>VyOS1.3.2-2</code>:</p> <pre><code class="shell">vyos@vyos:~$ configure vyos@vyos# set interfaces ethernet eth0 address '192.168.21.254/24' vyos@vyos# set interfaces ethernet eth1 address '192.168.1.2/24' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.21.0/24' default-router '192.168.21.254' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.21.0/24' name-server '192.168.21.254' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.21.0/24' range 0 start '192.168.21.17' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.21.0/24' range 0 stop '192.168.21.126' vyos@vyos# set service https api keys id my_id key 'my_secret_key' vyos@vyos# set service https certificates system-generated-certificate lifetime '65535' vyos@vyos# set service https virtual-host vyos1 listen-address '192.168.21.254' vyos@vyos# set service https virtual-host vyos1 listen-port '6443' vyos@vyos# set service https virtual-host vyos1 server-name 'vyos1.example.com' vyos@vyos# commit vyos@vyos# save vyos@vyos# exit </code></pre> <p>ちなみに、 VyOS の仮想デバイスは、 一通り設定を完了させてから、仮想デバイスを複製できる。<br /> VyOS のインストールなどの作業が 1回 で済む点は便利なのだが、 コピー後 MAC アドレスが変更になるため、仮想デバイス内のインターフェース名が、 eth0, eth1, eth2 から eth3, eth4, eth4 へと名前を変えてしまうことが多く、 GNS3 UI 上の NIC のインターフェース名と、 仮想デバイス内の名前が一致しなくなってややこしい事になるので、ご注意を。</p> <h2 id="ネットワークの構成 2"><a href="#%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E6%A7%8B%E6%88%90+2">ネットワークの構成 2</a></h2> <p>さて、ここで各端末 (<code>tmp-net-tools-1</code>, <code>-2</code>) が DHCP サーバーに割り当てられた IP アドレスを使って、お互いに ping を打っても、当然届かず失敗する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-03.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-03.png" alt="" /></a></p> <p>ここで VyControl を使って、 それぞれの VyOS に静的ルーティングを定義する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-05.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-05.png" alt="" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-06.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-06.png" alt="" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-07.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-07.png" alt="" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-08.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-08.png" alt="" /></a></p> <p>その後改めてお互いに ping を打つと、無事疎通ができるようになった。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-04.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-04.png" alt="" /></a></p> <h2 id="外部との接続"><a href="#%E5%A4%96%E9%83%A8%E3%81%A8%E3%81%AE%E6%8E%A5%E7%B6%9A">外部との接続</a></h2> <p>さらなる応用として、 "Cloud" デバイスを使って外部機器との接続もできる。</p> <p>まず、適当な物理NIC (USB LAN アダプタ) を、仮想マシン管理ツール側で GNS3 VM のネットワークアダプタに割り当てる。<br /> その後、 GNS3 内で "Cloud" デバイスをその物理NIC に割り当ててやれば、物理ルーターと仮想ルーターとの間で、論理的なネットワークの接続を構成できる。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-09.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-09.png" alt="" /></a></p> <h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2> <p>…とまあ、こんなところが GNS3 の基本的な使い方となる。<br /> 慣れてきたら、不完全な VyControl なんか使わず、 直接 VyOS に CUI コマンドで設定を定義してやると良いかもしれない。</p> <p>長々となる解説となったが、誰かの役に立てば幸いだ。</p> advanceboy tag:crieit.net,2005:PublicArticle/18355 2022-12-28T23:45:39+09:00 2022-12-29T00:00:03+09:00 https://crieit.net/posts/GNS3-VyOS-63ac5693838af GNS3 に VyOS 仮想ルーターを追加する長い道のり③ 実践編 <p>本記事は <a target="_blank" rel="nofollow noopener" href="https://qiita.com/advent-calendar/2022/nw-engineering-are-core-output">【アットホームな現場です】🎄★☆ネットワーク系エンジニア★☆アレコレアウトプット★☆🎄 Advent Calendar 2022</a> 17日目の記事だ。</p> <p><a target="_blank" rel="nofollow noopener" href="https://gns3.com/">GNS3</a> という OSS のネットワークエミュレータを、 Cisco の IOS などの取得なしに、無料のライセンス内で利用できるようにしようという話。</p> <p>環境導入編、イメージ準備編に続く実践編。<br /> 以前の投稿はこちら。<br /> <a href="https://crieit.net/posts/GNS3-VyOS">https://crieit.net/posts/GNS3-VyOS</a> (① 環境導入編)<br /> <a href="https://crieit.net/posts/GNS3-VyOS-63ac561ed5a75">https://crieit.net/posts/GNS3-VyOS-63ac561ed5a75</a> (② イメージ準備編)</p> <p>実際に、 GNS3 上で VyOS を使ってみよう。</p> <h2 id="GNS3 プロジェクトを作成"><a href="#GNS3+%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E4%BD%9C%E6%88%90">GNS3 プロジェクトを作成</a></h2> <p>GNS3 を開き、適当なプロジェクトを新規作成(ないし開く)する。</p> <p>平行して、 GNN3 VM が起動するまで待とう。</p> <h2 id="VyOS の起動"><a href="#VyOS+%E3%81%AE%E8%B5%B7%E5%8B%95">VyOS の起動</a></h2> <p>GNS3 GUI 上で、テンプレート一覧から VyOS のデバイスをドラッグ&ドロップして、プロジェクトに追加する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-run-vyos-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-run-vyos-01.png" alt="" /></a></p> <p>デバイスアイコンの右クリックで Configure をクリックしてプロパティを開き、 On close の動作を Save the VM state (休止状態) にしておくとよいだろう。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-run-vyos-02.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-run-vyos-02.png" alt="" /></a></p> <p>その後、 デバイスアイコンの再度右クリックで Start を選択し、仮想マシンをスタートさせる。<br /> デバイスアイコンをダブルクリックすると、 コンソールが起動する。 iso ファイルがブータブルディスクになっていてるため、VyOS の起動ログが表示されているはずだ。<br /> ログイン画面が出るまで待つ。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-run-vyos-03.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-run-vyos-03.png" alt="" /></a></p> <p>デフォルトの認証情報 <a target="_blank" rel="nofollow noopener" href="https://docs.vyos.io/en/equuleus/installation/install.html#live-installation">(login: <code>vyos</code>, password: <code>vyos</code>)</a> を使ってログインする。</p> <h3 id="VyOS 仮想 HDD へのインストール"><a href="#VyOS+%E4%BB%AE%E6%83%B3+HDD+%E3%81%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">VyOS 仮想 HDD へのインストール</a></h3> <p>このままでも VyOS として利用できるのだが、 "<a target="_blank" rel="nofollow noopener" href="https://phabricator.vyos.net/T2958">T2958 DHCP server doesn't work from a live CD</a>" といった問題もあるようなので、一旦仮想 HDD にインストールする。<br /> → <a target="_blank" rel="nofollow noopener" href="https://docs.vyos.io/en/equuleus/installation/install.html#permanent-installation">Permanent installation — VyOS 1.3.x (equuleus) documentation</a></p> <p>ログイン後、以下のコマンドを実行し、いくつかの質問に答えれば OK だ。</p> <pre><code class="shell">vyos@vyos:~$ install image </code></pre> <p>その後、再起動する。</p> <pre><code class="shell">vyos@vyos:~$ reboot </code></pre> <p>再起動前は、 <code>cat /proc/cmdline</code> のカーネルに渡された <code>BOOT_IMAGE</code> が <code>/live/vmlinuz</code> となっていたのが、</p> <pre><code class="shell">vyos@vyos:~$ cat /proc/cmdline # 再起動前 BOOT_IMAGE=/live/vmlinuz boot=live components hostname=vyos username=live nopersistence noautologin nonetworking union=overlay console=ttyS0,115200 console=tty0 net.ifnames=0 biosdevname=0 initrd=/live/initrd.img </code></pre> <p>再起動後は、 <code>install image</code> の途中で入力したイメージ名のものに変更されていることがわかる。</p> <pre><code class="shell">vyos@vyos:~$ cat /proc/cmdline # 再起動後 BOOT_IMAGE=/boot/1.3.2/vmlinuz boot=live rootdelay=5 noautologin net.ifnames=0 biosdevname=0 vyos-union=/boot/1.3.2 console=tty0 console=ttyS0,115200 </code></pre> <h3 id="VyOS の初期設定"><a href="#VyOS+%E3%81%AE%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A">VyOS の初期設定</a></h3> <p>VyOS の操作は VyContol に任せたい… が、どうしても VyControl から VyOS にアクセスできるようにするため、以下の 3点 はコマンドで設定する必要がある。</p> <ul> <li>インターフェースへの IP の設定 <ul> <li>以下の例では、 <code>192.168.11.254/24</code> に設定</li> </ul></li> <li>DHCP サーバーの起動 <ul> <li>以下の例では、 <code>192.168.11.0/24</code> のサブネットに、 DNS, デフォルトゲートウエイを自分自身、 DHCP の貸し出し範囲を <code>.17</code> から <code>.126</code> の範囲で指定</li> </ul></li> <li>(VyControl で操作させるための) <a target="_blank" rel="nofollow noopener" href="https://docs.vyos.io/en/equuleus/configuration/service/https.html">HTTP API</a> の有効化 <ul> <li>API のアクセスキーを <code>my_secret_key</code> (任意の文字列) に設定</li> </ul></li> </ul> <p>このため、 VyOS のコンソールでログインし、以下のコマンドを入れる。</p> <pre><code>vyos@vyos:~$ configure vyos@vyos# set interfaces ethernet eth0 address '192.168.11.254/24' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.11.0/24' default-router '192.168.11.254' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.11.0/24' name-server '192.168.11.254' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.11.0/24' range 0 start '192.168.11.17' vyos@vyos# set service dhcp-server shared-network-name 'subnet01' subnet '192.168.11.0/24' range 0 stop '192.168.11.126' vyos@vyos# set service https api keys id my_id key 'my_secret_key' vyos@vyos# set service https certificates system-generated-certificate lifetime '65535' vyos@vyos# set service https virtual-host vyos1 listen-address '192.168.11.254' vyos@vyos# set service https virtual-host vyos1 listen-port '6443' vyos@vyos# set service https virtual-host vyos1 server-name 'vyos1.example.com' vyos@vyos# commit vyos@vyos# save vyos@vyos# exit </code></pre> <p>これで、 VyOS 側の設定は完了だ。</p> <h2 id="VyControl の起動"><a href="#VyControl+%E3%81%AE%E8%B5%B7%E5%8B%95">VyControl の起動</a></h2> <p>GNS3 GUI 上で、テンプレート一覧から VyControl をドラッグ&ドロップして、プロジェクトに追加する。</p> <p>スイッチングハブか何かを間に咬ませて(2デバイスを繋ぐだけなら無くても良いけど)、 VyOS と VyControl を結線する。</p> <p>デバイスアイコンの右クリックで Edit config をクリックして、コンテナの <code>/etc/network/interfaces</code> を編集する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-01.png" alt="" /></a><br /> <code># DHCP config for eth0</code> の部分のコメントアウトを外せば、 VyOS の DHCP から IPアドレスを取得するようになる。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-02.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-02.png" alt="" /></a></p> <p>その後、 デバイスアイコンの再度右クリックで Start を選択し、コンテナをスタートさせる。<br /> デバイスアイコンをダブルクリックすると、 コンテナ内にフォワードされるアドレスがブラウザ側で開く。</p> <h3 id="VyControl の初期設定"><a href="#VyControl+%E3%81%AE%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A">VyControl の初期設定</a></h3> <p>VyControl の初回アクセス時は、 管理者アカウントを作るように表示されるので、適当なユーザー名とパスワードで作成しておく。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-03.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-03.png" alt="" /></a></p> <p>そして、 VyControl のコントロール対象の VyOS インスタンス情報を設定してやる。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-04.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-04.png" alt="" /></a></p> <p>Router の Interfaces 情報を開き、 VyOS ルーター側の interface 一覧が表示されていれば、設定は完了だ。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-05.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-start-vyctrl-docker-container-05.png" alt="" /></a></p> <p>以上で、 VyControl から VyOS が操作できるようになった。</p> <h2 id="トラブルシューティング"><a href="#%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0">トラブルシューティング</a></h2> <h3>VyOS 起動時に <code>KVM acceleration cannot be used</code> と出る</h3> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-01.png" alt="" /></a><br /> VyOS 起動時に、 以下のようなエラーが出て起動に失敗するケース。</p> <p><code>text/plain KVM acceleration cannot be used (/dev/kvm doesn't exist). It is possible to turn off KVM support in the gns3_server.conf by adding enable_kvm = false to the [Qemu] section.</code></p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1708">① 環境導入編</a> で触れていた、「入れ子になった(ネストされた)仮想化」が機能しておらず、 GNS3 VM の中で更に、 KVM という仮想化支援機能を使用して二重の仮想化にて VyOS を起動するのに失敗している。<br /> GNS3 VM を開くと以下のように "KVM support available: True" となるべきところが "False" となっていると思われる。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-02.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-02.png" alt="" /></a></p> <p>まずは、 OS のバージョンや CPU, 仮想化管理ツールのバージョンが、ネストされた仮想化をサポートしているかをもう一度確認しよう。</p> <p>しかし、 CPU や仮想化管理ツールの組み合わせによっては、どうしても有効化できない場合がある。</p> <p>そういった場合は、動作速度は遅くなるが KVM による仮想化支援機能を無効化してしまう方法もある。</p> <ol> <li>まず、 VM管理ツールや ssh で GNS3 VM の管理画面に入る</li> <li>メニューから Configure を選択する<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-03.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-03.png" alt="" /></a></li> <li><p>以下の内容を追記し、 Ctrl+X で保存、 その後 GNS3 VM を再起動する。</p> <pre><code>[Qemu] enable_kvm = false </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-04.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-trouble-01-04.png" alt="" /></a></p></li> </ol> <p>ただし、 VyOS の動作速度がかなり落ちるので注意。</p> <h2 id="次回"><a href="#%E6%AC%A1%E5%9B%9E">次回</a></h2> <p>最後となる<a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1748">次回</a>は応用編。</p> advanceboy tag:crieit.net,2005:PublicArticle/18354 2022-12-28T23:43:42+09:00 2022-12-28T23:57:22+09:00 https://crieit.net/posts/GNS3-VyOS-63ac561ed5a75 GNS3 に VyOS 仮想ルーターを追加する長い道のり② イメージ準備編 <p>本記事は <a target="_blank" rel="nofollow noopener" href="https://qiita.com/advent-calendar/2022/nw-engineering-are-core-output">【アットホームな現場です】🎄★☆ネットワーク系エンジニア★☆アレコレアウトプット★☆🎄 Advent Calendar 2022</a> 15日目の記事だ。 (空いていたので埋め)</p> <p><a target="_blank" rel="nofollow noopener" href="https://gns3.com/">GNS3</a> という OSS のネットワークエミュレータを、 Cisco の IOS などの取得なしに、無料のライセンス内で利用できるようにしようという話。</p> <p>前回の環境導入編に続く第2回。<br /> <a href="https://crieit.net/posts/GNS3-VyOS">https://crieit.net/posts/GNS3-VyOS</a></p> <p>GNS3 のインストールと GNS3 VM へのアタッチが完了している状態から始める。</p> <h2 id="VyOS イメージの取得"><a href="#VyOS+%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E5%8F%96%E5%BE%97">VyOS イメージの取得</a></h2> <p>GNS3 のマーケットプレイスには、 <a target="_blank" rel="nofollow noopener" href="https://gns3.com/marketplace/appliances/vyos">VyOS のテンプレート</a> が用意されており、これを使うと手軽に GNS3 内で VyOS のルーターを追加できる。</p> <p>このテンプレートを使うためには、 VyOS の特定のバージョンの ISO イメージファイルが必要だ。<br /> しかし、 VyOS の LTS 版では、ビルド済みイメージのダウンロードは、サブスクリプション契約者(または非営利団体など)のみとなっている。<br /> <a target="_blank" rel="nofollow noopener" href="https://docs.vyos.io/en/equuleus/installation/install.html#download">https://docs.vyos.io/en/equuleus/installation/install.html#download</a></p> <p>一方で、 VyOS 自体は OSS であり、 GPL のライセンスを守る限りソースコードを自由にビルドして利用できる。 そのビルド自体も docker を利用したツールセットが用意されていたりと、比較的しっかり整備されていて失敗しにくい。<br /> あまり性能が高くないノートPC でも 10分 程度でビルド可能だ。</p> <h3 id="VyOS イメージを自分でビルド"><a href="#VyOS+%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92%E8%87%AA%E5%88%86%E3%81%A7%E3%83%93%E3%83%AB%E3%83%89">VyOS イメージを自分でビルド</a></h3> <p>このため、 <a target="_blank" rel="nofollow noopener" href="https://docs.vyos.io/en/equuleus/contributing/build-vyos.html#build-iso">マニュアルの Build 手順</a>に従って VyOS 1.3 を自分でビルドしてイメージファイルを作成しよう。</p> <p>そのビルドには、前回インストールした Docker が必要となる。<br /> 加えて、 Docker は WSL2 内のディストリビューションから利用する必要がある。<br /> Docker 自体は、 Windows のシェル (コマンドプロンプトや PowerShell) から直接起動できるが、今回行う作業では Windows と Linux のファイルシステム違いによる問題で、ビルドが失敗してしまうためだ。</p> <p>というわけで、 前回 WSL Integration を有効にした、適当な WSL2 ディストリビューション (<a target="_blank" rel="nofollow noopener" href="https://apps.microsoft.com/store/detail/ubuntu-22041-lts/9PN20MSR04DW">Ubuntu 22.04.1 LTS</a> など) を起動する。<br /> 適当な空のフォルダをカレントフォルダに設定し、以下のように実行する。</p> <ol> <li><p>git でビルドスクリプトを clone して、 docker でビルド環境を起動する</p> <pre><code class="shell">$ git clone -b equuleus --single-branch https://github.com/vyos/vyos-build.git $ cd ./vyos-build/ $ docker run --rm -it --privileged -v $(pwd):/vyos -w /vyos vyos/vyos-build:equuleus bash </code></pre></li> <li><p>docker コンテナに入ったら、以下のコマンドでビルドする。</p> <pre><code class="shell">vyos_bld@xxxx:/vyos# ./configure --architecture amd64 --build-type release --version 1.3.2 vyos_bld@xxxx:/vyos# sudo make iso </code></pre></li> <li><p>ビルドが成功すれば、 <code>build</code> ディレクトリに .iso ファイルが出力されているはずだ。 ホスト PC 側から WSL2 内のビルドディレクトリを開き、 ホスト PC にコピーする。</p> <ul> <li><code>\\wsl$\<WSL ディストリビューション名>\...</code> のネットワークパスで、 ホスト PC側から WSL2 のファイルを参照できる。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-vyos-iso-image.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-vyos-iso-image.png" alt="" /></a></li> </ul></li> </ol> <p>ちなみに、 このビルド手順に関しては、 プロキシ環境下ではどうしてもうまくビルドができなかった。<br /> ビルドスクリプトが、プロキシ環境下のことをあまり考慮していないのだと思われる。</p> <h3 id="VyOS イメージの野良ビルドを取得する"><a href="#VyOS+%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E9%87%8E%E8%89%AF%E3%83%93%E3%83%AB%E3%83%89%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B">VyOS イメージの野良ビルドを取得する</a></h3> <p>もし自分でイメージのビルドができなかった場合…</p> <p>GPL のライセンス上、ビルドしたイメージを再配布することも再配布されたビルドを利用することも、ライセンスを守る限り問題は無い。<br /> このため、 VyOS の LTS版 のビルドを公開している人がいるので、それを取得して利用することもできる。</p> <p>→ <a target="_blank" rel="nofollow noopener" href="https://github.com/9l/vyos-build-action/releases">Releases · 9l/vyos-build-action</a></p> <p>GitHub Actions でビルドされており、比較的信頼できそうなイメージではあるが、 VyOS 以外の第三者によるもので何か余計な物が仕込まれているリスクは上がるので、利用に関しては自己責任で。</p> <p>最初からこれを紹介しとけよって? まぁまぁ、自分でビルドできるならそれに越したことはないし。</p> <h2 id="VyOS のテンプレートを GNS3 に取り込み"><a href="#VyOS+%E3%81%AE%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%92+GNS3+%E3%81%AB%E5%8F%96%E3%82%8A%E8%BE%BC%E3%81%BF">VyOS のテンプレートを GNS3 に取り込み</a></h2> <ol> <li>GNS3 のマーケットプレイス Appliances から <a target="_blank" rel="nofollow noopener" href="https://gns3.com/marketplace/appliances/vyos">VyOS のテンプレート</a> (<code>vyos.gns3a</code>) をダウンロードする。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-01.png" alt="" /></a></li> <li>GNS3 GUI の [File]->[Import appliance] メニューから、ダウンロードした <code>vyos.gns3a</code> を取り込む。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-02.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-02.png" alt="" /></a></li> <li>取り込み先をどこにするか聞いてくるので、 GNS3 VM を選択する。 (これまで手順通りなら、他の選択肢はグレーアウトされているはず)<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-03.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-03.png" alt="" /></a></li> <li>GNS3 VM 内で VyOS を動かす仮想マシン (入れ子の VM) をどれにするか選択する。 デフォルトの選択で問題ないはず。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-04.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-04.png" alt="" /></a></li> <li>必要なファイルをインポートする。 <ol> <li>まず、 empty8G.qcow2 を選択し、 [Download] をクリックすると、 自動的に sourceforge.net のダウンロードページに飛ばされるので、それをダウンロードする。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-05.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-05.png" alt="" /></a></li> <li>[Import] ボタンで、 ↑ でダウンロードされたファイルを選択すれば、 "Found on GNS3 VM" と表示が変わる<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-06.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-06.png" alt="" /></a></li> <li>vyos-x.x.x-amd64.iso のほうは、 "Allow custom files" のチェックボックスにチェックをつけてからインポートする。 これは、 セルフビルドや野良ビルドをインポートする際に、 公式提供の .iso とファイルハッシュが異なるために、エラーとなるのを回避するためだ。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-07.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-07.png" alt="" /></a><br /> [Import] ボタンから .iso ファイルをインポートすると MD5 チェックサムが異なると怒られるが、それでもインポートを続行させる。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-08.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-08.png" alt="" /></a></li> </ol></li> <li>Ready to install 表記に変わったら、 その version を選択して、 Next をクリックする。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-09.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns2-import-vyos-appliances-09.png" alt="" /></a> <ul> <li>他のバージョンの VyOS を用意する場合は、インポートの動作を繰り返す。</li> </ul></li> </ol> <p>これで、 GNS3 で VyOS を利用する準備が整った。</p> <h2 id="VyControl Docker イメージを GNS3 に取り込み"><a href="#VyControl+Docker+%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92+GNS3+%E3%81%AB%E5%8F%96%E3%82%8A%E8%BE%BC%E3%81%BF">VyControl Docker イメージを GNS3 に取り込み</a></h2> <p>VyOS を操作するフロントエンドとなる <a target="_blank" rel="nofollow noopener" href="https://github.com/vycontrol/vycontrol">VyControl</a> を、 Docker で導入する。</p> <p>公式で用意されている <a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/r/robertoberto/vycontrol">robertoberto/vycontrol</a> イメージを入れれば良い… と言いたいところなのだが、別途用意した <a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/r/advanceboy/vycontrol-host">advanceboy/vycontrol-host</a> のイメージを使う。</p> <p>GNS3 で vycontrol コンテナがホストする HTTP サーバーを操作する際、 GNS3 がフォワーディングしてくれので、 ホスト側のブラウザを使用する。<br /> ところが、 vycontrol の公式イメージは 127.0.0.1 以外でのアクセスを禁止しているので、フォワーディングされたアドレスで UI に入ることができない。</p> <p>そこで、 <code>ALLOWED_HOSTS</code> という環境変数経由でアクセスに使える IPアドレス を指定可能に改造したイメージを使用する。<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/advanceboy/vycontrol-host">https://github.com/advanceboy/vycontrol-host</a></p> <ol> <li>GNS3 の [Edit]->[Preferences] から "Docker container templates" の設定を開き、 [New] をクリック。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-01.png" alt="" /></a></li> <li>Docker コンテナを実行する場所をどこにするか聞いてくるので、 GNS3 VM を選択する。 (これまで手順通りなら、他の選択肢はグレーアウトされているはず)<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-02.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-02.png" alt="" /></a></li> <li>New image の Image name に、先ほどの <code>advanceboy/vycontrol-host:latest</code> のイメージ名を設定する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-03.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-03.png" alt="" /></a> <ul> <li>ちなみに、 GNS3 VM のシェル側で <code>docker pull</code> をあらかじめ実行しておけば、 "Existing imases" の選択肢に現れるようになる。</li> </ul></li> <li>Template name は、適当にわかりやすい名前で。 Adapter 数は 1 で OK。 Start Command も 空でよい。</li> <li>Console type を "http" に設定する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-04.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-04.png" alt="" /></a></li> <li>Environment で、 <code>ALLOWED_HOSTS=*</code> を設定して、コンテナテンプレートの設定を完了させる、<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-05.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-05.png" alt="" /></a></li> <li>"Docker container templates" の設定から [Edit] で詳細設定画面を開き、 "HTTP port in the container" を <strong>8000</strong> に設定する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-06.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-06.png" alt="" /></a></li> <li>更に、 Advanced タブに移動して、 コンテナの永続化パスに <code>/code/db.sqlite3</code> を追加する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-07.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-add-vyctrl-docker-container-07.png" alt="" /></a></li> </ol> <p>これで、 GNS3 で VyControl を利用する準備が整った。</p> <p>ついでに、 curl などが利用できる <a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/_/buildpack-deps">buildpack-deps:stable-curl</a> イメージあたりも追加しとくと便利かもしれない。</p> <h2 id="次回"><a href="#%E6%AC%A1%E5%9B%9E">次回</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1747">次回</a>は、いよいよ GNS3 で VyOS を実行する。</p> advanceboy tag:crieit.net,2005:PublicArticle/18350 2022-12-23T23:58:54+09:00 2023-02-02T02:35:40+09:00 https://crieit.net/posts/GNS3-VyOS GNS3 に VyOS 仮想ルーターを追加する長い道のり① 環境導入編 <p>本記事は <a target="_blank" rel="nofollow noopener" href="https://qiita.com/advent-calendar/2022/nw-engineering-are-core-output">【アットホームな現場です】🎄★☆ネットワーク系エンジニア★☆アレコレアウトプット★☆🎄 Advent Calendar 2022</a> 8日目の記事だ。 (空いていたので埋め)</p> <p><a target="_blank" rel="nofollow noopener" href="https://gns3.com/">GNS3</a> という、オープンソースのネットワークエミュレータがある。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-00.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-applied-00.png" alt="" /></a></p> <p>GUI 上で、様々なネットワーク機器を仮想環境に設置して、仮想ネットワークを構築できる、大変優れたツールだ。</p> <p>実際に、ルータや端末を沢山用意して物理的に結線せずとも、 PC 上で簡単にネットワークを作成できるので、ネットワークの勉強の為に、いわゆる ネットワーク ラボ環境 を準備には最適だ。</p> <p>しかし、一つ大きな問題がある。<br /> GNS3 自体には、基本的なハードウェアのエミュレータしか含まれていないため、ルーターなどを使うには、 "Cisco の IOS" といった「ルーターのソフトウェア」を別途用意しなくてはならない。</p> <p>すでに Cisco のルーターを持っていて、 IOS イメージなどが手に入るならよいのだが、そうではない場合合法的にこういったイメージを入手するのは(主に金銭的な意味で)厳しい。</p> <p>ネットワークの検証や勉強をする目的であれば、何も Cisco のルーターでなくとも、使う分には問題ないはずだ。</p> <p>…ということで、 <a target="_blank" rel="nofollow noopener" href="https://github.com/vyos">VyOS</a> という OSS のネットワークデバイスを、 Windows 上の GNS3 で使えるようにするまでの長い道のりを、数回に分けて紹介しようと思う。</p> <p>とりあえず、今回は環境導入編。</p> <h2 id="OS"><a href="#OS">OS</a></h2> <p>実行する Windows のバージョンは、 CPU が Intel なら Windows 10 で問題ないが、 CPU が AMD (Ryzen/Epic) の場合 Windows 11 以上が望ましい。<br /> これは、 <a target="_blank" rel="nofollow noopener" href="https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/user-guide/nested-virtualization">入れ子になった(ネストされた)仮想化による仮想マシン</a> のサポートが、 OS 側に必要であるためだ。<br /> (一応、 AMD のサポートは Windows 10 Build 19640 以上となっているが、 このバージョンはプレビュービルドしか存在しない)</p> <p>一応、上記を満たしていなくても動作させることは可能だが、内部で仮想化支援機能が働かないので、 VyOS の動作が著しく遅くなる。</p> <p>ちなみに、 ARM Windows はそもそもサポートされない。</p> <h2 id="VyOS と VyControl"><a href="#VyOS+%E3%81%A8+VyControl">VyOS と VyControl</a></h2> <p>VyOS とは、 オープンソースのネットワーク機器向けの OS で、 Linux をベースとしたディストリビューションである。</p> <p>ルーティングからファイアウォール、パケットフィルタから負荷分散まで、商用ルータに劣らない様々な機能を持っている。</p> <p>VyOS の設定は、基本的に専用のコマンドを用いて行うのだが、最初からそれを学ぶのは学習コストが高い。<br /> そこで、 <a target="_blank" rel="nofollow noopener" href="https://github.com/vycontrol/vycontrol">VyControl</a> という VyOS 向けの シンプルな GUI フロントエンドと組み合わせるところまで、構築していきたいと思う。</p> <h2 id="環境構築に必要なもの"><a href="#%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AB%E5%BF%85%E8%A6%81%E3%81%AA%E3%82%82%E3%81%AE">環境構築に必要なもの</a></h2> <p>しかし、 GNS3 上で VyOS を利用できるようにする道のりは長い。</p> <p>まず、 VyControl を使うためには、 VyOS 1.3 以上が必要となる。<br /> 実は、ビルド済みの安定板の VyOS イメージは、サブスクリプション契約をしないとダウンロードできない。</p> <p>VyOS 自体は、前述のとおり OSS なのでソースコードを自由に取得できる。<br /> そのビルド自体も docker を利用する仕組みがしっかりと用意されおり、環境依存なども少なく失敗しにくい。<br /> あまり性能の高くないノートPCでも、 10分程度でビルド可能だ。</p> <p>Windows 上で VyOS 1.3 のイメージをビルドするには、 WSL2 と Docker (Docker Desktop または <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1703">Rancher Desktop</a>) が必要だ。<br /> Docker Desktop を使えば、 Windows のシェルから直接 Docker を起動できるが、ファイルシステムの問題でビルドエラーになるため、 WSL が必要となる。</p> <p>また、 GNS3 を Windows 上で使うには、 別途 VirtualBox などの仮想マシン管理ツールが必要となる。 <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup><br /> 以降、無料で使用できる VirtualBox での利用方法を中心に説明するが、他の仮想マシン管理ツールを利用する場合は適宜読み替えていただきたい。</p> <p>GNS3 は、この VirtualBox の中に "GNS3 VM" という仮想マシンを作成し、 その中でさらに QEMU の仮想マシンや、 docker コンテナ (※) を作成し、 ネットワークをエミュレーションを行うのが、基本的な仕組みとなる。</p> <p>※: VyOS のビルドに使用した docker とはまた別の環境。</p> <p>…とまあ、いろいろツールの名前が出てきたが、これらの構成をまとめると、以下の図のようになる。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-with-vyos-overview.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-with-vyos-overview.png" alt="" /></a></p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://learn.microsoft.com/ja-jp/windows/wsl/install">WSL2</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.docker.com/products/docker-desktop/">Docker Desktop</a> (または <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1703">Rancher Desktop</a>)</li> <li><a target="_blank" rel="nofollow noopener" href="https://www.virtualbox.org/">VirtualBox</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.gns3.com/">GNS3</a></li> </ul> <p>これらを順にインストールしていこう。</p> <p>なお、このうち WSL2 と Docker Desktop については、 VyOS の ISO イメージのビルドを自分でせず、野良ビルドを使う場合はインストール不要だ。 (詳しくは<a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1722">次回②</a>に記載)</p> <h3 id="WSL2"><a href="#WSL2">WSL2</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://learn.microsoft.com/ja-jp/windows/wsl/install">WSL のインストール | Microsoft Learn</a><br /> のページの内容に則り、以下の手順でインストールする</p> <ol> <li>PowerShell または Windows コマンド プロンプトを<strong>管理者モード</strong>で開く</li> <li><p>以下のコマンドを入力して PC を再起動する</p> <pre><code>wsl --install </code></pre></li> <li><p>以下のコマンドで、 WSL で作成される WSL バージョンを WSL2 を規定にする。</p> <pre><code>wsl --set-default-version 2 </code></pre></li> <li><p>Microsoft Store などから、適当な WSL ディストリビューション (<a target="_blank" rel="nofollow noopener" href="https://apps.microsoft.com/store/detail/ubuntu-22041-lts/9PN20MSR04DW">Ubuntu 22.04.1 LTS</a> など) をインストールする</p></li> </ol> <h3 id="Docker Desktop"><a href="#Docker+Desktop">Docker Desktop</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://www.docker.com/products/docker-desktop/">Docker Desktop</a> のインストーラを取得し、 ウィザードに従ってインストールする。</p> <p>インストール後、設定から WSL Integration を有効にする。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-enable-wsl2-on-docker-desktop.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-enable-wsl2-on-docker-desktop.png" alt="" /></a></p> <p>もし、ライセンス的に Docker Desktop が使いづらい環境なら、以下の Rancher Desktop の手順を参照。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1703">https://aquasoftware.net/blog/?p=1703</a></p> <h3 id="VirtualBox"><a href="#VirtualBox">VirtualBox</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://www.virtualbox.org/">VirtualBox</a> で、 Version 6.1 以上を取得して、ウィザードに従ってインストール。</p> <p>こちらは特に気を付けるべきことはなかったと思う。</p> <h3 id="GNS3"><a href="#GNS3">GNS3</a></h3> <h4 id="GNS3 本体のインストール"><a href="#GNS3+%E6%9C%AC%E4%BD%93%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">GNS3 本体のインストール</a></h4> <p>GitHub の <a target="_blank" rel="nofollow noopener" href="https://github.com/GNS3/gns3-gui/releases">gns3-gui プロジェクトのリリースページ</a> から、最新バージョンの</p> <ul> <li><code>GNS3-*-all-in-one.exe</code></li> </ul> <p>をダウンロードし、実行する。</p> <p>インストールするコンポーネントを選択するところで、</p> <ul> <li>GNS3 Desktop</li> <li>GNS3 VM</li> </ul> <p>の<strong>2つだけを選択して</strong>それ以外の選択を(外せる物は)全て外す。 <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup><br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-00.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-00.png" alt="" /></a></p> <p>ウィザードを進めると、 GNS3 の VMタイプ を選ぶ場面になるので、 VirtualBox を選択する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-01.png" alt="" /></a></p> <p>そのままインストールを進め、初回起動の段階で一旦休憩。</p> <h4 id="GNS3 VM のインポート"><a href="#GNS3+VM+%E3%81%AE%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88">GNS3 VM のインポート</a></h4> <p>次に、 インストール途中で "ダウンロード" フォルダあたりにダウンロードされていた、 <code>GNS3.VM.VirtualBox.*.zip</code> を解凍して <code>GNS3 VM.ova</code> を取り出す。 <sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p> <p><strong>VirtualBox</strong> を起動し、この <code>GNS3 VM.ova</code> を「仮想アプライアンスのインポート」にて、 "GNS3 VM" という名前でインポートする。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-02.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-02.png" alt="" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-03.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-03.png" alt="" /></a></p> <p>その後、 PowerShell を立ちあげ、以下のコマンドを実行する。<br /> これにより、前述の入れ子になった(ネストされた)仮想化による仮想マシンの機能が有効化される。 <sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup></p> <pre><code class="PowerShell">$env:Path += ';' + 'C:\Program Files\Oracle\VirtualBox\'; VBoxManage.exe modifyvm 'GNS3 VM' --nested-hw-virt on; </code></pre> <h4 id="GNS3 上の VM の設定"><a href="#GNS3+%E4%B8%8A%E3%81%AE+VM+%E3%81%AE%E8%A8%AD%E5%AE%9A">GNS3 上の VM の設定</a></h4> <p>GNS3 の初回起動に戻ると、 GNS3 のネットワークシミュレーションをどのように実行するか選択肢が出てくる。</p> <blockquote> <p>The GNS3 VM option is strongly recommended on Windows and Mac OSX.</p> </blockquote> <p>と書かれているように、 Virtual Machine を選択する。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-04.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-04.png" alt="" /></a></p> <p>Local server の設定はデフォルトのままで良い。 この設定を使って、 GNS3 VM で動くサービスがホストされ、 GNS3 GUI がそのサービスと通信することでツールが動作する仕組みとなる。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-05.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-05.png" alt="" /></a></p> <p>改めてもう一度 GNS3 VM がどの仮想マシンマネージャーを使うか効いてくるので、 VirtualBox を選択する。</p> <p>vCPU や RAM のサイズ (特に前者) は、ホスト PC のリソースが許す限り豊富に設定しておいた方が良い。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-06.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-06.png" alt="" /></a></p> <p>GNS3 起動後、 [Edit]->[Preferences] の [GNS3 VM] の設定でも、もう少し細かい GNS3 VM の設定ができる。<br /> "Run the VM in headless mode" や "Action when closing GNS3: suspend the GNS3 VM" あたりの設定は ON にしておいた方が便利。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-07.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-07.png" alt="" /></a></p> <p>正しくセットアップできていれば、 GNS3 起動後暫くしたら、 Servers Summary ウィンドウの GNS3 VM がグリーンになっているはずだ。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-08.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-08.png" alt="" /></a></p> <h4 id="GNS3 VM 側の設定"><a href="#GNS3+VM+%E5%81%B4%E3%81%AE%E8%A8%AD%E5%AE%9A">GNS3 VM 側の設定</a></h4> <p>VirtualBox 側で立ち上がった GNS3 VM を開くと、以下のように VM 情報が表示されている。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-09.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2022/12/gns3-install-vm-to-virtualbox-09.png" alt="" /></a></p> <p>この画面 (TUI) を直接操作したり、 画面に書かれているアドレスやパスワードで ssh することで、 GNS3 VM 内部のより細かい設定ができる。</p> <p>例えば、プロキシ環境下でプロキシの設定が必要な場合、以下の 2カ所 の設定を行う。</p> <ol> <li>VM 情報のページから [OK] -> メニューで [Proxy] と選択し、 <code>http://203.0.113.99:8080</code> と言った形で指定する。 <ul> <li>VM 内からホストPCで設定されている DNS は見れず、 DNS は 8.8.8.8 や 8.8.4.4 が決め打ちされている。 イントラネット内の名前解決はできないので、 プロキシがイントラネット内なら、ホスト名では無くて IPアドレス で指定する方が良い。</li> </ul></li> <li><p>メニューで [Shell] を選択して以下のように実行し、 docker デーモン (dockerd) にもプロキシの設定を反映させる。</p> <pre><code class="shell">gns3@gns3vm:~$ sudo mkdir -p /etc/systemd/system/docker.service.d gns3@gns3vm:~$ sudo tee -a /etc/systemd/system/docker.service.d/http-proxy.conf /dev/null [Service] Environment="HTTP_PROXY=$http_proxy" Environment="HTTPS_PROXY=$https_proxy" EOF gns3@gns3vm:~$ sudo systemctl daemon-reload gns3@gns3vm:~$ sudo systemctl restart docker gns3@gns3vm:~$ cat ~/.docker/config.json {"proxies":{"default":{"httpProxy": "$http_proxy","httpsProxy": "$https_proxy","noProxy": "127.0.0.0/8"<span>}</span><span>}</span>} EOF </code></pre></li> </ol> <p>GNS3 から VirtualBox を操作する部分の作り込みが甘いのかもしれないが、 GNS3 VM が再起動されると GNS3 から VM を正常に操作できなくなってエラーが起きがちだ。<br /> このため、 一通り GNS3 VM の設定が終わったら、 GNS3 (GUI) 側を再起動したほうが良い。</p> <h2 id="次回"><a href="#%E6%AC%A1%E5%9B%9E">次回</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/?p=1722">次回</a>は、 GNS3 に入れる VyOS イメージのビルドと、 GNS3 に VyControl のコンテナを準備する。</p> <div class="footnotes" role="doc-endnotes"> <hr /> <ol> <li id="fn:1" role="doc-endnote"> <p>VirtualBoxではなくHyper-Vなども使えることは使えるが、仮想NICの扱いの仕組み上Hyper-Vだと若干ややこしい。(GNS3 VMのIPアドレスが毎回わかるとか、VPN環境下で使いにくいとか) <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> <li id="fn:2" role="doc-endnote"> <p>GNS3は、VMではなくホストPC上で直接ネットワークをエミュレートする方法もあり、そういった場合にTool以下のソフトが必要になるのだが、今回はVM上でエミュレートしているので、これらの殆どはホストPC側にインストールする必要が無い。強いて言うならNPCAPとWiresharkはインストールしても良いかも。 <a href="#fnref:2" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> <li id="fn:3" role="doc-endnote"> <p>ダウンロードし間違えたり、どこにダウンロードされたかわからない場合、前述のリリースページから手動でダウンロード可能。 <a href="#fnref:3" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> <li id="fn:4" role="doc-endnote"> <p>Hyper-Vの場合は、<code>GNS3.VM.Hyper-V.*.zip</code>内の<code>install-vm.bat</code>のバッチを実行すれば、自動的にネストされた仮想化が有効になる。 <a href="#fnref:4" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> </ol> </div> advanceboy tag:crieit.net,2005:PublicArticle/17180 2021-05-19T09:57:20+09:00 2021-05-21T01:14:28+09:00 https://crieit.net/posts/Vagrant-Temporary-failure-resolving-DNS Vagrant で Temporary failure resolving となる問題の解決 - イントラネット DNS 編 <p>Vagrant で Ubuntu の VM を立ち上げたとき、 apt 等を行おうとすると、以下のようなエラーに遭遇した。</p> <pre><code class="plain">client: Err:1 http://security.ubuntu.com/ubuntu focal-updates/main amd64 libjpeg-turbo8 amd64 2.0.3-0ubuntu1.20.04.1 client: Temporary failure resolving 'proxy.local.example' </code></pre> <p>上記のエラーの内容はプロキシに接続できないというものだが、 問題のポイントはプロキシかどうかはあまり関係が無く、 名前解決に失敗しているという部分だ。<br /> こういうのはだいたい <code>systemd-resolved</code> のスタブリゾルバ周りの問題だと相場が決まっている。</p> <p>…ということで、順番に確認しながら問題を解決していこう。</p> <p>なお、 使った box は <code>generic/ubuntu2004</code> で、 VirtualBox で VM をホストしている。</p> <h2 id="スタブリゾルバの確認"><a href="#%E3%82%B9%E3%82%BF%E3%83%96%E3%83%AA%E3%82%BE%E3%83%AB%E3%83%90%E3%81%AE%E7%A2%BA%E8%AA%8D">スタブリゾルバの確認</a></h2> <p>まず、 <code>resolv.conf</code> を確認してみる。</p> <pre><code class="plain">$ cat /etc/resolv.conf # This file is managed by man:systemd-resolved(8). Do not edit. # # This is a dynamic resolv.conf file for connecting local clients to the # internal DNS stub resolver of systemd-resolved. This file lists all # configured search domains. # # Run &quot;resolvectl status&quot; to see details about the uplink DNS servers # currently in use. nameserver 127.0.0.53 </code></pre> <p>テキストファイルのコメントに書いてあるとおり、コイツを書き換えるのは悪手。</p> <p>ネームサーバーが 127.0.0.53 を指しているが、 これが <code>systemd-resolved</code> のスタブリゾルバだ。</p> <p>ここで言う<strong>リゾルバ</strong>とは、ドメイン名を元にIPアドレスを解決する仕組みのことを指していて、 DNS なども同様の機能を持っている。<br /> その中でも、<strong>スタブリゾルバ</strong>は、(「スタブ」と言うだけあって、)それ自身はドメイン名とIPの対応リストを持たずに、 DNS 等の他のリゾルバを呼び出して解決する仕組みをもっている、ローカルのサービスだ。<br /> ローカルアプリケーションが直接 DNS を参照せず、一旦スタブリゾルバを参照することで、 <code>systemd</code> で管理された適切な DNS を自動的に参照されるようになったり、 DNS では解決できない <code>hostname.local</code> といったホスト名ベースの名前解決 (mDNS) を行えるようになっている。</p> <p>さて、 そのスタブリゾルバがどう動いているか <code>resolvectl status</code> で確認してみよう。</p> <pre><code class="plain">$ resolvectl status [...] Global Current DNS Server: 4.2.2.1 DNS Servers: 4.2.2.1 4.2.2.2 [...] Link 2 (eth0) Current Scopes: DNS DNSSEC supported: yes Current DNS Server: 4.2.2.1 DNS Servers: 4.2.2.1 4.2.2.2 208.67.220.220 10.0.2.3 </code></pre> <p>4.2.2.1 や 208.67.220.220 などが DNS に設定されているのがわかる。<br /> これらは、いわゆるパブリックDNSだ。</p> <p>実は、先ほど名前解決できなかったプロキシは、 LAN 内のサーバーだった。 このため、 パブリックDNSに問い合わせられてしまっては、名前解決ができないのも当然だ。</p> <h2 id="パブリックDNS はどこで設定されているのか"><a href="#%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AFDNS+%E3%81%AF%E3%81%A9%E3%81%93%E3%81%A7%E8%A8%AD%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%8B">パブリックDNS はどこで設定されているのか</a></h2> <p>名前解決に失敗する理由はわかった。 しかし、この DNS はどこで設定されているのか?</p> <p>ざっと確認してみたところ、 <code>resolved.conf</code> の設定と、 仮想マシン内の NAT を繋いだ NIC の netplan 設定に、それっぽい設定が書かれていた。</p> <pre><code class="plain">$ cat /etc/systemd/resolved.conf [Resolve] DNS=4.2.2.1 4.2.2.2 208.67.220.220 </code></pre> <pre><code class="plain">$ cat /etc/netplan/01-netcfg.yaml network: version: 2 renderer: networkd ethernets: eth0: dhcp4: true dhcp6: false optional: true nameservers: addresses: [4.2.2.1, 4.2.2.2, 208.67.220.220] </code></pre> <p>これらは通常の Ubuntu のインストールプロセスでは設定されないので、 <code>generic/ubuntu2004</code> の box の作成者の味付けなのだろう。</p> <p>これらの DNS のアドレスの設定を、プライベートネットワーク内の DNS のアドレスに書き換えてしまえば、きっと意図した動作に近づくはずだ。</p> <h2 id="スタブリゾルバを使わずに LAN内 の DNS を指定する"><a href="#%E3%82%B9%E3%82%BF%E3%83%96%E3%83%AA%E3%82%BE%E3%83%AB%E3%83%90%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%9A%E3%81%AB+LAN%E5%86%85+%E3%81%AE+DNS+%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">スタブリゾルバを使わずに LAN内 の DNS を指定する</a></h2> <p>スタブリゾルバは、細かい優先度合いの制御などを外から行えない。 これはネットワークの状況に応じて最適調整してくれる設計だからなのだが、 Vagrant で立ちあげる VM のように、 NAT の DNS や ローカルの DNS が混在していると、うまく調整できずに、こういった問題の解決がやりにくい。</p> <p>スタブリゾルバを動かしているままでも問題なく動いているのならそれでもかまわないのだが、 上記の DNS の書き換えを行ってもどうも意図通りに名前解決されない場合は、 <code>systemd-resolved</code> のスタブリゾルバを使わずに、 <code>/etc/resolv.conf</code> の nameserver を切り替えるようにしたい。</p> <p>具体的には、 <code>/etc/resolv.conf</code> が <code>../run/resolvconf/resolv.conf</code> へのシンボリックリンクになっているところ、 <code>../run/systemd/resolve/resolv.conf</code> へのシンボリックリンクに書き換える。<br /> こうすることで、 <code>resolved.conf</code> や netplan で設定した DNS が直接 <code>/etc/resolv.conf</code> の nameserver に書かれるようになる。<br /> 詳しくは、 <a target="_blank" rel="nofollow noopener" href="https://translate.google.com/translate?hl=ja&sl=en&u=https://man.archlinux.org/man/systemd-resolved.8.en&prev=search&pto=aue">systemd-resolved.service のマニュアル</a> あたりを見て欲しい。</p> <p>…と、このような書き換えを、 Vagrantfile の定義に書き落とすと、以下のようになる。<br /> なお、以下は <code>192.168.11.1</code> がローカルネットワークの DNS のアドレスである場合の例なので、適宜書き換えていただければと。</p> <pre><code class="ruby">config.vm.provision :shell, inline: <<-'SHELL' ln -sf ../run/systemd/resolve/resolv.conf /etc/resolv.conf sed -i -E '/nameservers:/{n; s/(addresses:).*/\1 [192.168.11.1]/}' /etc/netplan/01-netcfg.yaml netplan apply sed -i -E 's/(^\s*DNS\s*=\s*).*$/\1192.168.11.1/' /etc/systemd/resolved.conf systemctl restart systemd-resolved.service SHELL </code></pre> <p>そうすると、 <code>resolv.conf</code> の中身が以下のように netplan の設定などから求められた DNS に置き換えられ、スタブリゾルバを経由せずに名前解決されるようになる。</p> <pre><code class="plain">$ cat /etc/resolv.conf # This file is managed by man:systemd-resolved(8). Do not edit. # # This is a dynamic resolv.conf file for connecting local clients directly to # all known uplink DNS servers. This file lists all configured search domains. # nameserver 192.168.11.1 nameserver 10.0.2.3 </code></pre> <p>このようになれば、ローカルの DNS でキチンと名前解決されるようになるだろう。</p> advanceboy tag:crieit.net,2005:PublicArticle/17056 2021-05-04T11:55:50+09:00 2021-05-04T11:55:50+09:00 https://crieit.net/posts/Windows-Server-CertReq-CSR Windows Server の CertReq で作成した CSR の文字化けを回避する <p>Windows Server の <code>certreq.exe</code> を使って、 https 等を目的に サーバー証明書署名要求 (CSR) を作成した際に、 その CSR や署名後の CER で、 サブジェクト字が文字化けしてしまう場合がある。</p> <p><a href="https://crieit.now.sh/upload_images/2a94ae5a87f998674df6b4d30b4427bd6090b6a8103f8.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/2a94ae5a87f998674df6b4d30b4427bd6090b6a8103f8.png?mw=700" alt="certreq-unicode-00.png" /></a> <a href="https://crieit.now.sh/upload_images/903a4a7899522cbe94fec78c2657d4e96090b6aeb36cc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/903a4a7899522cbe94fec78c2657d4e96090b6aeb36cc.png?mw=700" alt="certreq-unicode-01.png" /></a></p> <p>この問題は、 <code>certreq.exe</code> にて、テキストファイル (.inf ファイル) から CSR を作成した場合に発生する。</p> <p>そしてこれは、 .inf ファイルを BOM付き UTF-16 LE で保存すれば解決する。<br /> (BOM付き/BOMなし の UTF-8 には対応していない)</p> <p><a href="https://crieit.now.sh/upload_images/86fdbbe43a80ce83bd3ac30183fe7f906090b6b15624c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/86fdbbe43a80ce83bd3ac30183fe7f906090b6b15624c.png?mw=700" alt="certreq-unicode-02.png" /></a><br /> Windows のメモ帳であれば、 文字コードを Unicode に設定すれば、 OK だ。</p> <p>対処法は単純だが、原因が少しややこしかったので、少し深堀りしてみる。</p> <h2 id="CSR が文字化けする要因"><a href="#CSR+%E3%81%8C%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91%E3%81%99%E3%82%8B%E8%A6%81%E5%9B%A0">CSR が文字化けする要因</a></h2> <p>そもそも、文字化けする要因は以下の3カ所あった。</p> <ol> <li>.inf ファイルが ASCII (Shift_JIS) で保存すると Unicode の情報が失われる</li> <li>certreq.exe が .inf ファイルの文字コードの解決に失敗する</li> <li>X.509 の文字列のエンコードが UTF-8 が指定されていない</li> </ol> <p>(1) はまぁわかりやすいだろう。<br /> テルグ文字や絵文字など、 Shift_JIS に存在しない Unicode の文字が文字化けするのは、これが原因だ。</p> <p>ところが、 古い Windows Server (2012 あたりとか) だったり、 .inf の内容によっては、 非 Shift_JIS 文字だけでなく、 非Ascii 文字 (上のスクショで言うと "京都府" のあたり) も文字化けする場合がある。<br /> これは (1) だけでは説明がつかない。</p> <p>(2) については、 .inf ファイルが Shift_JIS や UTF-8 で保存されていると、 certreq.exe が文字コードの解決を誤ってしまう場合があるのが原因だ。<br /> おそらく、 OS のロケールなどを見て、 BOM付き UTF-16 LE ではないファイルが .inf ファイルに渡されたときの挙動が決まるのだと思われる。</p> <p>この問題も、 .inf ファイルを .inf ファイルを BOM付き UTF-16 LE で保存すれば、文字の解釈が明確になるので、文字化けしなくなる。</p> <p>なお、 (3) については、現行のサポート中の OS では気にする必要はないだろう。 古い OS だと、 HTTPS サーバー証明書の規格である X.509 で、扱う文字列を UTF-8 で記述するバージョンに対応していない可能性がある。</p> <h2 id="サーバー証明書のサブジェクトに顔文字を入れる"><a href="#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%AE%E3%82%B5%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AB%E9%A1%94%E6%96%87%E5%AD%97%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B">サーバー証明書のサブジェクトに顔文字を入れる</a></h2> <p>試しに、 以下のような内容の <code>request.inf</code> ファイルを、 BOM付き UTF-16 LE で保存して、 certreq.exe で CSR ファイルを作成してみよう。</p> <pre><code class="text">[NewRequest] Subject = "CN=(´◉◞౪◟◉); OU=🥺; O=aquasoftware.net; L=京都市; ST=京都府; C=JP; [email protected]" X500nameflags = "CERT_NAME_STR_SEMICOLON_FLAG" KeyLength = 3072 KeySpec = AT_KEYEXCHANGE KeyUsage = "CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_KEY_ENCIPHERMENT_KEY_USAGE" HashAlgorithm = sha256 MachineKeySet = True ProviderName = "Microsoft RSA SChannel Cryptographic Provider" ProviderType = 12 RequestType = CMC [EnhancedKeyUsageExtension] OID=1.3.6.1.5.5.7.3.1 [Extensions] 2.5.29.17="{text}" _continue_ = "DNS=aaa.example.com&" _continue_ = "DNS=bbb.example.com&" _continue_ = "IPAddress=192.0.2.1&" _continue_ = "IPAddress=192.0.2.2" </code></pre> <pre><code class="console">PS> certreq.exe -new .\request.inf .\csr.req CertReq: 要求が作成されました </code></pre> <p>.inf ファイルの書き方については、 <a target="_blank" rel="nofollow noopener" href="https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/certreq_1">certreq | Microsoft Docs</a> のドキュメントを参照のこと。<br /> いくつか特徴的な部分について解説しておくと、</p> <ul> <li>Subject 内のパラメーターに <code>","</code> が使えるよう、 <code>X500nameflags</code> に <code>CERT_NAME_STR_SEMICOLON_FLAG</code> を指定して、区切りを <code>";"</code> に変更している。</li> <li><code>OID=1.3.6.1.5.5.7.3.1</code> の部分では、「拡張キー使用法」に「サーバー認証」の仕組みを与えている。</li> <li><code>[Extensions]2.5.29.17=...</code> の部分では、 SubjectAltName (SAN) に、 DNS や IpAddress を指定している。 SAN の指定がないと、 Chrome で証明書エラーになってしまうため。</li> </ul> <p>これを CA で署名してもらってサーバー証明書として使えば、サーバー証明書内で絵文字ですら使えるようになる。</p> <p><a href="https://crieit.now.sh/upload_images/6cb04d4d5eacfaa773cbe305c0c9f30e6090b6b40a165.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6cb04d4d5eacfaa773cbe305c0c9f30e6090b6b40a165.png?mw=700" alt="certreq-unicode-03.png" /></a> <a href="https://crieit.now.sh/upload_images/8ff19ca50b52e7e778d73072cb57cf9c6090b6b70a776.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8ff19ca50b52e7e778d73072cb57cf9c6090b6b70a776.png?mw=700" alt="certreq-unicode-04.png" /></a></p> advanceboy tag:crieit.net,2005:PublicArticle/16657 2021-01-27T09:33:58+09:00 2023-02-22T12:42:54+09:00 https://crieit.net/posts/VPN-WSL2-Hyper-V-VM VPN に繋ぐと WSL2 や Hyper-V VM でネットワークに繋がらなくなる問題を解消する <p>OpenVPN や Cisco AnyConnect, GlobalProtect 等といった VPN に接続した際、 Hyper-V 仮想マシン内からや、 WSL2 のディストリビューション内、 Windows Sandbox 内、 WSL2 ベースの Docker コンテナ内 等々、 Hyper-V 系の技術を使った仮想環境から、 PC 外のネットワークにアクセスしようとすると、 以下のようなエラーが発生して失敗する。</p> <pre><code class="console">$ # curl 利用時の例 curl: (6) Could not resolve host: example.com curl: (5) Could not resolve proxy: proxy.example.com $ # apt で更新しようとした場合の例 W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease Temporary failure resolving 'archive.ubuntu.com' W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease Temporary failure resolving 'proxy.example.com' </code></pre> <p>エラーの内容からわかるとおり、アクセス先やプロキシーのドメイン名を DNS で解決できなくなっている。</p> <p>このような問題が発生することは以前から知っていたのだが、このご時世で VPN 使うことが増えてきて、いい加減鬱陶しくなってきたので、なんとかしようと思う。</p> <h2 id="解決方法"><a href="#%E8%A7%A3%E6%B1%BA%E6%96%B9%E6%B3%95">解決方法</a></h2> <p>とりあえず、まずは解決方法から。</p> <p>以前は AnyConnect でもこの方法が使えたはずなのだが、どうやら対策されて打つ手なしになってしまった模様。<br /> 今のところ、以下の方法で回避の確認が取れているのは、 GlobalProtect のみだ。</p> <ol> <li>WSL2 の場合は何らかの WSL2 を使ったディストリビューションを立ち上げる。 <ul> <li>WSL 2 based engine が有効になった Docker Desktop を起動するだけでも OK。</li> <li>WSL2 を使っていないなら、何もする必要はない。</li> </ul></li> <li>VPN を接続状態にする。</li> <li><p>管理者権限で Windows PowerShell を立ち上げ、以下のコードを実行する。 (GlobalProtect の例)</p> <pre><code class="powershell">$targetIfName = 'PANGP Virtual Ethernet Adapter'; # define function function Get-NetworkAddress { param([Parameter(Mandatory, ValueFromPipelineByPropertyName)][string]$IPAddress, [Parameter(Mandatory, ValueFromPipelineByPropertyName)][int]$PrefixLength); process { $bitNwAddr = [ipaddress]::Parse($IPAddress).Address -band [uint64][BitConverter]::ToUInt32([System.Linq.Enumerable]::Reverse([BitConverter]::GetBytes([uint32](0xFFFFFFFFL -shl (32 - $PrefixLength) -band 0xFFFFFFFFL))), 0); [pscustomobject]@{ Addr = $IPAddress; Prfx = $PrefixLength; NwAddr = [ipaddress]::new($bitNwAddr).IPAddressToString + '/' + $PrefixLength; }; } } # extend route metric $targetAddresses = Get-NetAdapter -IncludeHidden | Where-Object InterfaceDescription -Match 'Hyper-V Virtual Ethernet Adapter' | Get-NetIPAddress -AddressFamily IPv4 | Get-NetworkAddress; $targetIfs = Get-NetAdapter -IncludeHidden | Where-Object InterfaceDescription -Match $targetIfName; $targetIfs | Set-NetIPInterface -InterfaceMetric 2; $targetIfs | Get-NetRoute -AddressFamily IPv4 | Select-Object -PipelineVariable rt | Where-Object { $targetAddresses | Where-Object { $_.NwAddr -eq (Get-NetworkAddress $rt.DestinationPrefix.Split('/')[0] $_.Prfx).NwAddr } } | Set-NetRoute -RouteMetric 6000; </code></pre> <ul> <li>GlobalProtect 以外の場合は、 上記コード一行目の <code>'PANGP Virtual Ethernet Adapter'</code> のところを VPN ソリューションの ネットワーク接続 アダプタ名に書き換える。<br /> 具体的には、 <code>Win+R</code> で <code>ncpa.cpl</code> を実行して「ネットワーク接続」を開き、該当する VPN の接続のプロパティを開いて、 "接続の方法" のところに書かれた名前 (の一部) を指定する。 <ul> <li>OpenVPN なら <code>TAP-Windows Adapter</code> とか、 AnyConnect なら <code>Cisco AnyConnect</code> とか。 環境によっても違うかも。</li> </ul></li> <li>管理者権限の PowerShell は、 スタート ボタンを右クリックで簡単に立ち上げられる。<br /> <a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2021/01/wsl-hyperv-with-vpn-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2021/01/wsl-hyperv-with-vpn-01.png" alt="" /></a></li> <li><p>1回の実行で成功しない場合、 <strong>上記コードの最後の行</strong> を、ルートメトリックが書き換わるまで何度もしつこく実行する。</p> <ul> <li><p>ルートメトリックが書き換わっていない状態の例:</p> <p>```text/plain<br /> $targetIfs | Get-NetRoute -AddressFamily IPv4 | Select-Object -PipelineVariable rt | Where-Object { $targetAddresses | Where-Object { $<em>.NwAddr -eq (Get-NetworkAddress $rt.DestinationPrefix.Split('/')[0] $</em>.Prfx).NwAddr } }</p> <p>ifIndex DestinationPrefix NextHop RouteMetric ifMetric<br /> ------- ----------------- ------- ----------- --------<br /> 36 172.30.175.255/32 0.0.0.0 0 0<br /> 36 172.30.160.1/32 0.0.0.0 0 0<br /> 36 172.30.160.0/20 0.0.0.0 0 0<br /> 20 172.18.31.255/32 0.0.0.0 0 0<br /> 20 172.18.16.1/32 0.0.0.0 0 0<br /> 20 172.18.16.0/20 0.0.0.0 0 0<br /> ```</p></li> <li><p>ルートメトリックの書き換えに成功した例:</p> <p>```text/plain<br /> $targetIfs | Get-NetRoute -AddressFamily IPv4 | Select-Object -PipelineVariable rt | Where-Object { $targetAddresses | Where-Object { $<em>.NwAddr -eq (Get-NetworkAddress $rt.DestinationPrefix.Split('/')[0] $</em>.Prfx).NwAddr } }</p> <p>ifIndex DestinationPrefix NextHop RouteMetric ifMetric<br /> ------- ----------------- ------- ----------- --------<br /> 36 172.30.175.255/32 0.0.0.0 6000 0<br /> 36 172.30.160.1/32 0.0.0.0 6000 0<br /> 36 172.30.160.0/20 0.0.0.0 6000 0<br /> 20 172.18.31.255/32 0.0.0.0 6000 0<br /> 20 172.18.16.1/32 0.0.0.0 6000 0<br /> 20 172.18.16.0/20 0.0.0.0 6000 0<br /> ```</p></li> </ul></li> </ul></li> <li>上記を、 <strong>PC を再起動したり、 VPN を接続しなおす度に、毎回実行</strong>する。</li> </ol> <h2 id="解説"><a href="#%E8%A7%A3%E8%AA%AC">解説</a></h2> <p>上記のコードは、 VPN プロバイダが ホスト PC に作成しているルーティングの設定のうち、 Hyper-V や WSL に関係する宛先ものだけ、ルーティングのメトリックをめっちゃ長くしている。</p> <p>Hyper-V や WSL のネットワークの仕組みに簡単に触れながら、もう少し細かく説明していこう。</p> <h3 id="Hyper-V と WSL2 の NAT"><a href="#Hyper-V+%E3%81%A8+WSL2+%E3%81%AE+NAT">Hyper-V と WSL2 の NAT</a></h3> <p>まずそもそもの前提として、 <strong>ホストPC と WSL2 の仮想環境で異なる IPアドレス を持っている</strong>。<br /> 利便性のため、 WSL2 の localhost のリッスンが、ホスト PC の localhost へ転送されているなど、 IPアドレス が異なることをあまり意識せずすむような仕組みにはなっているけれども。</p> <p>そして その WSL2 や、 Hyper-V の VM では、 PC の外と通信する際に NAT を経由して通信を行う仕組みがメインとなる。</p> <p>このとき、 Hyper-V や WSL2 のバックエンドとなる Hyper-V ハイパーバイザーは、 ホスト PC 上に 仮想 NIC を作成する。<br /> そしてその仮想 NIC に、 <a target="_blank" rel="nofollow noopener" href="https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/user-guide/setup-nat-network">WinNAT</a> と呼ばれる 機能を割り当て、 更に WSL2 向けには DNS の機能も割り当てて、 ホスト PC の外との通信の中継を担わせるようになっている。</p> <p>これら、 仮想 NIC や、 WSL2 に自動で割り当てられる IP アドレスは、 ホスト PC と被らない適当なプライベート IP アドレスが割り当てられる。</p> <p>なお、 <strong>やっかいなことに、この割り当てられた IP アドレスは、起動する度に毎回異なる。</strong></p> <p><img src="https://www.plantuml.com/plantuml/svg/VP51R-8m48Nl_XMZx6Nt0DBsY42YWggjH14I5HoQ7enj4Wjd78qTAAheRwzDqYQAr1wYEEFtldapcJhFoLU5OUwWiUJ42n2S9BmpW9qbgMXcZILOw2ptzyJFxCAOHgzepuK2zHPEo0rZf8Jdc1a5oODr7hOQfJqvMCsI2AkfoVAn-GHe8SagFpijk84xdoV07PIeHL-qqI5ehKbnRmasg-LLV2onhpq6aI9K7lxErPvNniFwfBt8_wKOtdbCjxnzhksXLtxyXR1TBtwmdPo9lkyjm7WmQBF70um_OhuH-0fH6OrPvseuR9gF8CKqadkNROi8wHZQKYlhGYxXARauy2p-ZdEfQB3vsZjQ6RVvL4zH_E_BmxWt7MrTWRbsdlIkyjhYrHawobYpZRyE1kF9onzIydNIe9jmdNfhlB2fGbaLvXC0.svg" alt="" /></p> <h3 id="VPN 側の動作"><a href="#VPN+%E5%81%B4%E3%81%AE%E5%8B%95%E4%BD%9C">VPN 側の動作</a></h3> <p>一方の ソフトウェア VPN では、 VPN の有効化と同時に、 ホスト PC のルーティングを片っ端から書き換えている。</p> <p>具体的には、 VPN の 仮想 NIC に対して短いメトリックとなるよう、 ルーティングを書き加える。<br /> それによって、全ての通信が VPN トンネルを通るようになっているのだ。</p> <p><img src="https://www.plantuml.com/plantuml/svg/VP4nRy8m48Lt_ufJkhG3IEs86AYWQYjHX4G50s4miKaid7DqTg2eeh-zDYQ2Hg9Pubo-z-xvRc0T9rUNcjcjmeeJBo7Z9E2R0QmD2Kb3emt1MEM5UoL-O4V653f96vv9a5_-X5mpHZ9p77Cj8Napri52eJ1x2zDX4ioYQp9vZv_-kPWaq-9WLSOrlBWY0MwXGfMreRaYLqScnOqXc4yd9tXNOPlTUKWIIWVt8xdXjNOmsokN5Gyf-dSHqasUFwFSzofs_pWiPkCRihtL9rqp1UXtEfViuG3zd-KTIR4AANlWQaIf5UPNG7TPA24ahhhdA3r8CGrzRaDDOs_g_pN2TYbWrsP7vkrujkLvMDAXajIPDzj08yACF-BToiSsxeVmz9Vr5HWfwqYjQwSCdfI-emWr4_NdO64kqRI95IfNy94D98gwrBy0.svg" alt="" /></p> <h2 id="そして悲劇が起こる"><a href="#%E3%81%9D%E3%81%97%E3%81%A6%E6%82%B2%E5%8A%87%E3%81%8C%E8%B5%B7%E3%81%93%E3%82%8B">そして悲劇が起こる</a></h2> <p>その結果、どうなるか。</p> <p>ホスト PC から ゲスト VM (あるいは WSL ディストロ) のプライベート IPアドレス へ通信しようとすると、 <strong>VPN のトンネリング側にルーティングされてしまう</strong>。</p> <p>例えば、 WSL2 から ホストPC へ DNS の問い合わせ (クエリ) を受けると、 そのレスポンスが明後日の方向にルーティングされてしまう。<br /> これが、 <strong>ゲスト側で DNS による名前解決ができなくなる原因だ。</strong></p> <p><img src="https://www.plantuml.com/plantuml/svg/ZP51ZzCm48Nl_XMZS853Lu9Z5AqMRH4WbQXGr1wQ7bnxcbXrnf7jj4Ie_7Ri9X0QLCGXYZFvtfldcIVdkVLjhPaxAcguvJK8RYLyPm1xOoNQPwEDXOKgA__UyevT65FaqHwuGC1luKHSCsPHU4wbHaW-6ETXeqYQiuFbSnBDUjSa_pXy0emcoRBgd19SmpjV9S0TDAJ455gh4BHd2ZeO2-jbVeLF3KtPKu3G4dfuESS3RxM7rLbvKRqgABohc2v_-xMNXrxLwHyEczNYZkpiTDJzdW9aizcOFHuW-x5zOL7kOieKV4k4Mb7v1_2mhPIKIBk78KeA1HMnppreR1nCmxzROIRYmjBGz37RFyxp5Nn1rnXoE9L4c__GNCBJS77aPTnjrw2ThNyjaOoCg_dKZwH-FSN3xDxSig42S-MyLVlMAqDNPGWYOytq-k4-SPpHD8M_ytrkqNO36TGH7Ltk2oxi2KcsjVu9.svg" alt="" /></p> <p>この問題を回避するため、 前述のスクリプトでは、 ルーティングテーブルを書き換えて、 ゲスト VM のアドレスに対して、 VPN の 仮想NIC のメトリックを長くすることで、 VPN にルーティングされないようにしているわけだ。</p> <p>本当は、 VPN へのルーティングを消してしまいたいところなのだが、 ルーティングを消しても、 VPN クライアントが即座にルーティングを復活させてしまうため、 メトリックを長くするだけにとどめている。</p> <p>なお、 GlobalProtect でも、書き換えたメトリックを戻される対策がされたようだが、 インターフェースメトリックを書き換えたり、 短期間に何度も書き換え直したりすると、メトリックを戻すことを諦めてくれる。<br /> このため、上記のようなコードになっている。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/microsoft/WSL/issues/5068#issuecomment-683917384">WSL2 , problem with network connection when VPN used (PulseSecure) · Issue #5068 · microsoft/WSL | GitHub</a><br /> ちなみに、 上記の Issue ではもっと単純に、 WSL2 へのメトリックは 1 にして、 全ての VPN 関係のルーティングのメトリックを 4000 くらいに延ばすワークアラウンドが紹介されている。<br /> しかしそれだと、本来 VPN 経由にしなくてはならない通信までもが VPN 通らなくなったりする場合があって、 VPN を使わせるポリシー上マズい。<br /> このため、上述のように、 必要な ネットワークアドレス だけに絞ってメトリックを書き換えている。</p> <h3 id="別解"><a href="#%E5%88%A5%E8%A7%A3">別解</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://docs.microsoft.com/ja-jp/windows/wsl/troubleshooting#bash-loses-network-connectivity-once-connected-to-a-vpn">Microsoft Docs 上の WSL のトラブルシューティング</a> では、 WSL の <code>/etc/resolv.conf</code> の DNS を、 ホストPC の WinNAT ではなく VPN のトンネリング先のネットワークの DNS に書き換える方法も掲載されている。</p> <p>……が、 これを行うと、ゲスト側の DNS の名前解決こそできるようになるものの、 依然 ホストPC から ゲストOS へのパケットが届かない問題は解消されない。<br /> このため、 ゲストで立てたサーバーに、 ブラウザでアクセスしたり、 ssh 等でログインしたりと言ったことはできないままだ。</p> <p>更に、イントラネット内で別途 DNS を運用していた場合、イントラネット内の名前解決ができなくなる問題もある。</p> <p>このため、この DNS を書き換える方法は、望ましい解決方法とは言えない。</p> <h2 id="改訂履歴"><a href="#%E6%94%B9%E8%A8%82%E5%B1%A5%E6%AD%B4">改訂履歴</a></h2> <ul> <li>2023-02-22: <ul> <li>コードの一部でエラーが発生していた部分を修正。</li> </ul></li> <li>2023-02-14: <ul> <li>各社のメトリック書き換え対策に対し、 GlobalProtect 向けにコードを変更し、 AnyConnect 向けには打つ手なしとなったことを追記。</li> </ul></li> <li>2021-04-04: <ul> <li>Windows Sandbox などでも問題となる旨追記</li> <li>いくつかの VPN ソフトについての設定例を追記</li> <li>Microsoft Docs 記載の改善方法について追記</li> </ul></li> <li>2021-01-28: <ul> <li>仮想ネットワーク上に DHCP は存在しないのに、 DHCP の存在がすると誤記があったので修正。</li> <li>スクリプトで Hyper-V の仮想スイッチをさかす際に、 NIC 名ではなくて、ネットワークアダプタの接続名で探すように変更。</li> </ul></li> </ul> advanceboy tag:crieit.net,2005:PublicArticle/16456 2021-01-01T05:43:33+09:00 2021-01-01T11:29:59+09:00 https://crieit.net/posts/Raspberry-Pi-5fee37f5d34e8 Raspberry Pi で作るネットワークエミュレータ <p>明けましておめでとうございます。</p> <p>この記事は、 <a target="_blank" rel="nofollow noopener" href="https://qiita.com/advent-calendar/2020/raspberry-pi">Raspberry Pi Advent Calendar 2020</a> 24日目の記事だ。<br /> <strong>…遅刻すぎるのもいいとこだわ。</strong></p> <hr /> <p>さて、ネットワーク回りの仕事をしていると、意図的にネットワークの遅延やパケロスを発生させて、検証したくなる状況がままある。</p> <p>対象のサーバーにネットワークを遅延させるようなモジュール入れるようなやり方も考えられるが、もっと手軽に、 LAN ケーブルの間に挟むだけで、そこを通る通信が全て遅延するみたいな、そんな機材が欲しくなる。</p> <p>もちろん、そのような需要があれば、それに応える製品があるわけで、それらは一般的に「ネットワークエミュレータ」として売られている。<br /> しかし、高いものでは数百万を軽く超え、安くても数万円はするものばかりだ。</p> <p>なんか安く作れないかなぁ…<br /> <strong>Raspberry Pi あたりで。</strong></p> <p>…ということで、 Raspberry Pi 4 を使って、遅延とパケロスを制御できる、お手軽ネットワークエミュレータを作ってみよう。</p> <h2 id="先駆者"><a href="#%E5%85%88%E9%A7%86%E8%80%85">先駆者</a></h2> <p>そもそもなのだが、そのものズバリなことを実践している先駆者様がいらっしゃった。</p> <p><a target="_blank" rel="nofollow noopener" href="http://dsas.blog.klab.org/archives/raspi-netem1.html">ラズパイで作るネットワークエミュレータ(前編) </a></p> <p>この記事の Raspberry Pi には、小型ドットマトリックス LCD ディスプレイや、様々な物理キーが GPIO に繋がっていて、 THE IoT という仕上がりになっている。</p> <p>かっこいいと思う。<br /> <strong>でも、電子工作するのめんどくさいよね。</strong></p> <h2 id="GUIで手っ取り早く作る"><a href="#GUI%E3%81%A7%E6%89%8B%E3%81%A3%E5%8F%96%E3%82%8A%E6%97%A9%E3%81%8F%E4%BD%9C%E3%82%8B">GUIで手っ取り早く作る</a></h2> <p>そんな複雑 (…というほど複雑でもないけど) な電子工作しなくても、 RasPi にタッチパネルディスプレイつけちゃえばいいじゃん。<br /> …ということで、 Amazon で割と評判のよい、 OSOYOO の 2,980円 タッチスクリーン付き LCD を取り付けて、めっちゃ簡単な UI をつくってみよう。</p> <p><a target="_blank" rel="nofollow noopener" href="https://amzn.to/3punHkf">OSOYOO(オソヨー) HDMI 3.5 インチ LCD ディスプレイ IPS モニター IPSタッチスクリーン 1920x1280ハイビジョン Raspberry Pi 4 3 2 Model B に対応 (3.5" HDMI LCD+クリアケース) </a></p> <p>もはや、 <strong>IoT 感を感じるのが難しく</strong>なってしまっているな……</p> <p>構成は、以下の図のように有線 LAN 2つ をブリッジ接続させる。</p> <p><img src="https://www.plantuml.com/plantuml/svg/TP9DRi8m44RtFiKKiMWNRWXjDrLKqN81n1e96SS1IydOjPqYLB5fxj13z0IzJovIs_n04CrgvlcDyzdoo3fcN5sLv4OYB-jSGEPgpNBpa71LLGfVhgmK2XrbQs5L9UXJOfZL2s7CPgxbkQwAGdAHZ1LoePrDh30V7ioPrgNapCcmkn7SCLoM0dfJLJjXUi0ic5WILBddat4QeUOfaUXvmRZ74A5T7wtXtXgItJXGUbhE-fsOCvmUMfX8U7oBiq6Hy4d0VsV1skQxRNxQfcc_Vk5sOGPtqVR5thtmXLiDeX6AVuJq8AH7mPyFGk83y2NGxXwXWVlkM6Y0XdD7jBrCd_MlNVmC9nktKWYlMk_kRREi9Jd-9AEqYz8JUWR7uJsNbiyml1A6kILRCXAO-wVq1m00" alt="" /></p> <p>これなら、 Raspberry Pi OS の標準の機能だけで実現できそうだ。</p> <p>なお設計的には、 Raspberry Pi が 2, 3, 4 どれでも機能するとは思うが、 1000BASE-T や USB 3.0 のポートを持っている Raspberry Pi 4B がオススメ。</p> <p>RasPi 4B には 1つ しか 有線LAN ポートがないので、適当にもう一つ USB 有線LAN アダプタをつける必要がある。<br /> Gigabit 対応のアダプタが良いだろう。</p> <h3 id="Raspberry Pi のセットアップ"><a href="#Raspberry+Pi+%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97">Raspberry Pi のセットアップ</a></h3> <p>まず、 <a target="_blank" rel="nofollow noopener" href="https://www.raspberrypi.org/software/operating-systems/">Raspberry Pi OS with desktop</a> イメージを SD カードに焼く。<br /> "and recommended software" <strong>ではない</strong> ほうでかまわない。</p> <p>今回は、 <code>2020-12-02-raspios-buster-armhf.img</code> のバージョンのイメージで試した。</p> <p>OS イメージを焼くツールは何でも良いが、 <a target="_blank" rel="nofollow noopener" href="https://www.balena.io/etcher/">balenaEtcher</a> あたりが良いだろう。</p> <p>Raspberry Pi OS が起動したら、以下の手順に従って、タッチスクリーンのドライバーが動くようにしておく。<br /> <a target="_blank" rel="nofollow noopener" href="http://osoyoo.com/ja/?p=4244">http://osoyoo.com/ja/?p=4244</a></p> <h3 id="Raspberry Pi の2つの有線NICでブリッジ"><a href="#Raspberry+Pi+%E3%81%AE2%E3%81%A4%E3%81%AE%E6%9C%89%E7%B7%9ANIC%E3%81%A7%E3%83%96%E3%83%AA%E3%83%83%E3%82%B8">Raspberry Pi の2つの有線NICでブリッジ</a></h3> <p>まず接続されている、 NIC のインターフェイス名を確認する。</p> <pre><code class="console">$ ip address show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 4: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 </code></pre> <p>Raspberry Pi の 有線LAN インターフェイスの場合は、 eth0, eth1... と名前がついていくため、 ここでは eth0, eth1 がブリッジ接続させる対象だとわかる。</p> <p>続いて、 <code>ip</code> コマンドを使って、ブリッジの作成する。</p> <pre><code class="console">$ sudo ip link add br0 type bridge $ sudo ip link set dev br0 up $ sudo ip link set dev eth0 promisc on $ sudo ip link set dev eth0 up $ sudo ip link set dev eth0 master br0 $ sudo ip link set dev eth1 promisc on $ sudo ip link set dev eth1 up $ sudo ip link set dev eth1 master br0 </code></pre> <p>※: ip link コマンドで設定したブリッジ設定は、 Raspberry Pi を再起動するとリセットされる。 起動時に自動設定させたければ Raspberry Pi OS であれば <code>/etc/network/interfaces.d/</code> 以下に、 Ubuntu であれば <code>/etc/netplan/</code> 以下に、 設定を書いておけば良いはず。</p> <p>この状態でブリッジが意図したとおり機能しているか、 PC1, PC2 を接続して iperf で速度を測ってみる。</p> <pre><code>> .\iperf3.exe -c PC2 Connecting to host 192.168.1.222, port 5201 [ 4] local 192.168.1.111 port 59582 connected to 192.168.1.222 port 5201 [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.00 sec 53.6 MBytes 449 Mbits/sec [ 4] 1.00-2.00 sec 56.9 MBytes 478 Mbits/sec [ 4] 2.00-3.00 sec 58.0 MBytes 486 Mbits/sec [ 4] 3.00-4.00 sec 57.1 MBytes 479 Mbits/sec [ 4] 4.00-5.00 sec 57.9 MBytes 487 Mbits/sec [ 4] 5.00-6.00 sec 58.6 MBytes 491 Mbits/sec [ 4] 6.00-7.00 sec 57.6 MBytes 483 Mbits/sec [ 4] 7.00-8.00 sec 55.0 MBytes 462 Mbits/sec [ 4] 8.00-9.00 sec 56.5 MBytes 474 Mbits/sec [ 4] 9.00-10.00 sec 58.9 MBytes 492 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth [ 4] 0.00-10.00 sec 570 MBytes 478 Mbits/sec sender [ 4] 0.00-10.00 sec 570 MBytes 478 Mbits/sec receiver iperf Done. </code></pre> <p>1Gbps 出てないが、まぁこんなもんだろう。</p> <h3 id="qdisc 制御 GUI コード"><a href="#qdisc+%E5%88%B6%E5%BE%A1+GUI+%E3%82%B3%E3%83%BC%E3%83%89">qdisc 制御 GUI コード</a></h3> <p>Raspberry Pi 上のブリッジを通過して通信が通るようになったので、お次は通過するパケットに遅延やパケロスを発生させるための UI を作る。</p> <p>UI 上でポチポチした値を基に、 <code>tc qdisc</code> コマンドを実行するような、単純な仕組みで良いだろう。<br /> Python と tkinter で適当に仕上げてみる。</p> <p><a target="_blank" rel="nofollow noopener" href="https://gist.github.com/advanceboy/b2bb75b1b1b95d7cd2af15c199c4a5b5">https://gist.github.com/advanceboy/b2bb75b1b1b95d7cd2af15c199c4a5b5</a><br /> <gist src="https://gist.github.com/advanceboy/b2bb75b1b1b95d7cd2af15c199c4a5b5.js"></gist></p> <p>試しに動かしてみた動画がこちら。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2021/01/pi-nw-emu-ping.mp4">https://aquasoftware.net/blog/wp-content/uploads/2021/01/pi-nw-emu-ping.mp4</a></p> <p>UI上で設定した値に応じて、 ping の遅延とパケロスが発生しているのが、一目瞭然だろう。</p> <p>遅延を 100ms (RTT 200ms) としたときに、先ほどと同じ組み合わせで iperf を動かしたところ、以下のようになった。</p> <pre><code>> .\iperf3.exe -c PC2 Connecting to host 192.168.1.222, port 5201 [ 4] local 192.168.1.111 port 59582 connected to 192.168.1.222 port 5201 [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.03 sec 256 KBytes 2.04 Mbits/sec [ 4] 1.03-2.03 sec 0.00 Bytes 0.00 bits/sec [ 4] 2.03-3.00 sec 512 KBytes 4.30 Mbits/sec [ 4] 3.00-4.00 sec 384 KBytes 3.14 Mbits/sec [ 4] 4.00-5.01 sec 640 KBytes 5.23 Mbits/sec [ 4] 5.01-6.01 sec 384 KBytes 3.14 Mbits/sec [ 4] 6.01-7.01 sec 512 KBytes 4.18 Mbits/sec [ 4] 7.01-8.01 sec 384 KBytes 3.14 Mbits/sec [ 4] 8.01-9.00 sec 640 KBytes 5.31 Mbits/sec [ 4] 9.00-10.00 sec 384 KBytes 3.14 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth [ 4] 0.00-10.00 sec 4.00 MBytes 3.35 Mbits/sec sender [ 4] 0.00-10.00 sec 3.95 MBytes 3.31 Mbits/sec receiver iperf Done. </code></pre> <p>輻輳制御が働いて 3.35Mbps しか速度が出なくなっていることがわかる。</p> <p>…とまぁ、こんな感じで目的を達成することができた。</p> <h2 id="余談"><a href="#%E4%BD%99%E8%AB%87">余談</a></h2> <h3 id="Raspberry Pi に Raspberry Pi OS 以外の OS を入れる場合"><a href="#Raspberry+Pi+%E3%81%AB+Raspberry+Pi+OS+%E4%BB%A5%E5%A4%96%E3%81%AE+OS+%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B%E5%A0%B4%E5%90%88">Raspberry Pi に Raspberry Pi OS 以外の OS を入れる場合</a></h3> <p>Raspberry Pi OS では、標準だと sudo コマンドにパスワードが不要な設定が visudo にされている。<br /> 一方、 Ubuntu など他の多くのディストリビューションではそうなっていない。</p> <p>他の OS で動かしたい場合、 visudo で <code>/usr/sbin/tc</code> コマンドをパスワードなしで実行できるように設定しておこう。</p> <h3 id="OSOYOO のタッチスクリーン付き LCD について"><a href="#OSOYOO+%E3%81%AE%E3%82%BF%E3%83%83%E3%83%81%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E4%BB%98%E3%81%8D+LCD+%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">OSOYOO のタッチスクリーン付き LCD について</a></h3> <p>先ほど挙げた OSOYOO のタッチスクリーン付き LCD は、 この価格帯のものなので過度な期待は禁物ではあるものの、 少なくともこの用途にはコスパ抜群だった。</p> <p>クリアケース付きのもののケースは、正直このクオリティだと +1,000円 分に達していないレベルのものだが、 LCD ディスプレイにちょうど合うサイズだったので、払ってしまっても損はないと思う。<br /> ただし、 Raspberry Pi 4B には端子の穴の位置が合わないため、サイドのアクリルが取り付けられなかった。</p> <p>また、同梱されていた紙のマニュアルに書かれていたリンクでダウンロードしたドライバーが古かったらしく、 最新の Raspberry Pi OS に入れたら、 タッチ位置が 90° 回転して認識されるトラブルに遭遇した。<br /> 以下のオンラインマニュアルのリンク先の、最新(?) のドライバーを使うようにしたら、上記のタッチ位置の問題は解消されたので、参考まで。<br /> <a target="_blank" rel="nofollow noopener" href="http://osoyoo.com/ja/?p=4244">http://osoyoo.com/ja/?p=4244</a></p> <p>同梱されていた Raspberry Pi 4B 用の HDMI - microHDMI コネクターが壊れていたのだが、 サポートにメールしたら即返事が来て代替品送ってくれたので、好印象。<br /> 代替品が届くまでは、家にあった変換ケーブルで我慢。</p> <p>一方で、タッチパネルの「ドライバー」とやらが、インストールスクリプトの中身をよく見ると、 何故かカーネルごとゴッソリ置き換える仕組みになっている。<br /> HW のドライバーという時点で、提供元を信頼しないとどうしようもないのだが、カーネルごと置き換えられるのにはちょっとモニョる。</p> <p>2020年末現在、 Raspberry Pi OS の Linux カーネルは 5.4系 なのだが、 このドライバーでカーネルが置き換えられると、 Linux カーネルが 4.19系 に落ちる点は注意。<br /> とりあえず、 <code>2020-12-02-raspios-buster-armhf</code> にインストールした限りは、問題なく動いていそうではあるが。</p> <p>マニュアルにも書いてあるが、 Kernel を更新すると正常に動作しなくなる可能性があるので、 apt の更新大将から Kernel を除外すると良いようだ。<br /> このため、常用するマシンにはオススメしない。</p> advanceboy tag:crieit.net,2005:PublicArticle/15559 2019-11-25T04:32:35+09:00 2019-11-25T04:53:32+09:00 https://crieit.net/posts/VM ルータを経由すると仮想ブリッジ接続の VM にアクセスできない? <p>今回は、ネットワークの話。</p> <p>解決してみれば割としょうも無いトラブルで、時間を浪費してしまったので、自戒の意味を込めて記事にしておく。</p> <h2 id="サブネット外から ping が通らない"><a href="#%E3%82%B5%E3%83%96%E3%83%8D%E3%83%83%E3%83%88%E5%A4%96%E3%81%8B%E3%82%89+ping+%E3%81%8C%E9%80%9A%E3%82%89%E3%81%AA%E3%81%84">サブネット外から ping が通らない</a></h2> <p>ある日、 ホストPC の NIC とブリッジ接続されている VM に、 サブネット外からアクセスできなくなってしまった。</p> <p>構成を図にすると、以下のような感じ。<br /> (あまり UML図 に明るくないので、書き方がヘタクソだったり本来の意味と違う記号の使い方をしている点は大目に見て欲しい。)</p> <p><a href="https://crieit.now.sh/upload_images/b16c4bd42afd117d10973821da5dac345ddad9df7b863.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b16c4bd42afd117d10973821da5dac345ddad9df7b863.png?mw=700" alt="data:application/gzip;base64,H4sIAAAAAAAEAIVTPU/DMBDdI+U/nLIihziUAhVC5UOCDmWgqAtlMM61jZTYleOIAbW/Hcdy6qQtwkt8757f3dkv40ozpeuyCIMw4IWsM4gmQqMSqCNgFeQuMFkptJIFRG+yNpjNKrsNA4VcM7EqECJ6lcZ0GA/SODlPBxH8hAGYxWW5kQKFhuhFVhqmjK9zgVZlwy3kmM2yVZeMo2O/Th4tE/W6iT2xU3g+raKuxoHO6/27lRBM9zm+s4PDBwKmNm2boMfMzoDzKTzXWGk3nN3/J5200kmfue2H7gKAfKzzLEPxSY4HMoDPn5BsENjtCa7BEZSoVc6BLgS9ad7wOr4cxmn/rCPDzt7CCPxr0+HpTnct9UHl2Qo9yU22PfKHswZIsRAzViLM6q/WjhtuGtqeNNzFn4brCj7lyyWqBu6pUqvamh1uCdl72ySB3Hmr2y+QTH4LcuYdaTpzYOLBMBijyMzv9QsMZU+SaAMAAA" /></a></p> <p>同一サブネット内 (図の "Machine on Same Subnet") から 172.16.42.16 を叩くと VM ゲストに到達するのだが、 サブネット外 (図の "Machine on Different Subnet") からだと ping すら通らない。</p> <p>以前は同じ構成で、サブネット外から繋がっていたはずだ。</p> <p>ちょうど直前に、ネットワーク機器のメンテナンスがあったため、 そちらで IPフィルタの動作がおかしくなったのではないかと疑ってしまった。<br /> しかし、繋がらなくなった直接的な原因は、 VM Gurest 側にあった。<br /> このため、答えにたどり着くのに時間がかかってしまった。</p> <h2 id="アクセスできなかった原因"><a href="#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E5%8E%9F%E5%9B%A0">アクセスできなかった原因</a></h2> <p>上の図で若干答えを示唆してしまっているが、 VM Guest に繋がっているもう一つの仮想ネットワークアダプタ (図の "eth0") が原因だ。</p> <p>この eth0 は NAT 経由でホスト側のネットワークに繋がっていた。<br /> そして、 eth0 の metric が、 eth1 よりも短くなる設定に変更してしまっていたのだ。<br /> (何故そんな繋ぎ方をしているかというと、 ホスト PC の IP として通信させたい事情があったから。 理由は察して。)</p> <p>構成を図にしてみると、以下のような感じ。</p> <p><a href="https://crieit.now.sh/upload_images/07d3ffeeebe96fb9c8cc4f0e4da132b25ddad9e7cd381.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/07d3ffeeebe96fb9c8cc4f0e4da132b25ddad9e7cd381.png?mw=700" alt="data:application/gzip;base64,H4sIAAAAAAAEAIVTy07DMBC8R8o/rHxFCXEo5SGEykOCHsqBop56Mc62jZTYleOIA2q/HceycdIW4Uu849nZXXsyaTRTuq2rOIojXsm2ADIVGpVATYA1ULrAnEqhlayAvMvWYPZU2W0cKeSaiXWFQOhVntJxOsrT7DwfEfiOIzCLy3orBQoN5FU2GmaMb0qBVmXLLeSY3bJVV4yjY79NnywT9aaLA7FXeDFrSF/jQOft4cNKCKaHnNDZQfKBgKlNfRP0mNkbcDGDlxYb7Yaz+/+kMy+dDZm7YeguAJLkeBADQHJCokNg7xu5hRq1KjnQpaA33Vtdp5fjNB/mOLJJ66YNOZlJ+n1gOj7d3N5nPaqyWGMguWF2R5ZwbgAplmLOaoR5++kduOWmt91Jj1386bG+4HO5WqHq4IEqtare33BnrtTb2RxCch/cbb+QFPJLJGfBhKYzB2YBjKMJisL8UT95NzD7WwMAAA" /></a></p> <p>このような構成だと、 VM Guest からの通信は全て、 より『距離が近い』と見做される eth0 と NAT 経由で行われるようになる。</p> <p>通常、ルータや L3スイッチ などが、 IPアドレス と MACアドレス の対照表である ARP テーブルに載っていない IP のパケットを受け取った場合、 サブネット内に ARP リクエストパケットをブロードキャストして、対象の MACアドレス を探しに行く。<br /> しかし このサブネットの間を取り持っているルータは、どうも ARP テーブルに載っかっていない IP へのパケットを全て破棄してしまうらしい。<br /> (レイヤ3 の知識が不十分なので、正確な説明ではないかも知れないが、雰囲気だけでも伝われば。)</p> <p>つまり、 VM Guest から eth1 を経由してルータに到達する通信がなかったために、 ルータが eth1 の MACアドレスを知らず、パケットが全て破棄されてしまっていたようだ。</p> <p>以前通信できていた頃は、 eth0 より eth1 からの通信の方が metric が近かったため、 eth1 からルータを経由してインターネットへ向かう通信が存在し、 ルータが eth1 の MACアドレス を知っていたため、 サブネット外からの通信がちゃんと eth1 に届いていたのだろう。</p> <p>一方、同一サブネット内の "Machine on Same Subnet" からの通信は、この Machine が直接 ARP リクエストパケットをブロードキャストして、 eth1 の MAC アドレスを見つけられるため、 metric の距離にかかわらず通信できていたのだと思われる。</p> <h2 id="解決策"><a href="#%E8%A7%A3%E6%B1%BA%E7%AD%96">解決策</a></h2> <p>VM Guest の eth1 から通信が外に出るように metric の設定を変更して、 適当なパケットを投げたところ、 サブネット外から eth1 の IPアドレスに通信ができるようになった。</p> <p>ルータがサブネット内の未知の IPアドレス へのパケットを全て握りつぶすというのは、盲点だった。。。</p> advanceboy