IPFW + natd for ADSL
 ADSL のための IPFW と natd の設定
バナー

■IPFW + natd はやってる人が少ない?

Google で検索しても ADSL + IPFW + natd の情報がちょっと少ないですね.
しかも natd によるポートフォワーディングはほとんど皆無.

仕方がないのでここでまとめることにします.

■とりきめ

まずは大まかな外見のとりきめ.

つぎに IPFW 定義のとりきめ.

  1. ICMP は全てをブロックしない
  2. ループバックパケットの許可
  3. 断片化されたパケットの破棄
  4. 内側のネットワークは制限無し
  5. アドレス詐称パケットの拒否
  6. NetBIOS を破棄
  7. NAT 用 divert 設定
  8. パケットが既に確立されているパケットを許可
  9. 内部から外側へのすべてのパケット通過の許可
  10. 外部 DNS 参照時の要求と返答を許可
  11. 外からの HTTP(S) を許可
  12. 外からの SMTP を許可
  13. 外からの SSH を許可
  14. NTP 返信を許可
  15. SNMP 返信を許可
  16. ICQ を受け付ける
  17. それ以外はログを取って全て拒否
  18. keep-state を使った、LAN から外部への UDP 通信の許可
  19. それ以外はログを取って全て拒否
説明の中のネットワーク構成は以下の通り.

・ed0 :内部接続用インターフェイス
・ed1 :外部接続用インターフェイス
・tun0:ダイアルアップ用仮想インターフェイス

          +----------> インターネット(ISP)
          |
          | ← tun0 (ed1) 側 (グローバル IP)
          |
         ■← FreeBSD ルーター (ipfw & natd & ppp)
         |
         | ← ed0 側 (プライベート IP - 192.168.1.0/24)
         |
LAN -----+-----------------+-----
         |                 |
         +--■ ←内部鯖     +--■←倉

■実際の設定

まずはカーネルを再構築しよう.
一部抜粋.

- /usr/src/sys/pc98/conf/KERNELNAME
# IPFW options
options         IPFIREWALL              #IP Fire wall
options         IPFIREWALL_VERBOSE      #IP Fire wall logging
options         IPDIVERT                #IP Divert (NAT)

# PPPoE optins
options         NETGRAPH
options         NETGRAPH_ETHER
options         NETGRAPH_PPPOE
options         NETGRAPH_SOCKET

# Dial up interface enable
pseudo-device	tun	1

この設定を書き込んでカーネルコンパイルする.
コンパイル方法は基本なので自分で調べよう.

次に ppp.conf の設定.

- /etc/ppp/ppp.conf

default: set device PPPoE:ed1 # PPPoE で使う NIC デバイスを指定. set log Phase Chat LCP IPCP CCP tun command set speed sync set mru 1492 set mtu 1454 # MTU 値 set ctsrts off set timeout 0 # タイムアウトを監視しない accept CHAP add default HISADDR enable tcpmssfix ## DNSは直接外に見に行く場合有効にする.ただし /etc/resolv.conf が強制的に書き換えられるので注意. #enable dns ## ppp で NAT 制御するときに使用する.今回は natd に任せるのでコメントアウト. #nat enable yes set authname USERID set authkey PASSWD

ppp.conf の作成が終わったらとりあえず最低限の設定をしよう.

- /etc/rc.conf

### インターフェイス系 # ゲートウェイになるように設定 gateway_enable="YES" # 内側インターフェイス ifconfig_ed0="inet 192.168.1.253 netmask 255.255.255.0" # 外側インターフェイス ifconfig_ed1="up" portmap_enable="NO" ### 防火壁系 # 防火壁を有効にする firewall_enable="YES" # 起動スクリプト firewall_script="/etc/rc.firewall" # 設定ファイルもしくは rc.firewall 内で指定されているルール名 firewall_type="open" # firewall_quiet="NO"

これでとりあえず外からも中からも通信が出来るようになる.
ここでもう一度再起動.

再起動が終わったらまずはテストしてみる.
ここからは Windows など複数ウィンドウの開けられる OS で設定すると良いだろう.
ppp コマンドは root 以外使えないので su で root になって起動すること.

% su
Password:
# ppp
Working in interactive mode
Using interface: tun0
ppp ON ortoros>

ここでおもむろに dial と打ってリターンを叩くと接続を開始する.
正常に接続できたら pppPPP と大文字になる.

% su
Password:
# ppp
Working in interactive mode
Using interface: tun0
ppp ON ortoros>
ppp ON ortoros>dial
ppp ON ortoros>
Ppp ON ortoros>
PPp ON ortoros>
PPP ON ortoros>

めでたく PPP になったらもう 1枚別のウィンドウで接続する.
接続したら外に繋がるかを確認しよう.

% ping www.yahoo.co.jp
PING www.yahoo.co.jp (210.152.236.50): 56 data bytes
64 bytes from 210.152.236.50: icmp_seq=0 ttl=241 time=39.359 ms
64 bytes from 210.152.236.50: icmp_seq=1 ttl=241 time=39.147 ms
64 bytes from 210.152.236.50: icmp_seq=2 ttl=241 time=43.584 ms
64 bytes from 210.152.236.50: icmp_seq=3 ttl=241 time=40.234 ms

--- www.yahoo.co.jp ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 39.147/40.581/43.584/1.781 ms

ping が通っていればとりあえず繋がったことは繋がった.

繋がったら次はルーティング用に natd の設定をする.

- /etc/natd.conf

### 基本設定 use_sockets yes same_ports yes port 8668 # NAT ルーティングに使用するポート unregistered_only yes dynamic yes # ルーティングインターフェイスの動的監視.ppp では必須 ### これ以降はポートフォワーディング設定 ## redirect_port PROT TARGET_ADDR:TARGET_PORT[-TARGET_PORT] IN_PORT[-IN_PORT] ## example: natd(8) redirect_port tcp 192.168.1.10:20-25 20-25 redirect_port tcp 192.168.1.10:80 80 redirect_port tcp 192.168.1.10:110 110

この設定で動的 NAT の利用及び内部公開サーバーへのルーティングが行える.
設定が終わったら実際に natd を起動してみよう.

# natd -config /etc/natd.conf -interface tun0

オプションの説明.

ちなみに natd によるポートフォワーディングは ppp が起動したままでもルールを変更できるので,ルールを変更するたびにつなぎ直しで IP アドレスが変わるということはなくなる.
しかしルールを変更した後は natd の再起動が必要になるので注意して欲しい.

起動が完了したら,ゲートウェイアドレスを ADSL PC ルーターに向けている PC で外へ繋がるか確認してみよう.
ping だと面白くないと思うので,ここはブラウザで適当な Web ページを見ることにする.

無事に Web ページを見ることが出来れば次の段階に進めるが,ここで見られない場合は natd と IPFW の設定が間違っている可能性が非常に高い.
natd による動的 NAT は,IPFW でパケットを 8668 に divert するように設定をしておかなければならない.
rc.conf に ppp と natd の設定を書き込むと,起動時に IPFW が 8668 への行き先を設定してくれるようだが,その設定をしていないと 8668 への行き先設定がされない.

とりあえず ipfw list してみよう.

# ipfw list
100 allow ip from any to any via lo0
200 deny ip from any to 127.0.0.0/8
300 deny ip from 127.0.0.0/8 to any
400 allow ip from any to any
65536 deny ip any to any

もし divert 8668 がなければ自分で定義する.

# ipfw 10 add divert 8668 ip from any to any via tun0
10 divert 8668 any to any via tun0

これで動的 NAT が有効になる.
設定し終えた後にもう一度テストしてみる.
これでダメなら natd の設定を見直すこと.

次は本命の IPFW の設定をする.
設定ファイルは既存の rc.firewall と入れ替えることを前提に作ってあるので,/etc/rc.conf の firewall_script を変更する.
まずはファイルの中身から.

- /etc/rc.ipfw

### 基本設定 IPFW="/sbin/ipfw" # ipfw のフルパス ALLOW="allow log" # allow 指定時の文字列.log を付け足すことでロギングも出来る. #ALLOW="allow" DENY="deny log" # deny 指定時の文字列.log を付け足すことでロギングも出来る. #DENY="deny" ### まずは初期定義を初期化 ipfw -q -f flush ### ICMP 用ルール - ADSL では ICMP をブロックしてはならない ${IPFW} 100 add ${ALLOW} icmp from any to any ### ループバックパケットの許可 ${IPFW} 200 add ${ALLOW} ip from any to any via lo0 ### 断片化されたパケットの破棄 ${IPFW} 300 add ${DENY} ip from any to any via tun0 frag ### 内側のネットワークは制限無し ${IPFW} 400 add ${ALLOW} ip from 192.168.1.0/24 to any via ed0 ${IPFW} 410 add ${ALLOW} ip from any to 192.168.1.0/24 via ed0 ### アドレス詐称パケットの拒否 ${IPFW} 500 add ${DENY} ip from 192.168.1.0/24 to any recv tun0 ${IPFW} 510 add ${DENY} ip from 127.0.0.1 to any recv tun0 ${IPFW} 520 add ${DENY} ip from any to 127.0.0.0/8 ${IPFW} 530 add ${DENY} ip from 127.0.0.0/8 to any ### NetBIOS を破棄 ${IPFW} 600 add ${DENY} tcp from any 137-139,445 to any ${IPFW} 610 add ${DENY} udp from any 137-139,445 to any ${IPFW} 620 add ${DENY} tcp from any to any 137-139,445 ${IPFW} 630 add ${DENY} udp from any to any 137-139,445 ### NAT 用 ${IPFW} 900 add divert 8668 ip from any to any via tun0 ### パケットが既に確立されているパケットを許可 ${IPFW} 1000 add ${ALLOW} tcp from any to any established ### tun0 を通過する内部から外側へのすべてのパケット通過の許可 ${IPFW} 1010 add ${ALLOW} ip from any to any out via tun0 ### 外部 DNS 参照時の要求と返答を許可 ${IPFW} 1300 add ${ALLOW} udp from any to any 53 ${IPFW} 1310 add ${ALLOW} udp from any 53 to any ### 外からの HTTP(S) を許可 ${IPFW} 1400 add ${ALLOW} tcp from any to 192.168.1.10 80 setup ${IPFW} 1410 add ${ALLOW} tcp from any to 192.168.1.10 443 setup ### 外からの SMTP を許可 ${IPFW} 1500 add ${ALLOW} tcp from any to 192.168.1.10 25 setup ### NTP 返信を許可 ${IPFW} 1600 add ${ALLOW} udp from any 123 to any ### SNMP 返信を許可 ${IPFW} 1700 add ${ALLOW} udp from any 161 to any ### 外からの POP3 を許可 ${IPFW} 1800 add ${ALLOW} tcp from any to 192.168.1.10 110 setup ### 外からの FTP を許可 ${IPFW} 1900 add ${ALLOW} tcp from any to 192.168.1.10 20 setup ${IPFW} 1910 add ${ALLOW} udp from any to 192.168.1.10 20 ${IPFW} 1920 add ${ALLOW} tcp from any to 192.168.1.10 21 setup ${IPFW} 1930 add ${ALLOW} udp from any to 192.168.1.10 21 # PASV 用 ${IPFW} 1940 add ${ALLOW} tcp from any to 192.168.1.10 7000-7500 ${IPFW} 1950 add ${ALLOW} udp from any to 192.168.1.10 7000-7500 ### ICQ を許可 ${IPFW} 2000 add ${ALLOW} udp from any 4000 to any in recv tun0 ### 外からの SSH を許可 ${IPFW} 2100 add ${ALLOW} tcp from any to 192.168.1.10 22 setup ### それ以外はログを取って全て拒否 ${IPFW} 9900 add ${DENY} tcp from any to any ### keep-state を使った、LAN から外部への UDP 通信の許可 ${IPFW} 20000 add ${ALLOW} udp from any to any keep-state out via tun0 ${IPFW} 20010 add check-state ### それ以外の UDP パケットの禁止 ${IPFW} 20020 add ${DENY} udp from any to any ### Default setting. Don't chage! ############## #ipfw 65536 add deny ip any to any ################################################

一番最後の 65536番のルールは誰も変更することが出来ない.

ファイルを作成したら,/etc/rc.conf の firewall_script に指定されているファイルを /etc/rc.ipfw に変更する.

設定が完了したらこれを実行してみよう.
設定ファイル内は sh スクリプトと同じ,というかそのものなので,sh にこれを食わせる.
食わせるときはコンソールから行わなければ叩き斬られるので注意.
念のため ADSL PC ルーターにログオンしている端末も全てログアウトしておく.

# sh /etc/rc.ipfw
100 allow log icmp from any to any
・
・
・
65536 deny ip any to any

どー っと流れるが,その間にエラーが出ないかを見ておこう.
help 表示が出た場合はなにかしらの指定間違いがあったということなので,その箇所の設定を見直す.
あとは以下の項目を確認すること.

外からの確認は,別の回線でつなぐことができない人は友達などに手伝ってもらおう.
別の回線でつなぐことが出来る場合 (AirH" や PacketOne など) は,それで接続してアタックしてみることをおすすめする.

ここまで来れば,あとは /etc/rc.conf の最終的な設定のみとなる.
最終設定を以下のようにする.

- /etc/rc.conf

### インターフェイス系 # ゲートウェイになるように設定 gateway_enable="YES" # 内側インターフェイス ifconfig_ed0="inet 192.168.1.253 netmask 255.255.255.0" # 外側インターフェイス ifconfig_ed1="up" # portmap_enable="NO" ### 防火壁系 # 防火壁を有効にする firewall_enable="YES" # 起動スクリプト firewall_script="/etc/rc.ipfw" ### ppp 系 ## OS 起動時に一緒に起動させる場合はコメントインしておくこと. # ppp を OS 起動時に起動する ppp_enable="YES" # 起動モード - ddial:切断されたときに自動的に接続し直す ppp_mode="ddial" ### natd 系 ## OS 起動時に一緒に起動させる場合はコメントインしておくこと. # natd を有効にする natd_enable="YES" # 実行ファイルの場所 natd_program="/sbin/natd" # nat に使用するインターフェイス natd_interface="tun0" # その他 natd に与えるフラグ natd_flags="-config /etc/natd.conf"

こうすることにより,OS が起動すると自動的に外につなぎに行くようになる.

これで設定は完了.
お疲れー.

■番外編 - ipfw のログのみ別ファイルに吐く

デフォルトでは,ipfw のログは /var/log/security に吐かれるようになっている.
しかしそれだと security.* ファシリティのログが混ざってしまい面倒なので,ipfw のログのみ別のファイルに吐き出すことにする.

- /etc/syslog.conf

security.notice;ipfw.none /var/log/security !ipfw *.* /var/log/ipfw.log

これで /var/log/ipfw.log に ipfw のみのログが取れる.

■参考リンク



←戻る Made with IBM ThinkPad i series 1124 "Fairy"
Made by HyperEdit for Windows