第14回 FreeBSD+mpdによるブロードバンドルータの高速化

2003/2/10作成
2005/12/27更新


FreeBSD標準添付のpppは使いやすいのですがあまり速くありません。
いろいろな文献を読んでみるとmpdがいいらしいということが判明しました。
でも、mpdに関するドキュメントが少ないですね。
英語のドキュメントはまだなんとか見つかるのですが、PPPoEをはじめとしたデータリンクまわりの仕様はMTUの設定などで日本独特の文化があるため、できれば日本人の書いたドキュメントがほしいものです。
結局googleで探しても見つからず、2chでようやく見つけることができました。
んで、うちでまとめます。ひょっとしたらうちがはじめてmpdに関するドキュメントをまとめたのかなと思いながらもドキュメントの出来についてはあまり自信がないまま、2ちゃんねるの難民が大挙して押し寄せてきたらどうしようと、2ちゃんねる用語で言うところのガクブルしながらで行ってみたいと思います(笑)

FreeBSD4.8が出たので内容を少し変えてあります。

うちの掲示板と某巨大掲示板から指摘があったので修正しました。
某巨大掲示板に書き込まれても、気が向かないと見に行かないし、めったに気が向かないので気がつくのが遅くなります。というか、まず気がつかないです。
別に、取って食いはしないので間違いを見つけた人は遠慮せずにこっちの掲示板でもいいし、直接メールを出すとかしてもらえると助かります。

(2005/12/27追記)
otsuneさんのアドバイスを受けて、mpd.linksに2行加えました。
反映が遅くなってしまいごめんなさい。
加えて、mpdのログの取り方について追記してあります。
お役立てください。



1.カーネルの準備

mpdはnetgraphを使うので、カーネルに以下の内容を書き加えて再構築します。
標準添付のpppでpppoeをやるときにすでにいくつか設定済みなのでNETGRAPH_ETHERを加えればOKですね。
いまさらながらカーネルの再構築手順については触れませんので他のドキュメントで補完してください。
options NETGRAPH
options NETGRAPH_PPPOE
options NETGRAPH_SOCKET
options NETGRAPH_ETHER

2.mpdのインストール

いろいろ調べてみたのですがmpdはportsコレクションからしか入手できないようです。
ソースからコンパイルしたいところですが、ここはぐっとこらえてportsコレクションから入れましょう。
# cd /usr/ports/net/mpd
# make install
ネットにつながっていて、ftpが使える状態であれば上のコマンドだけでOKです。
portsを入れていない場合はftpでソースを持ってきてpkg_addするとかしましょう。
ネットワーク経由でpkg_addすればコマンド一つで完了です。詳しくはマニュアルpkd_add(1)読んでください。

3.mpdのconfigファイル

mpdのコンフィグは以下の4つとなります。
ファイル名 意味
mpd.conf mpdのメインとなるコンフィグ ppp.confみたいなもの
mpd.links mpd.confから参照されるインタフェースまわりのコンフィグ。主にレイヤ2以下の内容が書かれているようです
mpd.secret pppのchap,papのauthnameに対応するパスワード。mpd.confに直接パスワードを書くよりも安全
mpd.script ppp接続時に実行されるスクリプトを記述。今回は使いません。
ではそれぞれについて書いてみましょう。
3−1.mpd.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
default:
       load PPPoE

PPPoE:
        new -i ng0 PPPoE PPPoE
        set iface addrs 1.1.1.1 2.2.2.2
        set iface route default
        set iface disable on-demand
        set iface idle 0
        set iface mtu 1454
        set bundle disable multilink
        set bundle authname xxxx@xxx.xxx.ne.jp
        set link no acfcomp protocomp
        set link disable pap chap
        set link accept chap
        set link mtu 1454
        set link mru 1454
        set ipcp yes vjcomp
        set ipcp ranges 0.0.0.0/0 0.0.0.0/0
        open iface
一番右側の数字は行番号です。
1,2はmpdのデフォルトで実行するプロファイルを指定しています。
単純に"mpd"とコマンドライン上で実行したとき、PPPoEが読み込まれます。
4はこのプロファイルの名前です。1,2から参照されたり、mpdコマンドの引数として認識されます。
5はPPPoEインタフェースの初期化コマンドです。
ng0はnetgraphのインタフェース名です。ppp(8)ではtun0を使っていたのですがmpdではng0になるようです。PPPoEはmpd.linksにある同プロファイルを参照しています。
6と7はインタフェースレイヤでのアドレスとゲートウェイになります。
6はあっても無くてもいいようです。
7はこれを追加しないとインタフェースがUPしたときにデフォルトルートが追加されません。
書いて置いた方が無難でしょう。(けんさん、BBSでの指摘ありがとうございます。)
8はon-demandモードを使用不可にしています。on-demandモードというのはパケットが来たときだけ接続しにいくというモードです。デフォルトはenableになっているので常時接続にあわせてdisableにしました。
9はpppのアイドルタイムということで、ここに設定した数字が秒に変換され、その秒間だけpppセッションを保持します。その間なにも通信が無ければ自動的に切断されてしまうようです。ここを0秒に設定すると常時接続になります。また、on-demandモードを切っている場合もあまり意味がないパラメータです。
10はインタフェースレイヤのmtuです。つまりEtherネットフレームの長さでなので、ここではふつうに1500でいいはずなのですが、なぜかそうするとスループットが低下します。どうも釈然としないのですが、1454にしておきます。
11はマルチリンク機能を有効にするかどうかという選択肢です。
マルチリンクはP-MP接続なのでISDNのPPPでは使うことがあると思いますが、普段は不要だと思います。
ちなみにFreeBSD5.0添付時点での最新バージョン(3.10)では問題があるようです。
それについては2chの猛者どもがパッチを作ってくれたようなので、試してみたい人は2chからパッチを入手しましょう。
2chの人たちが作者にもパッチを送ったようなので、近いうちにマージされることでしょう。
(MPについて2chで指摘があったようなのでなおしました。)
12はauthに関する情報です。このあたりが日本独特の文化を醸し出しています。
フレッツADSLにしてもBフレッツにしてもフレッツシリーズではauthnameが"@"付きになる場合がほとんどです。
ちょっと心配でしたが、遠慮なく"@"付きのauthnameを入れてやりましょう。xxxx@xxx.xxx.ne.jpのところだけ書き換えればOKです。
ちなみにパスワードはこの後set bundle password xxxxとしてもOKですが、いちおうmpd.secretファイルが用意されているのでこっちを使っていきます。
セキュリティも若干ながら向上することですし。
13からはlinkレイヤの設定ということでppp関連ですね。
acfcompはAddressとcontrol fieldの圧縮で、protocompはプロトコルの圧縮です。フレッツの技術参考資料(pdf)の4.1.3にはLCPによりどちらも使用不可と書いてあるのでフレッツを使っている間はdisableが正解です。CATVとかの別のキャリアを使っている人はそれぞれ置き換えてください。
Windowsのpppクライアントにもこの辺の設定がチェックボックスか何かで提供されていたと思います。
14と15はpapとchapに関する情報です。
disable/enableとaccept/denyがありますが、それぞれの違いは自分の役割にあります。自分がpppサーバになる場合はdisable/enableを設定し、クライアントになる場合はaccept/denyを設定します。今回はサーバになるつもりはないのでpap/chapの両方をdisableにして、クライアント側の設定はセキュリティを考慮してchapのみをacceptに設定しています。
16,17はlinkレイヤのmtuとmruです。pppフレームのmtuは上述の技術参考資料にLCPにより1454にされているので1454を書いておきます。
おなじmtuでもインタフェースとpppで二つあるのに違和感を覚えるかもしれませんが、こういうものだと思ってください。
18はipcpのVan JacobsonTCPヘッダ圧縮方式を有効にするかどうかです。
ほとんどの場合はyesなのでこのままにします。
19はipcpによって与えられるIPアドレスを定義します。実は0.0.0.0/0にするとゼロにするなと怒られてしまいます。
でも、ipcpでIPアドレスもらってくるときはここをゼロにするのが定番らしいので、そのままにしておきましょう。これで問題なく使えますし。
IPアドレスが固定の場合は遠慮なく書いてもOKです。
20でインタフェースを開いてセッション開始です。
3−2.mpd.links
PPPoE:
        set link type pppoe
        set pppoe iface fxp1
        set pppoe service "whatever"
        set pppoe enable originate
        set pppoe disable incoming
1行目のPPPoEはmpd.confによって呼び出されるときのインデックスみたいな役割をします。
2行目はこのlinkがpppoeであることを明示し、3行目でpppoeをバインドするインタフェースを指定します。fxp1はintelチップのネットワークカードで2枚目のものですね。
4行目はpppoeのサービス名を明示しているのですが、適宜書き換えてもいいようです。しかも、このサービス名ですが、何のために使うのかいまいちよくわかりません。とりあえず"whatever"で問題ないでしょう。
(2005/12/27追記)
mpdの新しいバージョンでは5,6行目を追加しないといけなくなりました。
originateは自分が発信する場合に、incomingは自分が着信する場合です。
3−3.mpd.secret
mpd.secretはauthnameとpasswordのペアが格納されています。
mpd.confのauthnameのところから参照され、第一フィールドにauthnameに書かれたキー値が入り、第二フィールドにパスワードを入れます。
でも、内容が平文なのはいけてないです。暗号化してくれたらうれしいのですけど。
# Authname		Password
xxxx@xxx.xxx.ne.jp		xxxxxx

4.mssの調整

Etherから吐き出されるtcpパケットにオプションでmss(Maximum Segment Size)というのを設定することができます。
End-Endのホスト間で一つのtcpパケットの最大サイズをいくつに設定するかを決めることができます。
パケットのサイズが大きければ大きいほど、一度に送ることができる情報が大きくなるので効率のよい通信が可能です。
小さいと、パケット全体におけるヘッダなどの管理情報の割合が大きくなるため効率が悪くなります。

mssはWindowsの場合1460がデフォルトとなっていますが、このままではPPPoEの許容パケットサイズを超えてしまうため一部のサイトが見えたり見えなかったりという現象が起きます。

pppの場合は、MTUとMRUの設定にあわせて自動的に書き換えてくれるのですが、mpdは書き換えないため、pppからmpdに移行するとデグレードを起こします。
この解決方法について、説明しておきます。
執筆時点で、mpdでmssを調整する機能がないので、それ以外の方法で調整しなければいけません。
2つの方法をあげます。
1.Windowsのレジストリをいじってmssを変更する
2.他の方法でサーバにmss調整機能を実装する
1はブロードバンドの恩恵によりいろいろなツールが落ちているので探してみてください。
2はつい先日までは八方ふさがりだったのですが、FreeBSD4.8が出てからは解決への糸口が見えてきました。

うちでもよく出てくるIPFilterですが、3.4.30からipnat(8)にmss調整機能が付きました。
たぶんこんな感じで設定します。
# ipnat.conf
map ng0 192.168.0.0/24 -> xxx.xxx.xxx.xxx/32 portmap tcp/udp auto mssclamp 1414
map ng0 192.168.0.0/24 -> xxx.xxx.xxx.xxx/32 mssclamp 1414
実はうちのはIPFilter3.4.29なので上の検証ができません。
これで試してOKだった人がいたら報告してもらえるとうれしいです。
(2005/12/27追記)
mpd-3.15からtcpmssfixが使えるようになりました。
これでmssの調整ができるなと思ったのですが、これにはバグがあるらしく動いてくれません。
私も実際に設定を入れて試してみたのですが、ダメでした。
ipnatのmssclampかpfのmax-mssで調節するしかないようです。
pfのmax-mssについてはこちらをご覧ください。

5.起動

mpdを起動します。
単純のmpdと入力すると対話型のインタフェースが現れます。
メッセージを見ることができるのでデバッグするするときに有効です。
正常動作が確認できたら今度はバックグラウンドで起動します。"&"をつけてもいいのですが、"-b"オプションが用意されているのでこれを使います。
# mpd -b
あとはrcファイルを編集です。
rc.localに書くのが手っ取り早い方法ですが、rc.confから呼び出したいという要望もあると思います。
rc.confを使う方法はまたの機会にして、今回はrc.localに書いてみました。とりあえずこれで起動しますがあとはお好みで修正してください。
一番先頭の行に追加することをおすすめします。
# rc.local FreeBSD 5.0
#
# mpd startup
#
mpd_command="/usr/local/sbin/mpd"
mpd_conf_file="/usr/local/etc/mpd/mpd.conf"
if [ -x ${mpd_command} -a -f ${mpd_conf_file} ]; then
        ${mpd_command} -b
        echo "mpd start pppoe connection"
fi

# Re-Sync ipfilter so it picks up any new network interfaces
#
sleep 5
/etc/rc.d/ipfilter resync
最後の行はipfilterのルールの再同期をとっています。ipfilterを使っていない人は必要ありません。
インタフェースがUPしてからでないとresyncかけても意味がないので、とりあえずsleepで5秒ほど待ってます。
掲示板で、もっとスマートな方法を教えてもらったのですが時間がなくて試してません。時間をみつけて実験してみたいです。
resyncはたぶんFreeBSD4.xでは用意されていないと思います。
上のスクリプトはrc.confに持っていくことを意識して書いたので、そのままrc.dに持っていってrc.confから導くといいでしょう。

6.注意点

ppp(8)から移行した場合はPPPoEのバインドされているインタフェースがtun0からng0に変わったのでipfやipnatのコンフィグも当然ながら変更になるので変更しておきましょう。

7.ログの取得(2005/12/27追記)

mpdをバックグラウンドで起動するとログが取れません。
ログはsyslogで取ることになっています。
mpdをコンパイルするときに、Makefileにファシリティ名を入れておくと、デフォルトのファシリティ名が決まるのですが、コマンドラインから"-s"オプションをつけることでファシリティ名を指定することができるようです。
# mpd -s mpd -b
rcも書き換えておきましょう。
次はsyslog.confを書き換えです。
# vi /etc/syslog.conf
---省略---
!mpd
*.*                  /var/log/mpd.log 
あとは、空のファイルを作って、念のためにsyslogdにHUPシグナルを送っておきましょう。
ログファイルにはpppアカウント名が表示されてしまうので、パーミッションしっかりしておきましょう。
# touch /var/log/mpd.log
# chmod 600 /var/log/mpd.log
# pkill -HUP syslogd
これでログがザクザク書き込まれます。
でも、このままだとログがあふれてしまうので、ログローテートの設定を入れておきます。
newsyslog.confです。
# vi /etc/newsyslog.conf

# logfilename          [owner:group]    mode count size when  flags [/pid_file] [sig_num]
 ---省略---
/var/log/mpd.log                        600  3     100  *     JC    /var/run/mpd.pid 
mpd.logが300kbyteになったらbzip2で圧縮して新しいファイルを作り、mpd.pidにHUPシグナルを送るという意味に解釈します。
容量じゃなく、定時になったらローテートさせる方法もあります。詳しくは"man 5 newsyslog.conf"を読みましょう。

ルータのマシンスペックをあげたことも影響しているかもしれませんが、この方法でうちは70Mbps近く出ました。
ちなみにマシンスペックはVIA-AppoloProPentium3-533x2-Dual PC133-SDRAM-512MB fxp0.fxp1
こちらが証拠写真です。


参考文献

Mpd user manual (/usr/local/share/doc/mpdにあるhtmlドキュメント)
FreeBSD-user-jp 72791から続く一連のトピックPPPoEのスループットについて
PPPoE performance under Linux and BSDs http://derbian.org/pppoe/
2ちゃんねる FreeBSDでBBルータを作ろう互助会 http://pc.2ch.net/test/read.cgi/unix/1038060563/
NetBSDドキュメンテーションhttp://www.jp.netbsd.org/ja/Documentation/network/pppoe/

もどる