おうちのネットワークは,サーバの棗さんがサーバやりつつルータもやってます.
棗さんは Linux Box なので,フィルタリングと NAT を iptables を使います.
ちなみに Firewall/NAT を行なうソフトウェアには ipfilter というのもあるので,
そっちを使ってみるのもいいかも知れません.
ipfilter は Solaris でも使えたりと,ちょっと汎用性高いです.
簡単に書くと接続図は下のような感じになります.
棗が DHCP でグローバルアドレスを拾ってきて,
下々のもの(主に芙容と皐)は NAPT で外と通信します.
ということで,棗に外から入ってくるパケットを絞ってやれば OK です.
とりあえず,iptables をインストールしましょう.
iptables を入れた後,netfilter を有効にしてカーネルを作り直す必要があります.
既にカーネルソースは /usr/src/linux にあるものとして, まずは iptables を作りましょう.
% bzip2 -d < iptables-1.2.7a.tar.bz2 | tar xvf -
% cd iptables-1.2.7a
% make KERNEL_DIR=/usr/src/linux
# make install KERNEL_DIR=/usr/src/linux
iptables をインストールしたら,カーネルを作り直し.
# cd /usr/src/linux
# make menuconfig
# make dep clean bzImage modules modules_install
# cp /vmlinuz /vmlinuz.old
# cp arch/i386/boot/bzImage /vmlinux
私は iptables をカーネルモジュールとして作ってますので,
それらを適切にロードしてやりましょう.
Slackware なので,/etc/rc.d/rc.modules に適当に書いてしまってます.
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_MASQUERADE
/sbin/modprobe iptable_filter
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_state
/sbin/modprobe ipt_REJECT
あと ip_conntrack なんかも使いますが,その辺は自動でロードされるので ここには書いてません.
NAPT を動かさないことには内側にいる芙容や皐が通信できないので, とりあえず NAPT (IP masquerade) します.
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
設定終わり.これだけで,動きます.
とりあえず NAPT が動いてプライベートマシンたちも外と通信できます.
しかし,インターネット上の悪意からおうちのネットワークを守るために,
なにかとフィルタリングすることにします.
とりあえず,デフォルトのポリシーは INPUT, FORWARD が DROP,
OUTPUT は ACCEPT です.
ループバックはデフォルト許可にしときましょう.
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
次に,INPUT chain を設定します.
とりあえず怪しいパケットは全部捨てポイです.
基本的にプライベート側の INPUT chain は全部 ACCEPT にするので,
設定はグローバル側の INPUT chain に関するものばっかりです.
送信元/先がプライベートアドレスなものはポイ.
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -d 10.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth0 -d 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i eth0 -d 192.168.0.0/16 -j DROP
送信元が自分 or プライベート側アドレスのもの(を偽装したパケット)もポイ.
感じ悪いので,ログに残しときます.
iptables -A INPUT -i eth0 -s 192.168.1.0/255.255.255.0 -j LOG --log-prefix="spoofed "
iptables -A INPUT -i eth0 -s 192.168.1.0/255.255.255.0 -j DROP
iptables -A INPUT -i eth0 -s (eth0 の IP) -j LOG --log-prefix="spoofed "
iptables -A INPUT -i eth0 -s (eth0 の IP) -j DROP
グローバルアドレスは DHCP でもらってるので,DHCP は許可です.
iptables -A INPUT -i eth0 -p udp -s 0.0.0.0/0 -d 0.0.0.0/0 --sport bootps --dport bootpc -j ACCEPT
Broadcast なんて無視.
iptables -A INPUT -i eth0 -d 255.255.255.255 -j DROP
iptables -A INPUT -i eth0 -d 224.0.0.0 -j DROP
iptables -A INPUT -i eth0 -d (グローバル側ブロードキャスト) -j DROP
IDENT はリセット.
iptables -A INPUT -i eth0 -p tcp --dport ident -j REJECT --reject-with tcp-reset
こちらからコネクションを張った戻りパケットは,もちろん受け取ります.
iptables -A INPUT -i eth0 -m state --state ESTABLISHED -j ACCEPT
サービスやってるポートは,受けるようにします.
TCP/UDP 両方許可していますが,ここはもうちょっと絞れますね.
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 22 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 25 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 8080 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 8080 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 123 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 123 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 143 -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 143 -j ACCEPT
最後に,プライベート側は信用して全部 ACCEPT にしときます.
iptables -A INPUT -i eth1 -j ACCEPT
NAPT しているので,FORWARD chain もちょっと設定が必要です.
プライベート側からコネクションを張りに行ったものと,
既に ESTABLISHED なコネクションについて ACCEPT するようにしてやります.
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -m state --state NEW,ESTABLISHED -j ACCEPT
ついでに,もうちょっといろいろやっときます.
対 SYN Flood attack 用に,SYN Cookies を有効にします.
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
Broadcast PING は無視.
echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
source-routing されたパケットも無視.
for i in /proc/sys/net/ipv4/conf/*/accept_source_route;
do
echo 0 > $i
done
ICMP redirect も,やっぱり無視.
for i in /proc/sys/net/ipv4/conf/*/accept_redirects;
do
echo 0 > $i
done
結果はこんな感じ.
# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere
DROP all -- 10.0.0.0/8 anywhere
DROP all -- anywhere 10.0.0.0/8
DROP all -- 172.16.0.0/12 anywhere
DROP all -- anywhere 172.16.0.0/12
DROP all -- 192.168.0.0/16 anywhere
DROP all -- anywhere 192.168.0.0/16
LOG all -- 192.168.1.0/24 anywhere LOG level warning prefix `spoofed '
DROP all -- 192.168.1.0/24 anywhere
LOG all -- YahooBBxxxxxxxxxxxx.bbtec.net anywhere LOG level warning prefix `spoofed '
DROP all -- YahooBBxxxxxxxxxxxx.bbtec.net anywhere
ACCEPT udp -- anywhere anywhere udp spt:bootps dpt:bootpc
DROP all -- anywhere 255.255.255.255
DROP all -- anywhere BASE-ADDRESS.MCAST.NET
DROP all -- anywhere YahooBBxxxxxxxxxxxx.bbtec.net
REJECT tcp -- anywhere anywhere tcp dpt:auth reject-with tcp-reset
ACCEPT all -- anywhere anywhere state ESTABLISHED
LOG all -- anywhere anywhere LOG level warning
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT udp -- anywhere anywhere udp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:smtp
ACCEPT udp -- anywhere anywhere udp dpt:25
ACCEPT tcp -- anywhere anywhere tcp dpt:domain
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:www
ACCEPT udp -- anywhere anywhere udp dpt:www
ACCEPT tcp -- anywhere anywhere tcp dpt:8080
ACCEPT udp -- anywhere anywhere udp dpt:8080
ACCEPT tcp -- anywhere anywhere tcp dpt:ntp
ACCEPT udp -- anywhere anywhere udp dpt:ntp
ACCEPT tcp -- anywhere anywhere tcp dpt:imap
ACCEPT udp -- anywhere anywhere udp dpt:imap
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state NEW,ESTABLISHED
ACCEPT all -- anywhere anywhere state NEW,ESTABLISHED
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
私の使ってる設定用シェルスクリプトを置いときます.
使って何が起きても責任は持ちませんので,使うにせよ参考にするにせよ,
とにかく自己責任で使って下さい.
設定にあたって,UNIX MAGAZINE 10月号 (2002年9月18日発売) の特集
「フィルタリングで守る SOHO 環境」を参考にしました.
というか,かなりそのままです.