動的に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 }
以上