Cloudflareがウェブサイトを完全に保護するとは限らない (2)

前回の記事:
Cloudflareがウェブサイトを完全に保護するとは限らない (1)
https://blog.crosslab.xyz/2016/12/30/cloudflareがウェブサイトを完全に保護するとは限らない/

前回の記事では、ここ最近日本国内でも導入するサイトが増加している CDN/DDoS保護サービスの「Cloudflare」について、同社が提供するウェブサイトの保護は簡単に破られてしまう恐れがあることについて書きました。
今回の記事は、Cloudflareを利用しているサイトでその保護を突破されないように防ぐ方法について書くつもりでしたが、この問題についてしばらく考えていたところ、Cloudflareにはある致命的な欠陥があることを発見しました。そのため、この記事で紹介する対策は、一部の攻撃に対してある程度の効果はありますが、完全な保護とはなりません。また、そのCloudflareの欠陥についても書きたいと思います。

※この記事に書かれていることはCloudflareに限ったものではなく、他のクラウドWAFでも同じことは十分に起こり得る問題です。今回は都合上Cloudflareと書いています。

Cloudflareの保護を回避する攻撃への対策

前回の記事でも書いたように、Cloudflareの利用を始めただけではその保護は完璧ではありません。それはなぜなのか、まずCloudflareのようなクラウドWAFの仕組みから説明しましょう。
クラウドWAFを利用しているサイトへのすべてのリクエストは、それらの企業が所有するサーバーを経由して、最終的に本来のサイトのサーバー(ここでは「元サーバー」とします)に送られます。これによって、クラウドWAF側のサーバーで悪意のあるリクエストはブロックし、安全なリクエストのみを元サーバーに送信することができるわけです。しかし、初めからクラウドWAFのサーバーを介さずに直接リクエストを元サーバーに送信されてしまえば、クラウドWAFによる保護を受けることはできません。
元サーバーのほとんどが、外部からのアクセスに対してなんの制限もかけていないことでしょう。そうしたままでは、ターゲットのドメイン名のHostヘッダを付与して元サーバーにHTTPリクエストを送信することで、簡単にクラウドWAFを迂回することができてしまいます。
元サーバーのIPアドレスはCloudflareによって隠蔽されていますが、それを見つけ出されてしまうこともあります(前回の記事を参照)。

したがって、元サーバーへのアクセスは、クラウドWAFのIPアドレスのみ許可するようにするのが望ましいです。Cloudflareであれば以下にそのIPアドレスのリストが公開されています。

IP Ranges | Cloudflare
https://www.cloudflare.com/ips/

忙しい方のためにコマンドを書きました。ポート番号の部分は必要に応じて変更してください。

FirewallD
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="103.21.244.0/22" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="103.22.200.0/22" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="103.31.4.0/22" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="104.16.0.0/12" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="108.162.192.0/18" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="131.0.72.0/22" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="141.101.64.0/18" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="162.158.0.0/15" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="172.64.0.0/13" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="173.245.48.0/20" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="188.114.96.0/20" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="190.93.240.0/20" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="197.234.240.0/22" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.41.128.0/17" port port="80" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="199.27.128.0/21" port port="80" protocol="tcp" accept'

UFW (for Debian/Ubuntu)
ufw allow from 103.21.244.0/22 to any port 80/tcp
ufw allow from 103.22.200.0/22 to any port 80/tcp
ufw allow from 103.31.4.0/22 to any port 80/tcp
ufw allow from 104.16.0.0/12 to any port 80/tcp
ufw allow from 108.162.192.0/18 to any port 80/tcp
ufw allow from 131.0.72.0/22 to any port 80/tcp
ufw allow from 141.101.64.0/18 to any port 80/tcp
ufw allow from 162.158.0.0/15 to any port 80/tcp
ufw allow from 172.64.0.0/13 to any port 80/tcp
ufw allow from 173.245.48.0/20 to any port 80/tcp
ufw allow from 188.114.96.0/20 to any port 80/tcp
ufw allow from 190.93.240.0/20 to any port 80/tcp
ufw allow from 197.234.240.0/22 to any port 80/tcp
ufw allow from 198.41.128.0/17 to any port 80/tcp
ufw allow from 199.27.128.0/21 to any port 80/tcp

これによって、万が一元サーバーのIPアドレスが攻撃者に知られたとしてもウェブサーバーへの攻撃を防ぐことができます。レイヤー7レベルのDDoS攻撃にも有効です。

Cloudflareの欠陥

では、この対策を講じても防ぐことができないCloudflareに存在する欠陥について説明します。

この画像は、かつてCloudflareを利用していた日本のある掲示板サイトに投稿された管理者の書き込みです。この投稿では管理者が、第三者から送られた不正利用の通報に対するCloudflareの返信を転載しています。注目すべき点は、”The actual host for gotanda.xyz is *****.” という文章です。
“gotanda.xyz” というのはこの掲示板サイトのドメインですが、問題は “*****” というマスクされた文字列で、これはこの掲示板サイトの元サーバーのIPアドレスを指していると思われます。その根拠に、この文には “Using the following command, you can confirm the site in question is hosted at that IP address:(訳:このコマンドを使って、当該サイトがそのIPアドレスにホストされていることを確認できます)”と続いています。
これは、第三者がCloudflareに顧客のサイトについて通報を行うと、Cloudflareは何のためらいもなくそのサイトのIPアドレスを開示するということを示しています。つまり、攻撃者のターゲットがCloudflareを利用しているサイトであった場合、攻撃者は通報を行うことで(それが虚偽であろうと)、隠されているはずのサイトのIPアドレスを入手し、元サーバーに攻撃を行うことが可能になってしまうのです。

上で紹介したファイアウォールによる対策では、Cloudflareを介したリクエストのみ受け付けるので、ウェブサーバーに対する攻撃はある程度防ぐことができます。しかし、レイヤー4レベルのDDoS攻撃などについては防ぐことができません。つまり、どんなに上のような対策でIPアドレスを制限し、元サーバーのIPアドレスを隠蔽することに努めようが、Cloudflare自身がそれを第三者に簡単に開示してしまうのです。これではどうにもなりません。

まとめ

一部のCloudflare利用者の間では、以前からこの問題について議論されていましたが、その頃のCloudflareの対応としては、元サーバーのサーバー管理会社の情報を記載するだけでした。ところが最近になってIPアドレスも記載する方針に変えたようです。この対応の変化についてはよくわかりません。ちなみに、このCloudflareの問題について調べてみましたが、海外でもほとんど話題になっていないようです。
CloudflareはクラウドWAFとしてとても優秀です。かつてCyberBunkerのユーザーによる大規模なDDoS攻撃からSpamHausを保護し、長年その機能を無料で提供し続けています。
しかし、クラウドWAF企業として顧客のサーバーのIPアドレスを簡単に提供するという行為は、ウェブサイトの保護を提供する企業としてとうてい理解できるものではありません。
最近ではCloudflareの流出事故も起こりました。個人的には、その件が問題なのではなく、クライアントとウェブサイトの間にサーバーが存在するというクラウドWAFそのもののシステムがどうなのかなあと感じます。重要な情報がやりとりされるウェブサイトならなおさらです。
Cloudflareを利用しているウェブマスターは、別のサービスへの乗り換えを検討すべきなのかもしれません。

コメントを残す