nftables를 사용하여 동적 블랙리스트 생성

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;
}
}

나에게 이것은 단지 일시적인 해결책일 뿐이다. 공식적인 예를 사용하고 싶습니다맨페이지동적 블랙리스트에 사용됩니다. 맨페이지의 공식 예제를 사용하면 내 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;
}

}

하지만 nft -f myfile을 사용하여 버전 0.8.3에서 이 nftables 파일을 로드하면 다음 오류가 발생합니다.

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

왜 이런 일이 일어나는지는 모르겠지만, 따르면위키피디아버전 0.8.1 및 커널 4.3부터 작동합니다.

내 버전은 0.8.3이고 커널은 4.19.94입니다.

나는 Debian Buster의 버전 0.9.0 공식 매뉴얼 페이지에서 규칙 세트를 테스트했습니다. 매뉴얼 페이지의 규칙 세트는 데비안에서 잘 작동하지만 IP는 한 번만 차단됩니다.

이 예에서는 내 장치에 대한 무차별 대입 공격이 발생할 경우 SSH 포트의 IP 주소를 차단하는 방화벽 규칙을 만들고 싶습니다. 하지만 예를 들어 5분 동안 IP를 차단하고 싶습니다. 이후에는 공격자의 IP에서 장치에 다시 연결할 수 있어야 합니다. 그가 다시 무차별 공격을 가하면 해당 IP는 5분 동안 다시 차단되어야 합니다. nftables를 사용할 수 있는 경우 임베디드 장치에 sshguard 또는 fall2ban과 같은 다른 소프트웨어를 사용하지 않고 싶습니다.

누구든지 나를 도울 수 있기를 바랍니다. 감사해요!

답변1

이것hydra이 도구는 SSH 서버에 동시에 여러 번 연결됩니다. OP의 경우 (논평:) hydra -l <username> -P </path/to/passwordlist.txt> -I -t 6 ssh://<ip-address>6개의 동시 스레드 연결을 사용합니다.

서버 설정에 따라 연결은 일반적으로 5~6개의 비밀번호를 시도할 수 있으며 SSH 서버에서 거부하는 데 약 10초가 소요되므로 10이 얼마나 빠른지 알 수 없습니다.연결하다초당 시도 횟수를 초과할 수 있습니다(그러나 실제로는 그렇습니다). 이는 트리거가 1/2초 이내에 5회 이상의 연결 시도가 완료되었음을 의미할 수 있습니다. 나는 정확성에 대해 그다지 확신하지 못하지만 10/s여기서 일어난 일이라고 가정할 수 있습니다.

버전 및 구문 문제

버전 0.8.1 또는 0.8.3에서 작동하지 않는 구문은 다음 버전에 나타나는 최신 구문입니다.이번에 제출하세요:

src: 패킷 경로의 세트와 맵을 업데이트하기 위해 구문을 다시 검토합니다.

컬렉션의 경우 다음을 허용합니다.

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

[...]

약속됐어뒤쪽에버전 0.8.3은 nftables >= 0.8.4에서만 작동합니다.

현재 위키 개정판은 다음과 같습니다.패킷 경로의 업데이트 세트, 같은 페이지에서 이전 구문의 명령이 계속 표시됩니다.

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

[...]

그리고 새로운 구문을 사용하여 결과를 표시합니다.

[...]

                add @myset { ip saddr }

[...]

일부 위키 페이지 또는 최신 맨페이지는 이전 nftables 버전에서 작동하지 않을 수 있습니다.

어쨌든 커널 4.19로 실행한다면,nftables추가 기능을 위해서는 >= 0.9.0을 선호해야 합니다. 예를 들어 다음과 같을 수 있습니다.데비안 10또는데비안 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집합에 적용되는 차이점

이제 이러한 설정을 사용하면 진행 중인 연결이 즉시 중단되더라도 공격자는 계속 시도하여 백만 년 후에 새로운 짧은 창을 얻을 수 있는데 이는 최적이 아닙니다.

항목은 다음과 같아야합니다고쳐 쓰다@blackhole ... drop규칙에 d를 입력합니다 . update항목이 이미 존재하는 경우 타이머가 새로 고쳐지고 add아무 작업도 수행되지 않습니다. 이는 공격자가 창을 열지 않고 포기할 때까지 SSH 서버에 대한 추가(실패) 연결 시도를 계속 차단합니다. (위에 추가한 출력 규칙은 변경되어서는 안 됩니다. 이는 공격자의 행동이 아닙니다.)

바꾸다:

ip saddr @blackhole counter drop

AND(여전히 이전 구문을 유지함):

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

ct state invalid규칙보다 먼저 이동해야 합니다 . 그렇지 않으면 공격자가 잘못된 패킷(예: 잊혀진 연결의 늦은 RST와 같이 알려진 연결의 일부가 아닌 TCP 패킷)을 시도하는 경우 세트가 업데이트되지 않습니다. 업데이트되었습니다.

설정된 최대 연결 수를 제한하십시오.

커널 >= 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를 처리하는 모든 규칙(두 글자 단어가 있는 경우 ) 은 IPv6 세트를 포함하고 작동하는 미러링 규칙 ip에 복사되어야 합니다 .ip6

관련 정보