■Debian Lennyにファイアウォールを設定する。
・許可制限対象はINPUT/FORWARDのIPv4の稼動中のポートのみ。
・本来はローカルネットワークやOUTPUTの設定も必要だが、
上位サーバの仕事なので今回は行わない。
・いずれのルールにもマッチしない場合は、ログを出力して破棄する。
$ echo "iptables iptables-save" | xargs whereis
iptables: /sbin/iptables /usr/share/iptables /usr/share/man/man8/iptables.8.gz
iptables-save: /sbin/iptables-save /usr/share/man/man8/iptables-save.8.gz
$ dpkg -L iptables | grep /sbin/
/usr/sbin/iptables-apply
/sbin/ip6tables
/sbin/ip6tables-restore
/sbin/ip6tables-save
/sbin/iptables
/sbin/iptables-restore
/sbin/iptables-save
■準備
tcpのすべてのソケットを数字で表示。
かつ、ipv4のポートを数の小さい順に並べる。
※uniqはIPやホストによる重複を排除する。
$ netstat -tan --protocol inet | awk -F\: '{print $2}' | awk '{print $1}' | sort -n | uniq
■/etc/servicesで引けるものを一覧する
$ netstat -tan --protocol inet | awk -F\: '{print $2}' | awk '{print $1}' | sort -n | uniq | \
for list in `xargs`;do sed s/"\t"/":"/g /etc/services | grep --color "\:$list\/tcp"; done
ftp::21/tcp
smtp::25/tcp::mail
pop3::110/tcp::pop-3::# POP version 3
sunrpc::111/tcp::portmapper:# RPC 4.0 portmapper
imap2::143/tcp::imap::# Interim Mail Access P 2 and 4
submission:587/tcp::::# Submission [RFC4409]
imaps::993/tcp::::# IMAP over SSL
pop3s::995/tcp::::# POP-3 over SSL
■マスカレードは行わない。
$ netstat -M
netstat: no support for `ip_masquerade' on this system.
■外からのssh接続を受け付ける。
例)外からはポート8022でNAT変換、Debian側ではポート22で応答
INPUTとFORWARDの両方を設定。
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A FORWARD -i eth0 -p tcp --dport 22 -j ACCEPT
$ sudo nmap -sX localhost -p 8022 | grep 8022
8022/tcp open|filtered unknown
■外からのwwwに対応する設定(普通はこんな風にはやらないw)
iptablesは8080ポートの受信を許可、外からの80ポートの転送を許可する
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
iptables -A FORWARD -i eth0 -p tcp --dport 80 -j ACCEPT
★以下のようにすることで、sshでアクセスし、かつトンネルセッションを繋げた時のみ
webサーバにアクセス出来る。つまり、自分が見える設定を行った時のみ外から見れるwebサーバです。
転送先ポートはapacheでもリバースプロキシでも構いません。
sshのトンネルセッションをログアウトすると使えなくなります。
スクリプトでなく、特定のputtyの設定からだけ等にすると、
更に自分でさえどうやって繋げるのか分からなくなります。
※webクライアントがproxy経由の場合、直ぐに見れなくなるわけではないので注意します。
例)
[クライアントPC]->[ブラウザ]->[プロキシ]->[ルータのNAT]->[ルータのNAT]->[外部]
[外部]->[ルータのNAT]->[ルータのNAT]->[Debianのsshトンネル]->[リバースプロキシ]->[apache]
ssh -p 22 -g -L 80:localhost:8080 usr@localhost
5123
logout
Connection to 127.0.0.1 closed.
★www.sh実行前、sshトンネルセッションログアウト後
$ sudo nmap -sX localhost -p 80 | grep 80
80/tcp closed http
★www.sh実行中
$ sudo nmap -sX localhost -p 80 | grep 80
80/tcp open|filtered http
■後は普通に(?)
参考URL:http://d.hatena.ne.jp/doublefree/20101124/1290573124
一時的に使用するポートはその都度、自身でiptablesコマンドを使用し許可する。
--------------------------------------------------------------------------------
■2011/11/05追記
itables-saveについての追記とシステムメールの追加。
参考URL
http://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/index.html
■iptablesコマンドは「-c」オプションで保存が出来る。
上記参考URLの「8.3. iptables-save」から。
iptables-save -c > /etc/iptables-save
■上記参考URLの「8.4. iptables-restore」からのリストア方法。
■カウンタの状況はメールで送信する。
THISDATE=`env LANG=C date '+%Y/%m/%d %H:%M:%S'`
cat /etc/iptables-save | mail -s "iptables report ${THISDATE}" root
私の環境ではベースとなる「firewall.sh」の後に、
サービス毎に必要となるポートを開放するスクリプトを追加する形式を取る。
その為、以下の制限が生まれる。
・一時的な追加分まで戻ってしまうiptables-restoreでは戻せない。
(テーブルやカウンタのリセットが必要)
※システムメールの送信箇所は、別のログに出力しても構わない。
--------------------------------------------------------------------------------
$ sudo cat firewall.sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin
THISDATE=`env LANG=C date '+%Y/%m/%d %H:%M:%S'`
cat /etc/iptables-save | mail -s "iptables report ${THISDATE}" root
iptables -F
iptables -Z
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
iptables -A FORWARD -i eth0 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A FORWARD -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 3128 -j ACCEPT
iptables -A INPUT -j LOG --log-prefix "IPTABLES_INPUT_LOG : " --log-level=info
iptables -P INPUT DROP
iptables-save -c > /etc/iptables-save
THISDATE=`env LANG=C date '+%Y/%m/%d %H:%M:%S'`
cat /etc/iptables-save | mail -s "iptables report ${THISDATE}" root
■ログの確認
※UDPの設定をしていないので、ログが沢山出るはずです。。。
sudo tail -f /var/log/kern.log | grep IPTABLES_INPUT_LOG --color
■設定の確認
$ sudo /sbin/iptables -L | grep 22
ACCEPT tcp -- anywhere anywhere tcp dpt:22
$ sudo /sbin/iptables -L -v | grep REJECT
23 1360 REJECT tcp -- any any anywhere anywhere tcp dpt:smtp reject-with icmp-port-unreachable
1 40 REJECT tcp -- any any anywhere anywhere tcp dpt:submission reject-with icmp-port-unreachable
$ sudo /sbin/iptables -L -v | grep DROP
Chain INPUT (policy DROP 53 packets, 6364 bytes)
Chain FORWARD (policy DROP 0 packets, 0 bytes)
■表示されないポートを番号で見たい。
$ sudo /sbin/iptables -L -v -n | grep 8080
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080