Loop - Alias Loops
This module implements alias loops in DNS using variety of different record (resource) types. It supports the following record types:
- CNAME (Canonical Name)
- DNAME (Delegation Name)
- HTTPS (HyperText Transfer Protocol Secure)
- SVCB (Service Binding)
- SPF (Sender Policy Framework)
- SRV (Service Locator)
- MX (Mail Exchange)
- NS (Name Server)
The loops can be a direct loop, where the alias points back to the same domain name as in the original query, or they can include multiple elements, cycling through a specified number of domains.
The idea is that if the client/resolver decides to resolve the response further, it will enter an infinite loop. In practice, however, most modern resolvers detect such loops and terminate the resolution.
Category: Alias loops
Tags: Domain Lock-Up, Denial of Service
RFCs: RFC1034, RFC1035, RFC2672, RFC2782, RFC2915, RFC3761, RFC4408, RFC6672, RFC7208, RFC9460
Format
loop.<NUMBER>.yourdomain.com
Where:
- The
<NUMBER>
parameter specifies the number of elements the loop should contain.
Examples
By default, the module generates a direct CNAME alias loop:
# dig loop.yourdomain.com @127.0.0.1 ; <<>> DiG 9.18.10-2-Debian <<>> loop.yourdomain.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41495 ;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;loop.yourdomain.com. IN A ;; ANSWER SECTION: loop.yourdomain.com. 60 IN CNAME loop.yourdomain.com. ;; Query time: 3 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Thu Nov 07 10:53:17 +04 2024 ;; MSG SIZE rcvd: 70
We can see that the CNAME alias points to the same domain name, effectively forming a direct loop.
Like other features, you can append anything to the feature name to avoid receiving cached responses from the target DNS resolver. This forces the target resolver to actively communicate with our PolarDNS server instead of responding with cached answers. Using a random number is the most effective strategy:
# dig loop${RANDOM}.yourdomain.com @10.211.55.2 ; <<>> DiG 9.18.10-2-Debian <<>> loop1079.yourdomain.com @10.211.55.2 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36755 ;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;loop1079.yourdomain.com. IN A ;; ANSWER SECTION: loop1079.yourdomain.com. 60 IN CNAME loop1079.yourdomain.com. ;; Query time: 7 msec ;; SERVER: 10.211.55.2#53(10.211.55.2) (UDP) ;; WHEN: Thu Nov 07 10:53:18 +04 2024 ;; MSG SIZE rcvd: 78
In this example, we request a MX alias loop consisting of 5 elements:
# dig MX loop.5.yourdomain.com @127.0.0.1 ; <<>> DiG 9.18.10-2-Debian <<>> MX loop.5.yourdomain.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44830 ;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;loop.5.yourdomain.com. IN MX ;; ANSWER SECTION: loop.5.yourdomain.com. 60 IN MX 0 loop.5.1.yourdomain.com. ;; Query time: 24 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Thu Nov 07 11:31:45 +04 2024 ;; MSG SIZE rcvd: 78
The resulting domain name loop.5.1.yourdomain.com
represents the 1st element of the loop.
By resolving the 1st element, we are pointed to the 2nd element of the loop:
# dig MX loop.5.1.yourdomain.com @127.0.0.1 ; <<>> DiG 9.18.10-2-Debian <<>> MX loop.5.1.yourdomain.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31031 ;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;loop.5.1.yourdomain.com. IN MX ;; ANSWER SECTION: loop.5.1.yourdomain.com. 60 IN MX 0 loop.5.2.yourdomain.com. ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Thu Nov 07 11:31:46 +04 2024 ;; MSG SIZE rcvd: 80
This continues up to the 5th and final element — loop.5.5.yourdomain.com
.
By resolving the final element of the loop, we are directed back to the 1st element again:
# dig MX loop.5.5.yourdomain.com @127.0.0.1 ; <<>> DiG 9.18.10-2-Debian <<>> MX loop.5.5.yourdomain.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63220 ;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;loop.5.5.yourdomain.com. IN MX ;; ANSWER SECTION: loop.5.5.yourdomain.com. 60 IN MX 0 loop.5.1.yourdomain.com. ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Thu Nov 07 11:31:47 +04 2024 ;; MSG SIZE rcvd: 80
We can see that we are indeed pointed back to the 1st element again, forming a loop.
In this example, we request an SPF alias loop consisting of 10 elements. Since SPF records are published within TXT records in DNS, we request a TXT record in this case:
# dig TXT loop.10.yourdomain.com @127.0.0.1 ; <<>> DiG 9.18.10-2-Debian <<>> TXT loop.10.yourdomain.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13350 ;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;loop.10.yourdomain.com. IN TXT ;; ANSWER SECTION: loop.10.yourdomain.com. 60 IN TXT "v=spf1 include:loop.10.1.yourdomain.com ~all" ;; Query time: 8 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Thu Nov 07 11:35:51 +04 2024 ;; MSG SIZE rcvd: 97
The resulting domain name loop.10.1.yourdomain.com
represents the 1st element of the loop.
By resolving the 1st element, we are pointed to the 2nd element of the loop:
# dig TXT loop.10.1.yourdomain.com @127.0.0.1 ; <<>> DiG 9.18.10-2-Debian <<>> TXT loop.10.1.yourdomain.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42805 ;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;loop.10.1.yourdomain.com. IN TXT ;; ANSWER SECTION: loop.10.1.yourdomain.com. 60 IN TXT "v=spf1 include:loop.10.2.yourdomain.com ~all" ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Thu Nov 07 11:35:52 +04 2024 ;; MSG SIZE rcvd: 99
This continues up to the 10th and final element — loop.10.10.yourdomain.com
.
By resolving the final element of the loop, we are directed back to the 1st element again:
# dig TXT loop.10.10.yourdomain.com @127.0.0.1 ; <<>> DiG 9.18.10-2-Debian <<>> TXT loop.10.10.yourdomain.com @127.0.0.1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43528 ;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;loop.10.10.yourdomain.com. IN TXT ;; ANSWER SECTION: loop.10.10.yourdomain.com. 60 IN TXT "v=spf1 include:loop.10.1.yourdomain.com ~all" ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Thu Nov 07 11:35:54 +04 2024 ;; MSG SIZE rcvd: 100
We can see that we are indeed pointed back to the 1st element again, forming a loop.
From the same category
- CnLoop - CNAME Alias Loops
- DnLoop - DNAME Alias Loops
- HtLoop - HTTPS Alias Loops
- MxLoop - MX Alias Loops
- NptEnumLoop - NAPTR ENUM Alias Loops
- NsLoop - NS Alias Loops
- PtrLoop1 - PTR Alias Loops (Variant 1)
- PtrLoop2 - PTR Alias Loops (Variant 2)
- SpfLoop - SPF (TXT) Alias Loops
- SrLoop - SRV Alias Loops
- SvLoop - SVCB Alias Loops