FreeBSDで作るブロードバンドルーター

以下のテキストは、執筆時当時の情報を元に書いたものであり、 現在の情勢にそぐわないことを含む場合があるので注意されたい。 また、テキストは最終提出原稿で校正を経る前のものなので、実際にUNIXUSER 本誌に記載されたものとは異なる。誤字脱字等そのままである。

致命的な誤り以外は加筆修正等は行なわないので情報の鮮度に気をつけつつ 利用して欲しい。

目次


Part II ルータを自作しよう

2001年は、ADSLによるインターネット接続環境が大躍進した年だったと言えよう。
新聞などによる、2001年を象徴する単語ランキングなどでは、色々なところで
ADSL接続に関する単語が見られ、一般的なことがらになって来たことを実感させ
られた。筆者の環境で2001年を語ると、酒田市という首都圏とは程遠く県庁所在
地でもない所に移り、当初ADSLなどまったくあきらめていたところに、予定が前
倒しされて夏にはADSL可能区域として加わることになった。このように目を見張
る速度で普及してますます身近になった「常時接続」環境を、いわゆる「ブロー
ドバンドルータ」という新たな機器への投資をすること無く手に入れよう、とい
うのが本稿の主題である。ルータを自作することで資金が節約できるだけでなく、
TCP/IPに関する基本的な知識も身についていくので、ぜひ試してみて欲しい。

■PC-Unixで作る「ブロードバンドルータ」

かつてはLAN環境を外部に結ぶルータも、専用ルータ機器ではなくUnixホストで
行なう「ワークステーションルータ」が一般的だった。末端のホストが10BASEか
ら100BASEに移り変わるにつれて、ルータ自身の高いパフォーマンスが必要にな
り、「ワークステーションルータ」は次第に主役の座から退いていった。

時代は変わり、家庭内にも常時接続がもたらされた。が、これは「ワークステー
ションルータ」が活躍した時代と同様な環境の再来ともいえる。筆者が10年程前
に経験したLAN環境では、

	代表的な端末ホスト	Sun3, SparcStation 1, 1+
	端末ホストのIF		10BASE-5
	対外接続		1.5Mbps

といったものであった。端末となるホストのCPUの速度は現在とは比較にならな
いほど遅いが、ネットワークの速度面においては現在のADSL接続環境に近いとい
える。当時のワークステーションルータはそれなりにスペックの高いものを利用
してはいたが、ひいき目に見ても100MHz以上のPentium互換CPUより速いとはいい
がたい。そんなコンピュータでもルータとしての機能を十分果たしていたのだか
ら、最近のPCで高々10Mbpsのネットワークのルータを果たせないわけがない。

本誌が発刊されPC-Unixが注目され始めた時代には、「1世代前の余っているPCで
軽快に動く」という風に形容されたものだった。現在で「余っているPC」といえ
ばクロックでいえば200MHz〜600MHzのものだろうか。もしそのクラスのPCが使え
るのなら、いわゆる「ブロードバンドルータ」として働かすには十分オツリが来
ると言ってよい。

今回は FreeBSD と Linux を例にADSL接続環境用のPCルータを作成する方法を解
説しよう。

■FreeBSDで作るADSL(PPPoE)ルータ

FreeBSD 4.4-RELEASE を利用してPCルータを作成しよう。今回はADSLを利用した
プロバイダからグローバルIPアドレスを1個もらい受けPCルータでそれを利用し、
家庭内のネットワークはプライベートIPアドレスを利用してPCルータからNATを
介してインターネットに接続するという利用形態を想定する(図い)。

---[図 い]------------------------------------------------------------

                     (グローバル)
[Internet] ---PPPoE--[PCルータ]
                       |
                       |↑NAT↓
                       |
                       |          (プライベート)
         +-------------+----+---------+----------
         |                  |         |
      [pc1]               [pc2]      [pc3] ....

----------------------------------------------------------------------

●NICの2枚差し

  ルータとして働かすのであるからネットワークカード(NIC)を装着する必要が
  ある。厳密に言えば1枚のNICでもできないことはないが、設定が複雑になりト
  ラブルが起きたときの問題点の切り分けが難しくなるので、熟練している場合
  でなければあまりお勧めしない。

  ここでは、装着しているNICとして intel EtherExpressPRO+ (デバイス名
  fxp0) と 3Com Fast Etherlink(デバイス名xl0) を想定して解説を進める。

●OSのインストール

  実際にPCルータとして動かすのに必要な設定を盛り込んだ状態でOSをインストー
  ルしよう。FreeBSD 4.4-RELEASE のインストールに先立ち、まずインストール
  用ブートフロッピーを作成する。4.4-RELEASE用の多国語インストーラが利用
  できる
 【脚註: ftp://daemon.jp.freebsd.org/pub/FreeBSD-jp/I18N-flp/4.4-RELEASE/
         または本誌付録CD-ROMに収録】
  のでこれを利用しよう。以下の例は執筆時事点の最新版 2001-11-21 でのもの
  だが、より新しいものがあればそちらを利用されたい。

	# dd if=kern_ja-20011112.flp of=/dev/rfd0a
	# dd if=mfsroot_ja-20011112.flp of=/dev/rfd0a

  kern_ja フロッピーをFDDに挿入しブートする。

	Please insert MFS root floppy and press enter

  と出たら mfsroot_ja フロッピーに入れ換えて [Enter] を押す。

	Skip kernel configuration and continue with installation
	Start kernel configuration in full-screen visual mode
	Start kernel configuration in CLI mode

  という画面が出るので、[Enter]を押して先に進むとFreeBSDのインストーラの
  初期画面が現れる(図ろ)。

---[図 ろ]------------------------------------------------------------


       %image(install-0.png)


----------------------------------------------------------------------

  ここでは、標準的インストール手順である Standard を選んだ。

  続いて、HDDのどの領域をFreeBSDで利用するかを決定する画面に移行する。今
  回は「余っているPCにインストール」するという前提に従い、HDD全てを
  FreeBSD領域(スライス)として利用することにする。"FDISK Partition
  Editor" 画面で a (=use entire disk) を選択した(図 は)。

---[図 は]------------------------------------------------------------


       %image(install-fdisk.png)


----------------------------------------------------------------------

  q (= Finish) を押して FDISK Partition Editor を抜けると、ブートローダ
  プログラムの導入選択画面になる。

	BootMgr		Install the FreeBSD boot Manager
	Standard	Install a standrd MBR (no boot manager)
	None		Leave the Master Boot Record untouched

  が提示されるが、デフォルトの BootMgr で良いだろう。

  続いて FreeBSD Disklabel Editor の画面に移行する。ひとつのOSで使うパー
  ティションの配分を決めるのはいつの時代も管理者の悩みどころであるが、こ
  こでは a (= Auto Defaults) をタイプしてデフォルトのパーティション構成
  にした(図 に)。

---[図 に]------------------------------------------------------------


       %image(install-disklabel.png)


----------------------------------------------------------------------

---- コラム  パーティションの分け方とOSのupgrade ------------------------

FreeBSD Disklabel Editor 画面でAuto Defaults を利用すると /usr パーティ
ション(のみ)が大きく取られることになり、システムファイルだけでなくユーザ
データも /usr パーティションに置くことになる。OSのupgrade時にシステム領
域とその他のパーティションを分けておいたほうが安心という考え方もある。実
際筆者も以前はかたくなに「ユーザデータを別パーティションに取る」流儀を守っ
ていたが、OSのupgradeをソースからの全コンパイル&インストール方法にしてか
らは、まちがってユーザ領域をnewfsしてしまう危険がほとんどないため、流儀
を守らなくても気にならなくなった。ソースからのOSのupgradeは FreeBSD のソー
スパッケージを全て /usr/src 以下に展開した状態でシングルユーザモードに落
とし、

	# cd /usr/src
	# make world

で行なうことができる。最も近いRELEASE版へのupgradeであれば問題なくコンパ
イル&インストールが行なわれる(可能性が高い)ので一度試してみてはいかがだ
ろう。
-------------------------------------------------------------------------

  Disklabel Editor を q で抜けると、"Choose Distributions" メニューに移
  る。PCルータとして利用する場合、Xウィンドウシステムを利用しないので
  User を選択すれば十分とも言えるが、Xライブラリを必要とするパッケージな
  どがあるのでもしディスクに余裕があれば X-User を選ぶのが良いだろう。た
  だし、カーネルソースをインストールしておくと、あとあと細かい設定を変え
  るときに便利なことがあるので、ここでは X-Kern-Developer を選択する(図
  ほ)。X Exit を選択するとインストールメディアの選択画面に移行する。
  
---[図 ほ]------------------------------------------------------------


       %image(install-choosedist.png)


----------------------------------------------------------------------

  自身の環境で利用可能なインストールメディアを選択する。本誌2001年12月号
  付属CD-ROMに、FreeBSD 4.4-RELEASE が収録されているので、手元にある場合
  はそれを利用するのも手だろう。

  インストールメディアからのファイルコピーが済むと最終設定に入る。ここで
  ルータとして機能するために必要な設定もあるので注意してYES/NOを選択する。

	イーサネット、SLIP/PPP ネットワークデバイスの設定
	→ YES
	→ LAN(プライベートアドレス) 側のNICのIPアドレスを指定する
  
  IPアドレスの設定がおわると、ゲートウェイとして機能させるかどうかの画面
  になるのでここで必ずYESを選択する(図 へ)。なお、インストーラでゲートウェ
  イ化を忘れてしまった場合は再起動後 /etc/rc.conf に gateway_enable="YES" 
  を追記すれば良い。この記述はカーネルにIPフォワーディング行なわせること
  を意味し、コマンドラインからは

	# sysctl -w net.inet.ip.forwarding=1

  によって行なうことができる。特定のホストをルータ(ゲートウェイ)として機
  能させる場合には必須かつ基本的な設定だが、別の設定に夢中になっていると
  熟練者でもうっかりIPフォワーディングのことを見落としがちなので是非気を
  つけたい。

---[図 へ]------------------------------------------------------------


       %image(install-gateway.png)


----------------------------------------------------------------------

  以後の設定メニューでとくに注意すべき選択肢を挙げておこう。

  「このマシンで anonymous FTP アクセスを提供しますか?」
    ↓
   外部に対して anonymous FTP サービスを提供することは、危険も伴うので慎
   重に行なわなければならない。過去に経験の無い場合は控えた方が良い(NOを
   選ぶのが良い)だろう。

  「このマシンをNFSサーバとして設定しますか?」
    ↓
  これも外部からのアクセスを禁じる手だてを理解していない場合はNOにした方
  が良い。

  「タイムゾーンの設定をいますぐ行ないますか?」
    ↓
  インストーラで行なわないと忘れがちである。YESを選択し、「5 Asia」のサ
    ブメニューから「Tokyo」を選んでおく。

  以上でインストール完了となる。フロッピーディスク(またはCD-ROM)をドライ
  ブから抜いて再起動するとFreeBSDが立ち上がる。

●PPPoEの設定

  FreeBSDでPPPoE接続を行なうには、

	* 付属のppp(user-ppp)を使う
	* rp-pppoe を使う

  方法が代表的である。rp-pppoe は多くのOSに対応している。Linux で広く利
  用されているものだが、もちろんFreeBSDでも利用することができる。本稿後
  半のLinuxでのPPPoE接続の解説とほぼ同じ手順でFreeBSDでも rp-pppoe を利
  用できるので、これを利用したい場合はLinuxでの手順を参考にして欲しい。

  ここでは、FreeBSDインストール直後の状態で使える user-ppp を利用する方
  法の解説をしよう。

  ・user-pppによるPPPoE接続

    FreeBSD付属のuser-pppには PPPoE をデバイスとする ppp 接続が可能となっ
    ている。古いFreeBSDではカーネルオプションとして

	options NETGRAPH

    を追加したカーネルを利用して起動する必要があるが、今回インストール解
    説した FreeBSD 4.4-RELEASE ではカーネルモジュールとして自動的にロー
    ドされるのでもし 4.4-RELEASE を利用して PPPoE 接続をする場合はカーネ
    ル再構築を行なう必要はない。

    ADSL回線とPPPoE接続相手となるプロバイダの契約が既に完了しているもの
    とみなし、接続のための条件が以下のようになっているものと仮定する。

	配給されたIPアドレス(※と)	192.168.1.12
	アカウント名			PPPoEaccount@provider
	パスワード			PPPoEpassword
	LANのネットワークアドレス	10.0.1.0/24
	LAN側インターフェース		fxp0 (Intel EtherExpress PRO+)
	ADSLモデムへのインタフェース	xl0 (3Com Fast Etherlink)
	ホスト名			venus

---[註 と]------------------------------------------------------------
 一般的にはプロバイダから配給されるIPアドレスはグローバルなものだが、こ
 この説明ではプライベートアドレスを用いる。実際には自身の環境で使えるグ
 ローバルIPアドレスで読みかえて欲しい。
----------------------------------------------------------------------

    /etc/ppp/ppp.conf ファイルを以下のように作成する。

default:
 set log Phase Chat LCP IPCP CCP tun command
 ident user-ppp VERSION (built COMPILATIONDATE)
 set device PPPoE:xl0
 set speed sync
 set mru 1454
 set mtu 1454
 set ctsrts off
 set openmode active

pppoe:
 accept chap
 accept pap
 set authname PPPoEaccount@provider
 set authkey PPPoEpassword
 set filter dial 0 deny icmp
 set filter dial 1 permit 0/0 0/0
 set filter alive 0 deny icmp
 set filter alive 1 permit 0/0 0/0
 add default HISADDR

    パラメータ設定の意味は以下のようになっている

    * set log
	ログに書き出すパラメータの指定
    * ident
	接続自体の識別子(名前)の設定
    * set device
	PPPセッションを張るために「語りかける」デバイス
	の指定。PPPoEの場合は
		PPPoE:<ネットワークインタフェース名>
	と指定する。シリアルデバイスやコマンドなども指定できる
    * set speed
	接続測度の指定 PPPoE の場合 sync
    * set mru, set mtu
	それぞれ MRU/MTU サイズの指定。ADSL接続の場合1492
    * set ctsrts
	ハードウェアフローコントロールの指定
    * set openmode
	LCP発信をこちらから(active)行なうか、待ち受け(passive)るかの指定
    * accept
	接続開始時のネゴシエーション方法の指定
    * set authname
	接続アカウント名の指定
    * set authkey
	パスワードの指定
    * set filter dial
	on-demand接続のフィルタの設定
    * set filter alive
	自動切断のタイムアウトを延ばすためのフィルタの設定
	dial/alive 両者は on-demand 接続の場合に効果的に設定すると便利で
	ある。詳しい設定例が/usr/share/examples/ppp/ppp.conf.sampleにあ
	る
    * add default
	デフォルトルートの設定。HISADDRは接続先のIPアドレスに置き換えら
	れる。

    ppp.conf をセーブしたら、まずはコマンドラインから正常に接続確立可能
    か確かめよう。作成した pppoe エントリを引数に与え ppp コマンドを起動
    する。

	# ppp pppoe
	  ~~~~~~~~~
    pppのプロンプトが現れるので、接続開始(dial)する。

	ppp on venus> dial
		      ~~~~
    認証通過し接続成功となる場合はpppのプロンプトが以下のように順次変化
    する(小文字pが大文字Pに変わってゆく)。

	ppp on venus>
	Ppp on venus>
	PPp on venus>
	PPP on venus>

    tun0デバイスを確認する。

	vv# ifconfig tun0
	tun0: flags=8051 mtu 1454
	        inet6 fe80::250:56ff:fed9:a2db%tun0 prefixlen 64 scopeid 0x6 
		inet 192.168.1.12 --> 192.168.1.1 netmask 0xffffff00 
		Opened by PID 886

    もし、接続に失敗する場合は以下の点を再確認してみるとよいだろう。

	* ADSL回線は繋がっているか(ADSLモデムのリンクランプの確認)
	* ADSLモデムとPC間の接続の確認
	* プロバイダからもらったアカウント名とパスワードの確認
	* ppp.conf の記述ミス
	* /var/log/ppp.log の確認

    以上 user-ppp による PPPoE 接続が成功することが確認できたら、システ
    ムのスタートアップ時に自動的にPPPoE接続を確立するように /etc/rc.conf
    ファイルに以下の記述を追加しよう。

	---[ /etc/rc.conf ]---
	  :
	  :(省略)
	  :
	ppp_enable=YES
	ppp_mode=dedicated
	ppp_profile=pppoe

    これらは上から順に

	* 起動時にpppセッションを自動的に開始するか
	* pppコマンドに与えるオプション
	* pppコマンドに与える ppp.conf 中のエントリ名

    となっている。念のため、システムを再起動し自動的に繋がることを確認し
    よう。

●LANと外部ネットワークとの接続

  PCルータとしたマシンをコンソールマシンとして使い、そしてそのマシンだけ
  しかインターネット接続しないのなら PPPoE 設定だけ行なえばいいのだが、
  実際は自宅のLANにあるクライアントPC全てからインターネット資源を利用し
  たいと思うだろう。ADSLを利用した接続ではグローバルIPアドレスを1個もら
  えるというのが一般的な利用形態だろう。このグローバルIPアドレスをLAN全
  てで活かすためのNAT設定を構築してみよう。

  ・FreeBSDにおけるNAT

    FreeBSD箱を利用したNATを行なう場合、

	1. ppp -nat (user-ppp)
	2. ipfw(IP Firewall)
	3. ipnat(IP Filter)

    などの選択肢がある。ここではもっとも手軽に使える1を利用する方法につ
    いて解説しよう。

  ・ppp -nat

    外部ネットワークとの接続にuser-pppを利用している場合、pppコマンドの
    オプションに -nat を付加するだけでLANからWANに出て行くパケットのNAT
    変換を行なってくれる。システムのスタートアップと同時にpppを起動する
    場合は /etc/rc.conf に

	ppp_nat=YES

    を追加することで、pppコマンド起動に -nat オプションを付加するように
    なる【註 る】。なお、-nat オプションは /etc/ppp/ppp.conf ファイル中に

	nat enable yes

    と記述することでも有効となる。

---[脚註 る]----------------------------------------------------------
4.4-RELEASEでは /etc/defaults/rc.conf にあるデフォルト設定が ppp_nat=YES 
になっている。IP Filter(ipnat) や IP Firewall(ipfw+natd) によるNATを利用
し、user-ppp のNATを無効にしたい場合は /etc/rc.conf で ppp_nat=NO と明示
指定する必要がある。
----------------------------------------------------------------------

●パケットフィルタリング(ファイアーウォール)

  当然のことだが、インターネットに接続することは、外部からも接続されるこ
  とをも意味する。無防備な状態では悪意ある者からのアタックを受けてどんな
  損失を被るか分からない。ルータとなる部分で外部からのパケットを必要なも
  の以外全て遮断するようにする設定、つまりパケットフィルタリングを施すこ
  とも重要である。

  パケットフィルタリングを行なうときには「何を守りたいのか」を明確にして
  おかなければ意味がない。真の意味で安全なのは「外部と繋がないこと」であ
  る。これはもっともなことだが、「危険に遭いたくなかったら外出しない」と
  同じくらい消極的である。外に出ることは楽しく、見聞も深めることができる。
  が、そのかわりなんらかの事故などに遭遇する可能性が無いとは言えない。ネッ
  トワーク接続もこれに似ている。たとえば、自宅から外へのアクセスだけを許
  可して外部からのアクセスを一切禁じてしまえばかなり安全になる。しかし
  「常時接続」にすることは、

	* 独自のWebサーバを上げてプロバイダの間借ではできない事を実現
	* 出先から自宅にあるファイルにアクセス
	* その他色々な種類の情報発信

  といった「楽しさ/快適さ」を得ることも目的のひとつである。自分がやりた
  いことと照らし合わせて、どの程度まで外部からの「通路」を開けるかを判断
  するのがパケットフィルタリングの出発点となる。利用したい(させたい)サー
  ビスだけを開け、それ以外は閉じておく。どこまで開けるかはサイト管理者の
  判断によって決まるものである。

  以下で述べる設定例は一般的な利用環境を想定した一例であることを念頭に置
  いて、自身の接続環境に即したものを設定するように気をつけて欲しい。もち
  ろんパケットフィルタリングではパケットがどこからどこに飛ぶのかといった、
  パケットの「外観」のみの判定となる。パケットに含まれる内容によって制限
  を掛けるためにはアプリケーションに応じた設定、たとえば apache における
  httpd.conf や .htaccess など、が必要になる。これらを組み合わせて初めて
  完全なフィルタリングが行なえる。本稿では、その片輪であるパケットフィル
  タリングのみを扱う。

  ・IP Firewall の有効化

    IP Firewall によるパケットフィルタリングを行なう場合には 
    /etc/rc.conf に以下の記述を追加する。

	firewall_enable=YES
	
    これにより、次回ブート以後ipfw(IP Firewallの制御コマンド)が利用でき
    る。以後、ipfwの初期設定を行なう場合は必ずコンソールから行なうように
    注意して欲しい。ipfwは有効化された直後は、デフォルトで全てのパケット
    通過を禁止する状態になるため、リモートから設定を行なっているとちょっ
    とした操作でコマンド入力不能状態に陥ってしまう。

    さて、パケットフィルタリングを行なう場合には二つのアプローチがある。

	* 全てを開いた状態から閉じて行く
	* 全てを閉じた状態から開けて行く

    既に運用しているドメインに新たにフィルタリングを適用する時は前者のア
    プローチを取らざるを得ない場合もあるだろうが、セキュリティを考えると
    後者の方が望ましい。今回は新規にPCルータを設置してインターネット接続
    を行なうことが前提なので後者のアプローチを取りたい。

  ・IP Firewallのログ有効化

    フィルタリングの設定を行なう場合には、そこまで設定したフィルタでどん
    なパケットが弾き落とされているのかを確認できた方が効率的である。IP
    Firewall でもログを出力できるのだが、FreeBSD 4.4-RELEASEのデフォルト
    では有効化されていない。ipfwモジュールがカーネルにロードされている形
    態により、以下の二つの手順が必要となる。

	* /module/ipfw.ko をロードしている場合(通常はこちら)

	  /usr/src/sys/modules/ipfw/ ディレクトリに移動し Makefile の

	  #If you want it verbose
	  #CFLAGS+= -DIPFIREWALL_VERBOSE

	  という箇所を修正し

	  #If you want it verbose
	  CFLAGS+= -DIPFIREWALL_VERBOSE

	  とする。続いてコンパイル&インストールする。

		# cd /usr/src/sys/modules/ipfw
		# make && make install

	  次回起動時にはロギングの有効化されたipfwモジュールがロードされ
	  る。

	* カーネルにIPFIREWALLオプションが組み込まれている場合

	  カーネル設定ファイルに IPFIREWALL_VERBOSE オプションを追加する。
	  つまり、

	  options      IPFIREWALL              #firewall
	  options      IPFIREWALL_VERBOSE      #print information about

	  の両者を含めてカーネル再構築とインストールを行なう。

    これらにより、ipfwでのフィルタに log アクションを指定することで、そ
    のときに処理されたパケットの詳細情報が /var/log/security に吐き出さ
    れるようになる。フィルタリングルールのデバッグを行なうときには、

	# tail -f /var/log/security

    などとしておくと問題解決が早くなるだろう。

  ・ipfwのルール設定

    まず、「全てを閉じる」設定にしたipfwのフィルタリングルールを参考にし
    よう。/etc/rc.conf で

	firewall_enable=YES
	firewall_type=closed

    と記述してシステムを起動し、ルールセットを確認する(結果 ち)。

---[結果 ち]----------------------------------------------------------
# ipfw l
00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 deny ip from 127.0.0.0/8 to any
65535 deny ip from any to any
----------------------------------------------------------------------

    このように、ipfwのルールは番号付けされて格納される。実際に通過パケッ
    トを評価するときは、若い番号のルールから順に比較され、条件にマッチし
    たところで通過(allow)と拒否(deny)が決定され、それ以後のルールは比較
    されない。最後の65535番のルールはipfwモジュールにデフォルトで組み込
    まれたもので、全てのIPパケットを拒否する。ここに到達する以前にどのルー
    ルにもマッチしなかったパケットは、65535番により弾き落とされることに
    なる。

    ルールを追加する場合はルール番号を指定することもできるし、番号を省略
    することもできる。省略した場合は自動的に100ずつ番号を増やしてルール
    を追加する。

    さて、【結果 ち】を再度見ると最初のルール(100番)ではループバックイン
    タフェース(lo0)を通過するパケットを全て許可(allow)している。次の2行
    で lo0 以外を通過する 127.0.0.0/8 (から|へ) のパケットを拒否している。
    この状態は、自己ホスト内部のパケット以外は全て拒否する強いものである。
    もちろん他のホストとの通信が全くできない状態なので、ここをスタート地
    点として必要なパケットを許可するルールを追加して行く。ルール追加のと
    きに利用する書式は

    ipfw add [prob <確率>] <アクション> [log [logamount <値>]] \
	 <プロトコル指定> from <送信元条件指定> to <送信先条件指定> \
	  [<インタフェース条件指定>] [<オプション>]

    となっている([]は省略可能を意味する)。"prob" は人工的にパケット落ち
    を作って実験したい場合などに有用なものなので、あまり利用することはな
    いかもしれない。

    ・<アクション> の部分には以下のいずれかが指定できる。

	allow		パケットを通過させる
	deny		パケットを破棄する
	unreace	<値>	パケットを破棄した上で ICMP unreachable notice
			の数値を返す
	reset		(TCPのみ)パケットを破棄した上で、TCP reset notice
			を送り返す。SMTP接続時のident(113)要求を即座に拒
			否する場合などに良く利用される
	count		ルールにマッチ場合カウンタだけを増やして次のルー
			ルに進む
	check-state	keep-stateで作られた動的ルールを調べ、パケットが
			そのルールに合致したら通過させ、ルール比較はここ
			で打ち切る
	divert <ポート>	パケットを <ポート>番ポートのソケットに結びつけ
			られたdivert(4)ソケットに宛先を変える。通常natd
			に受け渡すときに利用する
	tee <ポート>	上記divertと同様だが、パケットのコピーを送る
	fwd [,<ポート>]
			パケットを  の <ポート>番にフォワー
			ドする。IPFIREWALL_FORWARD カーネルオプションが
			必要。リダイレクトとは違うので注意。
			詳細はipfw(8)参照。
	pipe <番号>	dummynet(4)の pipe(トラフィックシェイパ) に渡す
	queue <番号>	dummynet(4)の queue(WF2Qによる帯域制御) に渡す
	skipto <番号>	ルール番号<番号>のものまでスキップする

    ・<プロトコル>の部分は /etc/protocols にあるプロトコル名(または番号)で
    指定する。「ip」または「all」を指定するとどんなプロトコルにもマッチ
    する。

    ・<送信元条件指定> と <送信先条件指定> では

	any				あらゆるアドレスにマッチ
	me				ローカルアドレスにマッチ
	[not] 	指定したアドレスにマッチ
					not を前置すると否定になる

    を指定できる。ここで  の部分には以下の書式が利用
    できる
	x.y.z.w			オクテット表記のIPアドレス。完全一致する
				IPアドレスのみがルールにマッチする
	x.y.z.w/ビット数	上位からの連続したビット数によるネットマ
				スク表記によるアドレス群
	x.y.z.w:a.b.c.d		x.y.z.wをa.b.c.dでマスクしたアドレス群

    さらにこれらのアドレス表記の直後に <ポート番号> を書くこともできる。

    ・省略可能な条件 <インタフェース条件指定> には以下のものが指定できる。

	in	   	入り方向のパケットのみにマッチする
	out		出方向のパケットのみにマッチする
	via 	というインタフェースを経由するパケットのみ
			にマッチする
	via *	という名前で始まる任意の番号のインタフェース
			を経由するパケットのみにマッチする
	via any		なんらかのインタフェースを経由するパケットのみに
			マッチする
	via  にというアドレスを持つインタフェー
			スを経由するパケットのみにマッチする

    "via" キーワードを使ったの場合はつねにインタフェースの比較が行なわれ
    るが、"recv", "xmit" キーワードを使った場合はパケットの方向に応じて
    比較が行なわれる。詳しくはipfw(8)参照。

    ・省略可能な条件 <オプション> には以下のものが指定できる。

	keep-state [メソッド]
			このルールにマッチした上で、このときに使った送信
			元と送信先の IP/ポート番号 間の通信を双方向で許
			可する動的ルールを生成する
	bridged		ブリッジされたパケットにマッチする
	frag		フラグメントパケットにマッチする
	ipoptions <オプション>
			IPヘッダオプションを指定する。ssrr, lsrr, rr, ts
			のいずれか(またはカンマで区切って列挙)
			!をつけると否定
	tcpoptions <オプション>
			TCPヘッダオプションを指定する。mss, window,
			sack, ts, cc のいずれか(またはカンマで区切って列挙)
			!をつけると否定
	establishd	(TCPのみ)RSTまたはACKビットのセットされたもの
	setup		(TCPのみ)SYNビットがセットされていてACKビットの
			セットされていないもの
	tcpflags <フラグ> (TCPのみ)TCPフラグの指定。fin, syn, rst, psh, 
			ack, urg のいずれか(またはカンマで区切って列挙)
			!をつけると否定
	icmptypes	(ICMPのみ) ICMPのタイプを数値で指定。
	uid 	ユーザIDが  のユーザによって 出された/受け
			取られる パケットにマッチする
	gid 	グループIDが  のユーザによって 出された/受け
			取られる パケットにマッチする
    
    なお、FreeBSDハンドブックの「ファイアーウォール」の項【脚註: たとえ
    ばhttp://docs.freebsd.org/handbook/ja/4.3R/firewalls.html】も非常に
    参考になるので参照すると良いだろう。

    * LAN内との通信を許可

      LAN内パケットは fxp0 インタフェースを通過する 10.0.1.0/24 のもので
      ある。

      ipfw add ip from 10.0.1.0/24 to me via fxp0
      ipfw add ip from me to 10.0.1.0/24 via fxp0

      複数のLANのパケットを受け取る必要があるときはアドレス指定の部分を
      適宜変更する。

    * 確立済TCPコネクション(established)の通過

      既に確立されたTCPコネクションの一部であれば許可する。多くのパケッ
      トはこれに該当するのでなるべくルールセットの先頭に近い位置に置くと
      効率が良い。同様の理由でフラグメントパケットも許可する。

      ipfw add allow tcp from any to any established
      ipfw add allow ip  from any to any frag

    * LANから外部へのTCP接続

      ipfw add allow tcp from 10.0.1.0/24 to any setup
      ipfw add allow tcp from me to any setup

    * 必要なUDPパケットの通過

      サーバの動作に必要なものとしてDNS(53)とNTP(123)を通過させる。

      ipfw add allow udp from 10.0.1.0/24 to any 53 keep-state
      ipfw add allow udp from me to any 53 keep-state
      ipfw add allow udp from 10.0.1.0/24 to any 123 keep-state
      ipfw add allow udp from me to any 123 keep-state

    * 外部に提供するサービスの通過

      もし外部ネットワーク向けに公開するサービスデーモンを起動するならそ
      れに応じたポート番号を解放する。たとえば SSH(22), SMTP(25),
      HTTP(80), POP3(110)を通過させたい場合は次のようになる。

      ipfw add allow tcp from any to me 22
      ipfw add allow tcp from any to me 25
      ipfw add allow tcp from any to me 80
      ipfw add allow tcp from any to me 110

    * ICMPの通過

      これはポリシーの問題だが、pingなどを利用して、ネットワークやホスト
      の到達性を確かめたい場合はICMPを許可する。

      ipfw add allow icmp from any to any

    * 上記以外のものを拒否

      以上のルールのどれにもマッチしなかったものを拒否する。明示的に拒否
      ルールを書かなくてもデフォルトの65535番ルールで落とされるが、はじ
      めのうちは落とされるパケットをログに取っておくと設定もれが発見しや
      すい。

      ipfw add deny log ip from any to any

	-	-	-

    以上の設定をまとめて、/etc/rc.firewall.local ファイルにまとめたものが
    【リスト り】である。

---[リスト り /etc/rc.firewall.local]---------------------------------
# IP Firewall rule definition
#
# packets from/to lo0
allow ip from any to any via lo0
deny ip from any to 127.0.0.0/8
deny ip from 127.0.0.0/8 to any
# LAN
ipfw add ip from 10.0.1.0/24 to me via fxp0
ipfw add ip from me to 10.0.1.0/24 via fxp0
# established tcp connection
ipfw add allow tcp from any to any established
# fragments
ipfw add allow ip from any to any frag
# from LAN to outside
ipfw add allow tcp from 10.0.1.0/24 to any setup
ipfw add allow tcp from me to any setup
# essential UDP's
ipfw add allow udp from 10.0.1.0/24 to any 53 keep-state
ipfw add allow udp from me to any 53 keep-state
ipfw add allow udp from 10.0.1.0/24 to any 123 keep-state
ipfw add allow udp from me to any 123 keep-state
# pass SSH, SMTP, HTTP, POP3
ipfw add allow tcp from any to me 22
ipfw add allow tcp from any to me 25
ipfw add allow tcp from any to me 80
ipfw add allow tcp from any to me 110
# allow ICMP
ipfw add allow icmp from any to any
#
# Then, deny all with logging
ipfw add deny log ip from any to any
----------------------------------------------------------------------

    これをシステムスタートアップ時に自動的にロードするために
    /etc/rc.conf の末尾に以下の記述を追加する。

    firewall_enable="YES"
    firewall_script="/etc/rc.firewall.local"

■DHCPサーバ

LANに何台もPCがある場合や、新しいPCを繋ぐ機会がそれなりに多い場合は、
DHCPサーバが一台あると各クライアントPCでのIPアドレス設定の手間が省けて効
率が良い。DHCPサービスは必ずしもルータとなるマシンで動かす必要はない。
ここでは、ISC-DHCP3 を利用してDHCPサービスを構築してみよう。

  ●ISC-DHCP3 のインストール

  ISC-DHCP3は FreeBSD Packages Collection にも含まれているので、これを利
  用するのが簡単だろう。
  ftp://ftp.jp.freebsd.org/pub/FreeBSD/ports/i386/packages-4.4-release/net/
  などから、isc-dhcp3-3.0.r11.tgz を入手し

	# pkg_add isc-dhcp3-3.0.r11.tgz

  とすれば、/usr/local 以下にインストールされる。もし、ソースからコンパ
  イルしてインストールする場合は、ftp://ftp.isc.org/isc/dhcp/ などからソー
  スパッケージを取得し、

	(以下の例は dhcp-3.0.1rc6.tar.gz の場合)
	# tar vzxpf dhcp-3.0.1rc6.tar.gz
	# cd dhcp-3.0.1rc6
	# less README		(READMEを読む)
	# ./configure && make && make install

  とすれば /usr 以下にインストールされる。インストール先ディレクトリを変
  更したい場合は、ソースディレクトリにある Makefile.conf ファイルを適宜
  修正すれば良い。DHCPサービスデーモンとなる dhcpd プログラムは、
  dhcpd.conf ファイルによって動作を決定する。dhcpd.confファイルの置き場
  所は、Packages からインストールした場合は、/usr/local/etc ディレクトリ、
  ソースパッケージからデフォルトのままコンパイル&インストールした場合は 
  /etc ディレクトリとなる。

  ここでは、LANのネットワークに関する情報を

	ネットワークアドレス	10.0.1.0
	ネットマスク		255.255.255.0
	ゲートウェイアドレス	10.0.1.1
	ネームサーバ		ns.example.com

  とし、クライアントPCに利用させるIPアドレスを 10.0.1.100〜10.0.1.120 と
  する。このような場合、dhcpd.conf には以下のように記述する。

----------------------------------------------------------------------
#
# dhcpd.conf
#

# ドメイン名とネームサーバ
option domain-name "example.com";
option domain-name-servers ns.example.com;
# ddnsを利用しない場合は none (必須)
ddns-update-style none;

# lease時間の指定
default-lease-time 600;
max-lease-time 7200;

# ログファシリティ
log-facility local7;

# LANの
subnet 10.0.1.0 netmask 255.255.255.0 {
	# ゲートウェイアドレス
        option routers 10.0.1.1;
        # Unknown clients get this pool.
        pool {
		# 使わせるIPアドレスの範囲指定
                range 10.0.1.200 10.0.1.253;
		# 全てのクライアントを許可
                allow unknown clients;
        }
}
----------------------------------------------------------------------

  ●dhcpdの起動

  Packages からインストールした場合は
  /usr/local/etc/rc.d/isc-dhcpd.sh.sample ファイルがサンプル起動スクリプ
  トとしておかれているので、これを isc-dhcpd.sh という名前にリネームする
  ことで次回ブート時以降dhcpdが起動する。また、ソースパッケージからイン
  ストールして、dhcpd が /usr/sbin/ にインストールされた場合は、以下のよ
  うなスクリプトを /usr/local/etc/rc.d に置くとよいだろう。

---[ /usr/local/etc/rc.d/dhcpd.sh ]-----------------------------------
#!/bin/sh

OPTIONS=""
IFACES=""

case "$1" in
start)  
        /usr/sbin/dhcpd $OPTIONS $IFACES > /dev/null 2>&1
        echo -n ' dhcpd'
        ;;
stop)   
        killall dhcpd
        ;;
restart)
        $0 stop
        $0 start
        ;;
status) 
        ps -auxww | egrep '(conserver|console)' | egrep -v "($0|egrep)"
        ;;
*)
        echo "usage: ${0##*/} {start|stop|restart|status}" >&2
        ;;
esac

exit 0
----------------------------------------------------------------------

  初回起動前に /var/db/dhcpd.leases ファイルを作成しておく必要がある。

	# touch /var/db/dhcpd.leases

  これでdhcpdが起動できるようになる。なお、dhcpd.conf のデバッグ中は

	# dhcpd -d

  と、-dオプションをつけて起動することでエラー箇所が分かりやすい。


yuuji@example.org
Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA
HIROSE Yuuji - ASTROLOGY / BIKE / EPO / GUEST BOOK / YaTeX [Tweet]