Part 2: How To Use IPTables to Block a Specific DNS Request?
This post does not aim to define DNS or describe its operation.
Using a DNS request, the post aims to describe how to interpret a network package on your Linux device.
Understanding the Network Packet
Numerous images regarding the contents of network packets are available on the internet.
We need to know which portion of the network package is an IP header, which part is a UDP header, and which part is the DNS request itself before we can verify those boilerplate packet images.
The following is the tcpdump output when you execute the dig mx google.com
command:
root@main:~# tcpdump -i any port 53 -Xn
16:30:35.684834 IP 10.211.55.7.50081 > 8.8.8.8.53: 58187+ [1au] MX? google.com. (51)
0x0000: 4500 004f f7c0 0000 4011 30f4 0ad3 3707 E..O....@.0...7.
0x0010: 0808 0808 c3a1 0035 003b 5236 e34b 0120 .......5.;R6.K..
0x0020: 0001 0000 0000 0001 0667 6f6f 676c 6503 .........google.
0x0030: 636f 6d00 000f 0001 0000 2910 0000 0000 com.......).....
0x0040: 0000 0c00 0a00 0845 048d 37f3 71f8 e9 .......E..7.q..
Tcpdump provides hexadecimal outputs (4500 004f …).
Each character in the hexadecimal output is 4-bit. So, the first column (4500) has 4 x 4 = 16 bits (2 bytes).
I will split the hexadecimal into four segments: IP header, UDP header, DNS header, and DNS Payload:
Orange : IP Header
Green : UDP Header
Purple : DNS Header
Blue : DNS Payload
How do I know Orange is the IP header?
Here’s the content of the IP header:
1 hexadecimal digit represents four bits. The first hexadecimal column is 4500.
4500 -> Version, Helen (Header Length), Service Type.
4 (4 bits) -> Version = IPv4
5 (4 bits) -> Length = 5
00 (8 bits) -> Service Type = None
Is the length of the IP header 5 bytes or 5 bits?
No. In the IP protocol, there is a term: double word. The term “double word” refers to the 32 bits (4 bytes)
The IP Protocol uses this formula to determine the length of the IP Header’s length: double word * length
32 bits * 5 = 160 bits
160 bits / 8 = 20 bytes
Based on this formula, I colored the first 40 hex characters orange. Because each hexadecimal character is 4 bits.
20 bytes * 8 = 160 bits
160 bits / 4 bits = 40 hexadecimal characters
Let’s move on to the next column:
004f -> Total Length
This is hexadecimal. Therefore, I’ll use an online tool to convert it to decimal.
There are 79 bytes in total length. We determined that there are 20 bytes in the IP header.
79 bytes - 20 bytes = 59 bytes
We have 59 bytes of data in this package
UDP Header + DNS Header + DNS Payload = 472 bits (59 bytes)
Let’s move on to the next column:
7762 -> Identification
If the IP packet is fragmented, identification is crucial. In order for the network devices to know which IP packet they are working on.
000 -> Flags
Fragmentation rules are indicated via flags.
Fragmentation offset is omitted. The packet is not fragmented anyway.
4011 -> Time to live, Protocol
40 -> Time to live (TTL) = 64
The TTL value of this packet will drop by 1 for every network device it passes. When the TTL value is zero, the packet will be dropped. As a result, no network package will remain on the internet indefinitely.
You may alter the TTL value as follows:
sysctl -w net.ipv4.ip_default_ttl=64
11 -> Protocol = 0x11 is UDP (11 hex = 17 decimal)
(Here are the more details)
30f4 -> Header checksum
The network devices use the packet’s checksum to determine if it is corrupted.
0ad3 3707 -> Source IP Address
0a -> 10
d3 -> 211
37 -> 55
07 -> 7
Source IP Address: 10.211.55.7
0808 0808 -> Destination IP Address
08 -> 8
08 -> 8
08 -> 8
08 -> 8
Destination IP address: 8.8.8.8
We examined the first 160 bits of the package.
UDP Header
c3a1 (16 bits, 2 bytes) -> Source Port
c3a1 (Hex) -> 50081 (Decimal)
0035 (16 bits, 2 bytes) -> Destination Port
0035 (Hex) -> 53 (Decimal)
003b (16 bits, 2 bytes) -> Length
003b (Hex) -> 59 (Decimal)
UDP Header (Green)+ DNS Header (Purple) + DNS Payload (Blue)= 59 bytes
5236 (16 bits, 2 bytes) -> Checksum
I analyzed the DNS payload here: