動的にiptablesを書き換えたい

こんな機能が欲しくてスクリプトを書いてみました。

  • 出来るだけポートを空けたくないけど、特定用途で特定のユーザにどこかのポートからサービスしたい
  • いちいち手動でiptables編集するのは面倒
  • 一定期間過ぎたらポート閉じたい

具体的には、zabbixの監視ページをhttpsで運用しているが、不特定多数からアクセスされるのは困る。
ただし、アクセス元は動的にIPが変わるので、sshでログインしてきたユーザのアクセス元だけはhttpsアクセスを許可する

前提となるiptablesの設定

# Generated by iptables-save v1.4.7 on Fri Dec 21 01:07:48 2012
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [4015990:239700491]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -s xxx.xxx.xxx.xxx/24 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT


この設定をいじってiptables restartしても達成は出来るがスマートではないので、

web-allow.sh というスクリプトを下記の通り作成して、cronに毎分実行して貰う。

#!/bin/bash
LANG=C
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

LOG=/var/log/web-allow.log

date >> $LOG 2>&1

for deleteip in `iptables -L -v -n|grep 'tcp dpt:443' |awk '{print $8}'`
do
 echo delete $deleteip  >> $LOG 2>&1
 iptables -D INPUT -p tcp -s $deleteip --dport 443  -j ACCEPT  >> $LOG 2>&1
done

for homeip in `last -i |grep -v -e "wtmp" -e "root" -e "reboot   system boot" |awk '{print $3}'|head -n 5|sor            t|uniq `
do
 echo add allow $homeip  >> $LOG 2>&1
 iptables -I INPUT 4 -p tcp -s $homeip --dport 443  -j ACCEPT  >> $LOG 2>&1
done

見て貰えばわかるが上部分で443当てのルールをすべて削除、
下部分でログイン履歴からアクセス元を求めて、許可ルールを追加している。

かなり適当に書いたので、ユーザがコンソールログインしてきたときはバグる可能性大。

その辺はttyとかでフィルタする何かを使って対処が必要だと思う。
継続許可という処理を考慮してないので、消して追加して...と無駄な動作しているがまあ気にしていない。
スクリプトが追加したルール以外も吹き飛ばす可能性が高いので、そのまま使わないでほしい。

ついでに、logrotateにも追加

cat /etc/logrotate.d/web-allow

/var/log/web-allow.log {
    missingok
    notifempty
    size 30k
    yearly
    create 0600 root root
}

以上