ipfw

 

ipfw と NAT の設定手順

ipfw は FreeBSD のパケットフィルタである. 現在の FreeBSD では,ipfw の機能はカーネルモジュールipfw.koipfw_nat.ko)として提供されており, カーネルの再構築は不要である. /etc/rc.conf の設定に従って,起動時に必要なモジュールが自動的に読み込まれる.

アドレス変換(NAT)には,カーネル内 NATipfw nat)と, divert ソケットを用いる旧来のユーザランド NAT(natd)がある. カーネル内 NAT はパケットをユーザランドに渡さないため処理の負荷が小さく, 新規の設定ではカーネル内 NAT を用いる.

  1. ゲートウェイとして動作させる
    /etc/rc.conf に以下の行を追加する.
        gateway_enable="YES"
    
  2. ipfw を有効にする
    /etc/rc.conf に以下の行を追加する.
        firewall_enable="YES"
        firewall_script="/etc/ipfw.rules"
        firewall_logging="YES"
        firewall_nat_enable="YES"
        firewall_quiet="YES"
    
    • firewall_script には,ルールを記述したファイルを指定する. /etc/rc.firewall を直接書き換えると,OS の更新時に変更が失われるため, 別ファイルを作成して指定する
    • firewall_logging="YES"net.inet.ip.fw.verbose を 1 に設定し, log キーワードの付いたルールに一致したパケットを syslog(facility は LOG_SECURITY)に記録させる. 旧来のカーネルオプション IPFIREWALL_VERBOSE は不要である.
    • firewall_nat_enable="YES" は,カーネル内 NAT のモジュール ipfw_nat.ko を読み込ませる.
  3. ipfw のルールを記述する
    ここでは次の方針でルールを作る.
    • 禁止したパケットについてのログを録ること
    • telnet での外部への接続を禁止
    • 192.168.33.* に向けての接続は telnet 以外すべて許可
    • tcp で外部に接続するのは telnet 以外すべて許可
    • udp で 192.168.33.* 以外への接続は DNS(ポート番号 53)のみ許可
    • icmp はすべて許可
    • 許可していないものはすべて禁止
    /etc/ipfw.rules を新規に作成し,以下のように記述する.
        #!/bin/sh
    
        fwcmd="/sbin/ipfw -q"
        oif="外側インターフェース名"
        onet="192.168.33.0/24"
        inet="192.168.40.0/24"
    
        ${fwcmd} -f flush
    
        # ループバック
        ${fwcmd} add 100 allow ip from any to any via lo0
        ${fwcmd} add 200 deny ip from any to 127.0.0.0/8
        ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any
    
        # カーネル内 NAT
        ${fwcmd} nat 1 config if ${oif} same_ports unreg_only reset
        ${fwcmd} add 400 nat 1 ip from any to any via ${oif}
    
        # telnet の禁止(ログを録る)
        ${fwcmd} add 1000 deny log tcp from any to any 23
    
        # 192.168.33.0/24 に向けての接続の許可
        ${fwcmd} add 2000 allow ip from any to ${onet}
    
        # tcp の許可(telnet はルール 1000 で禁止済み)
        ${fwcmd} add 3000 allow tcp from any to any
    
        # DNS の許可
        ${fwcmd} add 4000 allow udp from any to any 53
        ${fwcmd} add 4100 allow udp from any 53 to any
    
        # icmp の許可
        ${fwcmd} add 5000 allow icmp from any to any
    
        # 上記以外はすべて禁止(ログを録る)
        ${fwcmd} add 65000 deny log ip from any to any
    
    ルールはルール番号の小さい順に照合され,最初に一致したルールの動作が行われるため, 禁止のルールを許可のルールより前に置く. ipfw -q-q は,ルール適用時のメッセージ出力を抑止する.
  4. ルールを反映させる
    再起動せずに反映させるには次のコマンドを実行する.
        # service ipfw restart
    
    遠隔ログイン中にルールを適用して接続が切れた場合は, コンソールから次のコマンドを実行すると,ルールの照合を一時的に停止できる.
        # ipfw disable firewall
    
  5. 確認
    以下のコマンドで ipfw のルールリストを表示する.
        # ipfw list
    
    カウンタの値も合わせて表示するには次のコマンドを実行する.
        # ipfw -a list
    
    NAT の設定と統計は次のコマンドで確認する.
        # ipfw nat 1 show config
        # ipfw nat 1 show log
    

natd を使う場合

divert ソケットを用いる natd を使用する場合は, /etc/rc.conf に以下の行を追加する.

    gateway_enable="YES"
    natd_enable="YES"
    natd_interface="外側インターフェース名"

このとき,ルールファイルでは NAT のルールを divert アクションで記述する.

    ${fwcmd} add 400 divert natd ip from any to any via ${oif}

ipfw のルール変更

この形式での使用法は:
      ipfw [-q] コマンド [ルール番号] [set N] アクション [log] プロトコル アドレス [ オプション ]
コマンド ルール番号 log アクション プロトコル アドレス
      from <address/mask>[port] to <address/mask>[port] [via <interface>]
port はポートをサポートするプロトコル(TCP と UDP)の場合にだけ指定可能.
via は必須ではなく,特定のインタフェースを通ったパケットだけにマッチさせるために, IP アドレス,ローカル IP インタフェースのドメイン名, またはインタフェース名(例えば em0)を指定することができる. パケットの向きを限定するには inout, 受信側・送信側のインタフェースを限定するには recvxmit を用いる.
<address/mask> の指定は:
      <address>
または
      <address>/mask-bits
または
      <address>:mask-pattern
IP アドレスのかわりにホスト名を指定することも可能である. mask-bits はアドレスマスクで上位何ビットを 1 にするかを示す十進数値である. 例えば次の指定
      192.216.222.1/24
は,192.216.222.0/24 の任意のアドレスにマッチするマスクを作成する. mask-pattern は,与えられたアドレスと論理 AND される IP アドレスである. キーワード any は「任意の IP アドレス」を指定するために使用することができる.

ipfw ルールリストの表示

この形式での使用法は:
      ipfw [-adnNStT] list
主なフラグは次の通りである.