どさにっき AI 〜2018年3月上旬〜

by やまや
<< = >>

2018年3月5日(月)

memcached フィルタ

_ memcached のアクセス制御に関する注意喚起とかまあそんな感じで、本来内部用途でしか使われないはずの memcached が外部におっぴらげになってるサーバが世の中にたくさんあって、認証なしでガバガバだもんだから外から自由にデータを出し入れできて情報流出/改竄できちゃうどころか、UDP でもアクセスできるもんだから増幅率超特大の reflection attack の踏み台に使えて あちこちで大規模 DDoS の被害多発とかそんなヤバい事態になってるそうでマジヤバい。

_ で、それに対する対処は、とーぜんムダに開いてる memcached のポートを閉じることなんだけど、増幅率がハンパなくて踏み台にされると超ヤバい(語彙貧困)ので、個々のホストではなく、ISP とかホスティング屋さんがネットワークのレベルでフィルタを入れてる例があるっぽい。

  1. 外部からの dst port 11211 のパケットをフィルタする
  2. 外部からの src port 11211 のパケットをフィルタする

_ 前者は意図せず開いている memcached が踏み台にされないようにするもの。それから、memcached からの応答パケットはソースポートが 11211 になるので、踏み台にされてしまった memcached からの巨大応答をネットワークの上流で叩き落とすためのフィルタが後者。amp 攻撃の踏み台を防ぐためならば対象は UDP のみのフィルタでいいはずだが、あわせて memcached からの情報漏洩/改竄を防ぐ意図で TCP も止めることも十分考えられる。

_ が、このフィルタ、副作用があるんですよ。memcached とはまったく無関係のクライアントが memcached とはまったく無関係なサーバにアクセスしにいくときのソースポートとして 11211 が使われてしまうことがたまにあるんで。クライアントがソースとしてたまたま 11211 を選んでしまうと後者のフィルタにひっかかるし、後者のフィルタがかかってなかったとしても、サーバからの応答は dst port 11211 になるので今度は前者のフィルタにひっかかる。1024 より小さい特権ポートを使ってるために「たまたま運悪くポート番号がかぶってしまった」ケースを考慮する必要がなかった DNS の IP53B や NTP の IP123B とはこの点が決定的に異なる。

_ 過去の事例では、2003年に SQL Slammer というワームが大流行したときに 1434/udp をフィルタしたら DNS が止まったという話が [janog:04421] にある。もう15年も前かよ。

_ 個々の実装について。

_ BIND の場合。デフォでは 1024-65535 のポートを使うようになってるのでひっかかる可能性あり。avoid-{v4,v6}-udp-ports で使わないポート範囲を、use-{v4,v6}-udp-ports で使う範囲を設定できるらしい(実際の挙動は未確認)。ただし、UDP だけで TCP は変更できないので要注意。ひっかかって名前解決できなくても、リトライで成功するので影響軽微。

_ Unbound の場合。ソースを確認したところ、デフォでは 11211 をソースポートとして使わないことを確認(utii/config_file.c:init_outgoing_availports(), util/iana_ports.inc)。いちおう、outgoing-port-permit、outgoing-port-avoid で使う/使わない範囲を指定できる。ただし、ソースは追ってないけど、こちらも UDP だけっぽい気配があるので TCP ではひっかかるかもしれない。

_ NTP の場合。一般的な NTP 実装はソースポート 123 固定かつ設定変更もできないのでひっかからない。Windows/Mac とも影響なし。

_ RHEL7/CentOS7 で使われている Chrony という新しい NTP 実装は、man によると ephemeral port を使うように読める。Linux ではこの範囲(/proc/sys/net/ipv4/ip_local_port_range)は 32768-61000 なので 11211 は使われないはず。変更も可能で、acquisitionport というパラメータでソースポートを指定できる。これをわざわざ 11211 に変更していることはないかと思うが、0 という値を設定したときは注意が必要。どうも起動時にランダムに決定されたポートが以後固定で使われるっぽい。運悪く起動時に 11211 が選ばれていると、プロセス再起動するまで一切の時刻合わせに失敗するかもしれない。

_ OpenBSD 由来の OpenNTPD はランダムなポートを使うようだが、ephemeral でない範囲も含む上、起動時に選ばれたポートが以後固定で使われるので、運が悪いと 11211 を掴んでしまってプロセス再起動するまで時計合わせができなくなる可能性がある。ただし、複数サーバを指定していれば、相手サーバごとに異なるポートが使われるので、その場合でも特定サーバと同期できないだけで、完全に時刻合わせができなくなるわけではない。設定による変更はできないっぽい。

_ ほかにも UDP を使ってるプロトコルはあるけど、自分はあんまり詳しくないので知らん。IP 電話(SIP)とかまったくわからん。ふつーの SNMP エージェントは ephemeral port を使ってるんじゃないかな。調べてないけど、たぶん。OpenVPN も UDP を使ってたような記憶があるけど、どの範囲を使うか知らん。

_ それから、NAT 箱は NAT テーブル上のセッションが混じらないようにソースポートを書き換えることがある。クライアントが 11211 を使わなかったとしても、NAT 箱がポートを書き換えた結果として 11211 になってしまうことがありうるので注意。

_ ということで、今回の memcached の騒ぎは、影響がひじょーに大きいので上流でそういったフィルタをかけるのもやむなしだとは思うんだけれど、副作用がないわけじゃないので、実施したならその旨ちゃんと周知していただけないですかねぇ。


<< = >>
やまや