해커가 DoS로 DNS 서버를 공격하는 이유는 무엇입니까?

Aug 15 2020

오늘 아침에 재부팅 된 서버로 깨어납니다. DNS 서버가 100 % 이상 실행되었습니다. 약간의 작업을 마친 후 이러한 모든 요청을 차단하기 위해 fail2ban을 설치했습니다.

요청 자체는 유효하며 초당 수백 번 반복됩니다. 블록에 많은 (수백) 개의 IP가 확보되면 몇 시간마다 1 백만 개의 UDP 히트를 차단하고 있음을 알 수 있습니다.

그게 [D] DoS 공격인가요? (많은 컴퓨터가 관련되어 있고 한 대가 충분히 오랫동안 차단되면 요청을 중지하는 것처럼 보이므로 동적으로 간주 될 수 있음)

내가 생각할 수있는 또 다른 가능성은 공격자가 DNS 서버를 중단하고 전체 컴퓨터를 다시 시작하거나 중단하고 다른 서비스에 대한 연결을 시도 할 때 액세스 권한을 얻으려고한다는 것입니다. (즉, 서비스를 시작하기 전에 방화벽을 설치하는 방법을 모르는 경우)

마지막 방화벽 재설정 이후 내 통계는 다음과 같습니다.

조회수 : 2,346,742
IP 수 : 473

빠르게 진행됩니다. 초당 수백 히트. 그러나 IP의 수는 많이 증가하지 않습니다.

답변

7 AlexisWilke Aug 17 2020 at 07:55

@Schroeder의 의견에서 몇 가지 추가 검색을 수행하고 이러한 유형의 공격에 대해 훨씬 더 많이 알아 냈습니다.

나는 표적이었다!

우선 내가 공격 대상인 것 같다. 왜? DNS 증폭 공격은 DNS 요청의 소스 포트가 53으로 설정되어 있음을 의미하기 때문입니다. 이렇게하면 내 DNS가 요청되지 않은 응답을 다른 서버로 보내도록 강제 할 수 있습니다 (아래 그래프 참조). 해당 포트를 사용하여 이러한 적중이 0.1 % 미만이므로 실제로 내 DNS가 증폭에 사용 된 것이 아니라 대상이라고 생각합니다.

공격은 어떻게 이루어 집니까?

공격자는 도메인 이름을 요청 하는 임의의 DNS 서버에 UDP 패킷을 보내는 소프트웨어로 컴퓨터를 설정합니다 . 패킷은 공격자가 자신의 IP 주소 대신 다른 컴퓨터의 IP 주소를 소스로 사용한다는 사실을 제외하고는 정상적으로 보입니다. 그 결과 DNS 가 잘못된 컴퓨터로 응답을 보냅니다 .

      10.0.0.1         10.0.0.2         10.0.0.3
+------------+   +------------+   +------------+
|            |   |            |   |            |
| Attacker   +-->| Some DNS   +-->| Me         |
|            |   |            |   |            |
+------------+   +--+---------+   +------------+
                    |      ^
                    v      |
                 +---------+--+   This step is not required, it happens if
                 |            |   your DNS is setup to accept recursive
                 | Master DNS |   requests (which is not a good idea)
                 |            |
                 +------------+
                       10.0.0.4

위의 예에서 공격자의 요청은 UDP 발신 주소로 10.0.0.1을 가져야합니다. 그러나 대신 공격자는 자신의 IP 주소를 10.0.0.3으로 변경합니다. 결과적으로 10.0.0.2의 DNS가 UDP 패킷을 수신하고 응답을 보낼 준비가되면 데이터를 10.0.0.3으로 보냅니다.

10.0.0.2의 DNS가 쿼리되는 도메인 이름에 대해 전혀 알지 못하는 경우 도메인의 마스터 DNS가 사용됩니다.

중요 참고 : 이는 모든 UDP 서비스에 해당됩니다. DNS는 아마도 증폭 측면에서 최악 일 수 있지만, 예를 들어 NTP도 타겟팅 할 수 있습니다.

소스 주소 만 확인하지 않는 이유는 무엇입니까?

10.0.0.2에서는 UDP가 패킷의 실제 소스를 기억하지 않기 때문에 불가능합니다.

가능한 것은 ISP가 주어진 컴퓨터에서 나가는 모든 패킷에 해당 컴퓨터의 IP 주소가 있는지 확인하는 것입니다. 일부는 그렇다고 생각하지만 대부분은 그렇지 않습니다. 속도에 약간의 영향을 미칩니다 ... 물론 DNS 증폭은 웃을 것입니다 (DNS 증폭은 UDP 패킷 출처의 작은 확인보다 인터넷에 더 나쁜 영향을 미칩니다).

다른 한 가지는 사용자가 ISP 확인을 우회하는 방식으로 인터넷에 연결하여 계속할 수 있다는 것입니다. 나는 그것이 가능할지 여부 및 / 또는 방법을 모르지만 그것이 가능하다는 것에 놀라지 않을 것입니다.

실제로 이러한 공격의 출처를 추적하기 어렵고 이러한 공격이 여전히 대량으로 발생하고 있기 때문에 이것은 매우 문제가됩니다.

왜 DDoS입니까?

여기서 일어나는 DNS 레코드를 요청하는 패킷은 300 바이트 정도로 매우 작습니다. 따라서 공격자는 하나의 작은 UDP 패킷 만 보내면됩니다.

그러나 응답은 수 킬로바이트의 데이터 일 수 있습니다. 특히 이러한 공격에 사용되는 도메인이 있습니다.

peacecorps.gov

그 도메인은 3Kb 이상의 데이터를 반환합니다! (증폭 공격에 사용되는 많은 'TXT'필드를 정의합니다.) 이것이 증폭 공격이라고하는 이유입니다.

결과적으로 공격자의 요청은 약 10 배 더 큰 응답으로 변환되고 공격을받는 컴퓨터 (10.0.0.3)는 다소 큰 UDP 패킷으로 가득 차게됩니다.

여기에 결과 항목이 표시됩니다 iptables. 첫 번째 숫자는 약 40 분 후 내 DNS 컴퓨터에 대한 적중 수를 나타냅니다 (따라서 분당 10,000 회 이상 ...).

pkts     bytes target     prot opt in     out     source               destination         
61637  4376227 DROP       udp  --  eno1   *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 STRING match  "|0a7065616365636f72707303676f76|" ALGO name bm TO 65535

또한 문자열이 16 진수로 완전히 변환 된 방법에 유의하십시오.

HTTP 요청이 더 나쁘지 않을까요?!

HTTP 0.9 / 1.0 / 1.1 / 2는 양방향 프로토콜 인 TCP를 사용하며 TCP로 증폭을 생성 할 수 없습니다. 즉, 전체 핸드 셰이크로 먼저 제대로 연결하지 않으면 TCP가 중단됩니다.

그러나 HTTP / 3 는 UDP 패킷을 통한 HTTP 인 QUIC 프로토콜을 도입합니다 . 지금까지 QUIC의 주요 문제에 대해 들어 본 적이 없지만 지난 6 ~ 7 년 동안 프로토콜이 많이 변경되었으며 아직 널리 구현되지 않았습니다. 여기에 QUIC가 증폭 공격을 방지하는 기능이 내장되어 있다는 사실에 대한 기사 가 있습니다.

어떤 사람들은 HTTP를 사용하여 도메인 이름을 쿼리하는 것에 대해 이야기하고 있습니다. (DoH — Domain over HTTP). 바라건대 그것은 QUIC를 사용하여 구현되지 않을 것입니다.

문제를 어떻게 해결할 수 있습니까?

증폭은 사용자가 제어하지 않는 도메인 이름 (즉, 소유자가 아닌 도메인)의 요청을 수락하도록 DNS가 설정되어 있기 때문에 발생합니다.

BIND에는 DNS 용어로 재귀라고하는 증폭을 수행 할 수있는 옵션이 있습니다. 이 기능은 이제 기본적으로 꺼져 있지만 실수로 켜졌을 수 있습니다.

다음은 잘못된 설정입니다 .

allow-recursion { any; };

원하는 것은 올바른 설정 을 사용하는 것입니다 .

trusted-servers { 192.0.2.4; }  // list all your trusted servers

allow-recursion { trusted-servers; };

이렇게하면 서버가 이러한 모든 요청을 자동으로 거부하게됩니다. 따라서 그렇지 않고 peacecorps.gov그러한 요청을 받으면 BIND는 바로 거기에서 중지하고 거부 된 요청에 대한 DNS 로그에 메모를 작성합니다.

이러한 요청에서 IP를 차단할 수 있습니까?

예. 내 서버가 CPU 시간에서 100 % 이상을 실행했기 때문에 시작했습니다. 그러나 그렇게하는 것이 현명하지 않을 수 있습니다. 위의 그림에서 DNS 서버가 공격자와 피해자 사이에 있음을 알 수 있습니다. 소스 IP 주소를 차단하면 차단하는 것은 공격자의 IP가 아니라 피해자의 IP입니다. 이것은 실제로 피해자가 귀하의 도메인 이름을 보지 못하게하고 합법적 인 요청을 수행하는 것을 의미합니다. 그것은 아마도 당신이 원하는 것이 아닐 것입니다!

처음에는 방화벽에서 로그 메시지를 생성했습니다. 짧은 시간 (5 초)에 동일한 IP 주소에서 포트 53 (UDP)에 대한 요청을 5 개 이상 감지하면 IP 주소를 차단합니다. 이를 위해 fail2ban.

먼저 UDP 및 포트 53을 대상으로하는 링크를 감지하는 필터가 있습니다.

# Filter: /etc/fail2ban/filter.d/named-fast-requests.conf
[Definition]
failregex = \sIN=[a-z0-9]+ .* SRC=<HOST> .* PROTO=UDP .* DPT=53\s

둘째, 다른 매개 변수를 제공하는 감옥이 있습니다.

# Jail: /etc/fail2ban/jail.d/named-fast-requests.conf
[named-fast-requests]
enabled  = true
filter   = named-fast-requests
action   = named-action[scheme=all,period=year,reason=named fast requests]
logpath  = /var/log/iptables/iptables.log
maxretry = 5
findtime = 5
bantime  = 1036800

여기서 요점 은 5 초 이내에 5 번으로 설정 되는 maxretryand findtime입니다. 이 경우 <HOST>.

자신의 것으로 작업을 업데이트하고 싶을 것입니다. iplock여기 에서는 내 도구를 사용합니다. 액션에서 사용하는 명령 :

actionban = /usr/sbin/iplock -s named -b <ip>

기본적으로 fail2ban은 iptables직접 사용 합니다. 그들의 행동을 검색하여 어떻게되었는지 확인하십시오.

증폭의 근원이되지 마십시오

소스 UDP 포트가 1024 미만인 요청을 차단해야합니다. 이는 유효하지 않습니다. 서버를 제공하는 경우 포트 53은 소스가 아닌 대상 포트가됩니다.

iptables -I INPUT 123 -i eth0 -p udp -m udp --sport 0:1023 -j DROP

경고 : 위치 (123)를 올바른 번호로 교체하십시오!

이 규칙은 eth0소스 포트가 0에서 1023 사이 인의 모든 수신 UDP 패킷에 대해 패킷을 삭제하도록 지정합니다. 이것은 누군가가 증폭을 위해 DNS 서버를 사용하는 것을 방지합니다. 그러나 다른 사람의 증폭으로부터 자신의 서버를 보호하지는 않습니다. 적절한 allow-recursion설정 을하더라도 공격자가 공격 을 위해 도메인 이름 중 하나를 적절하게 선택 하면 증폭 공격을 방지 할 수 없습니다 .

참고 : 컴퓨터에서 도메인 이름을 확인하기 위해 다른 이름 서버를 지정하는 경우 포트 0에서 1023까지의 모든 것을 차단하기 전에 해당 연결을 열 수 있습니다. 다음과 같습니다.

iptables -I INPUT 123 -i eth0 -p udp -m udp --sport 53 -s 8.8.8.8 \
                    -d <your-static-ip> -j ACCEPT

이것은 아마도 수신하고자하는 네임 서버 8.8.8.8에서 반환 된 데이터입니다. 공급자 나 다른 공식 네임 서버가 UDP 공격의 직접적인 원인 이 아닐 가능성이 높습니다 . 고정 IP 주소가없는 경우 -d옵션 을 포함 할 필요가 없습니다 .

그러나 ESTABLISHED현재 UDP 메시지에 사용할 수 있는 기능 을 사용하는 것이 훨씬 더 나을 것입니다 (한동안 사용되었지만 사용할 수 없었던 시간을 기억합니다 ...).

iptables -I INPUT 123 -i eth0 -p udp -m state \
      --state ESTABLISHED,RELATED -m udp -d <your-static-ip> -j ACCEPT

즉, 방화벽은 사용자가 요청을 보냈 음을 알고 응답을 수락하기를 원하므로 도메인 이름 서버 공급자의 답변을 자동으로 수락합니다. 이 규칙은 DROP위 의 규칙 앞에 나타나야합니다 .

원치 않는 요청을 조기에 삭제

분명히 BIND가 이러한 모든 요청을 수락하는 peacecorps.gov것은 누구도 원하는 것이 아닙니다. 실제로 방화벽에서 직접 차단할 수 있습니다. 이는 UDP 패킷이 암호화되지 않아 도메인 이름이 표시되기 때문에 작동합니다.

다음은 이러한 도메인 이름 요청을 차단하는 데 사용할 수있는 규칙입니다.

sudo iptables -I INPUT 123 -i eno1 -p udp -m udp --dport 53 \
           -m string --hex-string "|0A|peacecorps|03|gov|" --algo bm -j DROP

당연히 DNS에 "peacecorps.gov"를 포함한 도메인 또는 하위 도메인이있는 경우 해당 iptables규칙을 사용해서는 안됩니다 . 우리 대부분에게는 드물지만.

--hex-string옵션을 사용하면 문자열을 지정할 수 있습니다. UDP 패킷에서 정의되는 방식은 P- 문자열 (크기 + 데이터) 형식을 사용합니다. "peacecorps"는 10 자 길이이므로 바로 앞에 0x0A를 넣습니다. 다시 말하지만 "gov"는 세 글자이므로 0x03을 사용합니다. "peacecorps.gov"문자열을 사용하면 마침표가 0x03 바이트와 일치하지 않으므로 작동하지 않습니다. 첫 번째 크기는 선택 사항 이지만 "bestpeacecorps"와 같이 동일하게 보이는 모든 항목과 일치 할 수 있습니다.

이러한 규칙이 있으면 도메인 이름 서비스가 완전히 원치 않는 트래픽을 많이 절약 할 수 있습니다.

업데이트 : 내 질문을 게시 한 지 약 2 주 후에 공격이 중단되었지만 "peacecorps.gov" 문제는 여전히 하루에 10 번 정도 발생합니다.

출처: https://defragged.org/2020/05/20/tips-and-tricks-blocking-dns-requests-via-iptables/

DNS 디버깅

DNS 서버가 수신하고 응답하는 쿼리를 확인하려면 콘솔에서 다음 명령을 실행할 수 있습니다.

sudo rndc querylog

이제 일반적으로 여기에서 로그를 살펴보십시오.

less /var/log/named.log

하단을 보면 ( G를 클릭 less) 원격 IP에서 쿼리를보기 시작해야합니다. 로그에는 확인중인 도메인 이름이 포함됩니다. 특히 2 차 또는 3 차 DNS에 자신의 도메인 이름을 입력하지 못한 경우 매우 실용적입니다.