回答:
-C --check
最近のiptablesバージョンには新しいオプションがあります。
# iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
iptables: Bad rule (does a matching rule exist in that chain?).
# echo $?
1
# iptables -A INPUT -p tcp --dport 8080 --jump ACCEPT
# iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
# echo $?
0
古いiptablesバージョンの場合、Garrettの提案を使用します。
# iptables-save | grep -- "-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT"
新しい-C
オプションは、使用時間(TOCTTOU)の競合状態に対して開かれているため、満足のいくものではありません。2つのプロセスが同じルールをほぼ同時に追加しようとしても、-C
2回追加されないように保護しません。
だから、それは本当にgrep
解決策よりも優れています。の出力に対する正確なテキスト処理ジョブは、その出力がテーブルの状態の信頼できるスナップショットであるため、とiptables-save
同じくらい確実に機能します-C
。
必要なのは、--ensure
ルールが存在しない場合にのみアトミックにチェックして追加するオプションです。さらに、ルールがまだ存在しない場合に新しいルールが挿入される正しい位置にルールが移動されると便利です(--ensure-move
)。たとえばiptables -I 1
、チェーンの先頭にルールを作成するために使用されるが、そのルールがすでに7番目の位置に存在する場合、既存のルールは最初の位置に移動する必要があります。
これらの機能がなければ、実行可能な回避策は、この擬似コードに基づいてシェルスクリプトループを記述することだと思います。
while true ; do
# delete all copies of the rule first
while copies_of_rule_exist ; do
iptables -D $RULE
done
# now try to add the rule
iptables -A $RULE # or -I
# At this point there may be duplicates due to races.
# Bail out of loop if there is exactly one, otherwise
# start again.
if exactly_one_copy_of_rule_exists ; then
break;
fi
done
このコードはスピンする可能性があります。一定の反復回数内で2人以上のレーサーが出ることを保証するものではありません。これを支援するために、ランダム化された指数バックオフスリープをいくつか追加できます。
これは少し逆に見えるかもしれませんが、私にとってはうまくいきます-最初にルールを削除してみてください。
iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP;
次のようなメッセージが表示されるはずです。
iptables:不適切なルール(そのチェーンに一致するルールが存在しますか?)
次に、通常どおりルールを追加します。
iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP;
リストして検索するだけですか?
iptables --list | grep $ip
...または、ただし、ルールが指定されています。使用grep -q
すると、何も出力されず、戻り値を確認できます$?
iptables-save|grep $ip
特にスクリプトでは、より簡単に解析可能な形式であるため、代わりに提案します。必要に応じて、コマンドの正確な構文も確認できます。
iptables-save|grep $ip
に非常によく一致する可能性があるためです。おそらくiptables-save
、完全なルール仕様をチェックするために使用できますが、それはまだ少しハックです:によって返される形式はiptables-save
、スクリプト内のルールと正確に一致しない場合があります。iptables-save
オプションを異なる順序で生成したり、物事を追加したりすることができます(など-m tcp
)。
iptables --list
well-knownポートを解決しようとします。そのため、ポートをgrepする前にそれを確認してください。
https://serverfault.com/questions/628590/duplicate-iptable-rulesで説明されているように、最初に重複を追加してから削除してください。最も簡単な(隣接する行の)ようです
iptables-save | uniq | iptables-restore
スクリプトからルールが重複しないようにするには、次の行を追加します。
iptables -C -INPUT -p tcp --dport 8080 --jump ACCEPT || iptables -A -INPUT -p tcp --dport 8080 --jump ACCEPT
最初に上記のコマンドを実行すると、次のメッセージが表示されます
iptables:不適切なルール(そのチェーンに一致するルールが存在しますか?)
これは単なる情報です。ただし、コマンドの後半では、ルールを確実に追加します。