ipset/iptables を使用して IP と CIDR をブロックするループがあります:
# this is just an example. the actual list IPs/CIDR is very large
cat blockip.txt
13.31.0.254
cat blockcidr.txt
13.32.0.0/15
ループ:
#!/bin/bash
ipset -F
ipset -N -! blacklist hash:net maxelem 1000000
for ip in $(cat blockip.txt blockcidr.txt); do
ipset -A blacklist $ip
done
iptables -A FORWARD -m set --match-set blacklist dst -j DROP
注: 私は常にこのipset -A
オプションを使用していますが、このオプションは「マン・イプセット」であり、この時点では、両方の場合の出力が同じであるため、 はadd
と同じであると想定しています。-A
#!/bin/bash
ipset -F
ipset -N -! blacklist hash:net maxelem 1000000
for ip in $(cat blockip.txt blockcidr.txt); do
ipset add blacklist $ip -q
done
iptables -A FORWARD -m set --match-set blacklist dst -j DROP
両方のケース:
sudo ipset -L
Name: blacklist
Type: hash:net
Revision: 7
Header: family inet hashsize 1024 maxelem 1000000 bucketsize 12 initval 0xbc0136c8
Size in memory: 552
References: 0
Number of entries: 2
Members:
13.31.0.254
13.32.0.0/15
「問題なく動作します」が、読みましたIPとCIDRを追加するのはipset -A
非常に遅いです。ipset の保存と復元しかし、どのように動作するのか理解できず、私の試みは失敗しました。
注: 保存/復元オプションを使用する方が速い理由については説明が見つかりませんでしたadd
。-A
#!/bin/bash
ipset -F
ipset -N -! blacklist hash:net maxelem 1000000
for ip in $(cat blockip.txt blockcidr.txt); do
ipset add blacklist $ip # ??
ipset save blacklist -f newblacklist.txt # ???
done
ipset restore -! < newblacklist.txt # ??
iptables -A FORWARD -m set --match-set blacklist dst -j DROP # ??
外:
sudo ipset -L
Name: blacklist
Type: hash:net
Revision: 7
Header: family inet hashsize 1024 maxelem 1000000 bucketsize 12 initval 0xcb0e583b
Size in memory: 552
References: 0
Number of entries: 2
Members:
13.32.0.0/15
13.31.0.254
cat newblacklist.txt # out wrong
create blacklist hash:net family inet hashsize 1024 maxelem 1000000 bucketsize 12 initval 0xcb0e583b
add blacklist 13.32.0.0/15
add blacklist 13.31.0.254
ご協力いただければ幸いです(提案されたループやループの修正を含む完全な回答をお願いします)。
答え1
これは私にとってはうまくいきました:
# remove any old reference to the ipset
iptables -D FORWARD -m set --match-set blacklist dst -j DROP
ipset destroy
ipset create blacklist hash:net family inet hashsize 1024
ipset save > /tmp/ipset.txt
ipset destroy
cat blockip.txt blockcidr.txt | while read line; do
if [ "${line:0:1}" = "#" ]; then
continue
fi
echo "add blacklist $line" >> /tmp/ipset.txt
done
ipset restore < /tmp/ipset.txt
iptables -A FORWARD -m set --match-set blacklist dst -j DROP
必要に応じて、create ステートメントのオプションを調整してください。セットのサイズによっては、これらのオプションが非常に重要です。さらに、ファイルにblockcidr.txt
次のような行のみが含まれていることを前提としています。
#comment
1.2.3.4/20
その後、復元は正常に機能します。
アップデート
このようなループのボトルネックは、この場合、常にサブプロセスの作成ですipset
。 10000 以上のエントリがある場合、実行可能 ipset がメモリにロードされ、追加する各行のオプションが解析されます...
私のループには bash 内部コマンドのみが含まれているため、実行可能ファイルをロード/実行する必要はありません。ファイルにテキストが書き込まれるだけです。そしてもちろん、ipset への 1 回の呼び出しは、ipset への 10000 回以上の呼び出しよりもはるかに高速です...