natd のための記述を追加する。
# vi /etc/rc.conf
追加する内容は次の通り。
gateway_enable="YES"
firewall_enable="YES"
firewall_script="/etc/rc.firewallnat"
#firewall_type="open"
natd_enable="YES"
natd_interface="ed1"
natd_flags="-same_ports -use_sockets"
ここでは ed1 であるが、構成に合わせて
natd_interface はグローバルネットワーク側 I/F を指定する。
また、natd を動作させるだけなら firewall_type は open (素通し) でもいいが、
セキュリティ的に特権ポートを塞ぐなども行なった方がいいので、
rc.firewall をベースにカスタマイズし、
rc.firewallnat というスクリプトを作成した。
############ # Setup system for firewall service. # 設定値の取り込み if [ -f /etc/rc.conf ]; then . /etc/rc.conf fi # セキュリティレベル if [ X"$1" != X"" ]; then firewall_type=$1 elif [ X"${firewall_type}" = X"" ]; then firewall_type="open" fi # natd_enable が YES でないか、natd_interface が未定義ならば処理しない if [ X"${natd_enable}" != X"YES" -o X"${natd_interface}" = X"" ]; then exit fi ############ # 実行コマンド if [ "x$firewall_quiet" = "xYES" ]; then fwcmd="/sbin/ipfw -q" else fwcmd="/sbin/ipfw" fi ############ # ネットワーク I/F 設定 oif=${natd_interface} oip=`/sbin/ifconfig ${oif} | /usr/bin/sed -n 's/^.*inet \([0-9\.]*\) .*$/\1/p'` iif=`/bin/echo ${network_interface} | /usr/bin/sed -e 's/ *'${oif}' *//' -e 's/ *lo0 *//'` iip="192.168.1.1" inet="192.168.1.0" imask="255.255.255.0" ############ # Flush out the list before we begin. $fwcmd -f flush ############ # NAT $fwcmd add 100 divert natd all from any to any via ${natd_interface} ############ # ループバック $fwcmd add 210 pass all from any to any via lo0 $fwcmd add 220 deny all from any to 127.0.0.0/8 ############ # 既にコネクションの確立した TCP は許可 $fwcmd add 1000 pass tcp from any to any established # IP フラグメントは許可 $fwcmd add 1100 pass all from any to any frag ############ # ICMP # 0:エコー応答, 3:終点到達不能, 4:始点抑制, 5:方向転換, 8:エコー要求, # 11:全体時間経過済, 12:パラメータ障害, 13:タイムスタンプ要求, # 14:タイムスタンプ応答, 17:アドレスマスク要求, 18:アドレスマスク応答 # 外部への送信はエコー要求/応答/到達不能を許可、受信は他に 11 (for traceroute) $fwcmd add 2000 pass icmp from any to any out via ${oif} icmptypes 0,3,8 $fwcmd add 2010 pass icmp from any to any in via ${oif} icmptypes 0,3,8,11 $fwcmd add 2020 deny icmp from any to any via ${oif} ############ # 内部プライベートネットワーク内通信と外部への送信は許可 $fwcmd add 3000 pass all from ${oip} to any out via ${oif} $fwcmd add 3010 pass all from ${iip} to any out via ${iif} $fwcmd add 3020 pass all from ${inet}:${imask} to any in via ${iif} $fwcmd add 3030 pass udp from any 68 to any 67 in via ${iif} # 外部からのプライベートアドレスを破棄 $fwcmd add 3100 deny all from 192.168.0.0/16 to any in via ${oif} $fwcmd add 3110 deny all from 172.16.0.0/12 to any in via ${oif} $fwcmd add 3120 deny all from 10.0.0.0/8 to any in via ${oif} ############ # SSH コネクション確立を許可 # $fwcmd add 10220 pass tcp from any to any 22 setup # SMTP コネクション確立を許可 $fwcmd add 10250 pass tcp from any to any 25 setup # DNS アクセスを許可 $fwcmd add 10530 pass udp from any 53 to any $fwcmd add 10532 pass udp from any to any 53 # $fwcmd add 10534 pass tcp from any to any 53 setup # DHCP サーバから DHCP クライアントへのパケットを許可 $fwcmd add 10680 pass udp from any 67 to any 68 # HTTP コネクション確立を許可 $fwcmd add 10800 pass tcp from any to any 80 setup # 外部 NTP サーバと自 NTP サーバ間のパケットを許可 $fwcmd add 11230 pass udp from any 123 to any 123 # 外部からの認証を拒否 (メールサーバによっては配信に支障が出ることもあり) $fwcmd add 11130 reject tcp from any to any 113 in via ${oif} setup $fwcmd add 11132 reject udp from any to any 113 in via ${oif} # 外部からの SMB は不許可 $fwcmd add 11370 deny tcp from any to any 137-139 in via ${oif} setup $fwcmd add 11372 deny udp from any to any 137-139 in via ${oif} # 外部からの特権ポートへのアクセスは不許可、ロギング $fwcmd add 20000 deny log tcp from any to any 1-1023 in via ${oif} setup $fwcmd add 20010 deny log udp from any to any 1-1023 in via ${oif} # 外部からの UDP ブロードキャストは破棄 $fwcmd add 20100 deny udp from any to 255.255.255.255 in via ${oif} # NFS サーバ機能を使う場合、外部からの NFS は不許可 if [ "X${nfs_server_enable}" != X"YES" ]; then $fwcmd add 30000 deny tcp from any to any 2049 in via ${oif} setup $fwcmd add 30010 deny udp from any to any 2049 in via ${oif} fi # X サーバへの接続を不許可 if [ -x /usr/X11R6/bin/X ]; then $fwcmd add 30100 deny tcp from any to any 6000 in via ${oif} setup $fwcmd add 30110 deny udp from any to any 6000 in via ${oif} fi if [ "${firewall_type}" = "open" -o "${firewall_type}" = "OPEN" ]; then # 他のコネクション確立は許可 $fwcmd add 40010 pass tcp from any to any setup # 他の UDP を全て許可 $fwcmd add 65000 pass udp from any to any else # 外部からのコネクション確立を不許可、ロギング $fwcmd add 40000 deny log tcp from any to any in via ${oif} setup fi # 残りのパケットは不許可
FreeBSD FAQ を見ると、 ipfw の性能は i486 66MHz CPU 時代で1つのルールの処理がμsオーダーだったらしい。 Celeron 533MHz の CPU 処理能力は1桁あがっているだろうから、 複数ルールが適用される実運用で ipfw によるパケットの遅延は1μsかそこらだろう、きっと。
DHCP サーバには WIDE 版と ISC 版があるが、
私は ISC 版の方が馴染みがあるので (WIDE 版は Solaris で動かなかったのだ)
私は ISC 版を使う。
まず、パッケージのインストールする。
# pkg_add isc-dhcp-2.0.tgz
設定ファイル
/usr/local/etc/dhcpd.conf を作成する。
この例では carrot と risotto は固定 IP アドレス。
動的アドレスは 192.168.1.100〜192.168.1.199 に設定。
# dhcpd.conf # # Configuration file for ISC dhcpd # server-identifier waffle.uminari.yi.org; option domain-name "uminari.yi.org"; option domain-name-servers 192.168.1.1; # default-lease-time 10800; max-lease-time 86400; subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.100 192.168.1.199; option routers 192.168.1.1; option subnet-mask 255.255.255.0; option broadcast-address 192.168.1.255; } host carrot { hardware ethernet 01:23:45:67:89:ab; fixed-address carrot.uminari.yi.org; option host-name "carrot"; } host risotto { hardware ethernet fe:dc:ba:98:76:54; fixed-address risotto.uminari.yi.org; option host-name "risotto"; }
ローカルネットワーク側のネットワーク I/F (fxp0) で起動するスクリプト /usr/local/etc/rc.d/dhcpd.sh を作成する。
#!/bin/sh
if [ -x /usr/local/sbin/dhcpd -a -f /usr/local/etc/dhcpd.conf ]; then
/usr/local/sbin/dhcpd -q fxp0
echo -n ' dhcpd'
fi
まず先に入れ替えた DHCP パッケージに合わせてクライアントの方も入れ替え、 /etc/rc.conf に次の記述を入れる。
dhcp_program="/usr/local/sbin/dhclient"
グローバル IP アドレスの取得に DHCP を使用しているため、そのままでは
/etc/resolv.conf が書き換えられてしまう。
本来ならば /usr/local/etc/dhclient.conf
を書き換えて、domain-name-server を固定化するのが本来である。
また某 CATV インターネット接続のようにプロバイダから
DHCP クライアントのホスト名を指定される場合も、
/usr/local/etc/dhclient.conf に記述する。
interface "ed1" { supersede domain-name "uminari.yi.org"; prepend domain-name-servers 127.0.0.1; send host-name "cj8888888-a"; }
ここでは、その方法を使わず、dhclinet-script の make_resolv_conf 関数部を修正し、DNS サーバ情報を反映する先を /etc/named.conf とし、 DHCP で受け取った DNS サーバ情報は、 DNS サーバが要求をフォワードする先として利用するように修正する。
まず dhclient-script をコピーしてから修正する。
# cp /usr/local/etc/dhclient-script /etc # vi /etc/dhclient-script
dhclient-script の記述の中で
echo search $new_domain_name >/etc/resolv.conf for nameserver in $new_domain_name_servers; do echo nameserver $nameserver >>/etc/resolv.conf done
と記述されている箇所(2ヶ所)を次のように書き換える。
cat <<E_NAMED >/etc/named.conf options { directory "/etc/namedb"; forwarders { E_NAMED for nameserver in $new_domain_name_servers; do echo " ${nameserver};" >>/etc/namedb/named.conf done echo " };" >>/etc/namedb/named.conf echo "};" >>/etc/namedb/named.conf cat /etc/namedb/named.conf.base >>/etc/namedb/named.conf
これにより localhost とプライベートドメインに対してはプライマリサーバとして機能し、
それ以外のドメインは DHCP サーバから通知された DNS サーバへ要求をフォワードするようになる。
(本当は /etc/dhclient-exit-hooks に関連する処理を記述するのがスジなんだろうけど……)
/etc/resolv.conf は次の内容で作成する。
search uminari.yi.org
nameserver 127.0.0.1
/etc/rc.conf に次の記述を入れる。
named_enable="YES"
/etc/namedb/named.conf.base を作成する。
acl "private" { 127.0.0.1; 192.168.1.0/24; }; zone "." { type hint; file "named.root"; }; zone "localhost" { type master; file "localhost.zone"; }; zone "0.0.127.in-addr.arpa" { type master; file "localhost.rev"; }; zone "uminari.yi.org" { notify no; type master; file "uminari.zone"; allow-transfer { private; }; allow-query { private; }; }; zone "1.168.192.in-addr.arpa" { notify no; type master; file "uminari.rev"; allow-transfer { private; }; allow-query { private; }; };
各正引きと逆引き用のファイルは次のようになる。
@ IN SOA waffle.uminari.yi.org. net.waffle.uminari.yi.org. ( 00111100 ; Serial 10800 ; Refresh 3H 3600 ; Retry 1H 4320000 ; Expire 1200H 86400 ) ; Minimum 24H IN NS waffle.uminari.yi.org. localhost. IN A 127.0.0.1
@ IN SOA waffle.uminari.yi.org. net.waffle.uminari.yi.org. ( 00111100 ; Serial 10800 ; Refresh 3H 3600 ; Retry 1H 4320000 ; Expire 1200H 86400 ) ; Minimum 24H IN NS waffle.uminari.yi.org. 1 IN PTR localhost.
@ IN SOA waffle.uminari.yi.org. net.waffle.uminari.yi.org. ( 00111100 ; Serial 10800 ; Refresh 3H 3600 ; Retry 1H 4320000 ; Expire 1200H 86400 ) ; Minimum 24H IN NS waffle.uminari.yi.org. IN A 192.168.1.1 localhost IN A 127.0.0.1 waffle IN A 192.168.1.1 carrot IN A 192.168.1.2 risotto IN A 192.168.1.3 www IN CNAME waffle
@ IN SOA waffle.uminari.yi.org. net.waffle.uminari.yi.org. ( 00111100 ; Serial 10800 ; Refresh 3H 3600 ; Retry 1H 4320000 ; Expire 1200H 86400 ) ; Minimum 24H IN NS waffle.uminari.yi.org. 1 IN PTR waffle.uminari.yi.org. 2 IN PTR carrot.uminari.yi.org. 3 IN PTR risotto.uminari.yi.org.