🔓

iptables入れたのにまだ27%直接アクセスされてた ー IPv6を忘れていた

に公開

前回のあらすじ

Cloudflareを導入したのに、75%が直接アクセス(バイパス)されていた話を書きました。

https://zenn.dev/dhc4aki/articles/af82b70c904faa

対策として、iptablesでCloudflare以外からのアクセスをDROPしました。

# Cloudflare IPv4 のみ許可
sudo iptables -A INPUT -p tcp --dport 80 -s 173.245.48.0/20 -j ACCEPT
# ... 他のCloudflare IPレンジ
sudo iptables -A INPUT -p tcp --dport 80 -j DROP

「これで完封だろう」と思っていました。

翌日の結果

ログを分析してみると...

項目 Before After
総リクエスト 1,732件 807件
直接アクセス 75% 27%
Cloudflare経由 25% 73%
エラー率 24.7% 12.02%

だいぶ改善した。でも、まだ27%が直接来てる。

直接アクセス数で言うと、1,124件 → 215件。81%減ったけど、ゼロじゃない。

おかしい

iptablesで全部DROPしてるはずなのに、なぜ通る?

$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  173.245.48.0/20      0.0.0.0/0            tcp dpt:80
# ... Cloudflare IP許可
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80

設定は正しい。IPv4は確実にブロックしてる。

...IPv4は。

原因はIPv6だった

$ ip -6 addr show
2: ens5: 
    inet6 2406:da14:f95:be00:xxxx:xxxx:xxxx:xxxx/128 scope global dynamic

サーバーにIPv6アドレスがついていた。

そしてip6tablesを確認すると...

$ sudo ip6tables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
# 何もない

IPv6は完全にノーガード。

なぜこうなったか

CloudflareでIPv6互換性がONになっていた。

つまり:

  • IPv4 → iptablesでブロック ✅
  • IPv6 → Cloudflare経由でオリジンへ → ip6tables未設定 → 素通り ❌

攻撃者がIPv6で直接叩けば、普通に通る状態だった。

対策

ip6tablesにもCloudflare IPv6レンジを設定。

# Cloudflare IPv6 のみ許可
sudo ip6tables -A INPUT -p tcp --dport 80 -s 2400:cb00::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -s 2606:4700::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -s 2803:f800::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -s 2405:b500::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -s 2405:8100::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -s 2a06:98c0::/29 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -s 2c0f:f248::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -j DROP

# HTTPS (443) も同様に設定
sudo ip6tables -A INPUT -p tcp --dport 443 -s 2400:cb00::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -s 2606:4700::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -s 2803:f800::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -s 2405:b500::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -s 2405:8100::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -s 2a06:98c0::/29 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -s 2c0f:f248::/32 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 443 -j DROP

# 永続化
sudo netfilter-persistent save

Cloudflare IPv6レンジは公式で確認できます。
https://www.cloudflare.com/ips/

設定後の確認

$ sudo ip6tables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp      2400:cb00::/32       ::/0                 tcp dpt:80
ACCEPT     tcp      2606:4700::/32       ::/0                 tcp dpt:80
# ...
DROP       tcp      ::/0                 ::/0                 tcp dpt:80
ACCEPT     tcp      2400:cb00::/32       ::/0                 tcp dpt:443
# ...
DROP       tcp      ::/0                 ::/0                 tcp dpt:443

これでIPv4もIPv6もCloudflare経由のみに。

現状の防御体制

レイヤー 対策 状態
DNS Cloudflare Proxy
WAF Cloudflareカスタムルール
Bot対策 Bot Fight Mode
IPv4直接 iptables
IPv6直接 ip6tables ✅ ← New!

これでようやく完封...のはず。

別の選択肢

今回はip6tablesで対応しましたが、他にも方法があります。

A. CloudflareでIPv6をOFFにする

Cloudflare Dashboard
  → Network
  → IPv6互換性 → OFF

これなら全部IPv4経由になるので、iptablesだけで済む。

ただし:

  • IPv6対応が必要な場合は使えない
  • 将来的にIPv6が主流になる可能性

B. nftablesで一元管理する

コメントで教えていただいたのですが、iptables/ip6tablesを別々に管理する代わりに、nftablesなら1ファイルでIPv4/IPv6をまとめて定義できます。

  • IPv4とIPv6のルールを一元管理
  • IPアドレスをセット(set)でまとめて指定
  • 増えても管理しやすい
  • リロードも高速(iptablesより体感で違うらしい)

nftablesは以下のバージョンから標準採用:

  • RHEL 8以降
  • Debian 10以降
  • Ubuntu 20.10以降

それ以前でもiptables-nft(nftables互換)が入っていることが多いです。

長期運用を考えるとnftablesの方がスマートかもしれません。

C. Cloudflared Tunnelを使う

Cloudflareのトンネル機能を使えば、オリジンIPを完全に隠せます。そもそも直接アクセスが発生しない構成。

Zero Trustの一部として無料で使えますが、今回は「Cloudflare無料プラン + ファイアウォール」というシンプル構成で進めているので選択肢から外しました。

興味がある方は別途検証してみてください。


環境や運用方針に合わせて選んでください。

学んだこと

1. iptablesとip6tablesは別物

「iptablesで設定した」はIPv4だけ。IPv6は別コマンド。

2. サーバーのIPv6有効化を確認する

ip -6 addr show

これでIPv6アドレスが出たら、ip6tablesも必要。

3. CloudflareのIPv6設定を確認する

Network → IPv6互換性がONだと、IPv6経由のアクセスが来る。

まとめ

iptablesで完封したつもり

まだ27%直接来てる

IPv6がノーガードだった

ip6tablesで対策

これで本当に完封(予定)

IPv4だけ守ってIPv6を忘れる。あるあるだと思います。

次回、本当に完封できたか数字で確認します。


関連記事


この分析は CloudLogAI で自動検知しました。

👉 仕組みの詳細はこちら:月170円で24時間AI監視

月170円で動くAI監視システムで、攻撃もパフォーマンス低下も早期に検知できます。

「うちのサイト、今どうなってるんだろう?」と思ったら、お気軽にどうぞ。

Discussion