web-dev-qa-db-ja.com

nftablesでダイナミックブラックリストを作成する

Nftablesで動的なブラックリストを作成したい。組み込みデバイスのバージョン0.8.3で、nftリストルールセットを使用して次のようなルールセットを作成します。

table inet filter {
set blackhole {
    type ipv4_addr
    size 65536
    flags timeout
}

chain input {
    type filter hook input priority 0; policy drop;
    ct state invalid drop
    ct state established,related accept
    iif "lo" accept
    ip6 nexthdr 58 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-done, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } accept
    ip protocol icmp icmp type { echo-reply, destination-unreachable, echo-request, router-advertisement, router-solicitation, time-exceeded, parameter-problem } accept
    ip saddr @blackhole counter packets 0 bytes 0 drop
    tcp flags syn tcp dport ssh meter flood { ip saddr timeout 1m limit rate over 10/second burst 5 packets}  set add ip saddr timeout 1m @blackhole drop
    tcp dport ssh accept
}

chain forward {
    type filter hook forward priority 0; policy drop;
}

chain output {
    type filter hook output priority 0; policy accept;
}
}

私にとってこれは一時的な解決策にすぎません。動的なブラックリストに公式の manpage の例を使用したいと思います。マンページの公式の例を使用すると、nftablesファイルは次のようになります。

table inet filter {
set blackhole{
        type ipv4_addr
        flags timeout
        size 65536
}
chain input {
        type filter hook input priority 0; policy drop;

        # drop invalid connections
        ct state invalid drop

        # accept traffic originating from us
        ct state established,related accept

        # accept any localhost traffic
        iif lo accept

        # accept ICMP
        ip6 nexthdr 58 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-done, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } accept
        ip protocol icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem, echo-request, echo-reply } accept

        # accept SSH (port 22)
        ip saddr @blackhole counter drop
        tcp flags syn tcp dport ssh meter flood { ip saddr timeout 10s limit rate over 10/second} add @blackhole { ip saddr timeout 1m } drop
        tcp dport 22 accept

}


chain forward {
        type filter hook forward priority 0; policy drop;
}

chain output {
        type filter hook output priority 0; policy accept;
}

}

しかし、このnftablesファイルをバージョン0.8.3でnft -f myfileを使用してロードすると、次のエラーが発生します。

Error: syntax error, unexpected add, expecting newline or semicolon
    tcp flags syn tcp dport ssh meter flood { ip saddr timeout 10s limit rate over 10/second} add @blackhole { ip saddr timeout 1m } drop

なぜそうなのかはわかりませんが、 wiki によると、バージョン0.8.1とカーネル4.3で動作するはずです。

私はバージョン0.8.3とカーネル4.19.94を持っています。

Debianバスターの下で、公式のマンページのバージョン0.9.0のルールセットをテストしました。マンページのルールセットはDebianで正常に機能しますが、IPは1回だけブロックされます。

この例では、デバイスに対してブルートフォース攻撃が開始された場合に、sshポートのIPアドレスをブロックするファイアウォールルールを作成します。しかし、私はIPを例えば5分間ブロックしたいです。その後、攻撃者のIPからデバイスに再び接続できるようになります。彼が再びブルートフォースを行う場合は、IPを5分間再びブロックする必要があります。 nftablesで可能な場合は、sshguardやfail2banなどの組み込みデバイス用の別のソフトウェアの使用を避けたいです。

誰かが私を助けてくれることを願っています。ありがとう!

2
user408169

hydra ツールは、SSHサーバーに複数回同時に接続します。 OPの場合( コメントhydra -l <username> -P </path/to/passwordlist.txt> -I -t 6 ssh://<ip-address>)は、6つの同時スレッド接続を使用します。

サーバーの設定にもよりますが、通常、1つの接続で5つまたは6つのパスワードを試行し、SSHサーバーに拒否されるまでに約10秒かかるため、10 connection 1秒あたりの試行回数がどの程度かを確認できません超過しました(ただし、そうです)。トリガーとなるのは、5回を超える接続試行が1/2秒未満で行われることです。 10/sの正確さはあまり信用しませんが、ここで発生するものと想定できます。

バージョンと構文の問題

バージョン0.8.1または0.8.3で機能しない構文は、 this commit に含まれる新しい構文です。

src:パケットパスからセットとマップを更新する構文を再確認

セットの場合、これを許可します:

  nft add rule x y ip protocol tcp update @y { ip saddr}

[...]

コミットされましたafterバージョン0.8.3なので、nftables> = 0.8.4でのみ使用できます

パケットパスからのセットの更新 の現在のWikiリビジョンは、同じページで、以前の構文のコマンドを引き続き表示します

 % nft add rule filter input set add ip saddr @myset

[...]

より新しい構文で表示された結果:

[...]

                add @myset { ip saddr }

[...]

一部のWikiページまたは最新のマンページは、古いnftablesバージョンでは動作しない場合があります。

とにかく、カーネル4.19で実行している場合、追加の機能を取得するにはnftables> = 0.9.0をお勧めします。たとえば、 Debian 1 または Debian 9バックポート で利用できます。

ブラックリストはステートフル受け入れルールの前に行う必要があります

IPがブラックリストに追加されると、SSHサーバー自体によって接続が切断されるまで、確立された接続が妨げられず、アカウンティングも続行されます。これは、以前に通常の短絡ルールが存在するためです。

        # accept traffic originating from us
        ct state established,related accept

このコメントは誤解を招く可能性があります:私たちからのトラフィックを受け入れるではなく進行中のトラフィックではありません。これは短絡ルールです。その役割は、新しい接続についてのみすべてのルールを解析することにより、ステートフルな接続を処理することです。これ以降のルールはすべて、新しい接続に適用されます。接続が受け入れられると、個々のパケットは接続が終了するまで受け入れられたままになります。

ブラックリスト処理の特定のケースでは、特定のブラックリストルールまたはその一部をこの短絡ルールの前に配置して、すぐに有効にする必要があります。 OPの場合は次のとおりです。

        ip saddr @blackhole counter drop

ct state established,related acceptルールの前に移動する必要があります。

これで、攻撃者がブラックリストに追加されると、他の進行中の接続は、パスワードを推測するための残りの無料の試行を受け取らず、すぐにハングアップします。

ブラックリストがある場合は、ホワイトリストを検討してください

補足として、安価なiif lo acceptルール自体を最適化とホワイトリストの両方の前に移動することができます。すべての(長命の)ローカルで確立された接続も、乱用の場合はブラックリストに登録されます(例: 127.0.0.1から)。 @blackholeルールの前に、さまざまなホワイトリストルールを追加することを検討してください。

必要に応じて、アプリケーションをより速く警告します

サーバーからの継続的な応答がブラックリストに記載されたIPに到達するのを防ぐためにも(特にUDPトラフィックの場合、SSHを含むTCPにはそれほど役立ちません)、daddrを使用する同等のルールをinet filter outputチェーンに追加することもできます、リジェクトを使用して、ローカルプロセスがエミットしようとしているローカルプロセスが異常終了することをより速く通知します。

    ip daddr @blackhole counter reject

セットに適用されるaddupdateの違い

このような設定が行われると、進行中の接続がすぐに停止した場合でも、攻撃者は試行を続け、1分後に新しい短いウィンドウを取得できますが、これは最適ではありません。

エントリは、入力@blackhole ... dropルールでpdate dである必要があります。 updateは、エントリがすでに存在する場合はタイマーを更新しますが、addは何もしません。これにより、攻撃者があきらめるまで、開いているウィンドウがゼロになるまで、SSHサーバーへの接続の試み(失敗)がブロックされます。 (上記で追加した出力ルールは変更しないでください。攻撃者のアクションではありません):

交換:

ip saddr @blackhole counter drop

(まだ古い構文を維持):

ip saddr @blackhole counter set update ip saddr timeout 1m @blackhole drop

ct state invalidルールの前に移動する必要があります。それ以外の場合、攻撃者が無効なパケットを試みた場合(例:TCPパケットは既知の接続の一部ではなく、すでに忘れられている接続からの遅いRSTなど) 、セットは更新されている可能性がありますが、更新されません。

確立された接続の最大数を制限する

カーネル> = 4.18およびnftables> = 0.9.0が必要であるため、OPの現在の構成では実行できません。

攻撃者は一度に何回も接続できないことに気づくかもしれませんが、接続が速すぎない限り、制限なく新しい接続を追加し続けることができます。

同時接続の制限 (iptablesの connlimit で使用可能)は、他のメータールールで追加することもできます。

tcp flags syn tcp dport 22 meter toomanyestablished { ip saddr ct count over 3 } reject with tcp reset

任意のIPアドレスに、3つの確立されたSSH接続のみを許可します。

または、それと同時に、代わりに@blackholeセットもトリガーします(今回は新しい構文を使用します)。

tcp flags syn tcp dport 22 meter toomanyestablished { ip saddr ct count over 3 } add @blackhole { ip saddr timeout 1m } drop

これは、OPの場合、前のメータールールの前でもトリガーされるはずです。正当なユーザーに影響が及ばないように注意して使用してください(ただし、opensshの ControlMaster オプションを参照してください)。

IPv4およびIPv6

一般的なIPv4 + IPv6セットアドレスタイプがないため、IPv4を処理するすべてのルール(2文字の単語ipがある場合はいつでも)は、ip6を含むミラールールに複製し、 IPv6セット。

1
A.B