複数のVLAN上のDHCPサーバー

問題の声明。



「クライアント」という用語は、ネットワークデバイス全体に対する責任の範囲を意味します。



このようなモードでは、数百のクライアントが特定の共有リソースにアクセスできるようにする必要があります。



  1. 各クライアントは他のクライアントのトラフィックを見ませんでした。
  2. 1つのクライアントの障害(ブロードキャストストーム、IPアドレスの競合、不正なクライアントDHCPサーバーなど)は、他のクライアントとシステム全体の両方の動作に影響を与えません。
  3. 各クライアントは他のクライアントのリソースに直接アクセスしてはなりません(ただし、特別な場合として、このトラフィックの解決を提供することは可能ですが、集中管理および/または管理が可能です)。
  4. クライアントは、共有外部リソース(個々のサーバーまたはインターネット全体)にアクセスできる必要があります。
  5. 共有リソースもクライアントリソースにアクセスできる必要があります(もちろん、共有リソースがクライアントリソースのIPアドレスを知っている場合)。
  6. クライアントのアドレス空間は集中的に割り当てられ、その管理は過度に複雑であってはなりません。


実際のアプリケーションの例には、大規模な組織の部門のローカルエリアネットワークの分離、VoIP通信の編成、または複数の独立した消費者のインターネットへのアクセスなどが含まれます。



説明

条件12は 、各クライアントに独自のVLANを割り当てることにより達成されます。 条件3〜5は、クライアントVLANとそれらの間の直接トラフィック転送の禁止を組み合わせることで実現できます。 一部のソースでは、このテクノロジーは「プライベートVLAN」と呼ばれ、一部の「ポート分離」では、その意味は次のとおりです。各クライアントVLANから共通VLANに簡単にアクセスでき(したがって、戻る)、クライアントVLAN間のトラフィックは禁止されます。 さて、条件6を満たすために、すべてのクライアントに10.12.8.0/23の形式の共通アドレススペースを割り当て、DHCPを使用して要求に応じて特定のIPアドレスを発行します。



したがって、クライアントが新しいデバイスを受信すると、そのデバイスのアドレスが自動的に発行されます(また、あるクライアントは自分のニーズに合わせてIPアドレスの単位を使用でき、別のクライアントは数十または数百を必要とするため、問題はありません)新しいクライアントを追加するときは、別のVLANを作成して、それを共通グループに追加するだけです。 多数のクライアントデバイスが原因で、最初に割り当てたアドレス空間が使い果たされたとしても、設定を2か所(DHCPサーバーとすべてのクライアントVLANを結合するインターフェイス)で変更するだけで、いつでも拡張できます。



技術的には、上記のソリューションは、L3スイッチのハードウェアまたはL2スイッチのハードウェアとソフトウェア(802.1qを理解している場合のみ)およびLinuxに似たオペレーティングシステムを搭載したコンピューターによってのみ実装できます。 私はすでにサーバーを持っているので(さらに、クライアントを対象としています)、ハードウェアとソフトウェアのバージョンに専念するのは論理的です。



したがって、各クライアントVLANに「アクセスモード」の物理スイッチポートが1つ、802.1qモードの共通ポートが1つあるようにスイッチをプログラムします(サーバーはこのポートに接続します)。 詳細には、セットアップテクノロジーは署名しません。 これは非常に簡単で、使用するスイッチの特定のモデルに依存します。



次に、サーバーの構成の作成に進みます。 スイッチの802.1qポートに接続する物理インターフェイスの名前をeth0にします。 私の特定のタスクでは、600から799までのVLAN IDを持つ200のクライアントVLANが必要だったので、それらを作成します。



VLANインターフェイス名タイプの一般的な構成。 VLANインターフェース名を「vlanXXX」のように見せたいです。XXXはVLAN IDです。



 vconfig set_name_type VLAN_PLUS_VID_NO_PAD


eth0インターフェイスに基づいてVLANを直接作成します。



 vconfig add eth0 600
 ifconfig vlan600 up
 vconfig add eth0 601
 ifconfig vlan601 up
 ...
 vconfig add eth0 799
 ifconfig vlan799 up


作成されたVLANを結合するブリッジを作成します。



 brctl addbr br1
 ifconfig br1 up


作成されたインターフェイスをブリッジで結合します。



 brctl addif br1 vlan600
 brctl addif br1 vlan601
 ...
 brctl addif br1 vlan799


ここで、すべてのクライアントのデフォルトゲートウェイとして機能するアドレスをbr1インターフェイスに割り当てます。



 ifconfig br1 10.12.8.1/23


そして、ebtablesを使用してクライアントVLAN間のトラフィックを禁止します。



 ebtables -A FORWARD --logical-in br1 --logical-out br1 -j DROP


(この場合、ebtables「フィルター」テーブルが使用され、論理ポートとしてブリッジに入るインターフェース間のトラフィックの転送が禁止されます)。 それでも、当社の管理下にあるクライアント間のトラフィック転送の可能性を許可する必要がある場合(参照条件の段落3を参照)、上記の規則の代わりに、以下を確立します。



 ebtables -t broute -A BROUTING -p ipv4 --logical-in -j DROP
 ebtables -t broute -A BROUTING -p arp --logical-in -j DROP


ここでは、「broute」テーブルを使用します。 ACCEPTおよびDROPの標準アクションはありません。 ACCEPTターゲットは、指定された条件でのトラフィック転送を許可します(つまり、トラフィックはL2レベルで送信されます)。DROPターゲットは、トラフィック転送を禁止し、ルーティングへの送信を保証します(したがって、iptablesを介して制御できます)。 ただし、 すべてのアドレスは同じIPサブネットに属しますが、異なるクライアントVLANに属することができます。br1インターフェイスでarpプロキシを有効にする必要があります。



 sysctl -w net.ipv4.conf.br1.proxy_arp = 1


クライアント間でトラフィックを渡すタスクがなかったことに注意してください。したがって、上記の拡張機能は単なる推測であり、実際にはテストされていません。



DHCPサーバーを構成し、それをbr1インターフェイスに配置するためだけに残ります。 この操作も簡単なため、この記事のフレームワークでは説明していません。



まあ、それは動作しますか? しかし、どのようにしても:



 #tcpdump -e -v -n -i br1 udp port 67またはport 68
 tcpdump:br1でリッスンし、リンクタイプEN10MB(イーサネット)、キャプチャサイズ65535バイト
 14:26:38.164169 00:0b:82:3b:9c:96> ff:ff:ff:ff:ff:ff、ethertype IPv4(0x0800)、長さ590:(tos 0x0、ttl 64、id 0、offset 0 、フラグ[なし]、プロトUDP(17)、長さ576)
     0.0.0.0.68> 255.255.255.255.67:BOOTP / DHCP、リクエスト00:0b:82:3b:9c:96、長さ548、xid 0x3c12d61a、フラグ[なし]
          クライアントイーサネットアドレス00:0b:82:3b:9c:96
           Vendor-rfc1048拡張
            マジッククッキー0x63825363
             DHCPメッセージオプション53、長さ1:検出
            クライアントIDオプション61、長さ7:エーテル00:0b:82:3b:9c:96
            ベンダークラスオプション60、長さ16: "GXV dslforum.org"
             T125オプション125、長さ36:3561.520160816,808469048,838994992,808469048,842220089,1127822851,122116182,858862640
            パラメーター要求オプション55、長さ11: 
              サブネットマスク、タイムゾーン、デフォルトゲートウェイ、ドメインネームサーバー
              ホスト名、ドメイン名、BR、NTP
              ベンダーオプション、TFTP、オプション125
 14:26:38.171041 00:25:90:d3:5e:fa> ff:ff:ff:ff:ff:ff、ethertype IPv4(0x0800)、length 336:(tos 0x0、ttl 64、id 0、offset 0 、フラグ[なし]、プロトUDP(17)、長さ322)
     10.12.8.1.67> 255.255.255.255.68:BOOTP / DHCP、返信、長さ294、xid 0x3c12d61a、フラグ[なし]
           Your-IP 12.10.8.200
          クライアントイーサネットアドレス00:0b:82:3b:9c:96
           Vendor-rfc1048拡張
            マジッククッキー0x63825363
             DHCPメッセージオプション53、長さ1:オファー
            サーバーIDオプション54、長さ4:10.12.8.1
            リース時間オプション51、長さ4:7200
            サブネットマスクオプション1、長さ4:255.255.254.0
            デフォルトゲートウェイオプション3、長さ4:10.12.8.1




ここではすべて問題ありません。1つのブロードキャストDHCPDISCOVER要求を受信し、1つのブロードキャストDHCPOFFER応答で応答しました。



次に、物理インターフェースで何が起こるかを見てみましょう。



 #tcpdump -e -n -i eth0 udp port 67またはport 68 tcpdump:警告:eth0:IPv4アドレスが割り当てられていないtcpdump:冗長出力が抑制されている、-vまたは-vvを使用して、eth0、リンクタイプEN10MBでリッスンする完全なプロトコルをデコードします(イーサネット)、キャプチャサイズ65535バイト14:31:07.829289 00:0b:82:3b:9c:96> ff:ff:ff:ff:ff:ff、ethertype 802.1Q(0x8100)、長さ594:vlan 603、p 0、ethertype IPv4、0.0.0.0.68> 255.255.255.255.67:BOOTP / DHCP、00からのリクエスト:0b:82:3b:9c:96、長さ548 14:31:07.834962 00:25:90:d3: 5e:fa> ff:ff:ff:ff:ff:ff、ethertype 802.1Q(0x8100)、length 340:vlan 799、p 0、ethertype IPv4、10.12.8.1.67> 255.255.255.255.68:BOOTP / DHCP 、返信、長さ294 14:31:07.834966 00:25:90:d3:5e:fa> ff:ff:ff:ff:ff:ff、ethertype 802.1Q(0x8100)、長さ340:vlan 798、p 0、 ethertype IPv4、10.12.8.1.67> 255.255.255.255.68:BOOTP / DHCP、返信、長さ294 14:31:07.834968 00:25:90:d3:5e:fa> ff:ff:ff:ff:ff: ff、ethertype 802.1Q(0x8100)、長さ340:vlan 797、p 0、ethertype IPv4、10.12.8.1.67> 255.255.255.255.68:BOO  TP / DHCP、返信、長さ294 14:31:07.834970 00:25:90:d3:5e:fa> ff:ff:ff:ff:ff:ff、ethertype 802.1Q(0x8100)、長さ340:vlan 796、 p 0、ethertype IPv4、10.12.8.1.67> 255.255.255.255.68:BOOTP / DHCP、応答、長さ294 14:31:07.834972 00:25:90:d3:5e:fa> ff:ff:ff:ff :ff:ff、ethertype 802.1Q(0x8100)、length 340:vlan 795、p 0、ethertype IPv4、10.12.8.1.67> 255.255.255.255.68:BOOTP / DHCP、Reply、length 294 14:31:07.834974 00 :25:90:d3:5e:fa> ff:ff:ff:ff:ff:ff:ethertype 802.1Q(0x8100)、length 340:vlan 794、p 0、ethertype IPv4、10.12.8.1.67> 255.255 255.255.68:BOOTP / DHCP、返信、長さ294 14:31:07.834976 00:25:90:d3:5e:fa> ff:ff:ff:ff:ff:ff、ethertype 802.1Q(0x8100)、長さ340 :vlan 793、p 0、ethertype IPv4、10.12.8.1.67> 255.255.255.255.68:BOOTP / DHCP、返信、長さ294 14:31:07.834978 00:25:90:d3:5e:fa> ff:ff :ff:ff:ff:ff、ethertype 802.1Q(0x8100)、長さ340:vlan 792、p 0、ethertype IPv4、10.12.8.1.67> 255.255.255.255.68:BOOTP / DHCP、応答、長さ294 ... 




どうした はい、構成したとおりです。





いずれかのクライアントのMAC / IPアドレスですべてのクライアントにスポットライトを当てただけでなく、物理スイッチで弱いブロードキャストストームも受信しました。 ちなみに、一部のスイッチにはこのような嵐から屋根があります。QTECHは私たちと協力しており、宣言された200個のクライアントVLANすべてへのブロードキャストを見逃しませんでした(つまり、任意の確率でエンドクライアントがDHCPサーバーからアドレスを受信するか、まったく答えがありません)、しかし、彼に知られているMACアドレスのテーブルを忘れていました(いずれにしても、コンソールでは、彼はすべてのポートに対して1つのMACアドレスしか見せませんでした)。 しかし、ASOTELスイッチはこのような負荷に対処し、クライアントはDHCPサーバーからアドレスを取得できました。



さて、状況を修正します。 サーバーに、最初の要求の送信元であるVLANにのみブロードキャストを送信するように強制する必要があり、利用可能なすべての場所でそれを増やす必要はありません。

ブロードキャスト用のDHCP追跡モジュールが見つかりませんでした。 後で判明したように、彼はこのケースでは助けにはならなかったでしょう。 ブロードキャスト応答は、システムコールを使用してDHCPサーバーによって生成されます

ソケット(PF_PACKET、SOCK_DGRAM、htons(ETH_P_IP))

ebtablesまたはiptablesテーブルのいずれも通過しません。 つまり それでも着信ブロードキャストをキャッチできる場合、回答はプロトコルスタックをバイパスしてドライバーに渡されます。 そして、これは論理的です:私たち自身がイーサネットヘッダーを形成する場合、それをカーネルでさらに処理するポイントは何ですか?



さて、各クライアントVLANでDHCPリレーエージェントをハングさせて、要求を処理のためにDHCPサーバーに転送してみましょう。 ただし、リレーエージェントは、ブリッジに含まれるインターフェイスからの要求をキャッチしないことが判明しました(これもおそらく論理的です)。 インターフェイスがブリッジから削除されるとすぐに、リレーエージェントは要求をキャッチし、それらをサーバーに送信し、必要なVLANに応答を返送し始めました。 VLANが再びブリッジに追加されると、エージェントのパフォーマンスが再び中断され、クライアントがDHCPにアクセスできなくなりました。

「じゃあ!」厳しいシベリア人は言った。 私たちはすべて大人の方法で行います。



まず、現代のLinuxカーネルには、仮想イーサネットデバイス(コンピューターからイーサネットトラフィックを蒸留するための適切なパイプを作成できる)やネットワークネームスペース(ネットワークスタックを分離するツール)などの便利な機能があることを思い出してください。 、VRFと呼ばれます)。 原則として、このタスクは仮想イーサネット(veth)でのみ実行できますが、ソリューションの美しさ(およびDHCPサーバー-DHCPリレーエージェントバンドルの簡素化)のために、ネットワークネームスペース(netns)も使用します。



Linuxでネットワークを初期化した後、デフォルトではルートネットは1つだけあり、そこにはネットワークスタック、ルーティングテーブル、インターフェースなどの単一のコピーがあります。 以下の説明では、明確にするために、次の用語を使用します。

ネットワーク名前空間は「レイヤー」(レイヤー)と呼ばれます。

ルートネットを「バックプレート」レイヤーと呼びましょう(実際には、このネットには空の文字列の形式の名前があります)。



私たちのアイデアはこれです:



各クライアントVLANを、DHCPリレーエージェントをハングさせるインターフェイス上の個別のブリッジに追加します。 このインターフェイスを介して、クライアントはエージェントにブロードキャスト要求を送信し、エージェントからブロードキャスト応答を受信できます。

各クライアントブリッジから、メインbr1へのイーサネットパイプを作成します。 一連の「顧客vlan」-「顧客vlanブリッジ」-「仮想イーサネット」-「br1」を通じて、有用なトラフィックがクライアントサービスと共有外部リソースの間を通過します。



DHCPリレーエージェント自体は、DHCPサーバーがある特別なイーサネットパイプ上の1つのインスタンス(複数のクライアントインターフェイスをリッスンできる)に存在します。

アプリケーションレベル全体(つまり、DHCPに関係のないすべて)は、バックプレートレベルに配置されます。

DHCPリレーエージェントに接続されているものはすべて、「リレー」という名前のレベルにあります。

DHCPサーバー自体は、DHCPリレーエージェント(ブロードキャストとして配信され、エージェントによってユニキャストに、またはその逆に変換されるメッセージを処理するため)、およびDHCPクライアントから直接アクセスできる必要があります(特別なケースを処理するため:ユニキャストクライアントによってそのDHCPに直接送信されるDHCPRELEASEメッセージこのアドレスを発行したサーバーへ)。



これらの要件を考慮して、DHCPサーバー自体はbr1インターフェイスのバックプレートレベルに配置されますが、エンドクライアントからブロードキャスト要求を受信しないように、特別なフィルターがインターフェイスに適用されます。



解決策



さあ、行こう...「リレー」レイヤーを作成する



 ip netns add relay


DHCPリレーエージェントとDHCPサーバー間の通信を目的とした、バックプレート層に仮想パイプを作成します。



 ip link add relay type veth peer name dhcpd


dhcpdテール(リレーエージェントが実行されるインターフェイス)をリレーレイヤーに転送します。



 ip link set dhcpd netns relay


リレーレイヤーでdhcpdインターフェイスを構成します。



 ip netns exec relay ifconfig dhcpd 10.12.8.2/23
 ip netns exec relay ifconfig dhcpd up


メインブリッジbr1を作成します。



 brctl addbr br1


このブリッジをスマートスイッチとして機能させます(つまり、MACアドレスのテーブルを保存し、ターゲットアドレスの存在に応じて特定のポートへの転送を実行します)。 これを行うには、トレーニング時間を30秒に設定します。



 brctl setfd br1 30


まあ、顧客はユニークなアイデンティティであり、リングを作るかもしれません。 誰かがこれを行う場合、他の人に影響を与えることなく、彼が自分自身を苦しめるようにします。 つまり 仮想スイッチSTPで実行します。



 brctl stp br1 on


なぜなら このブリッジはクライアントのデフォルトゲートウェイでもあるため、IPアドレスを(グリッドとともに)ハングさせ、インターフェイス自体を上げます。



 ifconfig br1 10.12.8.1/23
 ifconfig br1 up


DHCPサーバーがエージェントと通信するためのインターフェースをブリッジに追加します。



 brctl addif br1リレー


ebtablesを使用したクライアントVLAN間のトラフィックを禁止します。



 ebtables -A FORWARD --logical-in br1 --logical-out br1 -j DROP


DHCPサーバーがブロードキャスト要求を処理することを禁止します(エージェントによってキャッチされ、ユニキャストとしてサーバーに送信される必要があります)。



 ebtables -A INPUT --logical-in br1 --pkttype-type broadcast --protocol IPv4 --ip-protocol udp --ip-destination-port 67 -j DROP


セキュリティのために、名前リレーを持つインターフェイス上でのみDHCPリレーエージェントに割り当てられたアドレスの使用を許可します。

 ebtables -A INPUT --in-interface!  relay --protocol IPv4 --ip-source 10.12.8.2/32 -j DROP


さて、最後のブラシストローク。 私は明確にクライアントを信頼していないため、クライアントからのIPパケットが10.12.8.0/23の形式の送信元アドレスを持っていることをカーネルに確認させます(たとえば、192.168.1.1ではありません)。 これを行うには、インターフェイスでrpフィルターを有効にします。



 sysctl -w net.ipv4.conf.br1.rp_filter = 1


eth0物理インターフェイスをバックプレートからリレーレイヤーに転送しません(このスキームに関係のない他のアプリケーションVLANをハングさせる必要があるとしましょう)。 したがって、最初にバックプレートレイヤーでVLANインターフェイスを作成し、次にそれらをリレーレイヤーに転送します。



VLANインターフェイス名タイプの一般的な構成。 VLANインターフェース名を「vlanXXX」のように見せたいです。XXXはVLAN IDです。



 vconfig set_name_type VLAN_PLUS_VID_NO_PAD


eth0インターフェイスに基づいてVLANを直接作成します。



 vconfig add eth0 600


作成したvlan600インターフェイスをバックプレートレイヤーからリレーレイヤーに転送します。



 ip link set vlan600 netns relay


vlan600インターフェイスを上げますが、すでにリレーレイヤーにあります。



 ip netns exec relay ifconfig vlan600 up


このクライアントVLANのリレー層にブリッジを作成します(DHCPリレーエージェントをハングアップします)。



 ip netns exec relay brctl addbr br600


このブリッジがハブとして機能するようにします(つまり、MACアドレスに関する情報を収集する期間を使用せずに、パケットを受信後すぐにブロードキャストします)。 これを行うには、最初のインターフェイスをブリッジに追加する前に、そのパラメーターを設定します。



 ip netns exec relay brctl setfd br600 0


さらに、このブリッジではSTPは必要ありません。



 ip netns exec relay brctl stp br600 off


ブリッジインターフェイスを上げます。



 ip netns exec relay ifconfig br600 up


そして、クライアントVLANを追加します:



 ip netns exec relay brctl addif br600 vlan600


br600クライアントブリッジとメインのbr1ブリッジを接続するために、バックプレートレイヤーにイーサネットパイプを作成します(とにかくそこに到達します)。



 ip link add dhcp600 type veth peer name backplate600


パイプの2番目の端をリレーレイヤーに転送します。



 ip link set backplate600 netns relay


そして、このパイプの端をブリッジに追加します:



 ip netns exec relay brctl addif br600 backplate600


さて、バックプレート層に残っているパイプの端をbr1ブリッジに追加します。



 brctl addif br1 dhcp600


必要な数量のクライアントVLANを作成する操作をループで繰り返します。



これで、バックプレートレイヤーでDHCPサーバー自体を、リレーレイヤーでDHCPリレーエージェントを起動するだけで十分です。 私の場合、BusyBoxのアセンブリが使用されますが、この場合は重要ではありません。 ISCエージェントとサーバーを使用しても、それほど大きな問題は発生しません。



そこで、エージェントを起動します。 Br600-br799はクライアントインターフェイスとして使用され、dhcpdはDHCPサーバーとの通信用インターフェイスとして使用され、DHCPサーバー自体のアドレスは10.12.8.1です。



 ip netns exec relay / usr / sbin / dhcprelay br600、br601、...、br799 dhcpd 10.12.8.1


最後に、DHCPサーバーを起動します。



 / usr / sbin / udhcpd /etc/udhcpd.conf




/etc/udhcpd.confファイルでは、このスキームに適用される唯一の行は次のとおりです。



 #DHCPサーバーが存在するインターフェイスの名前
インターフェイスbr1


これで、ユーザーVLANのブロードキャスト要求は、対応するbr-interfaceを介してDHCPリレーエージェントによってキャッチされ、その後、ユニキャスト要求はdhcpdインターフェイスを介してサーバーに送信されます。 サーバーは、リレーインターフェイスを介してユニキャスト応答を送信します。エージェントは、dhcpdインターフェイスから受信し、ブロードキャストをソースVLANに変換します。



クライアントはDHCPを介してアドレスを受信し始め、ブロードキャストストームは消滅しました。 また、クライアントはDHCPRELEASEを10.12.8.1のサーバーに直接送信できます。



©Copiright 2015 by Vedga 。 著者の同意なしにテキストを他のリソースにコピーすることは禁止されています。




この記事の検索対象:



  1. DHCP-動的ホスト構成プロトコル
  2. プライベートVLAN(WikipediA)
  3. プライベートVLANについて (@amario)
  4. Linuxで複数のネットワークスタックを使用する



All Articles