これはかなりハマった。
Debian lenny上のopenvzではiptablesのrecentが動かない。
VEにiptablesのsshアタック防止設定をしようとした。
sudo vzctl enter 1001 iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --rttl --name SSH -j DROP
こんなエラーとか出る。
iptables: No chain/target/match by that name
または、こんなエラー
iptables: invalid argument
iptablesエラーメッセージの読み方。
ここのサイトに詳しく載っている。>>12.4. iptablesのデバグ
以下に抜粋を載せる。
通常、カーネルに内蔵済みでないモジュールがあると iptables は自動的に modprobe する能力を持っているので、こうしたエラーの出た原因はふた通り考えられる。カーネルをコンパイルしなおしてから depmod を適切に行わなかったか、あなたがそのモジュールのことをはなから忘れていたかのどちらかだ。ところが一方、問題のモジュールがマッチに関するものだった場合、エラーメッセージはもっと暗号じみて、理解が困難となる。例としてこのエラーメッセージを見ていただこう。
work3:~# iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
iptables: No chain/target/match by that name(中略)
depmod のし忘れなのかモジュールそのものが欠如しているのかを知る一番手っ取り早い方法は、モジュールが存在するはずのディレクトリを確認してみることだ。
つまり原因はipt_recentモジュールの欠如だが・・・
ここまで原因がつかめてきた。OpenVZのフォーラムなどを読んで大体を理解した。原因はipt_recentの欠如である。そしてOpenVZの仮想サーバー(以下VE)のiptablesはホスト側のモジュールと共有しているらしい。
Matt,
in 2.6.18 kernels we have changed iptables support and now all targets/matches loaded on the node are accessible inside VE.
But all targets and matches should be accessible inside VE, I've checked it on your node:
考えられる原因は二つ
考えられる原因は二つある。ここが重要。
- ホスト側にモジュールがロードされていない。
- ホスト側のモジュールをopenvzが共有してない。
このそれぞれに対してエラーメッセージは対応している
ホストとモジュール共有をしているか?
ここで12.4. iptablesのデバグの記述を振り返ってみよう。
通常、カーネルに内蔵済みでないモジュールがあると iptables は自動的に modprobe する能力を持っているの・・・・(ry
ホスト側のiptablesを設定する。
通常のiptablesの設定方法。
アクセス数が一定以上なら、sshのポートブロックする。
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH;\ sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --rttl --name SSH -j DROP
ipt_recentがロードされる。
$> sudo lsmod | grep ipt_r ipt_recent 8152 2 x_tables 14404 17 xt_DSCP,xt_helper,xt_conntrack,ipt_LOG,xt_length,ipt_ttl,xt_tcpmss,xt_TCPMSS,xt_multiport,xt_limit,xt_dscp,ipt_REJECT,ipt_recent,xt_state,xt_tcpudp,iptable_nat,ip_tables
ちゃんとロードされた。
再起動時にipt_recentがロードされる設定。
iptables設定が再起動後にロードされるようにする。このためにiptablesの設定が自動ロードされるようにする。
OpenVZのホスト側で以下の設定をする。
sudo iptables-save > /etc/iptables.rules sudo echo '#!/bin/bash iptables-restore /etc/iptables.rules ' >> /etc/network/if-pre-up.d/iptables sudo chmod +x /etc/network/if-pre-up.d/iptables
再起動してロードを確認する。
$> sudo reboot The system is going down for reboot NOW! $> sudo lsmod | grep ipt_r ipt_recent 8152 2 x_tables 14404 17 xt_DSCP,xt_helper,xt_conntrack,ipt_LOG,xt_length,ipt_ttl,xt_tcpmss,xt_TCPMSS,xt_multiport,xt_limit,xt_dscp,ipt_REJECT,ipt_recent,xt_state,xt_tcpudp,iptable_nat,ip_tables
ちゃんとロードされた。
OpenVZのVEでモジュールが使えるか調べる。
$> sudo vzctl exec 105 cat /proc/net/ip_tables_matches | grep re recent
ちゃんとロードされたね。でもまだ、iptablesするまえに行う設定がある。
VEが使えるiptablesモジュールを追加指定する
方法A:OpenVZのVE全部に設定する。
/etc/vz/vz.conf (debian lenny)
#IPTABLESを以下のように書き換え #IPTABLES="ipt_REJECT ipt_tos ipt_limit ipt_multiport iptable_filter iptable_mangle ipt_TCPMSS ipt_tcpmss ipt_ttl ipt_length" #↓↓ IPTABLES="ipt_REJECT ipt_tos ipt_limit ipt_multiport iptable_filter iptable_mangle ipt_TCPMSS ipt_tcpmss ipt_ttl ipt_length ip_conntrack ip_conntrack_ftp ip_conntrack_irc ipt_LOG ipt_conntrack ipt_helper ipt_state iptable_nat ip_nat_ftp ip_nat_irc ipt_TOS"
centの場合は/etc/sysconfig/vz (たぶん)
方法B:VEごとに設定する。
sudo vzctl set 105 \ --iptables ipt_REJECT --iptables ipt_tos --iptables ipt_limit --iptables ipt_multiport \ --iptables iptable_filter --iptables iptable_mangle --iptables ipt_TCPMSS \ --iptables ipt_tcpmss --iptables ipt_ttl --iptables ipt_length --iptables ip_conntrack \ --iptables ip_conntrack_ftp --iptables ip_conntrack_irc --iptables ipt_LOG \ --iptables ipt_conntrack --iptables ipt_helper --iptables ipt_state \ --iptables iptable_nat --iptables ip_nat_ftp --iptables ip_nat_irc --iptables ipt_TOS \ --iptables ipt_recent \ --save
準備ができたらVEを再起動
for i in {101..120} ;do sudo vzctl restart $i; done;
OpenVZのVEにiptablesによるSSH総当たり対策を施す。
sudo vzctl enter 102 iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH; iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --rttl --name SSH -j DROP sudo iptables-save > /etc/iptables.rules sudo echo '#!/bin/bash iptables-restore /etc/iptables.rules ' >> /etc/network/if-pre-up.d/iptables sudo chmod +x /etc/network/if-pre-up.d/iptables
VE再起動後も有効か調べる。
sudo vzctl restart 102 sudo vzctl exec 102 iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: SET name: SSH side: source DROP tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: UPDATE seconds: 60 hit_count: 3 TTL-Match name: SSH side: source
ちゃんと有効になっており問題なく成功した。
参考スレッド
http://forum.openvz.org/index.php?t=msg&goto=8831&
http://forum.openvz.org/index.php?t=selmsg&&frm_id=0&mr=1&start=160&reply_count=0
http://forum.openvz.org/index.php?t=msg&goto=28800&&srch=conf
iptablesの使い方。
少し古いけれど、基本的なことはシッカリ載っているので参考に。
http://www.asahi-net.or.jp/~AA4T-NNGK/ipttut/output/index.html