2004/06/02 Beta7 Update.
      2004/04/07 Beta6 Update.
      2004/03/31 Beta5 Update.
      2004/01/30 Beta4 Update.
      2003/11/22 Beta3 Update.
      2003/11/21 Beta2 Update.
      2002/12/23 Beta1 Update.
    
で、秋葉原に行ってルータを見てみるものの安いやつはそれなりのフィルタリング機能しか 無いようだしスループットもあまり良くないような感じ。
    「ええい、ならば!」ということで安いPCを使ってルータを作ることにする。
    UNIXを使えば自宅サーバにするにも都合が良いのでOKか。
なので
    
    

    
    
|   | 
    
    


    
    
|   | 
    *2.5InchのHDDは熱ダレで連続運用には向かないそうなので、現段階のカスタマイズでは
    意味無し
    
    (後日512MBのCFにでも交換するかな)。
で、試しに電源投入
    なんだか最初よりも騒音が増したような気が。ケースFANは当初から「ちょっとうるさいかな」
    とは感じていたが今はあからさまに耳につく。
    おそらくCD-ROM Driveを撤去したことでCPU FANの音が通りやすくなってしまったのかなぁと
    推測。
で、会社帰りに秋葉に行って静音FANを探す。ポイントとしてはケースFANはサイズを 40cm→60cmとすることで風量を確保しつつ騒音を減らす。 CPU FANは撤去してしまう(CPUの動作時温度が37℃なので、まだ余裕があるかなと)。で…
でトライ。
    
    
|  | 
    
    で、再度電源投入
    少なくとも耳で感じられるほどの動作音はしなくなったようで、成功したみたい。
    ただ、HDDアクセス時のシーク音はするので、やっり無音というわけにはいかない。
    CFに交換することで完全な物になるかな。
    BIOSの設定
| IDE Primary Master | Manual | 
| Access Mode | CHS | 
| IDE Primary Slave | None | 
| Drive A | None | 
| First Boot Device | HDD-0 | 
| Second Boot Device | LAN | 
| Third Boot Device | Disabled | 
| DRAM Clock | Host CLK | 
| Fram Buffer Size | 2M | 
| AGP Aperture Size | 4M | 
| Onboard USB | Disabled | 
| Primary Slave UDMA | Disabled | 
| Onboard FDD Controller | Disabled | 
| Onboard Serial Port 1 | Disabled | 
| Onboard Parallel Port | Disabled | 
| MODEM Use IRQ | NA | 
| Keyboard Power On | Disabled | 
| Wake On LAN/Ring | Enabled | 
一応、WOLは使えるようにしておく。
    FreeBSDのインストール
    4-STABLEはCVSサーバからソースコードで提供されているのでいきなりインストールすることが
    できない。
    そこで一度FreeBSD 4.7をCD-ROMからインストールし、4-STABLEのソースコードを展開し
    コンパイル→インストールすることにする。
まずは撤去したCD-ROM Driveを再度接続してCD-ROMからミニマムインストールする。 パーティションはログが貯まる/varを大きく取りたいので
| / | ufs | 300MB | 
| swap | 512MB | |
| /usr | ufs | 1024MB | 
| /var | ufs | 7600MB | 
とした(インストール方法の詳細は省略、オフィシャルの ハンドブックでも見てね)。
    STABLEへのバージョンアップ
で、シングルユーザモードに移行して
とする(このまま実行すると/etc以下の全てを上書きしてしまうで注意)。
としてお掃除する。
    OS構成のカスタマイズ
    BIOSで電源ボタンのアクションをサスペンドに設定。
    んで、ファイルを以下のように変更する。
| 
    apm_event SUSPENDREQ, USERSUSPENDREQ { 
          exec "sync";
          exec "sync";
          exec "sync";
          exec "shutdown -p now";
    } | 
    カーネルの再構築
    また、使用するカーネル機能はダイナミックモジュールよりもスタティックにカーネルに
    組み込んでしまうほうが効率が良いのでモノシリックで作成することに。
    まずはカーネルの構成ファイルを/usr/src/sys/i386/conf/GENERICファイルを見本に
    作成する。
    出来上がったのがこれ。
で、カーネルを生成してインストール
    PPPoEの設定
| 
    default:
        set device PPPoE:rl0
        set mru 1454
        set mtu 1454
        set speed sync
        set log Phase
        set dial
        set login
        set ifaddr 10.0.0.1/0 10.0.0.2/0
        add default HISADDR
        set cd 5
        set crtscts off
        enable tcpmssfixup
        accept CHAP
    rimnet:
        set authname xxxxxxxx@xx.rim.or.jp 
        set authkey xxxxxxxx | 
電源を入れたら勝手に上の設定が有効になるように以下の設定を追加する。
| 
    # PPP
    ppp_enable="YES"
    ppp_nat="NO"
    ppp_mode="ddial"
    ppp_profile="rimnet"  | 
    NAT(Dynamic NAT)については次の章で説明する。
    GATEWAYとしての設定
| 
    # Gateway/NAT
    gateway_enable="YES"
    natd_enable="YES"
    natd_interface="tun0 -f /etc/natd.conf -s" | 
NATの挙動を設定。上のnatdの挙動設定で指定しているファイルを以下のように記述する。
| 
    log                     yes
    deny_incoming           no
    log_denied              no
    log_facility            security 
    use_sockets             yes
    same_ports              yes
    verbose                 no
    unregistered_only       no
    dynamic                 yes | 
動作的には、起動時に/etc/rc.confが実行されるので、中で指定しているNATの設定も有効と なる。
    フィルタリングの設定
    また、TCPの送信パケットに対して受信パケットのルールについては、ダイナミックにフィルタリング
    ルールが生成される(UDPについてはダイナミック生成はできないので、手で書くしかない)。
| 
    # IP Firewall rule
    LAN="192.168.100.0/24"
    MODEM="192.168.0.254"
    NTP1="210.173.160.27"
    NTP2="210.173.160.57"
    NTP3="210.173.160.87"
    IPFW="/sbin/ipfw -q add"
    /sbin/ipfw -f flush
    # fragment packet
    ${IPFW} deny ip from any to any via tun0 frag
    # for GENERAL(DCOM, NetBIOS, Windows Network)
    ${IPFW} deny tcp from any to any 135,137,138,139,445 via tun0
    ${IPFW} deny udp from any to any 135,137,138,139,445 via tun0 
    # W32/Blaster
    ${IPFW} deny udp from any to any 69 via tun0
    ${IPFW} deny tcp from any to any 4444 via tun0
    # for ADSL MODEM
    #${IPFW} allow all from ${LAN} to ${MODEM} keep-state
    # NAT
    ${IPFW} divert natd all from any to any via tun0
    # established
    ${IPFW} pass tcp from any to any established
    # Dynamic Rule
    ${IPFW} check-state
    # for lan
    ${IPFW} allow all from ${LAN} to any keep-state
    # me
    ${IPFW} allow all from me to any keep-state
    ${IPFW} allow udp from ${NTP1} 123 to me
    ${IPFW} allow udp from ${NTP2} 123 to me
    ${IPFW} allow udp from ${NTP3} 123 to me
    # for ftp.t3.rim.or.jp ftp-data connection
    ${IPFW} allow tcp from ftp.t3.rim.or.jp 20 to ${LAN}
    # RFC2979
    ${IPFW} allow icmp from any to any in via tun0 icmptypes 3
    # Disregard
    ${IPFW} deny icmp from any to me in via tun0 icmptypes 8
    # loging
    ${IPFW} deny log logamount 1000000 ip from any to any | 
     
    fragment(こまぎれ)なパケットは受け取らない。 
    "for GENERAL"でWindowsのセキュリティ上危険なサービスは明示的に閉じておく。 
    念のためW32/Blasterウィルスについても明示的にフィルタリング。 
    "NAT"でパケットをルールに従って変換。 
    "established"で、コネクションが確保されているパケットは許可。 
    "for lan"で、内部から任意に向けたパケットを許可。 
    "NTP"で外部NTPサーバとの通信を許可。 
    "for ftp.t3.rim.or.jp"はホームページ更新用。リムネットはPASSIVEモード禁止なの。 
    RFC2979で宛先不明のパケットは受け取らないといけないので記述しているんだけど基本的に
    は関係無いハズ。 
    インターネット側から許可していないアクセスがあった場合には記録を取るが
    ping(ICMP-ECHO)はあまりにも多いので無視。
    
    
    始めにルールを明示的に初期化。後から手動でipfwを実行する場合の手順を簡略化するため。
起動時にファイアウォールを自動的に有効にするために設定を追加する。
| 
    firewall_enable="YES"
    firewall_script="/etc/ipfw.conf"  | 
    
    適当に抜出して説明しているが理解するにはTCP/IPの基本的な知識を要する。
    BIND9
FreeBSDはBIND8が標準なのでportsから別途インストール
最近ルートサーバのIPアドレスが変ったという話しがあったのでアドレスを確認 しておく。
| 
        B.ROOT-SERVERS.NET.      3600000      A     192.228.79.201  | 
の一文を確認。上のとおりなら更新済。
rndcによるbindの制御(旧named.reloadとかnamed.restart)。リモート制御できるので 秘密鍵共有で認証して安全に使おうねって話。
生成したrndc.keyを編集して以下のようにする
| 
        key example.jp {
              algorithm "HMAC-MD5";
              secret "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; 
        }; | 
"XXXXXXXXX"の中身は生成された値。key以下のファイルは不要なので消しましょう。
| 
        options {
             directory "/etc/namedb";
             pid-file "named.pid";
        };
        include "rndc.key";
        controls {
            inet 127.0.0.1 allow { 127.0.0.1; } keys { localnet.jp; }; 
        };
        acl "SERVERS" {
            127.0.0.1;
            192.168.0.253;
            192.168.100.254;
        };
        view "internal" {
            match-clients {
                127.0.0.0/8;
                192.168.0.253/32;
                192.168.100.0/24;
            };
            zone "." {
                type hint;
                file "named.root";
            };
            zone "localhost" {
                type master;
                file "localhost";
            };
            zone "0.0.127.IN-ADDR.ARPA" {
                type master;
                file "localhost.rev";
            };
            zone "example.jp" {
                type master;
                file "localnet.jp";
            };
            zone "100.168.192.IN-ADDR.ARPA" {
                type master;
                file "example.jp.rev";
            };
            zone "rimnet" {
                type forward;
                forward only;
                forwarders {
                    202.247.130.5;
                };
            };
        }; | 
controls { ... } でrndcのアクセス制限を定義。
aclでゾーン転送の許可。
        view "internal" { ... } でアクセスの制限を掛ける。
        続けて view "external" { ... } を定義するときは"internal"の下でないとダメ
        (と言うよりは、match-clients { any; } とするので一番最後のviewとして定義する)。
        アクセス制限を掛けているところは明示的に自身のIPアドレス(2つ)を書いておく。
      
| 
         include "/etc/namedb/rndc.key" 
         options {
             default-server 127.0.0.1;
             default-key example.jp;
         }; | 
リンクをはっておく
| 
        $TTL    3d
        @       IN      SOA     gw.example.jp. postmaster.gw.example.jp. ( 
                                20040331;
                                172800;
                                3600;
                                1728000;
                                172800 );
        ;
                IN      NS      gw.example.jp.
                IN      A       192.168.100.254
        ;
        foo     IN      A       192.168.100.10
        bar     IN      A       192.168.100.11
        gw      IN      A       192.168.100.254 | 
上の例ではfoo,barという内部LANに存在するホストを登録している。
| 
        $TTL    3d
        @       IN      SOA     gw.example.jp. postmaster.gw.example.jp. ( 
                                20040331;
                                172800;
                                3600;
                                1728000;
                                172800 );
        ;
                IN      NS      gw.example.jp.
        ;
        10      IN     PTA      foo.example.jp.
        11      IN     PTA      bar.example.jp.
        254     IN     PTA      gw.example.jp. | 
named権限で動作させるので設定ファイルの所有者を設定。
手動起動してみて
digとか使って適当に確認しましょう。デバックオプションは -g -d [debug level]。
/etc/rc.dに以下の設定を追加。
| 
        named_enable="YES"
        named_program="usr/local/sbin/named"
        named_flags="-u bind -c /etc/namedb/named.conf"  | 
| 
    ssh     stream  tcp     nowait  root    /usr/sbin/sshd          sshd -i  | 
うちはipfwでアクセス制限してるので不要だけど、気になる場合にはアクセス制限して おきまふ。
| 
    sshd : foo.bar.jp : allow 
    ALL  : ALL        : deny | 
上の例では、foo.bar.jpからのみsshによるアクセスを許可。
    NTP
| 
    server  210.173.160.27
    server  210.173.160.57
    server  210.173.160.87
    driftfile /etc/ntp.drift | 
    上で指定している3つのサーバは一般公開されているNTPサーバ。
    次に起動設定。以下の一文を追加する。
| 
    xntpd_enable="YES" | 
デーモン起動させたら10分ぐらい待ってからステータスを確認してみる。
行頭に"*"のマークが付いているやつを今はマスタとして同期してますよということ。 で、各パラメータにそれらしい値が入っていればOK。
    SNMP
    複数のネットワーク機器を監視する場合(そういう使い方のほうが多いでしょう)は監視対象機器で
    SNMPエージェントを動かし、管理ホスト(監視者)上でSNMPマネージャを動かしたりするが、今回は
    自己監視が目的なのでエージェントとマネージャは1つのホストの上で動くことになる。
    また、SNMPの実装として色々な物があるが今回はucd-snmp(NET-SNMP)を使うことにする。
毎度おなじみportsから導入する。今回は途中で幾つかの質問に答えないといけない。
前のステップでコピーしたSNMPエージェントの設定ファイルのcom2secで始まる行を 変更する。
| 
        com2sec local     localhost           private 
        com2sec mynetwork 192.168.100.0/24    public | 
SNMPで管理したい範囲とコミュニティ名(private,public)を指定している(現時点ではLAN内に管理 したい機器は無いが後のために書いておく)。また、ここで設定したコミュニティ名はパスワード としても使われるので、本当はこんな推測されやすい名前はペケだしファイルのパーミッションも 気をつけるべき。
続けてsnmpd.confの編集。SNMPでは管理情報の書込みも出来るが、今回は使用しないので無効にする。 「group MyRWGroup...」を全てコメントアウトもしくは削除する(設定ファイルの下のほうに記述され ている「access MyRWGroup...」でセキュリティグループの定義が行われており、書込みしないなら こっちもコメントアウトしておいたほうが安心かも)。
さらに続けてsnmpd.confの編集。エージェントが公開する管理情報の範囲を設定する。デフォルトで 以下のように全情報を公開するように設定されており、今回はそのままで行く。
| 
        view all    included  .1                    80  | 
またもやsnmpd.confの編集。マネージャに対してどのような操作を許可するのか設定する。
| 
        access MyROGroup ""      any       noauth    exact  all    none   none | 
デフォルトでは上のようになっているが、noauthをauthとかprivにすれば認証したりできる。 今回はこのまま。
まだまだsnmpd.conf。コンパイル時に指定したメールアドレスとかロケーション情報をここで変更できる。 デフォルトのままであればコンパイル時の設定が使われるらしい。
| 
        syslocation Home Gateway Server 
        syscontact foo.bar@example.jp  | 
やっとこさ起動。
とりあえずテストということで、コミュニティ"private"の全ての情報を取得してみる。
*portsだとsnmpdにtcp_wrapperが組込まれているので要注意!
    MRTG
    Webから参照したい場合には別途Webサーバが必要となる。
作成したmrtg.cfgを開いて生成するグラフの場所を指定する (指定したディレクトリは別途作成)。
| 
        WorkDir: /var/mrtg_data  | 
グラフを見るためにWebサーバをインストール(本当はこんなとこでする話しじゃないね)。
MRTGで生成するグラフをWebサーバで見せる設定。 /usr/local/etc/apache2/httpd.confのDocumentRootを以下のとおり変更。
| 
        DocumentRoot "/var/mrtg_data" | 
下に続くディレクティブ(という表現でいいんだっけなぁ)設定も /usr/local/www/dataから/var/mrtg_dataに変更
手動でグラフを生成してみる。
*1回目、2回目はワーニングが出る。
適当にアクセスしてみる。例えばhttp://localhost/localhost_4.htmlとか。
ちなみに、MRTG(のデフォルト)はインターフェースごとにレポートを作成するので、うちの場合には rl0,rl1,pppの3つになる(3はlocalhostかな?)。
cronを使って定期的にMRTGを動かすことによりレポートを自動更新する。
        # crontab -eで、5分ごとに動くようにしてみる。
| 
        0,5,10,15,25,30,35,40,45,50,55 * * * * /usr/local/bin/mrtg /usr/local/etc/mrtg/mrtg.cfg  | 
1日ぐらい放置しておくとそれらしいグラフが出来上がる。
CPUの稼働率、メモリとSwapの使用率も取りたいので以下の設定を追加。
| 
        ### CPU Load Avalage
        Target[cpu]: 1.3.6.1.4.1.2021.10.1.5.2&1.3.6.1.4.1.2021.10.1.5.3:private@localhost:
        MaxBytes[cpu]: 2000
        Title[cpu]: CPU Load Avalage
        PageTop[cpu]: <H1>CPU Load Avalage</H1>
        Options[cpu]: nopercent, integer, gauge, absolute, withzeroes
        YLegend[cpu]: CPU Load Avalage
        ShortLegend[cpu]: percent
        Legend1[cpu]: 5 min CPU Load Avalage
        Legend2[cpu]: 15 min CPU Load Avalage
        LegendI[cpu]: 5min
        LegendO[cpu]: 15min
        ### Memory
        Target[mem]: 1.3.6.1.4.1.2021.4.6.0&1.3.6.1.4.1.2021.4.4.0:private@localhost:
        MaxBytes1[mem]: 128000
        MaxBytes2[mem]: 512000
        Title[mem]: Memory Used
        PageTop[mem]: <H1>Memory Used</H1>
        Options[mem]: gauge, absolute
        YLegend[mem]: Mem Free kBytes
        ShortLegend[mem]: kBytes
        Legend1[mem]: Real Memory
        Legend2[mem]: Swap Memory
        LegendI[mem]: Real
        LegendO[mem]: Swap | 
上記のコマンドだけではindex.htmlが作成されないので、作る。
portsから。
        HotSaNICを入れる。これはSNMPやOSに実装されているコマンドを使って
        CPUやメモリ等の使用状況データを収集するperlスクリプト。
        収集したデータをグラフ化するためにRRDToolを使っている。
        これはportsに含まれないので手で入れる。
        hotsanic.sourceforge.netからソースを取って
        きて
上記のセットアップで生成されたファイルに以下の設定を追加。
| 
        BINPATH="/usr/local/bin"
        WEBDIR="/var/rrdtool_data"
        IMAGEFORMAT="png"
        CONVERTMETHOD="ImgMgck"
        CONVERTPATH="/usr/local/bin/convert" | 
"WEBDIR"で指定したディレクトリにHTMLファイルが置かれることになるので別途作成しておく。
RRDToolから呼ばれるようなので入れておく。
パーミッション744で作成。
| 
        #!/bin/sh
        HOTSANIC=/usr/local/HotSaNIC/rrdgraph
        if [ ! -x ${HOTSANIC} ] ; then
              echo "${HOTSANIC} not found."
              exit 1
        fi
        case "${1}" in
        start)
              ${HOTSANIC} ${1} && echo -n ' HotSaNIC' 
              ;;
        stop)
              ${HOTSANIC} ${1} && echo -n ' HotSaNIC' 
              ;;
        *)
              echo "Usage: ${0} {start|stop}" >&2
              ;;
        esac
        exit 0 | 
setup.plでは設定してくれないので手動設定。以下の行を追加。
| 
        SENSOR=TEMP0,TEMP0,CPU Temp,,,,C
        SENSOR=TEMP1,TEMP1,Motherboard Temp,,,,C 
        SENSOR=FAN0,FAN0,FAN Speed,,,,RPM
        SENSOR=VC0,VC0,VCORE,,,,V
        SENSOR=VC1,VC1,+2.5V,,,,V
        SENSOR=V33,V33,+3.3V,,,,V
        SENSOR=V50P,V50P,+5.0V,,,,V
        SENSOR=V12P,V12P,+12.0V,,,,V | 
で、HTMLを作る。
インデックスには+12Vの値しか出てこない… グラフは作られているのでBUGかな?
bindデーモンの状態を監視する。sensorsと同様に自動では作られないので手動で追加。
| 
        BINDPATH=/usr/local/sbin/rndc
        BINDSTAT=/etc/namedb/named.stats  | 
HTMLの作成は同様に。
SNMPのコミュニティ名関係を設定。
| 
        HOST=SNMP:localhost:private,Home Gateway Server  |