Ethernetのセカンドポートの有効な活用法

 最新のPC本体やマザーボードを購入すると、Ethernetポート2基ないしEthernetポート/Wi-Fiポート各1基という2つのネットワークインタフェースが付いてくるケースも多くなっている。こうしたセカンドポートの標準装備というのも、メーカ側にすれば製品カタログの仕様欄に記載する項目を増やす安価な方法なのかもしれないが、ユーザ側からすれば実際何に使用すればいいのか分からないというのが実状だろう。しかしながらあなたがLinuxユーザであれば、具体的な使い道はいくつも存在しているのだ。

 ごく安易な発想をすると、セカンドポートに2本目のEthernetケーブルを接続すれば回線速度を2倍にできそうなものだが、実際にはLinuxのネットワーキング用サブシステムに双方のアダプタを認識させた上で、2つのポートでトラフィックの送受信をさせる方法をOSレベルで指定しなくてはならない。後者の設定に関しては複数の方法が存在し、実のところ本稿もそのための手法を説明するために書き起こしたものである。

 この場合に取りうるオプションは複数存在するが、それらの選択肢については、ネットワークデバイス間でのトラフィックルーティングや透過的なリンクなど、ネットワークに接続されたデバイス(コンピュータ、ルータ、その他の機器)間でどのような形態の交信を許すかという観点で分類することができる。ただし最もシンプルな状況を確立するには複雑なセットアップが必要というケースも珍しくはないので、最終的にどのオプションを利用するかは、すべての候補を検討し終わってから選択すべきだろう。

ボンディング

 ネットワーク的な観点から最もシンプルなオプションはチャンネルボンディング(channel bonding)ないしポートトランキング(port trunking)と呼ばれる運用法で、これはコンピュータに装備された2つのインタフェースを1つのインタフェースとして振る舞わせる技術であり、実際に他のアプリケーションからはそのように見えるようになるのである。

 2つのインタフェースを論理的に1つにまとめることは、ロードバランス(負荷分散)やフォールトトレランス(耐障害性)の能力を与えてくれる。トラフィックをどちらのインタフェースから送出するかはOSが選択できるし、一方に障害が発生した場合は他方へフェイルオーバさせることもできる。あるいはDSLと光ファイバといった複数のワイドエリアネットワーク(WAN)接続の間でトラフィックを分散させることも可能であり、こうしたロードバランスのペアとしてはダイアルアップも使えるし、あるいは不用心な隣人の使用しているWi-Fiに便乗するといった手口もありかもしれない。

 2つのEthernetインタフェース間でのボンディングを行わせるには、各自のカーネル用にコンパイルされたボンディング用モジュール(最新のディストリビューションであれば通常そのまま使用できるはずである)およびifenslaveパッケージ(標準ユーティリティの1つではあるがディストリビューションによってはRPMないしAPTリポジトリからのインストールが必要)を取得する必要がある。

 一般的に2つのポートを装備したマザーボードの場合、Ethernetアダプタはeth0およびeth1という名称にされているので、ここでの設定例でもそれに従うことにしよう。ifenslaveをインストールしたら次に「sudo ifdown eth0」および「sudo ifdown eth1」を実行して、これら2つのEthernetアダプタをオフラインにしておく。次にmodprobeを用いて、ボンディング用モジュールをLinuxカーネルに読み込ませる。このモジュールについてはmodeおよびmiimonという2つのオプション指定が重要な意味を持っており、modeはボンドの種類を(ラウンドロビンやフェイルオーバなど)、miimonはリンクに対する障害検出の頻度(単位はミリ秒)を規定する。例えば「sudo modprobe bonding mode=0 miimon=100」という指定は、2つのEthernetアダプタ間で交互にネットワークパケットの送信を行うというラウンドロビン(round-robin)モードを設定している。またmiimon値を100とするのは標準的な指定であり、必要であれば各自のネットワークに適した値に調整すればいい。

 実際のボンド作成(ここでは便宜上bond0と呼ぶことにする)を行うには「sudo ifconfig bond0 192.168.1.100 up」を実行してボンドへのIPアドレス割り当てを実行した後、「ifenslave bond0 eth0」および「ifenslave bond0 eth1」を実行して、物理Ethernetインタフェースに接続をさせる。

 ここで用いたラウンドロビンは、2つのアダプタ間で行うロードバランス方式としての汎用的なモードであり、この場合は一方に障害が発生しても他方を使ってリンクを維持し続けることができる。その他にもmodeオプションには6つのモードが用意されており、これらはそれぞれ次のような特徴を備えている。

  • モード1 アクティブバックアップ(active backup):一方のアダプタのみを使用し、そこでの障害発生時には他方に切り替える。
  • モード2 バランスXOR(balance XOR):送出するパケット群をアダプタ間で分割することでトラフィックのロードバランスを試みるが、特定の宛先に関しては可能な限りどちらか一方のアダプタを使用し続けるようにする。
  • モード3 ブロードキャスト(broadcast):トラフィックの送出をすべてのインタフェースで行うようにする。
  • モード4 ダイナミックリンクアグレゲーション(dynamic link aggregation):複雑なアルゴリズムを用いて、速度その他の設定を基に複数のアダプタを1つにまとめる。
  • モード5 アダプティブトランスミットロードバランシング(adaptive transmit load balancing):現在の状況を基にして、送出するトラフィックを臨機応変に分散させる。
  • モード6 アダプティブロードバランシング(adaptive load balancing):これもモード5と同様の処理を行うがARPアップデートを送信することで、受信する側のトラフィックについてのロードバランスも試みる。

 ホームユースの場合、こうした複雑なモードを使用する機会はほとんどないだろう。そうではなく、多量のネットワークトラフィックに対する管理を行いたいという場合は、ボンディング用ドライバについてのドキュメントを参照して頂きたい。なお一般のユーザがボンディングを使用することで得られるものは、ロードバランスやフォールトトレランスといった能力であり、リンク速度に関するメリットはそれほど期待できない。例えば2つのWANリンク間でボンディングを施すと、ロードバランスやフォールトトレランスを行えるようにはなるが、個々の接続(Webページ用のHTTPリクエストなど)はどちらか一方のルートを使うだけなので、アップストリーム側のスループットが2倍になる訳ではないのである。

ブリッジング

 先に見たボンディングは、同一マシンの有す2つのネットワークアダプタを論理上1つのアダプタとして振る舞わせるというソリューションである。その他のソリューションとしては、新規ないし異なるサービスをローカルネットワークに接続する際に2つのアダプタを個別に使用するという運用法も存在する。

 例えばブリッジングは、2つのネットワークアダプタを単純なハブで接続されているかのようにリンクさせて、両者の間でEthernetフレームを自由に流すという技術である。この場合一方のインタフェースで受信されたトラフィックはすべて他方からも流されるようになる。

 ブリッジのセットアップではコンピュータ本体をネットワークにまったく関与しない形にすることもでき、その場合このコンピュータは、機能に比して高額なEthernetリピータとして使用されることになる。しかしながらポート間でトラフィックをブリッジさせると同時にインターネットへのアクセスも行うというのが通常の使用法であろう。いずれにせよそのための準備は特に難しいものではない。

 ブリッジングを行うために必要となるbridge-utilsパッケージは、最近のLinuxディストリビューションであれば標準コンポーネントの1つとして用意されているはずで、これにはbrctlというコマンドラインユーティリティが含まれている。

 2つのネットワークアダプタ間でブリッジ作成を行うには、まずifdownコマンドにて双方のアダプタをオフラインにしておく。ここで想定しているeth0/eth1というペアの場合は、コマンドラインから「sudo ifdown eth0」および「sudo ifdown eth1」を実行すればいい。

 次に「sudo brctl addbr bridge0」によるブリッジ作成を行う。ここで使用しているaddbrは“仮想的”なネットワークアダプタをbridge0という名称で新規に作成するためのコマンドである。その後addifを用いてブリッジを物理的なネットワークアダプタに接続させる必要があり、ここでの設定例では「sudo brctl addif bridge0 eth0」で1つ目のアダプタ、「sudo brctl addif bridge0 eth1」で2つ目のアダプタを接続させればいい。

 以上の準備が終了したら、物理的に存在する通常のEthernetカードの場合と同様に、bridge0という仮想的なアダプタの有効化をしなければならない。IPアドレスの割り当てについては、「sudo ifconfig bridge0 192.168.1.100 netmask 255.255.255.0」といったコマンド指定により静的な割り当てをすることもできるが、「sudo dhclient bridge0」によってDHCPから必要な設定を取得させるようにしてもいい。

 すべてが問題なく設定されていれば、Ethernetポートを介してコンピュータ、ハブ、スイッチ、その他のデバイスを必要な数だけ接続させることができ、これらのデバイスどうしは相互に通信できるようになっているはずである。ただしこの利用法については、多量のトラフィックを扱う環境の場合、2つのアダプタで行うEthernetフレームのやりとりにコンピュータ処理能力の多くが費やされるというデメリットも潜んでいる。

ファイヤウォールおよびゲートウェイ

 多量なトラフィックが通過するタイプのコンピュータの場合、個々の宛先アドレスを基にしたフィルタリングを施したり、頻繁にリクエストされるWebページをキャッシュするといった、より有用な処理をOSに施させることもできる。また光ファイバないしDSL接続においてアップストリーム側とローカルネットワークとの間にデュアルポートコンピュータを配置すれば、インターネット接続共有用の簡易的なゲートウェイや、ネットワークインタフェース間を通過するパケットを監視するファイヤウォールとして利用できるはずだ。

 最初に行うべき準備作業は、双方のネットワークアダプタを有効化してIPアドレスの割り当てを行うことだが、この場合はそれぞれ異なるサブネットのIPアドレスを割り当てておくという点が重要である。1つの設定例としては「sudo ifconfig eth0 192.168.1.100 netmask 255.255.255.0」および「sudo ifconfig eth1 192.168.2.100 netmask 255.255.255.0」として、eth0は192.168.1.xのアドレス空間に、eth1は192.168.2.xのアドレス空間に属すようにしておけばいい。この場合はその後ネットワークに他のデバイスを追加する際にも、こうした使い分けを維持していくことが肝要である。

 インターネット接続用のアダプタとLAN接続用のアダプタとの間でパケット転送を行わせるには、LinuxカーネルにIPフィルタリング用のサブシステムを構成するiptablesというツールを使用すればいい。例えば「sudo iptables -A FORWARD --in-interface eth1 --out-interface eth0 --source 192.168.2.0/255.255.255.0 -m state --state NEW -j ACCEPT」というコマンドは、LAN側のインタフェースとしたeth1に接続されたコンピュータ群での新規接続および、インターネット側のインタフェースとしたeth0でのパケット転送を行わせるための指定である。これに引き続き「sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT」というコマンドを実行すると、これらの接続から出されるパケット送信をスムースに処理させることができるようになる。

 次に「sudo iptables -A POSTROUTING -t nat -j MASQUERADE」によってネットワークアドレス変換(NAT:Network Address Translation)を有効化させ、LAN側からのトラフィックに付けられたIPアドレスを密かに書き換えることにより、これらのトラフィックがルーティング用のLinuxマシンから直接インターネットに出されたものであるかのように擬装させるようにする。こうした擬装工作は一般家庭からインターネットに接続する場合における一種の必要悪であって、これはプライベートIPアドレスである192.168.x.xブロックからのインターネット接続を可能にすると同時に、複数コンピュータからのトラフィック送信を快く思わないインターネット接続プロバイダ(ISP)の目をあざむく効果があるのだ。

 最後に「sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward」によって、カーネルによるパケット転送を有効化する。

 以上の処理によりLANからインターネット側へのトラフィック送信は行えるようになるはずだが、LAN上のコンピュータ群におけるネットワーク設定までは行われない。後者については、IPアドレス、ゲートウェイ、ネットワークに関する情報および、有効なDNSサーバアドレスの指定も必要となるはずだ。ただしデュアルアダプタLinuxマシンをNATゲートウェイとして運用する場合、これらの情報をクライアント側に指定する作業はDHCPを用いて簡単に実行させることができる。ディストリビューションによっては標準でdhcpdパッケージが同梱されているはずだが、dhcpdの詳細は本稿の範囲を超える話となるので、その使用法については、ディストリビューションの付属ドキュメントに記載されているインターネット接続共有に関する説明などを参照して頂きたい。

 iptablesを用いた基本的なNATおよびパケット転送のセットアップ法に習熟したユーザであれば、もう少し掘り下げた設定法を学習し、送信元や宛先アドレスおよびポートやプロトコル別にトラフィックへの細かなフィルタリングを施すためのルールを指定することで、高機能ファイヤウォールとして利用することもできるはずである。

ネットワークからの分離という使用法

 最後に解説するのは、2つ目のネットワークアダプタをLANから完全に隔離した状態で使用するといった使い方である。

 通常の用途に供するコンピュータの場合、こうした使い方で得られるメリットはほとんどないが、特定の相手のみにデータ送信をする目的でEthernet接続をするデバイスの場合は、むしろこうした使用法が一般的なのである。例えばデジタルビデオレコーダを自作する場合は、このテクニックを用いることでHDHomerunのHDTV受信機をMythTVのバックエンドに直結させ、帯域幅を専有しかねないMPEGストリーミングをLANから分離させてしまうという使われ方がされている。こうしたトラフィックの分離という手法は、専用のネットワーク接続ストレージ(NAS:Network-Attached Storage)やネットワーク接続型の監視カメラなどの単一目的で作成されたデバイスでも使われているが、世の中は広いもので観葉植物のEthernet接続なる用途を提案している人間もいるくらいだ。

 多くのケースにおいて2つ目のアダプタをネットワークから分離させる場合は、ゲートウェイとしての使用例でも触れたDHCPサーバ用のコンピュータ設定が必要となるが、そのクライアントとネットワークの残り部分との間に関するNATルールなどは気にする必要がないはずである。

設定変更は自己責任で

 以上、本稿で紹介したうちのどのテクニックを自分は使用するべきだろうか? 私から言えるアドバイスは、各自のネットワークにおいて解決すべき最大の問題は何なのかを検討してみなさい、ということである。例えば多量のトラフィックをさばくためのサーバとしてデュアルアダプタの搭載マシンを使用したり、2つのWAN接続間でトラフィックのロードバランスを施したいのであれば、ボンディングが適しているはずだ。そうではなくHDHomeRunを購入してMythTVのバックエンドに接続するのならば、空いているインタフェースを専用化して直結する使用法が適していることになる。

 ブリッジおよびゲートウェイとしての使用法は、デュアルアダプタの搭載マシンを介して各種の異なるデバイスを同一ネットワークに接続するという点において、両者は基本的に共通している。このうちどちらの使用法を採用するべきかを考えている場合は、ブリッジングが機能するのはプロトコルスタックにおけるTCPおよびIPではなくEthernetリンクレベルである点を考慮に入れなくてはならない。こうしたEthernetレベルにて唯一実行可能なトラフィック制御は、コンピュータのハードウェアMACアドレスを基にしたものだけなのであって、それ以上の細やかな制御を施すのであれば、より本格的なNATゲートウェイとしての運用が必要となるはずだ。

 いずれのオプションを選ぶにせよ、ネットワーク設定を変更する場合は、何か1つの失敗をするだけで即座にネットワーク接続が絶たれる事態に陥ることも覚悟しておかなくてはならない。そのため本稿で紹介した設定例のコマンドは、いずれもLinuxが起動時に読み込む設定ファイルには手を付けない“ライブ”システムを変更するものばかりにされているのである。つまりこの場合、何らかの設定ミスをしたとしても再起動によりシステムを稼働状態に復帰させることができるのだ。

 あるいは自分の行った設定変更を恒久的なものとしたいケースもあるだろうが、その場合はディストリビューションの付属ドキュメントを参照する必要が生じてくる。ネットワークについての設定スクリプトを格納する方法と場所はディストリビューションごとに異なる場合があるからだ(例えばRed Hatでの格納先は/etc/sysconfig/network-scripts/であるのに対してUbuntuでは/etc/network/とされている)。

 この種の設定法についてより詳しく調べていけば、Linuxを使って2つ目のネットワークアダプタを利用するその他の方法が見つかるかもしれない。いずれにせよ本稿で解説したのは、2つのアダプタにてネットワークとの同時通信を行わせる一般的な利用法に過ぎないが、それだけの知識であっても無用の長物的な2つ目のネットワークアダプタを何らかの形で有効に利用できるはずだ。

Linux.com 原文