既存のルールを照会する必要があるだけでなく、ルールを簡単に追加および削除できる必要があります。これを行うためのAPIは見つかりませんでした。何か足りないものはありますか?
私が解決策に至った最も近いのはiptables-save | iptables-xml
iptablesコマンド自体を照会して手動で呼び出し、ルールを追加/削除します。私が検討した別の解決策は、アプリケーションのデータベースからルールセット全体を再生成し、チェーン全体をフラッシュしてから、再度適用することです。しかし、これを避けたいのは、パケットをドロップしたくないからです。これを原子的に行う方法がない限り。もっと良い方法があるかしら。
CのAPIはすばらしいでしょう。ただし、これをスタンドアロンのsuidプログラムに組み込むことを計画しているため、これを任意の言語で行うライブラリも問題ありません。
netfilter FAQ から:
残念ながら答えは次のとおりです。いいえ。
さて、あなたは「しかしlibiptcについてはどうですか?」と考えるかもしれません。メーリングリストで何度も指摘されているように、libiptcは[〜#〜] [〜#〜]として使用されることを意図されていませんでした公開インターフェース。安定したインターフェースを保証するものではありません。また、Linuxパケットフィルタリングの次の実装で削除する予定です。 libiptcは非常に低層なので、とにかく合理的に使用できません。
そのようなAPIには根本的な不足があることを十分に認識しており、その状況の改善に取り組んでいます。それまでは、system()を使用するか、iptables-restoreのstdinへのパイプを開くことをお勧めします。後者の方がパフォーマンスが向上します。
Iptables-saveおよびiptables-restoreを使用してクエリを実行し、ルールを再生成することは、最も効率的な方法です。これらはかつてはシェルスクリプトでしたが、現在は非常に効率的に動作するCプログラムになっています。
ただし、iptablesの保守をはるかに容易にするツールを使用できることを指摘しておきます。ほとんどの動的ルールセットは、実際には次のように何度も繰り返される同じルールです。
iptables -A INPUT -s 1.1.1.1 -p tcp -m --dport 22 -j ACCEPT
iptables -A INPUT -s 2.2.2.0/24 -p tcp -m --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -j REJECT
ポート22にアクセスできるポートを変更するたびにこれらのルールを置き換える(ポートノッキングに役立つ)代わりに、ipsetsを使用できます。 Viz:
ipset -N ssh_allowed nethash
iptables -A ssh_allowed -m set --set ssh_allowed src -p tcp -m --dport 22 -j ACCEPT
ipset -A ssh_allowed 1.1.1.1
ipset -A ssh_allowed 2.2.2.0/24
セットは、IPアドレス、ネットワーク、ポート、MACアドレスを保持でき、レコードにタイムアウトがあります。 (これまでに1時間だけ何かを追加したいと思ったことはありますか?)。
あるセットを別のセットと交換するアトミックな方法さえあります。したがって、更新とは、新しい一時セットを作成し、それを既存のセットの名前として交換することを意味します。
IptablesのREST APIである rfw の使用を検討してください。同時に発生する可能性のあるさまざまなソースからのiptablesコマンドをシリアル化し、その場でiptablesをリモートで実行します。
rfwは、複数のボックスでファイアウォールルールを更新しようとする分散システム用に設計されていますが、localhostインターフェース上の単一のマシンでも実行できます。この場合、プレーンHTTPで実行できるため、SSLと認証のオーバーヘッドを回避できます。
コマンド例:
PUT /drop/input/eth0/11.22.33.44
これは以下に対応します:
iptables -I INPUT -i eth0 -s 11.22.33.44 -j DROP
ルールを挿入および削除したり、現在のステータスをクエリして、既存のルールをJSON形式で取得できます。
GET /list/input
免責事項:私はそのプロジェクトを始めました。 MITライセンスでオープンソースです。
私が理解している限り(言及がないようですが)、_iptables-restore
_はアトミックです。最後に、COMMIT
行が読み取られると、iptables
はlibiptc
内の_iptc_commit
_を呼び出します(これは、内部インターフェースでは使用しないはずです)。次に、新しいルールセットでsetsockopt(SO_SET_REPLACE)
を呼び出します。
それはあなたが得ることができるのとほぼ同じくらいアトミックに聞こえます:1つのカーネル呼び出しで。ただし、これについて異議を唱えるために、より知識のある当事者が招待されています。 :-)
編集:私はあなたの説明が正しいことを確認できます。 _iptables-restore
_は、カーネルのアトミック操作として実行されます。
さらに言えば特定操作「のみ」は、CPU単位でアトミックです。ルールセットBLOB全体をCPUごとに格納するため(キャッシュの最適化のため)。
これらのルールを管理するための意図的なAPIはありません。あなたはそうしたくないはずです。か何か。
/ sbin/iptablesの実行のパフォーマンスを気にする十分に動的なルールが必要な場合は、他の方法で実行できます。
今朝目が覚めたとき、それはロシアからのサービス妨害(DOS)攻撃を受けていたことがわかりました。彼らは何十ものIPブロックから私を襲っていました。彼らは、大規模なIPプールまたは何らかのプロキシリスト/サービスを持っている必要があります。 IPをブロックするたびに、別のIPがポップアップしました。最後に、スクリプトを探したところ、独自のソリューションを作成する必要があることがわかりました。以下は少し攻撃的ですが、彼らは私のトップロードレベルを200以上に実行していました。
これは、DOSをリアルタイムでブロックするために私が作成した簡単なスクリプトです。
cat **"output of the logs"** | php ipchains.php **"something unique in the logs"**
==> PHPスクリプト:
<?php
$ip_arr = array();
while(1)
{
$line = trim(fgets(STDIN)); // reads one line from STDIN
$ip = trim( strtok( $line, " ") );
if( !array_key_exists( $ip, $ip_arr ) )
$ip_arr[$ip] = 0;
$regex = sprintf( "/%s/", $argv[1] );
$cnt = preg_match_all( $regex, $line );
if( $cnt < 1 ) continue;
$ip_arr[$ip] += 1;
if( $ip_arr[$ip] == 1 )
{
// printf( "%s\n", $argv[1] );
// printf( "%d\n", $cnt );
// printf( "%s\n", $line );
printf( "-A BLOCK1 -s %s/24 -j DROP\n", $ip );
$cmd = sprintf( "/sbin/iptables -I BLOCK1 -d %s/24 -j DROP", $ip );
system( $cmd );
}
}
?>
仮定:
1) BLOCK1 is a Chain already created.
2) BLOCK1 is a Chain that is run/called from the INPUT CHAIN
3) Periodically you will need to run "ipchains -S BLOCK1" and put output in /etc/sysconfig file.
4) You are familiar with PHP
5) You understand web log line items/fields and output.
これは、bashとiptablesを使用して、CentOSでsshdを悪用するハッカーを動的にブロックする例です。この場合、私はsshdを設定して、パスワードログインを許可しない(キーを許可する)ようにしました。/var/log/secureで「バイバイ」のエントリを探します。これは、sshdのf-offの丁寧な言い方です...
IP=$(awk '/Bye Bye/{print $9}' /var/log/secure |
sed 's/://g' |sort -u | head -n 1)
[[ "$IP" < "123" ]] || {
echo "Found $IP - blocking it..." >> /var/log/hacker.log
/sbin/iptables -A INPUT -s $IP -j DROP
service iptables save
sed -i "/$IP/d" /var/log/secure
}
私はこれを毎秒、または毎分、または私を幸せにするものなら何でもループで実行します。 $ IPの値をテストして、有用な値が見つかったことを確認します。その場合、iptablesを呼び出して削除し、sedを使用して$ IPのログファイルを削除して、エントリが再度追加されないようにします。
少し前処理を行って(図には示されていません)、常に有効であり、接続に問題があった(ユーザーエラーが原因で)可能性がある重要なIPをホワイトリストに登録しました。
時々、私はiptablesフィルターリストを並べ替えて、それらからIP範囲を作成します(別のスクリプトを使用して-チェックすると、それらは通常、インド、中国、ロシアからのIP範囲です)。したがって、私の全体的なiptablesフィルタールールセットは50から500エントリの範囲にとどまります。 ipsetは、短いリストではあまり改善しません。
MarkRの権利、あなたはこれを行うべきではありません。最も簡単な方法は、スクリプトからiptablesを呼び出すか、iptables構成を記述して「復元」することです。
それでも、必要に応じて、iptablesのソースを読んでください。 iptablesは、一致とテーブルを共有オブジェクトとして使用します。ソースまたはそれらを使用できます。
Linux netfilterには、/ usr/include/netfilter *の下にいくつかのインクルードファイルもあります。これらはやや低レベルの関数です。これはiptablesが使用するものです。これは、iptablesなしで取得できるAPIに近いものです。
しかし、このAPIは「乱雑」です。 iptablesでのみ使用するように設計されていることを覚えておいてください。十分に文書化されていないため、非常に具体的な問題が発生する可能性があります。APIは警告なしにかなり迅速に変更される可能性があるため、アップグレードするとコードが破損する可能性があります。