6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ルールの書き方やそのルールで何をしようとしているかを覚えられない私の iptables 管理方法

Last updated at Posted at 2015-01-10

概要

iptables を使っているけど、ルールの書き方を覚えられない(覚える気がない)し、個々のルールが何の目的で設定してあるのかすぐに忘れてしまう(たとえば、あるサービスを提供しなくなったのでルールを削除したいが、どれを削除していいのか、また削除して他に影響がないのかすぐには判断できない)、そんなダメ管理者がやっている iptables 管理方法を晒します。

基本方針

  • /etc/iptables.sh に、何をどうするのか、という形で iptables の設定を書く。
  • 何 (たとえば、443 というのは https のポート番号である、とか) を、どうする (たとえば TCP のサーバを動かすためにパケットを通す、とか) という定義は /etc/iptables.inc.sh にまとめて書く。
  • 引数なしで起動すれば設定するルールを表示し、引数として exec をつければ実際に iptables コマンドを実行する。
  • 両スクリプトは /etc/ に置いて etckeeper の対象にする。
[root@heaven /etc]# ./iptables.sh

とやると、ずらずらと実行する予定の iptables コマンドが表示され、

[root@heaven /etc]# ./iptables.sh exec

とすると実際に実行されます。

中身

iptables.sh の方はこんな感じ。

iptables.sh
 #!/bin/bash
exec=${1}
. /etc/iptables.inc.sh
set_policy DROP
# create_new_chain NAMED_IN DROP
# create_new_chain NAMED_OUT DROP
accept_any_packets_on_loopback_if
drop_private_packets eth0
for ip in $bad_ip1; do
  drop_packets_from eth0 $ip
done
for port in $ssh $smtp $submission $http $imap $squid; do
  tcp_server eth0 $port
done
for port in $smtp $http $ftp $https; do
  tcp_client $port
done
for ip in $ns1_dns_ne_jp $ns2_dns_ne_jp; do
  udp_service_to $dns $ip
done
for port in $ntp $dns; do
  udp_client $port
done
# drop_broadcast_packets
accept_established_or_related_packets
# end of file

iptables.inc.sh の方はこんな感じ。

iptables.inc.sh
if [ "${exec}" = "exec" ] ; then
  iptables=/sbin/iptables
else
  iptables='echo x'
fi

ssh=___secret___
squid=15120
smtp=25
submission=587
ntp=123
dns=53
http=80
https=443
ftp=21
imap=143
ns1_dns_ne_jp=210.188.224.9
ns2_dns_ne_jp=210.224.172.13


add_in_drop_rule() {
  i=${1}
  privates="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"
  for net in ${privates}; do
    $iptables -A INPUT -i $i -s $net -j DROP
    $iptables -A INPUT -i $i -d $net -j DROP
  done
}

set_policy() {
  policy=${1}
  # clear
  $iptables -F
  $iptables -X
  # default policy
  $iptables -P INPUT $policy
  $iptables -P FORWARD $policy
  $iptables -P OUTPUT $policy
}

accept_any_packets_on_loopback_if() {
  $iptables -A INPUT -i lo -j ACCEPT
  # $iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
  # $iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
}

drop_private_packets() {
  i=${1}
  add_in_drop_rule $i
}

tcp_server() {
  i=${1}
  port=${2}
  $iptables -A INPUT -i $i -m state --state NEW -m tcp -p tcp --dport $port -j ACCEPT
}

tcp_client() {
  port=${1}
  $iptables -A OUTPUT -m state --state NEW -m tcp -p tcp --dport $port -j ACCEPT
}

udp_server() {
  port=${1}
  $iptables -A INPUT -p udp --dport $port -j ACCEPT
}

udp_client() {
  port=${1}
  $iptables -A OUTPUT -p udp --dport $port -j ACCEPT
  $iptables -A INPUT -p udp --sport $port -j ACCEPT
}

drop_broadcast_packets() {
  touch /tmp
  # $iptables -A INPUT -i $i -d 255.255.255.255 -j DROP
  # $iptables -A INPUT -i $i -d 224.0.0.1 -j DROP
}

accept_established_or_related_packets() {
  $iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  $iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
}

drop_packets_from() {
  i=${1}
  ip=${2}
  $iptables -A INPUT -i $i -s $ip -j DROP
}

create_new_chain() {
  name=${1}
  policy=${2}
  $iptables -N $name
  $iptables -P $name $policy
}
# end of file

補足

  • 基本的に、そのとき必要な関数や定数はそのとき追加しているので、汎用的なものにはなっていません。
  • sshd はポートをデフォルト (22) と変えてサービスしてます。
  • drop_broadcast_packets 関数は実質 nop みたいだけど、なぜそうなっているかは 2 年前の私に聞かないとわかりません。

議論

  • iptables.inc.sh にはどのサイトでも使える関数、定数を定義しておいて、サーバごとの個別の設定は別の、たとえば iptables.config.sh とかにまとめて書くと配布とか使いまわしとかの点で便利かも。
  • って、iptables.config.sh を用意するなら ...
iptables.config.sh
...
tcp_server_ports="$squid $ssh $smtp $submission $http $https $imaps"
tcp_client_ports="$smpt $http $ftp $https"
...

とかしといて、iptables.inc.sh に、これらの変数を見て iptables コマンドを発行する関数 accept_site_tcpip_packets とか用意して、iptables.sh には

iptable.sh
...
accept_site_tcpip_packets
...

とだけ書くのがスマートかも。

  • ポートの定数は /etc/services から自動的にとってくるほうがかっこいいかも。
  • IP アドレスの定数を DNS 問合せして動的にとってくる、というのはたぶんやりすぎ。
  • 最近、管理しているサーバが攻撃を受けているので、ログ周り含め、いろいろ細かく設定しようとしているので、もっと変わっていくことでしょう。

オチ

最近、久々に新しいサーバを立てたので、このスクリプトをコピペして使おう、と思ったら iptables じゃなくて firewalld になってて ...

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?