※本記事はBPSアドベントカレンダー2016の投稿です
morimorihogeです。最近久々にインフラ周りの作業をすることが多く、色々新しくなったなあと感じつつ時代に取り残されているのを感じています。
今回は以前弊社yamasitaの書いたiptablesで鉄壁?の守りを実現する3つのTipsのおまけみたいな感じです。
外部からのお行儀の悪いクローラやBotnetからの攻撃的アクセスに対してiptablesの拡張モジュールであるhashlimitを使うことがあります。
#iptablesの設定の書き方自体はyamasitaの記事を参照していただければ問題ないかと思います。
今回は実運用の中で実際に当該ホストに繋がらないという連絡が来たときに、それがiptables hashlimitモジュールの設定によってBANされているのかを確かめる方法を解説します。つまりhashlimitモジュールが作成しているBANリストの参照方法ですね。
参照方法
/proc/net/ipt_hashlimit/
の下に--hashlimit-name
で指定した名前のファイルがありますので、それをcatすればOK。
※以下IPは伏せてます
# cat /proc/net/ipt_hashlimit/web_limit
309 1.2.3.4:0->0.0.0.0:0 22400000 22400000 32000
263 2.3.4.5:0->0.0.0.0:0 22400000 22400000 32000
316 3.4.5.6:0->0.0.0.0:0 22400000 22400000 32000
352 4.5.6.7:0->0.0.0.0:0 22400000 22400000 32000
178 5.6.7.8:0->0.0.0.0:0 22400000 22400000 32000
(略)
読み方
このテーブルはhashlimitモジュールの利用するテーブルというだけなので、ここに書かれているリストが全てBANされているというわけではありません。
どれがBANリストされているかという中身の読み方についてですが、検索してみるとこちらも調べている方の記事が見つかりました。
参考: iptables hashlimitのエントリテーブルの見方: つゆむーみん谷
こちらのサイトによると、3列目数値(クレジット)が通信の度に引かれて行き、5番目の数値(コスト)を下回った時点でDROPされるようになるということの用です。
以下のiptables設定でちょっと試してみます。
iptables -A INPUT -p tcp -m multiport --dport 80,443 -m state --state NEW -m hashlimit \
--hashlimit-name web_limit --hashlimit 60/m --hashlimit-burst 700 \
--hashlimit-mode srcip --hashlimit-htable-expire 360000 -j ACCEPT
実際に連続アクセスをさせながら値が変わるか見てみます。
# cat /proc/net/ipt_hashlimit/web_limit |grep w.x.y.z
281 w.x.y.z:0->0.0.0.0:0 22400000 22400000 32000
# cat /proc/net/ipt_hashlimit/web_limit |grep w.x.y.z
358 w.x.y.z:0->0.0.0.0:0 22211584 22400000 32000
# cat /proc/net/ipt_hashlimit/web_limit |grep w.x.y.z
358 w.x.y.z:0->0.0.0.0:0 22052224 22400000 32000
# cat /proc/net/ipt_hashlimit/web_limit |grep w.x.y.z
358 w.x.y.z:0->0.0.0.0:0 21884160 22400000 32000
# cat /proc/net/ipt_hashlimit/web_limit |grep w.x.y.z
358 w.x.y.z:0->0.0.0.0:0 21942400 22400000 32000
こんな感じで最初は22400000というクレジットがあったのが確かに減って行っていることがわかります。また、最後の方でクレジットが増加しているのは時間経過とともに回復するようになっているためですね。
このあたりのhashlimitのアルゴリズムについては詳細がよくわからなかったので以下のサイトが参考になりました(ただし著者の方もあっているか自信は無いとのことなので、確実な情報が欲しければソースコードや他オフィシャルな資料をあたった方が良いと思います)。
参考: iptablesのhashlimitの設定が難しすぎて理解しようと頑張った話
まとめ
そんなわけでちょうど直近繋がらない報告に対応したので書いてみました。
今回僕が対応している中では「hashlimitのエントリってどこにあるのかなー?」と思いつつ/sys/modules
あたりを漁っていたのですが、社内Slackでyamasitaがサクッと/proc/net/ipt_hashlimit/
のパスを教えてくれました。
#というかよく読めばyamasitaの元記事のコメントにもパスが書いてありました
わからんなーと思いつつiptables hashlimitのソースコードでもgrepするかとソースをDLしに行っていた矢先の出来事だったので、おかげで調べる時間が短縮できました。タスカルタスカル。
こういう作業をしていると、以下の2chコピペを思い出しますね(ソース多数のため元ネタ不明)。
どんな機械でも修理してしまう、凄腕のエンジニアがいました。
彼は会社に30年忠誠を尽くして働いたあと、円満に定年退職しました。
数年が経ち、会社では何億円もする機械が修理不能になったのですが、社員たちはあの手この手で修理を試みるも、どうにもうまく直ってくれません。
そこで会社は退職した凄腕エンジニアに連絡を取ってみたのです。
現役時代に数々の問題を解決してきた彼は、しぶしぶながらその挑戦を受けることにしました。
そして丸一日かけ、その巨大な機械の調査にとりかかりました。
やがて1日が終わる頃、彼は機械の構成部品にチョークで小さな「x」マークを付け、「ここが問題の箇所です」と記述しておきました。
その部分はただちに取り替えられ、機械はまた元通りに動くようになったのです。
しばらく経って、会社にエンジニアから修理料金として5000ドル(約50万円)の請求書が届きました。
会社は彼に、請求額の根拠となる内訳の詳細を要求しました。
するとエンジニアが返答した内訳は以下のとおりでした。
・チョーク1本 …… 1ドル
・どこに書いたらいいのかの知識 …… 4999ドル
世の中ググることで解決できることが大半になりましたが、ググるキーワードは知らないと調べようがないし、そもそも知識として知っていればO(1)
で回答にたどり着くことができるという意味で、勉強や経験というのは大事だと改めて認識しました。
ではでは。