ipsetで大量のIPをブロック
ipsetを使ってスマートにiptablesを設定する | ギークを目指しての記事を参考にAnsibleで実施
不正なアクセス試行の多い国をCIDRで丸っとブロックしたい
ただCIDRが1万以上存在し、Ansibleのufwモジュールとwith_itemsループだと1時間では終わらないくらいめちゃくちゃ時間がかかる
あとサーバの負荷がだいぶ上がる
ipsetコマンドを使って効率的にブロックする
これらをAnsibleでやる
Ansibleのコード
ipsetのインストール自体は以下
ufwも使うのでufwもインストール
code:main.yml
- name: Install packages
package:
name:
- ufw
- ipset
update_cache: true
ipsetを作成してiptablesに登録する必要があるけれど、Ansibleにはipsetモジュールはなさそう
なので、仕方なくshellモジュールで作成する
エラーを防ぐために、grepで検索して、存在しないときだけ作成・IP/CIDRの登録をするというシェルにする
また、IPの一覧が1万以上あり、それらをwith_itemsのループ変数にセットするとdryrunにもめちゃくちゃ時間がかかるようになる
shellモジュールを使わざるを得ない次点で差分チェックとかは期待できない
YAMLとは別ファイルに分離し、scpしてからサーバ上でwhileループで処理するようにした
少なくともこれでdryrunは一瞬で終わる
code:main.yml
---
- name: Put blacklist file
copy:
src: tmp/blacklist.ip
dest: /tmp/blacklist.ip
- name: Initialize config
ufw:
state: reset
- name: Set logging
ufw:
logging: 'on'
- name: Create ipset
shell: "ipset list blacklist || ipset create blacklist hash:net"
- name: Add entries
shell: "while read -r ip; do ipset list blacklist | grep $ip || ipset add blacklist $ip; done < /tmp/blacklist.ip"
- name: Set iptables
shell: "iptables -A INPUT -m set --match-set blacklist src -j DROP"
- name: Delete blacklist file
file:
path: /tmp/blacklist.ip
state: absent
シェルスクリプトをYAMLで書いてるだけやないか、って気持ちになる
結果
3分~5分くらいで終わった
AnsibleMitogenでAnsibleの動作を高速化したのもあるかもしれない
ちゃんとブロックされてるかの確認
code:sh
grep BLOCK /var/log/kern.log