FreeBSD NAT ipfw

ゲートウェイ

gateway_enable="YES" マシンがゲートウェイとして動作するように設定します。
sysctl net.inet.ip.forwarding=1 コマンドを実行しても同じ効果がえられます。

21.13. ネットワークアドレス変換 (NAT)

ipfw

firewall_enable="YES"
firewall_type="open"

このように、ファイアウォールのタイプにとりあえず "open" を指定しておかないと、再起動後に別のマシンから telnet が出来なくなり("closed" を指定したのと同じ状態なんかな?)、コンソールから操作をしなくてはいけなくなるので面倒やで。
ファイアウォール(ipfw)を利用する

ipfwのNAT機能を使う

/etc/rc.conf

gateway_enable="YES"
firewall_enable="YES"
firewall_type="OPEN"
firewall_nat_enable="NO"
firewall_nat_enable="YES"
firewall_nat_interface="em0"
firewall_nat_flags="unreg_only"

ipfw + natd

ipfw と natd の間の接続として、divertソケットというものが存在し、そこにポートという概念があります。

http://www.abk.nu/~nabe/document/ipfw_natd.htm

/etc/rc.conf

gateway_enable="YES"
firewall_enable="YES"
firewall_type="OPEN"
natd_enable="YES"
natd_interface="em0"
natd_flags="-f /etc/natd.conf"

/etc/natd.conf

deny_incoming no
use_sockets yes
same_ports yes
unregistered_only yes
dynamic yes

/etc/natd.conf ファイルの作成
# ログの記録 (yes なら /var/log/alias.log に記録)
log no
# 起動時のメッセージ
verbose no
# 外部からの接続要求 (yes なら拒否)
deny_incoming no
# 拒否したパケットの記録
log_denied yes
log_facility security
# socket を利用し NAT の失敗を回避
use_sockets yes
# 可能な限り同じポート番号を利用
same_ports yes
# プライベートアドレスのみの変換
unregistered_only yes

http://www.gadgety.net/shin/tips/unix/ipfw.html

# ipfw -a list
00050  616  57691 divert 8668 ip4 from any to any via em0
00100    0      0 allow ip from any to any via lo0
00200    0      0 deny ip from any to 127.0.0.0/8
00300    0      0 deny ip from 127.0.0.0/8 to any
00400    0      0 deny ip from any to ::1
00500    0      0 deny ip from ::1 to any
00600    0      0 allow ipv6-icmp from :: to ff02::/16
00700    0      0 allow ipv6-icmp from fe80::/10 to fe80::/10
00800    0      0 allow ipv6-icmp from fe80::/10 to ff02::/16
00900    0      0 allow ipv6-icmp from any to any ip6 icmp6types 1
01000    0      0 allow ipv6-icmp from any to any ip6 icmp6types 2,135,136
65000 1202 114877 allow ip from any to any
65535  277  30370 deny ip from any to any

FreeBSD9.0の起動プロセスのエラー

上述のとおり,ipfwのdivert機能でnatdに転送するのですから,natdの方がipfwより先に起動していないとdivertできません。ところが,FreeBSD9.0起動プロセスでは,ipfwの方がnatdより先に起動しているようです。
natdをipfwの前に起動させるPatch - Mathematics@HSCUC