2007/11/30

ポート毎に帯域制御したい

ポート毎に帯域制御したい
最終更新: 2007/1/1

[概 要]

サーバからの送信される情報の帯域をポート毎(HTTPやFTP等のプロトコル毎)に制御したい。

[対 策]

カーネルのQoS(Quality of Service)機能を使用すると比較的簡単に帯域制御できます。但し、帯域制御できるのはサーバからの送信だけで受信は制御できないため、例えばFTPのアップロードを制御したい場合はデーモンの機能を併用する必要があります。
事前準備

カーネルのQoS(Quality of Service)機能を使用するには iproute+tc が必要であるが、最近のデストりには既に入っているのでこちらのインストールは不要である。tcを使用するといろいろなQoS制御ができる反面、かなり時間をかけて内容をしっかり理解しないとほとんど設定不可能であるが、cbq.init というスクリプトを使用するとポート毎の帯域制御であれば簡単に設定できるため、ここではこれを使用する。cbq.initをこちらからダウンロードし、システム起動時に自動起動できるようにする。なお、RedHat系ならそのままで良いが、SuSEの場合はtcのパスが異なるので、2行目でmvする代わりに3行目のようにsedで変換する。
# wget http://jaist.dl.sourceforge.net/sourceforge/cbqinit/cbq.init-v0.7.3
# mv cbq.init-v0.7.3 /etc/init.d/cbq.init
(# sed -e "s/TC=\/sbin\/tc/TC=\/usr\/sbin\/tc/g" cbq.init-v0.7.3 > /etc/init.d/cbq.init)
# chmod 755 /etc/init.d/cbq.init
# chkconfig --add cbq.init


QoS設定

QoS制御で使用する cbq.init 関係の設定ファイル名称及び設置場所はデフォルトで決まっている。

[設定ファイルの設置場所]

設定ファイルは、/etc/sysconfig/cbq/ディレクトリ配下に設定することになっているので、下記で作成しておく。
# mkdir /etc/sysconfig/cbq


[設定ファイル]

設定ファイルの名称と形式も決まっているので下記のとおりとする。clsid(クラスID)が異なれば複数の設定ファイルが記述できる。

ファイル名称: cbq-.

cbq-: ここは固定でこのとおりとすること。
:実質的にCBQのクラスIDであり、10進で2-65535の値(16進で0002-FFFF)で指定する。他の設定ファイルと重複は不可。
:クラスIDのニックネームなので自分でわかりやすいものを適当に付与する。


例: cbq-1280.My_first_shaper


[設定ファイルのパラメータ]
No. 種 別 パ ラ メ ー タ 概 要 備考
1 デバイス DEVICE=,[,]
例:DEVICE=eth0,10Mbit,1Mbit

:帯域制御するインタフェース名。
:インタフェースの物理速度。100BASE-TXなら100Mbit、10BASE-Tなら10Mbitと指定。
:に比例するパラメータで原則の1/10の値にすること。 必須
2 クラス RATE=
例:RATE=5Mbit

:このクラスに割り当てる帯域を指定。単位としてはKbit, Mbitが使用できる。bps, Kbps, Mbps も使用できるが、bytes/secであることに注意しなければならないのと、インタフェース速度との関係がわかりにくいので使用しないほうが無難。 必須
3 WEIGHT=
例:WEIGHT=500kbit

:RATEに対応したパラメータで、原則RATEの1/10(WEIGHT ~= RATE / 10. 適当に四捨五入でもする。)の値にすること。 必須
4 PRIO=<1-8> デフォルト:5
例:PRIO=5

トラヒックの優先度を1-8で指定。値が小さいほど優先的に処理されるので、プロトコル間で差をつける(SSHを最優先にする等)場合に使用できる。 OP
5 フィルタ RULE=[[saddr[/prefix]][:port],][daddr[/prefix]][:port]

ここで、実際に制御するアドレス/ネットワークとポートを指定する。前者のパラメータ[saddr[/prefix]]は制御するパケットのソースアドレス/ネットワークで、[daddr[/prefix]]が本スクリプトが動作しているサーバがデータを送信する相手を示す。両者の区切りである「,」は、前者のパラメータ指定の最後に付与するものなので注意が必要である。

例:
・WWWサーバへのアクセスに対するコンテンツ配送の制御
サーバの80番ポートをソースとするパケットを制御することになるので、下記のように [サーバアドレス:80,] とRULEに設定する。ソースをキーに制御するので最後の「,」を忘れずに。

RULE=192.168.1.100:80,
+---------+
| linux |-eth0------*-[client]
+---------+
Server:192.168.1.100 Client: any

80 --------------> any
・FTPサーバからのダウンロードトラヒックの制御
FTPサーバからのデータダウンロードは、ActiveモードとPassiveモードで使用するポートが異なる。
Activeモードの場合、サーバ側が20番となるコネクション(ftp-data)で送信されるので、以下のように設定する。

RULE=192.168.1.100:20,

Passiveモードの場合、サーバ側で使用するポートを指定できるデーモンでないと制御できない。おやじのサイトで紹介しているProftpd/vsftpdとも設定が可能なので、使用ポート範囲を設定する。ダウンロードデータはそのポートがソースとなるパケットで送信される範囲指定になるので、以下のように [開始ポート番号/ANDマスク] 設定する。
指定方法のANDマスクの考え方は、ネットワークのサブネットマスクの考え方(192.168.1.0/24の/24)と同じであり、/24を16進で表現したものである。例えば、4096から4127までの32ポートを設定したとすると、[ 4096/0xffe0 ]となり、下記のように4096~4127の数字は[ 0xffe0 ]でANDをとると全て4096となり同じ扱いになる。これでわかるように、開始ポート番号は、使用するポート数に応じて下位nビットが0となる値にしないと関係ないポートまで制限してしまうので、Proftpd等の設定例で示している4000~4029という設定は変更する必要がある。

4096(0x4000) 0100000000000000 [開始ポート]
32(0xffe0) 1111111111100000
---------------------------------
AND 0100000000000000

4127(0x401f) 0100000000011111 [終了ポート]
32(0xffe0) 1111111111100000
---------------------------------
AND 0100000000000000

RULE=192.168.1.100:4096/0xffe0,
+---------+
| linux |-eth0------*-[client]
+---------+
Server:192.168.1.100 Client: any

20/4096-4127 --------------> any 必須
6 タイマ TIME=[,, ...,/]-;/
例:TIME=0,1,2,5/18:00-06:00;256Kbit/25Kbit
TIME=18:00-06:00;256Kbit/25Kbit

本設定でタイマにより上記で設定した値と異なる帯域で制御することができる。
:ルールを適用する曜日を指定。0-6で 0 が日曜に対応している。
-:このルールの適用開始時刻と終了時刻を24時制で指定。
/:上記の2項、3項に同じ。 OP



[設定例] 下記のようなファイルを/etc/sysconfig/cbqディレクトリに設定する。

・cbq-100.http: WWWサーバへの過大なアクセスにより回線を使い切るのを制限する例。

DEVICE=eth0,100Mbit,10Mbit
RATE=5Mbit
WEIGHT=500Kbit
PRIO=5
RULE=192.168.1.100:80,

・cbq-101.ftp: FTPサーバからのダウンロードを制限する例。

DEVICE=eth0,100Mbit,10Mbit
RATE=10Mbit
WEIGHT=1Mbit
PRIO=6
RULE=192.168.1.100:20,
RULE=192.168.1.100:4096/0xffe0,

cbq.initの起動

cbq.init自体が起動スクリプトなので単純に起動すればよい。起動したら設定どおり制限されているかテストする。
# /etc/init.d/cbq.init start

No comments: