ping6.net
セキュリティ

IPv6ファイアウォール設定:必須ルール

接続を壊さずにIPv6用のファイアウォールを設定します。必須ICMPv6ルール、Linuxの例、避けるべき一般的な間違い。

ping6.net2024年12月14日5 min read
IPv6ファイアウォールセキュリティiptablesnftablesICMPv6

IPv4ファイアウォールでは、大きな結果なしにICMPをブロックできます。IPv6はそのようには機能しません。間違ったICMPv6メッセージをブロックすると、パスMTU検出、近隣探索、および基本的な接続が壊れます。ファイアウォールは、デバッグに何時間もかかる接続障害を静かに引き起こします。

TL;DR - 要点まとめ

重要ポイント:

  • ICMPv6は必須:IPv4のICMPと異なり、ICMPv6をブロックすると基本的なネットワーク操作が壊れる
  • 特定のタイプを許可:タイプ1-3(エラー)、128-129(ping)、133-136(NDP)が必要
  • タイプ2をブロックしない:Packet Too Bigメッセージはパス MTU検出に重要
  • NDPにホップリミット255を使用:オフリンクの近隣探索スプーフィングを防止
  • すべてのプロトコルファミリーに適用:iptablesとip6tablesの両方の設定を忘れずに

ジャンプ: 必須ICMPv6タイプ | Linuxの例 | よくある間違い


IPv6ファイアウォールが異なる理由#

IPv4では、ICMPはpingやtracerouteなどの診断を処理します。それを完全にブロックでき、ほとんどのものがまだ機能します。ARPはレイヤー2で実行され、DHCPはUDPを使用し、ルーターは専用プロトコルを使用します。

IPv6はこれらの機能をICMPv6にマージしました。アドレス解決、ルーター検出、重複アドレス検出はすべて、特定のICMPv6タイプに依存します。それらをブロックすると、ホストはデフォルトゲートウェイを見つけることができず、隣接者は同じリンクで通信できず、MTUの不一致が発生すると接続がハングします。

プロトコル設計者はこの選択を意図的に行いました。ICMPv6はIPv6仕様の一部であり、診断アドオンではありません。

必須ICMPv6タイプ#

ファイアウォールは、基本機能のためにこれらのICMPv6タイプを許可する必要があります:

タイプ名前目的これをブロック?
1宛先到達不能ポート/プロトコルがクローズいいえ - TCPを壊す
2パケットが大きすぎるパスMTU検出決してしない - 接続を壊す
3時間超過ホップ制限に達したいいえ - tracerouteを壊す
128エコー要求pingリクエストオプション(でもなぜ?)
129エコー応答ping応答オプション(でもなぜ?)
133ルーター要請デフォルトゲートウェイを見つける決してしない - 接続を壊す
134ルーターアドバタイズメントゲートウェイアナウンスメント決してしない - 接続を壊す
135近隣要請アドレス解決(ARP相当)決してしない - すべてを壊す
136近隣アドバタイズメントアドレス解決応答決してしない - すべてを壊す

ICMPv6タイプ2、133、134、135、または136をブロックすると、IPv6接続が微妙でデバッグが難しい方法で壊れます。しないでください。

タイプ2(パケットが大きすぎる)は特別な注意に値します。IPv6には中間ルーターでのフラグメンテーションがありません。パケットがパスMTUを超えると、ルーターはそれをドロップし、パケットが大きすぎるメッセージを送信します。これをブロックすると、最初のSYN/ACKの後に接続がハングします。HTTPSは機能するが、大きな転送が失敗する理由をデバッグするのに何時間も費やすことになります。

Linux ip6tablesの例#

最小ホストファイアウォール#

トラフィックをルーティングしないクライアントマシンまたはサーバーの場合:

# 既存のルールをフラッシュ
ip6tables -F
ip6tables -X
 
# デフォルトポリシー
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT
 
# ループバックを許可
ip6tables -A INPUT -i lo -j ACCEPT
 
# 確立された接続を許可
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
 
# 必須ICMPv6を許可
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 1 -j ACCEPT   # 宛先到達不能
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 2 -j ACCEPT   # パケットが大きすぎる
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 3 -j ACCEPT   # 時間超過
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 128 -j ACCEPT # エコー要求
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 129 -j ACCEPT # エコー応答
 
# 近隣探索を許可(ホップ制限255のリンクローカルである必要がある)
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 133 -m hl --hl-eq 255 -j ACCEPT # ルーター要請
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 134 -m hl --hl-eq 255 -j ACCEPT # ルーターアドバタイズメント
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT # 近隣要請
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT # 近隣アドバタイズメント
 
# DHCPv6を許可(必要な場合)
ip6tables -A INPUT -p udp --dport 546 -j ACCEPT
 
# ドロップされたパケットをログ(オプション)
ip6tables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "ip6tables-dropped: "

ホップ制限チェック(--hl-eq 255)は、オフリンクソースからのスプーフィングされた近隣探索パケットを防ぎます。正当な近隣探索は常にホップ制限255を使用します。

サーバーファイアウォール#

ICMPv6ルールの後にサービスを追加します:

# SSH
ip6tables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
ip6tables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
 
# HTTP/HTTPS
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
 
# DNS(DNSサーバーを実行している場合)
ip6tables -A INPUT -p udp --dport 53 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 53 -j ACCEPT

SSHルールはrecentを使用して基本的なレート制限を実装します。同じアドレスから60秒間に4回の接続試行の後、追加の試行はドロップされます。

ルーター転送ルール#

トラフィックを転送するルーターまたはシステムの場合:

ip6tables -P FORWARD DROP
 
# 確立された接続を許可
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
 
# ICMPv6転送を許可(PMTUDに重要)
ip6tables -A FORWARD -p ipv6-icmp --icmpv6-type 1 -j ACCEPT
ip6tables -A FORWARD -p ipv6-icmp --icmpv6-type 2 -j ACCEPT
ip6tables -A FORWARD -p ipv6-icmp --icmpv6-type 3 -j ACCEPT
ip6tables -A FORWARD -p ipv6-icmp --icmpv6-type 128 -j ACCEPT
ip6tables -A FORWARD -p ipv6-icmp --icmpv6-type 129 -j ACCEPT
 
# 内部ネットワークがインターネットにアクセスすることを許可
ip6tables -A FORWARD -i eth1 -o eth0 -j ACCEPT

近隣探索メッセージ(133-136)を転送しないでください。それらはリンクローカルのみです。

Linux nftablesの例#

最新のディストリビューションは、iptablesの代わりにnftablesを使用します。構文はよりクリーンです:

# テーブルを作成
nft add table ip6 filter
 
# チェーンを作成
nft add chain ip6 filter input { type filter hook input priority 0\; policy drop\; }
nft add chain ip6 filter forward { type filter hook forward priority 0\; policy drop\; }
nft add chain ip6 filter output { type filter hook output priority 0\; policy accept\; }
 
# ループバック
nft add rule ip6 filter input iif lo accept
 
# 確立された接続
nft add rule ip6 filter input ct state established,related accept
 
# ICMPv6
nft add rule ip6 filter input icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply } accept
 
# ホップ制限チェック付き近隣探索
nft add rule ip6 filter input icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } ip6 hoplimit 255 accept
 
# レート制限付きSSH
nft add rule ip6 filter input tcp dport 22 ct state new limit rate 4/minute accept
 
# HTTP/HTTPS
nft add rule ip6 filter input tcp dport { 80, 443 } accept

セット表記({ 80, 443 })は、2つではなく1つのルールを作成し、ルールセットをより効率的にします。

Windowsファイアウォール#

WindowsファイアウォールはデフォルトでIPv6 ICMPv6をほとんどの必須タイプに対して有効にしますが、確認する必要があります:

# 現在のICMPv6ルールを表示
Get-NetFirewallRule -DisplayName "*ICMPv6*" | Format-Table DisplayName, Enabled, Direction
 
# すべてのICMPv6インバウンドを有効化(無効の場合)
Enable-NetFirewallRule -DisplayName "Core Networking - Destination Unreachable (ICMPv6-In)"
Enable-NetFirewallRule -DisplayName "Core Networking - Packet Too Big (ICMPv6-In)"
Enable-NetFirewallRule -DisplayName "Core Networking - Neighbor Discovery Solicitation (ICMPv6-In)"
Enable-NetFirewallRule -DisplayName "Core Networking - Neighbor Discovery Advertisement (ICMPv6-In)"
Enable-NetFirewallRule -DisplayName "Core Networking - Router Advertisement (ICMPv6-In)"
 
# IPv6でSSHサーバーを許可
New-NetFirewallRule -DisplayName "SSH (IPv6)" -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow -Profile Any -RemoteAddress Any

Webサーバーの場合:

New-NetFirewallRule -DisplayName "HTTP (IPv6)" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
New-NetFirewallRule -DisplayName "HTTPS (IPv6)" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow

クラウドセキュリティグループ#

AWS#

セキュリティグループはステートフルで、確立された戻りトラフィックを自動的に許可します。次の明示的なルールを追加:

  • ICMPv6:「すべてのICMPv6」を使用するか、特定のタイプを選択
  • サービス:TCP/UDPポートを追加

Azure#

ネットワークセキュリティグループ(NSG)はIPv6を処理します。デフォルトルールは、送信および確立されたトラフィックを許可します。サービスの受信ルールを追加します。

GCP#

ファイアウォールルールはIPv6をサポートします。IPv6用に--source-ranges=::/0で別々のルールを作成します。デフォルトルールにはICMPv6が含まれていないため、明示的に追加します。

3つのプロバイダーすべてが、最初にVPC/ネットワークでIPv6を有効にする必要があります。IPv6はデフォルトで有効になっていません。

一般的な間違い#

すべてのICMPv6をブロック#

最も一般的なIPv6ファイアウォールの間違いです。管理者は、すべてのICMPをブロックするIPv4ルールを移植し、IPv6が機能しない理由を疑問に思います。この記事から1つだけ覚えている場合:すべてのICMPv6をブロックしないでください

IPv6ファイアウォールルールなし#

一部の管理者はiptablesを慎重に設定しますが、ip6tablesを完全に無視します。IPv6は完全に開いています。両方のプロトコルファミリにファイアウォールルールが必要です。

エグレスフィルタリングを忘れる#

ほとんどの例は受信ルールのみを示しています。厳格なエグレスフィルタリングを実装する場合(すべきです)、送信ICMPv6タイプ133、135、および128を許可します。送信近隣要請をブロックすると、ホストが隣接者を解決できなくなります。

近隣探索で間違ったホップ制限#

ホップ制限を確認せずに近隣探索パケットを受け入れると、攻撃者がインターネット上のどこからでもスプーフィングされたルーターまたは近隣アドバタイズメントを送信できます。常にホップ制限を確認してください。

多すぎる許可#

「すべてのICMPv6」を有効にすることは、すべてをブロックするよりも安全ですが、それでも過剰です。たとえば、インターネットからのマルチキャストリスナー検出メッセージを許可する必要はありません。特定のタイプを使用してください。

ファイアウォールのテスト#

ルールを設定した後、基本的な接続を確認します:

# pingをテスト(ICMPv6タイプ128/129が必要)
ping6 -c 3 2001:4860:4860::8888
 
# パスMTU検出をテスト(ICMPv6タイプ2が必要)
# 大きなパケットを送信し、ハングしないことを確認
curl -6 -v https://ipv6.google.com/
 
# 近隣探索を確認(タイプ135/136が必要)
ip -6 neigh show
 
# ルートを確認(タイプ133/134が必要)
ip -6 route show

別のホストから、無許可のポートが実際にブロックされていることをテストします:

# タイムアウトまたは「接続が拒否されました」を返すはず
telnet -6 your:server::address 23
 
# 動作するはず(SSHが許可されている場合)
ssh -6 your:server::address

IPv6ポートスキャナー(ipv6-tools.com)やtest-ipv6.comなどのオンラインスキャナーを使用して、外部ネットワークからファイアウォールを確認します。


IPv6ファイアウォールには、ICMPv6が何をするかを理解する必要があります。プロトコルはオプションでも診断用でもありません。必須のタイプを許可し、近隣探索が機能することを確認し、実際のトラフィックでパスMTU検出をテストします。これらを正しく行うと、IPv6ファイアウォールは安全で機能的です。

関連記事#