2010/02/06

IPv6 - ip6tablesによるFirewall設定

IPv6用の設定にはip6tablesコマンドを使用します。 今回のスクリプトの中はだいたい、次の図のような流れになっています。

The ip6tables Process Flow

基本的な構成について

Feel6を使ったIPv6接続は、まだ手動で接続しています。 アドレス空間が膨大でDNSサーバに登録していないとはいってもポートスキャンの脅威がないわけではないですからね。接続の自動化よりもFirewallの設定を先にする事にしました。

設定したFirewallルールの確認

外出用にPHSカードは持っていて、IPv4のFirewallチェックにも使いました。 PRINはIPv6用のトンネルインタフェースも提供しているので、何も考えなくともPHSモデム経由でIPv6で接続する事ができるようになっています。

PRINのIPv6提供は実験的サービスのようですが、これが使えて助かりました。

PHSが使えると気がつくまでは、稼働の確認にSubnetOnline.comONLINE PING IPV6とONLINE PORT SCANNER IPV6も使いました。 IPv4向けにはいろいろなサービスがあるんですけどね、IPv6に対応した接続確認サービスを提供しているところは案外少ない印象です。

スクリプトの作成方針

まだ十分にIPv6の構造について勉強が進んでいるわけではないのですが、 とりあえず現行のIPv4用のiptables設定をベースにしています。

TCPヘッダのフラグチェックは同様に必要だよね、UDPも動きに変更ないよね、とか思いながら設定を削ったり付け加えたりしています。 ICMPはICMPv6になり機能は増え、考え方は変っていませんが、ARPの代替機能を持ったりしています。

ICMPv6は基本的に制限を加えない事にしました。 その代りログに出力をさせて将来必要なものと不要なものを振り分けるルールを追加しようとしています。 もし制限を加えるのであれば、後ろ向きですがecho-replyのように不要なものを個別に設定するのが良さそうです。

ログの取り方

使用頻度が低そうなところではログを取るようにしています。 必要に応じてACCEPT⇔logaccept、DROP⇔logdropを変更して使っています。

config_ip6tables.shスクリプト

次のようなスクリプトを/usr/local/sbinに配置して、interfacesファイルの中でpost-upに指定しています。

/etc/network/interfacesファイルの設定抜粋

auto dsl-provider
iface dsl-provider inet ppp
  pre-up /sbin/ifconfig eth0 up # line maintained by pppoeconf
  provider dsl-provider
  post-up /usr/local/sbin/config_iptables.sh
  post-up /usr/local/sbin/config_ip6tables.sh

ここで指定しているconfig_ip6tables.shの全体は次のとおりです。

config_ip6tables.shスクリプト

#!/bin/bash

## Initialize Script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH

#######################
## Initialize Chains ##
#######################
ip6tables -F
ip6tables -X
ip6tables -Z

ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP

########################
## Creating new rules ##
########################
ip6tables -N insit  ## from internet to home-lan
ip6tables -N outsit ## from home-lan to internet
ip6tables -N logdrop        ## logging rule
ip6tables -N logaccept      ## logging rule
ip6tables -N dumpdrop       ## for un-expectation connections
ip6tables -N deny_ip_flags  ## for ip flag check
ip6tables -N deny_localaddr ## for local ip address group

## [logdrop] Prepare the logging interface
IP6TABLES_OPTS="-m limit --limit 5/minute -j LOG"
ip6tables -A logdrop ${IP6TABLES_OPTS} --log-level warn --log-prefix "netfilter6 drop "
ip6tables -A logdrop -j DROP

## [logaccept] Prepare the logging interface
ip6tables -A logaccept ${IP6TABLES_OPTS} --log-level debug --log-prefix "netfilter6 accept "
ip6tables -A logaccept -j ACCEPT

## [dumpdrop] Prepare the logging interface
ip6tables -A dumpdrop ${IP6TABLES_OPTS} --log-level warn --log-prefix "netfilter6 dumpdrop "
ip6tables -A dumpdrop -j DROP

## [deny_ip_flags] Prepare the logging interface
ip6tables -A deny_ip_flags ${IP6TABLES_OPTS} --log-level error --log-prefix "netfilter6 ipflagcheck "
ip6tables -A deny_ip_flags -j DROP

## [deny_localaddr] Prepare the logging interface
ip6tables -A deny_localaddr $IP6TABLES_OPTS} --log-level error --log-prefix "netfilter6 deny_localaddr "
ip6tables -A deny_localaddr -j DROP

##############################
## prepare the lo interface ##
##############################
ip6tables -A INPUT -i lo -j logaccept
ip6tables -A OUTPUT -o lo -j logaccept

##########################################
## prepare sit+ interfaces without sit0 ##
##########################################
## [insit] Default Chain Policy from outside attackers.
ip6tables -A INPUT   -i sit+ -j insit
ip6tables -A FORWARD -i sit+ -j insit
## [outsit] Default Chain Policy to stop leaking private connection.
ip6tables -A OUTPUT  -o sit+ -j outsit ## manage from localhost, so may be useless.
ip6tables -A FORWARD -o sit+ -j outsit ## manage from home-lan clients, so it's essential.

## [insit] check tcp flags before default rules
ip6tables -A insit -p tcp --tcp-flags ACK,FIN FIN -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags ACK,PSH PSH -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags ACK,URG URG -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags FIN,RST FIN,RST -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags SYN,FIN SYN,FIN -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags SYN,RST SYN,RST -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags ALL ALL -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags ALL NONE -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags ALL FIN,PSH,URG -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j deny_ip_flags
ip6tables -A insit -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j deny_ip_flags

## [insit/outsit] Adding Deny Rules for local,
##   private reserved and broadcast addresses from outside.
ip6tables -A insit -s fe80::/8       -j deny_localaddr
ip6tables -A outsit -d fe80::/8     -j deny_localaddr

########################
## Default sit+ rules ##
########################
## - allow already used connections
ip6tables -A insit -m state --state ESTABLISHED,RELATED -p tcp -j ACCEPT
ip6tables -A insit -m state --state ESTABLISHED,RELATED -p udp -j ACCEPT
ip6tables -A insit -m state --state ESTABLISHED,RELATED -p icmpv6 -j ACCEPT
##
## - allow outbound connections
ip6tables -A outsit -m state --state ESTABLISHED,RELATED -p tcp -j logaccept
ip6tables -A outsit -m state --state ESTABLISHED,RELATED -p udp -j logaccept
ip6tables -A outsit -m state --state ESTABLISHED,RELATED -p icmpv6 -j logaccept
ip6tables -A outsit -m state --state NEW -p tcp -j ACCEPT
ip6tables -A outsit -m state --state NEW -p udp -j ACCEPT
ip6tables -A outsit -m state --state NEW -p icmpv6 -j ACCEPT

################################
## Define other special rules ##
################################
## for ICMPv6
ip6tables -A insit -p icmpv6 -j logaccept
ip6tables -A outsit -p icmpv6 -j logaccept
## for SSH connection
ip6tables -A insit -p tcp --dport 22 -j logaccept

##################################
## Adding Deny Rules as default ##
##################################
ip6tables -A insit -j dumpdrop 
ip6tables -A outsit -j dumpdrop

################################
## End of Processing for sit+ ##
################################


################################
## Default rules for eth[012] ##
################################
ip6tables -A INPUT -i eth+ -j ACCEPT
ip6tables -A FORWARD -i eth+ -j ACCEPT
ip6tables -A OUTPUT -o eth+ -j ACCEPT
ip6tables -A FORWARD -o eth+ -j ACCEPT

###################################
## Drop all packets with logging ##
###################################
ip6tables -A FORWARD -j dumpdrop
ip6tables -A INPUT -j dumpdrop
ip6tables -A OUTPUT -j dumpdrop

############
## Fin... ##
############
exit 0

2010/02/10追記:
輻輳を防ぐためにローカルに存在しないアドレスへの問い合せが外部に流れないように、フィルターでプリフィックス宛てのパケットをブロックします。
ついでに外部からプリフィックスを発信元とする不正なパケットの流入も禁止します。

fe80::/8の後ろに新たに追加した設定内容

...
ip6tables -A insit  -s 200x:xxx:xxx::/48 -j deny_localaddr
ip6tables -A outsit -d 200x:xxx:xxx::/48 -j deny_localaddr
...

さいごに

このスクリプトはとりあえずでっち上げたものなので、2、3日すると構造は変わると思います。 このまま使う事をお勧めするものではないので、ログをこまめに取るなどご注意ください。

0 件のコメント: