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.