Router(PPPOE + IPFIREWALL + NATD)

FreeBSDマシンをルーター化します。今までは市販のルーターを使っていましたが、unnumberedに対応していなかったり、SNMPが取れなかったり、フィルタリングやNATが貧弱だったり、スループットが出なかったりと、いろいろ不満がありました。そこでFreeBSDマシンをルーター化しようということになりました。接続ツールとしてはPPPOEを使うので、フレッツADSLやBフレッツに対応できると思います。高村さんのページを参考にさせていただきました(ほとんどそのままです)。深謝。なお、ここではファイアウォールにIPFIREWALL + NATDを使う場合を記述してます。IPFILTER + IPNATを使う場合は別に記載しました。

前提として、次のようなネットワークを仮定します。
Global IP address  202.***.***.16/29
Private IP address 192.168.1.0/24

        Internet
            |
            | rl0
    ________|_______
   |                |
   |      Router    |
   | 202.***.***.17 |
   | (192.168.1.1)  |
   |________________|
            |
            | rl1
            |_______________________
            |                       |  192.168.1.0/24
    ________|________          _____|_____
   |                 |        |           |
   |      Server     |        |  Clients  |
   | 202.***.***.18  |        |___________|
   | (192.168.1.2)   |
   |_________________|

1.Kernelの再構築

ルーターマシンのIPFIREWALLとNATDを有効にします。

# cd /usr/src/sys/i386/conf
# cp GENERIC MyKernel
# ee MyKernel
----------------
ident		Mykernel

options         IPFIREWALL              #firewall
options         IPFIREWALL_VERBOSE      #enable logging to syslogd(8)
options         IPFIREWALL_VERBOSE_LIMIT=100    #limit verbosity
options         IPV6FIREWALL            #firewall for IPv6
options         IPV6FIREWALL_VERBOSE
options         IPV6FIREWALL_VERBOSE_LIMIT=100
options         IPDIVERT                #divert sockets
----------------
# config MyKernel
# cd ../../compile/MyKernel
# make depend
# make
# make install

IPV6を使わないならIPV6関連は削除してください。NETGRAPH関係のoptionsはFreeBSD 4.7Rでは必要ありませんでした。

2.PPPの設定

PPPの設定ファイルを編集します。必要なファイルは、/etc/ppp/ppp.confと/etc/ppp/ppp.linkupです。次のようにしましたが、環境によってmodifyが必要でしょう。IPFILTERとIPFIREWALLの区別はありません。

ppp.conf

default:
 set device PPPoE:rl0
 set log Phase Chat LCP IPCP CCP tun command
 set speed sync
 set mru 1492
 set mtu 1454
 set ctsrts off
 set timeout 0
 accept CHAP
 add default HISADDR
 enable tcpmssfix
 disable deflate
 disable pred1
pppoe:
 set authname loginID@***.sphere.ne.jp
 set authkey himitsu

ppp.linkup

pppoe:
 ! ifconfig tun0 delete
 ! ifconfig tun0 202.***.***.208.17 netmask 255.255.255.248 HISADDR
 add! default HISADDR

このppp.linkupは、tun0に202.***.***.17を名乗らせるために必要のようです。でないと、tun0がネットワークアドレス(この場合202.***.***.16)を名乗ってしまう。

3.rc.confの設定
rc.confの追加事項は次のとおりになります。

rc.conf

network_interfaces="rl0 rl1 lo0"
tcp_extensions="YES"
ifconfig_rl0="media 10BaseT/UTP up"
# B fletsの場合は以下のようにする
# ifconfig_rl0="media 100baseTX mediaopt full-duplex up"
ifconfig_rl1="inet 202.***.***.17 netmask 255.255.255.248"
gateway_enable="YES"
ppp_enable="YES"
ppp_mode="ddial"
ppp_profile="pppoe"
ppp_nat="NO" # ipnatを使わない場合はYES

firewall_enable="YES"
firewall_script="/etc/ipfw.nat"
natd_enable="YES"
natd_interface="tun0"
natd_flags="-f /etc/natd.conf"

PPP接続の前にnatdが起動するとエラーとなり止ってしまうので、natdの起動ファイルをrc.localにも記載しました。

rc.local

/sbin/natd -f /etc/natd.conf -n tun0

4.IPFIREWALLの設定

/etc/ipfw.natの例です。環境によって書き換えてください。なお、ここは木村博美さんのページを参考にしました。深謝。

ipfw.nat

# IPFW + NAT 用のルール設定スクリプト(静的ルール)

# Suck in the configuration variables.
if [ -r /etc/defaults/rc.conf ]; then
        . /etc/defaults/rc.conf
        source_rc_confs
elif [ -r /etc/rc.conf ]; then
        . /etc/rc.conf
fi

fwcmd="/sbin/ipfw -q"

# ルールを全部捨てる
${fwcmd} -f flush

############################
# Internet (外)側のインターフェイス
oif="tun0"
onet="202.***.***.16/29"
oip="202.***.***.17"

# プライベート(内)側のインターフェイス
iif="rl1"
inet="192.168.1.0/24"
iip="192.168.1.1"

# ローカルホストはOK!
${fwcmd} add pass ip from any to any via lo0
${fwcmd} add pass ip from ${inet} to ${inet} via ${iif}

############################
# ループバックへのルール
${fwcmd} add pass all from any to any via lo0
${fwcmd} add deny all from any to 127.0.0.0/8

# 断片化されたパケットを破棄
${fwcmd} add deny ip from any to any via ${oif} frag

# NetBIOS を破棄
${fwcmd} add deny udp from any to any 137-139,445
${fwcmd} add deny tcp from any to any 137-139,445
${fwcmd} add deny udp from any 137-139,445 to any
${fwcmd} add deny tcp from any 137-139,445 to any

# 偽装されたパケットを破棄
${fwcmd} add deny all from ${inet} to any in via ${oif}
${fwcmd} add deny all from ${onet} to any in via ${iif}

# プライベートアドレスやマルチキャストなどの破棄
${fwcmd} add deny all from any to 10.0.0.0/8 via ${oif}
${fwcmd} add deny all from any to 172.16.0.0/12 via ${oif}
${fwcmd} add deny all from any to 192.168.0.0/16 via ${oif}
${fwcmd} add deny all from any to 0.0.0.0/8 via ${oif}
${fwcmd} add deny all from any to 169.254.0.0/16 via ${oif}
${fwcmd} add deny all from any to 192.0.2.0/24 via ${oif}
${fwcmd} add deny all from any to 224.0.0.0/4 via ${oif}
${fwcmd} add deny all from any to 240.0.0.0/4 via ${oif}

############################
# NAT
${fwcmd} add divert natd all from any to any via ${natd_interface}

# プライベートアドレスやマルチキャストなどの破棄
${fwcmd} add deny all from 10.0.0.0/8 to any via ${oif}
${fwcmd} add deny all from 172.16.0.0/12 to any via ${oif}
${fwcmd} add deny all from 192.168.0.0/16 to any via ${oif}
${fwcmd} add deny all from 0.0.0.0/8 to any via ${oif}
${fwcmd} add deny all from 169.254.0.0/16 to any via ${oif}
${fwcmd} add deny all from 192.0.2.0/24 to any via ${oif}
${fwcmd} add deny all from 224.0.0.0/4 to any via ${oif}
${fwcmd} add deny all from 240.0.0.0/4 to any via ${oif}

# 接続された TCP パケットを許可
${fwcmd} add pass tcp from any to any established

# FTP
${fwcmd} add pass tcp from any to ${inet} 20 setup
${fwcmd} add pass tcp from ${inet} 20 to any setup
${fwcmd} add pass tcp from any to ${inet} 21 setup
${fwcmd} add pass tcp from ${inet} 21 to any setup

# 外部からの SSH の接続開始を許可
${fwcmd} add pass tcp from any to ${inet} 22 setup

# 外部からの SMTP の接続開始を許可
${fwcmd} add pass tcp from any to ${inet} 25 setup

# IDENT には答えない
${fwcmd} add reset tcp from any to any 113

# DNS サーバを立てている場合
${fwcmd} add pass tcp from any to ${inet} 53 setup
${fwcmd} add pass udp from any to ${inet} 53
${fwcmd} add pass udp from ${inet} 53 to any

# WWW サーバを立てている場合
${fwcmd} add pass tcp from any to ${inet} 80 setup

# POP3
${fwcmd} add pass tcp from any to ${inet} 110 setup

# IMAP4
${fwcmd} add pass tcp from any to ${inet} 143 setup

# それ以外の外側からの TCP 接続を拒否し、ログに残す
${fwcmd} add deny log tcp from any to any in via ${oif} setup

# 上記以外(つまり内側から)の TCP の接続開始を許可
${fwcmd} add pass tcp from any to any setup

# 外部への DNS の問い合わせとその応答を許可
${fwcmd} add pass udp from any to any 53
${fwcmd} add pass udp from any 53 to any

# 外部の NTP サーバへの参照
${fwcmd} add pass udp from any 123 to any
${fwcmd} add pass udp from any to any 123

# 内部から外部への ping とその応答のみ許可
${fwcmd} add pass icmp from any to any via ${iif}
${fwcmd} add pass icmp from any to any out via ${oif} icmptypes 8
${fwcmd} add pass icmp from any to any in via ${oif} icmptypes 0

# RFC2979
${fwcmd} add pass icmp from any to any in via ${oif} icmptypes 3

# それ以外の ICMP は破棄し、ログを取る
${fwcmd} add deny log icmp from any to any

# それ以外は拒否

次に、NATDの設定ファイルを書きます。クライアントから外へ出られたり、あるいは外から内のサーバーを見にゆけたり設定します。/etc/natd.confを作成(編集)します。

natd.conf

log                     yes
verbose                 no
deny_incoming           no
log_denied              yes
log_facility            security
use_sockets             yes
same_ports              yes
unregistered_only       yes

redirect_address 192.168.1.2 202.***.***.18
redirect_address 192.168.1.1 202.***.***.17

redirect_address はstatic natで、202.***.***.17(18) 宛のパケットはすべて、192.168.1.1(2)宛に変換されます。もちろん、ipfw.natでも接続が許可されていなければなりません。このままでは、内から外へのFTP接続がPASV(PASSIVE)モードでしか接続できないので、pinch_fwをnatd.confに加えます。これにはまず、ipfw.natのルールをipfw -a listコマンドで確かめます。

#ipfw -a list
.
.
03000     0        0 allow tcp from any to 192.168.1.0/24 20 setup
03200     0        0 allow tcp from any to 192.168.1.0/24 21 setup
03300     0        0 allow tcp from 192.168.1.0/24 21 to any setup
.
.

ここで、FTP関連の最後のルール番号を3300とすると、natd.confに punch_fw 3300:100 という行を加えることで通常接続が可能になります。これは、FTPのPORTコマンドが送られたら、対応するルールをIPFIREWALLの3000から3099番までの間に動的にルールが挿入されるという意味らしいのですが詳しくは知りません。

5.DHCPサーバー
市販のルーターには必ず備わっているDHCP機能をこのFreeBSDルーターにもインストールしましょう。まずportsを使ってインストールします。2002年12月現在、Version 3.0.1.rc9 です。

# cd /usr/ports/net/isc-dhcp3
# make
# make install

Sampleをコピーしてdhcpd.confを編集します。

#cd /usr/local/etc
# cp dhcpd.conf.sample dhcpd.conf

dhcpd.conf

# dhcpd.conf
#
# Sample configuration file for ISC dhcpd
#

# option definitions common to all supported networks...
option domain-name "fujie.org";
option domain-name-servers ns.fujie.org, ns2.fujie.org;

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
#authoritative;

# ad-hoc DNS update scheme - set to "none" to disable dynamic DNS updates.
#ddns-update-style ad-hoc; ddnsを使わない場合noneは必須です。
ddns-update-style none;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# No service will be given on this subnet, but declaring it helps the
# DHCP server to understand the network topology.

# subnet 10.152.187.0 netmask 255.255.255.0 {
# }

# This is a very basic subnet declaration.

subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.20 192.168.1.99;
  option routers router.local.fujie.jp;
}

このDHCPサーバーが自動で192.168.1.20から192.168.1.99までのIPアドレスを自動で割り振ってくれます。そして起動ファイルをコピーして再起動すればおしまいです。

# cd /usr/local/etc/rc.d/
# cp isc-dhcpd.sh.sample isc.dhcpd.sh

6.SNMPサーバー
ルーターのトラフィックデーターを知るためのSNMPDをインストールします。これはトラフィックデーター以外にも、CPU使用率やメモリー占有率などを知ることもできる優れもののようです。詳しくはZDNet/JAPAN のページ(大澤文孝さん)を参考にしてください。LINUX向けのページですがFreeBSDもほとんど同じです。まずSNMPをportsからインストールします。2002年12月現在のバージョンは5.0.6です。

# cd /usr/ports/net/net-snmp/ # make; make install

次に、EXAMPLEからコピーしてsnmpd.confを編集します。

# cd /usr/ports/net/net-snmp/work/net-snmp-5.0.6/
# cp EXAMPLE.conf /usr/local/share/snmp/snmpd.conf

snmpd.conf

####
# First, map the community name (COMMUNITY) into a security name
# (local and mynetwork, depending on where the request is coming
# from):

#       sec.name  source          community
com2sec local     localhost       PUBLIC
com2sec mynetwork 192.168.1.0/24      PUBLIC

####
# Second, map the security names into group names:

#               sec.model  sec.name
# group MyRWGroup       v1         local
# group MyRWGroup       v2c        local
# group MyRWGroup       usm        local
group MyROGroup v1         mynetwork
group MyROGroup v2c        mynetwork
group MyROGroup usm        mynetwork

syslocation FreeBSD router
syscontact FUJIE Masao 

ここで、PUBLIC はコミュニティ名になります。またセキュリティのため、読み出しは mynetwork に可能ですが、書き出しは local でも不可能な設定にしました。

起動ファイルは、/usr/local/etc/rc.d/snmpd.sh にありますが、これだけでは起動できず、/etc/rc.confに次の1行を追加してください。

net_snmpd_enable="YES"

TOP PAGE