Skip to content

Commit

Permalink
Check IPs in a dnstap capture of resolver traffic
Browse files Browse the repository at this point in the history
Add a system test that checks whether IP addresses are present in a
dnstap capture of resolver traffic if "query-source" is explicitly set.
  • Loading branch information
kempniu committed Jun 22, 2022
1 parent 366f7a9 commit 1f5c2ea
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 2 deletions.
1 change: 1 addition & 0 deletions bin/tests/system/conf.sh.common
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ export CDS
export CHECKZONE
export DESCRIPTION
export DIG
export DNSTAPREAD
export FEATURETEST
export FSTRM_CAPTURE
export GENCHECK
Expand Down
3 changes: 1 addition & 2 deletions bin/tests/system/dnstap/clean.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ rm -f */named.run
rm -f */named.run.prev
rm -f */named.stats
rm -f dig.out*
rm -f dnstap.out dnstap.hex
rm -f dnstap.out.save
rm -f dnstap.*
rm -f fstrm_capture.out
rm -f ns*/dnstap.out
rm -f ns*/dnstap.out.save
Expand Down
83 changes: 83 additions & 0 deletions bin/tests/system/dnstap/tests_dnstap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/python3

# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.

import os
import re
import subprocess

import pytest

pytest.importorskip("dns")
import dns.resolver


def run_rndc(server, rndc_command):
"""
Send the specified 'rndc_command' to 'server' with a timeout of 10 seconds
"""
rndc = os.getenv("RNDC")
port = os.getenv("CONTROLPORT")

cmdline = [rndc, "-c", "../common/rndc.conf", "-p", port, "-s", server]
cmdline.extend(rndc_command)

subprocess.check_output(cmdline, stderr=subprocess.STDOUT, timeout=10)


def test_dnstap_dispatch_socket_addresses(named_port):
# Prepare for querying ns3.
resolver = dns.resolver.Resolver()
resolver.nameservers = ["10.53.0.3"]
resolver.port = named_port

# Send some query to ns3 so that it records something in its dnstap file.
ans = resolver.query("mail.example.", "A")
assert ans[0].address == "10.0.0.2"

# Before continuing, roll dnstap file to ensure it is flushed to disk.
run_rndc("10.53.0.3", ["dnstap", "-roll", "1"])

# Move the dnstap file aside so that it is retained for troubleshooting.
os.rename(os.path.join("ns3", "dnstap.out.0"), "dnstap.out.resolver_addresses")

# Read the contents of the dnstap file using dnstap-read.
output = subprocess.check_output(
[os.getenv("DNSTAPREAD"), "dnstap.out.resolver_addresses"], encoding="utf-8"
)

# Check whether all frames contain the expected addresses.
#
# Expected dnstap-read output format:
#
# 22-Jun-2022 12:09:06.168 RR 10.53.0.3:0 -> 10.53.0.1:7523 TCP ...
# 22-Jun-2022 12:09:06.168 RR 10.53.0.3:0 <- 10.53.0.1:7523 TCP ...
# 22-Jun-2022 12:09:06.168 RQ 10.53.0.3:56306 -> 10.53.0.2:7523 UDP ...
# 22-Jun-2022 12:09:06.168 RQ 10.53.0.3:56306 <- 10.53.0.2:7523 UDP ...
#
bad_frames = []
inspected_frames = 0
addr_regex = r"^10\.53\.0\.[0-9]+:[0-9]{1,5}$"
for line in output.splitlines():
_, _, frame_type, addr1, _, addr2, _ = line.split(" ", 6)
# Only inspect RESOLVER_QUERY and RESOLVER_RESPONSE frames.
if frame_type not in ("RQ", "RR"):
continue
inspected_frames += 1
if not re.match(addr_regex, addr1) or not re.match(addr_regex, addr2):
bad_frames.append(line)

assert (
len(bad_frames) == 0
), "{} out of {} inspected frames contain unexpected addresses:\n\n{}".format(
len(bad_frames), inspected_frames, "\n".join(bad_frames)
)

0 comments on commit 1f5c2ea

Please sign in to comment.