Linux環境でnftablesを用いてSSH接続のレート制限を設定する際、想定通りに動作せずに困るケースがあります。この記事では、よくある設定ミスや動作の誤解を解説し、正しい制御方法を紹介します。
nftablesのレート制限の仕組み
nftablesでは、’limit rate’を使って特定のIPアドレスやサービスへの接続回数を制御できます。例えば、’limit rate over 5/minute’は、1分間に5回を超える新規接続に対してルールを適用します。
注意点として、rate制限は接続ごとのパケットではなく、new stateのトラフィックを対象にカウントされるため、カウンターやセットへの追加タイミングが直感と異なる場合があります。
誤解されやすい動作例
質問例のように一回しか接続していないIPがNG-SSHセットに入る現象は、’limit rate over’がトラフィックの到達順序やタイミングにより、1回目のnew stateパケットでも条件評価が行われるためです。
具体的には、nftablesはルール内でセットへの追加を評価する際、’limit’判定が同時に行われ、パケットが実際にdropされなくてもIPがセットに登録される場合があります。
推奨する設定方法
想定通りに「1分間に5回を超える接続のみNG」としたい場合、以下のアプローチが効果的です。
- まず、カウンター専用のsetを作り、アクセスごとにカウントする。
- カウンターの値が5を超えたIPのみNGセットに追加。
- limit rateを直接セット追加に使用するのではなく、カウンター判定後にaddする。
これにより、1回だけのアクセスでNGセットに入る誤動作を避けられます。
実例設定
以下は参考例です。
set ssh_counter { type ipv4_addr; flags dynamic,timeout; timeout 10m; } set NG_SSH { type ipv4_addr; flags dynamic,timeout; timeout 10m; } tcp dport 22 ct state new add @ssh_counter { ip saddr } counter accept update @NG_SSH { ip saddr timeout 10m } # ssh_counterで5以上ならNG
このように、まずアクセスをカウントしてから条件判定でNGセットに追加する方式をとると、期待通りの挙動になります。
まとめ
nftablesのrate制限ルールでは、setへの追加やパケットカウントの仕組みが直感と異なる場合があります。重要なのは、アクセスごとのカウントを別途管理し、条件判定後にNGセットに追加することです。
今回紹介した手順を実践すれば、1分間に5回以上のSSH接続のみを正しくdropし、それ以下のアクセスはacceptする設定を実現できます。


コメント