こういうことがしたい:
  1. 会社に持ち込んだ私物のPCを社内ネットワークを通じてインターネットに接続した い。
  2. 社内ネットワークへのアクセスは遮断しなければいけない。
ネットワーク構成はこんな感じで、仕事につかっているPC(FreeBSD)にはイーサネットが2口ついている。
   the Internet
         |
         |
 ________|________
|                 |
|       NAT       |
|_________________|
         |
         |10.1/16
 ________|________    nfe0 inet 10.1.3.67/16
|                 |        inet 10.1.3.66/32 alias
|                 |
| Desktop Machine |  会社のPC (FreeBSD)
|                 |
|_________________|   nfe1 inet 192.168.0.1/24
         |
         |192.168.0/24
 ________|________
|                 |
| Nomadic Machine | これが持ち込みPC (Windows)
|_________________|

DHCP/DNSの設定

持ち込みPCに対してDHCPとDNSをサービスするのにdnsmasqをつかった。
% su
Password:
# cd /usr/ports/dns/dnsmasq
# make
# make install
# vi /usr/local/etc/dnsmasq.conf
項目数が膨大でめまいがするが、なんとか最低限の設定をすませる:
  • 社内のDNSをみせないようにするためGoogle Public DNSをつかう。
  • どのインタフェイスでサービスするか。持ち込みPCをつなぐ側のインタフェイスを 指定する。
  • DHCPで払い出すアドレス範囲を指定する。
  • 心配なのでログをどんどん吐かせる。(標準的な設定だと、ログは/var/log/debug.logにでる。)
% diff -u /usr/local/etc/dnsmasq.conf.example   /usr/local/etc/dnsmasq.conf
--- /usr/local/etc/dnsmasq.conf.example 2010-07-01 18:54:02.808850994 +0900
+++ /usr/local/etc/dnsmasq.conf 2010-11-04 12:28:11.392594322 +0900
@@ -39,6 +39,7 @@
 # file, getting its servers from this file instead (see below), then
 # uncomment this.
 #no-resolv
+no-resolv

 # If you don't want dnsmasq to poll /etc/resolv.conf or other resolv
 # files for changes and re-read them then uncomment this.
@@ -47,6 +48,7 @@
 # Add other name servers here, with domain specs if they are for
 # non-public domains.
 #server=/localnet/192.168.0.1
+server=8.8.8.8

 # Example of routing PTR queries to nameservers: this will send all
 # address->name queries for 192.168.3/24 to nameserver 10.1.2.3
@@ -83,6 +85,7 @@
 # interface (eg eth0) here.
 # Repeat the line for more than one interface.
 #interface=
+interface=nfe1
 # Or you can specify which interface _not_ to listen on
 #except-interface=
 # Or which to listen on by address (remember to include 127.0.0.1 if
@@ -134,6 +137,7 @@
 # repeat this for each network on which you want to supply DHCP
 # service.
 #dhcp-range=192.168.0.50,192.168.0.150,12h
+dhcp-range=192.168.0.50,192.168.0.150,12h

 # This is an example of a DHCP range where the netmask is given. This
 # is needed for networks we reach the dnsmasq DHCP server via a relay
@@ -543,9 +547,11 @@
 # For debugging purposes, log each DNS query as it passes through
 # dnsmasq.
 #log-queries
+log-queries

 # Log lots of extra information about DHCP transactions.
 #log-dhcp
+log-dhcp

 # Include a another lot of configuration options.
 #conf-file=/etc/dnsmasq.more.conf
/etc/rc.conf に
ifconfig_nfe1="inet 192.168.0.1/24"
dnsmasq_enable="YES"
を追加してから、
# ifconfig nfe1 inet 192.168.0.1/24 up
# /usr/local/etc/rc.d/dnsmasq start
で起動する。

NATの設定

FreeBSDで使えるNATは2つあって ipfw nat と /sbin/natd がある。 カーネルにipfw natを組み込んでなかったので /sbin/natd をつかった。 いろいろ試しながら設定したので/etc/rc.firewallをつかわずに自前で設定した。 ちょっとした工夫は、インタフェイス nfe0 にエイリアスアドレスをつけて natはこのエイリアスアドレスをつかうことで、natdに無駄なトラフィックが流れないよ うにしている。
#!/bin/sh
set -x

OUTGOING="recv nfe1 xmit nfe0"
INCOMING="recv nfe0"
NATADDR="10.1.3.66"

ipfw delete 2010
ipfw add 2010 deny ip4 from any to 10.0.0.0/8 ${OUTGOING}
ipfw add 2010 deny ip4 from any to 172.16.0.0/12 ${OUTGOING}
ipfw add 2010 deny ip4 from any to 192.168.0.0/16 ${OUTGOING}
ipfw delete 2020
ipfw add 2020 divert natd ip4 from any to any ${OUTGOING}
ipfw add 2020 divert natd ip4 from any to ${NATADDR} ${INCOMING}

natd -alias_address ${NATADDR}
この設定では持ち込みPCから仕事PCへの接続は拒否していない。 制限したいのであれば ipfw add 2010 deny ip4 from any to 10.1.3.67 ${OUTGOING} を追加すればいいとおもう。

そのほか

topless -c ipfw show はどのルールにひっかかっているリアルタイムでみるのに具合がよいが、パケットがたくさんとびかっているとわけがわからなくなるので、できるだけ通信するプログラムを止めた状態でやるのがいいとおもう。