この記事では、Linuxでのネットワークパケットのルーティングに焦点を当てます。 具体的には、
ポリシールーティング (
ポリシーベースルーティング )と呼ばれるルーティングの種類について。 このタイプのルーティングでは、従来の
宛先ルーティングルーティングメカニズム(宛先アドレスに基づく
ルーティング )とは異なり、かなり柔軟なルールに基づいてパケットをルーティングできます。 ポリシールーティングは、複数のネットワークインターフェイスがあり、特定のパケットを特定のインターフェイスに送信する必要がある場合に適用され、パケットは宛先アドレスだけでなく宛先アドレスによっても決定されません。 たとえば、ポリシールーティングを使用して、複数の外部チャネル(アップリンク)間でトラフィックのバランスを取り、複数のアップリンクの場合にサーバーへのアクセスを提供し、必要に応じて異なる外部インターフェイスを介して異なる内部アドレスからパケットを送信し、異なるTCPポートにパケットを送信することもできます異なるインターフェースなどを介して
Linuxでネットワークインターフェイス、ルーティング、およびシェーピングを管理するには、
iproute2ユーティリティパッケージを使用します。
このユーティリティセットは設定のみを設定し、実際にはすべての作業はLinuxカーネルによって実行されます。 ポリシールーティングをサポートするには、カーネルを
IP:高度なルーター (
CONFIG_IP_ADVANCED_ROUTER )および
IP:ポリシールーティング (
CONFIG_IP_MULTIPLE_TABLES )
オプションを有効にしてコンパイルする必要があります。
IPルート
ルーティングを設定するには、ip routeコマンドを使用します。 パラメータなしで実行すると、現在のルーティングルールのリストが表示されます(すべてのルールではなく、詳細は後ほど)。
#ip route
192.168.12.0/24 dev eth0 proto kernel scope link src 192.168.12.101
デフォルトは192.168.12.1 dev eth0経由
これは、eth0インターフェイスでサブネットマスク255.255.255.0とデフォルトゲートウェイ192.168.12.1を使用してIPアドレス192.168.12.101を使用する場合のルーティングのように見えます。
192.168.12.0/24サブネット上のトラフィックがeth0インターフェイスを通過することがわかります。
proto kernel
は、IPインターフェースの設定時にルーティングがカーネルによって自動的に設定されたことを意味します。
scope link
は、このエントリがこのインターフェイス(eth0)に対してのみ有効であることを意味します。
src 192.168.12.101
は、このルーティングルールに該当するパケットの送信者のIPアドレスを設定します。
192.168.12.0/24サブネットに分類されない他のホストへのトラフィックは、eth0インターフェイス(
default via 192.168.12.1 dev eth0
て192.168.12.1ゲートウェイに送られます。 ところで、パケットをゲートウェイに送信する場合、宛先IPアドレスは変更されません。イーサネットフレームでは、ゲートウェイのMACアドレスが受信者のMACアドレスとして示されます(多くの場合、経験のある専門家でもこの時点で混乱します)。 ゲートウェイは、NATが使用されている場合は送信者のIPアドレスを変更するか、単にパケットをさらに送信します。 この場合、プライベートアドレス(192.168.12.101)が使用されるため、ほとんどの場合、ゲートウェイはNATを実行します。
次に、ルーティングの詳細を説明します。 実際、いくつかのルーティングテーブルがあり、独自のルーティングテーブルを作成することもできます。
local 、
main、および
defaultテーブルは最初に事前定義されています。 カーネルは、ローカルIPアドレス(これらのIPアドレスへのトラフィックがローカルのままであり、外部ネットワークに行かないようにするため)およびブロードキャストキャストのエントリをローカルテーブルに書き込みます。
メインテーブルはメインテーブルであり、コマンドが使用するテーブルを示していない場合に使用されます(つまり、上記の
メインテーブルを見ました)。
デフォルトのテーブルは、最初は空です。 ローカルテーブルの内容を簡単に見てみましょう。
#ip route show table local
ブロードキャスト127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
ブロードキャスト192.168.12.255 dev eth0 proto kernel scope link src 192.168.12.101
ブロードキャスト192.168.12.0 dev eth0 proto kernel scope link src 192.168.12.101
ローカル192.168.12.101 dev eth0 protoカーネルスコープホストsrc 192.168.12.101
ブロードキャスト127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
ローカル127.0.0.1 dev lo protoカーネルスコープホストsrc 127.0.0.1
ローカル127.0.0.0/8 dev lo protoカーネルスコープホストsrc 127.0.0.1
broadcast
と
local
が記録のタイプを決定します(上記の
default
タイプを見てください)。
broadcast
タイプは、このレコードに対応するパケットが、インターフェイス設定に従ってブロードキャストパケットとして送信されることを意味します。 local-パケットは
local
送信されます。
scope host
は、このエントリがこのホストに対してのみ有効であることを示します。
特定のテーブルの内容を表示するには、
ip route show table TABLE_NAME
コマンドを使用します。 すべてのテーブルの内容を表示するには
unspec
all
、
unspec
または
0
指定して
unspec
指定します。 すべてのテーブルには実際にデジタル識別子があり、それらのシンボル名はファイル
/ etc / iproute2 / rt_tablesに設定されており、便宜上使用されています。
IPルール
カーネルはパケットを送信するテーブルをどのように選択しますか? すべてが論理的です-これにはルールがあります。 私たちの場合:
#IPルール
0:すべてのローカル検索から
32766:すべてのルックアップメインから
32767:すべての検索デフォルトから
行の先頭の数字はルールの識別子であり、
from all
が条件であり、任意のアドレスからのパケットを意味し、
lookup
はパケットを送信するテーブルを示します。 パケットが複数の規則に該当する場合、識別子の昇順ですべて通過します。 もちろん、パケットがルーティングレコードと一致する場合、後続のルーティングレコードと後続のルールは通過しません。
可能な条件:
- from-すでに上で検討した、これはパケットの送信者のチェックです。
to
はパケットの受信者です。iif
は、パケットが送信されたインターフェイスの名前です。oif
パケットが送信されるインターフェースの名前。 この条件は、特定のインターフェイスにバインドされたローカルソケットから発信されたパケットにのみ適用されます。tos
は、IPパケットのTOSフィールドの値です。fwmark
-FWMARKパケットの値を確認します。 この条件により、ルールの柔軟性が大幅に向上します。 iptables
ルールを使用すると、膨大な数の記号でパケットをフィルタリングし、特定のFWMARK値を設定できます。 そして、ルーティング時にこれらの値を考慮します。
条件は、たとえば
from 192.168.1.0/24 to 10.0.0.0/8
に組み合わせることができ、プレフィックスc
not
使用することもできます。これは、パッケージがこのルールに該当するために条件を満たさないことを示します。
そこで、ルーティングテーブルとルーティングルールが何であるかを把握しました。 また、独自のテーブルとルーティングルールを作成することは
ポリシールーティングであり 、
PBR (ポリシーベースのルーティング)でもあります。 ところで、Linuxの
SBR (ソースベースのルーティング)または
ソースルーティングは、ポリシールーティングの特殊なケースです。これは、ルーティングルールで
from
句を使用することです。
簡単な例
簡単な例を考えてみましょう。 特定のゲートウェイがあり、IP 192.168.1.20のパケットが到着します。 このIPからのパケットは、10.1.0.1ゲートウェイに送信する必要があります。 これを実装するには、次を実行します。
単一のルールでテーブルを作成します。
#10.1.0.1テーブル120経由でip route add default
必要なパケットを目的のテーブルに送信するルールを作成します。
#192.168.1.20テーブル120からIPルールを追加
ご覧のとおり、すべてがシンプルです。
複数のアップリンクによるサーバーの可用性
より現実的な例です。 最大2つのプロバイダーに対して2つのアップリンクがあります。両方のチャネルからサーバーの可用性を確保する必要があります。

プロバイダーの1つは、どのルートに関係なく、デフォルトルートとして使用されます。 この場合、Webサーバーはこのプロバイダーのネットワークを介してのみ使用可能になります。 別のプロバイダーのネットワークを介した要求は送信されますが、応答パケットはデフォルトゲートウェイに送信され、何も送信されません。
これは非常に簡単に解決されます。
テーブルを定義します。
#11.22.33.1表101を介してip route add default
#55.66.77.1表102を介したip route add default
ルールを定義します。
#11.22.33.44表101からIPルールを追加
#55.66.77.88テーブル102からのipルールの追加
今、これらの行の意味を説明する必要はないと思います。 同様に、3つ以上のアップリンクでサーバーの可用性を高めることができます。
アップリンク間のトラフィックのバランス
それは、1つのエレガントなチームによって行われます。
#ip routeはデフォルトのスコープをグローバルに置き換えます\
11.22.33.1 dev eth0を介したnexthop weight 1 \
55.66.77.1 dev eth1 weight 1を介したnexthop
このエントリは、メインテーブルの既存のデフォルトルーティングを置き換えます。 この場合、ゲートウェイの
weight
(
weight
)に応じてルートが選択されます。 たとえば、重み7と3を指定すると、接続の70%が最初のゲートウェイを通過し、30%が2番目のゲートウェイを通過します。 考慮しなければならない点が1つあります。カーネルはルートをキャッシュし、特定のゲートウェイを経由するホストのルートは、このレコードへの最後のアクセス後しばらくテーブルでハングします。 また、頻繁に使用されるホストへのルートは、リセットされるのに間に合わず、キャッシュ内で絶えず更新され、同じゲートウェイに残ります。 これが問題になる場合は、
ip route flush cache
コマンドを
ip route flush cache
してキャッシュを手動でクリアできる場合があります。
iptablesでパケットラベリングを使用する
11.22.33.1のみを通過するために、ポート80のパケットが必要だとします。 これを行うには、次を実行します。
#iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 80 -j MARK --set-mark 0x2
#11.22.33.1 dev eth0 table 102を介したip route add default
#IPルール追加fwmark 0x2 / 0x2ルックアップ102
最初のコマンドは、ポート80に向かうすべてのパケットをマークします。 2番目のコマンドは、ルーティングテーブルを作成します。 3番目のチームは、すべてのパッケージを目的の表に示されたマークでラップします。
繰り返しますが、すべてが簡単です。 iptables
CONNMARKモジュールの使用も検討してください。 特定の接続に関連するすべてのパケットを追跡およびマークできます。 たとえば、
INPUTチェーンの特定の特性に従ってパケットをマークし、これらの接続および
OUTPUTチェーンに関連するパケットを自動的にマークできます。 次のように使用されます。
#iptables -t mangle -A INPUT -i eth0 -j CONNMARK --set-mark 0x2
#iptables -t mangle -A INPUT -i eth1 -j CONNMARK --set-mark 0x4
#iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
eth0で到着するパケットには2のラベルが付けられ、eth1-4(行1および2)が付けられます。 3行目のルールは、パケットが特定の接続に属しているかどうかを確認し、発信パケットのマーキング(着信パケットに設定されている)を復元します。
提示された資料が、Linuxでのルーティングの完全な柔軟性の評価に役立つことを願っています。 ご清聴ありがとうございました:)