大規模Linuxルータ


Linuxで多数のsubnet間ルータを作ってみようというWebページです。

注: ルータとブロードバンドルータの違い

コレガやIOデータが販売しているブロードバンドルータは、正確には「NAT bridge」です。ルータではありません。全く別物です。

このページにはNAT Bridgeの事は書いてありませんのでご了承ください。

特に、このページで解説している「ルーティングデーモン」をNAT Bridgeで起動すると、 ネットワークに障害が発生します。決して起動しないでください。

実際はグローバルIPアドレスのルータを作成したが、10.0.0.0/16に書き換え ました。資料中の10.0.0.0/16はグローバルIPアドレスと考えてください。

このページにはルータのFAQ的な話しは書いてありません。まず、2個のsubnet のルータを作成してから、本ページを読んでください。


下記構成のネットワークでルータ構築を行いました。

パーティション構成

HDD構成は、40GB SATAが2台(/dev/sda,sdb)です。負荷分散および、障害対策 のため、起動デバイスはsda, /var/logのみsdbにしています。sdaとsdbは同一 構成の分割を行い、定期的にクロスmirrorを行っています。
[root@router init.d]# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda2             10080520    951580   8616872  10% /
/dev/sdb2             10080520   1152344   8416108  13% /b
/dev/sdb1               101086      9430     86437  10% /b/boot
/dev/sda4             27751572    146880  26194992   1% /b/var/log
/dev/sda1               101086      9433     86434  10% /boot
none                    257812         0    257812   0% /dev/shm
/dev/sdb4             27751572    101856  26240016   1% /var/log

余計なネットワーク設定は停止

  • IPv6停止
    /etc/modprobe.conf
    alias net-pf-10 off
    
  • APIPA(Automatic Private IP Addressing)169.254.0.0/16を停止
    /etc/sysconfig/network
    NOZEROCONF=yes
    

    ルーティング

    学内のルーティングプロトコルはripである。ルーティングデーモンとして、 (zebraからforkした)quaggaを使った。

    本ルータは基本的にはグローバルIPアドレスであるが、eth0のみプライベート IPアドレスである。192.168.0.0/24。外部へプライベートIPアドレスのripを流 してはいけない。そのためRIPの制御が必要。標準的なルーティングデーモン routedはRIPの制御が出来ない。そのためquaggaを使った。

    quaggaはFedoraCore3に標準で含まれる。

    設定例

    追記: 2006/7ごろのquaggaの仕様変更が入った模様

    arpテーブルの固定

    一部subnetでは接続機器の限定のため、arpテーブルの固定を行った。

    使ってないIPアドレスにはでたらめなMACアドレスを設定している。

    設定例


    dhcpサーバ

    一部subnetに対してdhcpのサービスを行った。

    多数NICがある構成では、dhcp対象のsubnetのLANインターフェースを/etc/sysconfig/dhcpdに書いたほうが良い。

    /etc/dhcpd.conf記入時の注意点として、同一MACの機器を異なるsubnetに接続する 場合、host名を同一にするとエラーになる。別名にした方が良い。


    アクセス制限

    iptablesを使った。

    2個のsubnetルータの場合はchain FORWARDでアクセス制限をかける場合が多い かと思うが、多subnetルータで、subnet毎のポリシーの違いが多すぎる場合は、 FORWARDでかけるのは少々厳しい。

    table mangle(iptable -t mangle)のchain PREROUTING/POSTROUTINGを使うほうが書きやすい。

    例えば、eth3に繋がっているSubnetのルールを書く場合は、

        /sbin/iptables -t mangle -N Subnet3
        /sbin/iptables -t mangle -A INPUT -i eth3 -j Subnet3
        /sbin/iptables -t mangle -A PREROUTING -i eth3 -j Subnet3
        /sbin/iptables -t mangle -A OUTPUT -o eth3 -j Subnet3
        /sbin/iptables -t mangle -A POSTROUTING -o eth3 -j Subnet3
    
    という感じで、新しい、chainを作成してSubnet毎にルールを書くのがやりや すい。なお、今回の構成ではINPUT/OUTPUTにも引っかけたが、 PREROUTING/POSTROUTINGだけでも十分かもしれない。

    logの蓄積については、iptableに次のようなlog専用chainを作成し、管理がしやすいようにした。

        /sbin/iptables -t mangle -N LDROP
        /sbin/iptables -t mangle -A LDROP -j LOG --log-prefix DROP: --log-level debug
        /sbin/iptables -t mangle -A LDROP -j DROP
    
        /sbin/iptables -t mangle -N LACCEPT
        /sbin/iptables -t mangle -A LACCEPT -j LOG --log-prefix ACCEPT: --log-level debug
        /sbin/iptables -t mangle -A LACCEPT -j ACCEPT
    
    logの出力ファイルについては、/etc/syslog.confに、新しいエントリを追加し、(スペースの部分はtabを挿入)
    kern.debug                                              /var/log/iptables
    
    専用ファイルに蓄積。logのrotateのために/etc/logrotate.d/iptablesを追加
    /var/log/iptables {
        rotate 100
        daily
        compress
        sharedscripts
        postrotate
            /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
        endscript
    }
    

    障害対策

  • kernelがエラーを出す

    下記エラーが多数出た。

    Mar 21 14:20:46 router kernel: Neighbour table overflow.
    Mar 21 14:21:39 router last message repeated 5 times
    Mar 21 14:22:44 router last message repeated 11 times
    Mar 21 14:37:51 router last message repeated 5 times
    Mar 21 14:37:51 router last message repeated 9 times
    
    エラーの出どころを調べると、linux-2.6.10/net/ipv4/route.c が出している。

    Googleで次のようなキーワードで検索した所、

    google: Neighbour table overflow net_ratelimit
    google: Neighbour table overflow /proc
    
    次のような情報が見つかった。
    http://www.in-addr.de/pipermail/lvs-users/2002-September/006703.html
    https://lists.netfilter.org/pipermail/netfilter/2002-November/040337.html
    
    英語がよくわからないのだが、多分下記のようにすれば良さそうです。
    % echo "4096" > /proc/sys/net/ipv4/neigh/default/gc_thresh3
    % echo 2048 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
    

    -- /etc/sysct.conf --
    net.ipv4.neigh.default.gc_thresh3 = 4096
    net.ipv4.neigh.default.gc_thresh1 = 2048
    ---------------------
    
    実際エラーが出なくなった。

    その他資料