From 7cc26ab4bfa90c4abe0c741d5a3eaf575544466a Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 28 Jul 2013 16:42:16 -0400 Subject: [PATCH] Explain the answer/authority section handling in the man page. Add the no-append-root option. --- doc/man1/haeredes.1 | 59 ++++++++++++++++++++++++++++++++++++++++++--- haeredes.cabal | 3 ++- src/CommandLine.hs | 33 ++++++++++++++++++++----- src/DNS.hs | 1 + src/Main.hs | 14 ++++++++--- 5 files changed, 96 insertions(+), 14 deletions(-) diff --git a/doc/man1/haeredes.1 b/doc/man1/haeredes.1 index facf5cc..31eeff7 100644 --- a/doc/man1/haeredes.1 +++ b/doc/man1/haeredes.1 @@ -32,11 +32,64 @@ important to remove domains from the old mail host as soon as the MX record is changed. .P Haeredes can alert administrators when NS/MX records are changed. +.SH NORMALIZATION +.P +By default, domain/hostnames given will be normalized in two ways: +.IP \[bu] 2 +All names will be lowercased. + +.IP \[bu] +All names will have a trailing dot (the DNS root) appended if one is +not present. This can be controlled with the +\fB\-\-no\-append\-root\fR flag. +.SH QUERY RESULTS +.P +When Haeredes makes a query for an MX record, the result is parsed +from the \(dqanswer\(dq section of the response. This is +straightforward. +.P +For NS records, however, there are two sections that may contain +results. If you query the authoritative nameservers for example.com, +they will return the response in the \(dqanswer\(dq section, as with +MX records: + +.nf +.I $ dig +short @a.iana-servers.net example.com NS +b.iana-servers.net. +a.iana-servers.net. +.fi +.P +However, if you ask a root server, they will return the response in another section, called \(dqauthority\(dq. The \(dqanswer\(dq section is empty: + +.nf +.I $ dig +short @a.gtld-servers.net example.com NS +.fi +.P +We have to request the \(dqauthority\(dq section explicitly: + +.nf +.I $ dig +noall +authority @a.gtld-servers.net example.com NS +example.com. 172800 IN NS a.iana-servers.net. +example.com. 172800 IN NS b.iana-servers.net. +.fi +.P +Given Haeredes' use case, it is useful to combine the two. You can +query a root server to check the registrar data, or a recursive +resolver to check the data on the authoritative nameservers. +.P +So that's what we do. In NS mode, Haeredes will check both the +\(dqanswer\(dq and \(dqauthority\(dq sections for results. .SH OPTIONS +.IP \fB\-\-no\-append\-root\fR,\ \fB-n\fR +Don't append a trailing dot to any DNS names. If you know what you're +doing, this can be used to check relative results. Otherwise, it will +probably just lead to false positives. +.SH EXAMPLES + .IP \fB\-\-server\fR,\ \fB-s\fR Use the given DNS server rather than the resolvers listed in -/etc/resolv.conf. +/etc/resolv.conf. Either an IP address or a hostname will work. .SH EXAMPLES .IP \[bu] 2 @@ -48,10 +101,10 @@ Make sure example.com has the expected name servers, .fi .IP \[bu] Check orlitzky.com against the expected name servers, using -d.gtld-servers.net: +a root nameserver (this checks the registrar configuration): .nf -.I $ haeredes --server 199.7.91.13 dns1.viabit.com dns2.viabit.com \\\\ +.I $ haeredes --server d.gtld-servers.net dns1.viabit.com dns2.viabit.com \\\\ .I " <<< \(dqorlitzky.com\(dq" .fi .IP \[bu] diff --git a/haeredes.cabal b/haeredes.cabal index 8c6754a..b53cb94 100644 --- a/haeredes.cabal +++ b/haeredes.cabal @@ -32,7 +32,8 @@ description: therefore important to remove domains from the old mail host as soon as the MX record is changed. . - Haeredes can alert administrators when NS/MX records are changed. + Haeredes can alert administrators when NS/MX records are changed. More + detail can be found in the man page. . /Examples/: . diff --git a/src/CommandLine.hs b/src/CommandLine.hs index 42fcd61..0ea89a0 100644 --- a/src/CommandLine.hs +++ b/src/CommandLine.hs @@ -30,11 +30,13 @@ import System.Console.CmdArgs ( import Paths_haeredes (version) import Data.Version (showVersion) +-- | Description of the 'NS' mode. ns_description :: String ns_description = "Confirm delegation of NS records. " ++ "This is the default mode." +-- | Description of the 'MX' mode. mx_description :: String mx_description = "Confirm delegation of MX records." @@ -44,14 +46,26 @@ program_name = "haeredes" my_summary :: String my_summary = program_name ++ "-" ++ (showVersion version) +no_append_root_help :: String +no_append_root_help = + "Don't append a trailing dot to DNS names." + +-- | Help string for the --server flag. server_help :: String server_help = - "IP address of server to query " ++ - "(will use resolv.conf if not specified)" + "IP address or hostname of server to query " ++ + "(will use resolv.conf if not specified)." +-- | The Args type represents the possible command-line options. The +-- duplication here seems necessary; CmdArgs' magic requires us to +-- define some things explicitly. data Args = - NS { server :: Maybe String, delegates :: [String] } | - MX { server :: Maybe String, delegates :: [String] } + NS { no_append_root :: Bool, + server :: Maybe String, + delegates :: [String] } | + MX { no_append_root :: Bool, + server :: Maybe String, + delegates :: [String] } deriving (Data, Show, Typeable) arg_spec :: Args @@ -68,10 +82,13 @@ arg_spec = name "v", groupname "Common flags"] where - -- The repetition here is necessary, some Template Haskell magic - -- going on. + -- The repetition here is necessary, some CmdArgs magic going on. ns :: Args ns = NS { + no_append_root = def + &= groupname "Common flags" + &= help no_append_root_help, + server = def &= groupname "Common flags" &= typ "IP" @@ -85,6 +102,10 @@ arg_spec = mx :: Args mx = MX { + no_append_root = def + &= groupname "Common flags" + &= help no_append_root_help, + server = def &= groupname "Common flags" &= typ "IP" diff --git a/src/DNS.hs b/src/DNS.hs index a1ed2bd..02e5a55 100644 --- a/src/DNS.hs +++ b/src/DNS.hs @@ -3,6 +3,7 @@ module DNS ( lookupMX', lookupNS', normalize, + normalize_case, resolve_address ) where diff --git a/src/Main.hs b/src/Main.hs index 4aa0c32..5c6f401 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -28,6 +28,7 @@ import DNS ( lookupMX', lookupNS', normalize, + normalize_case, resolve_address ) import ExitCodes (exit_bad_server) @@ -63,9 +64,14 @@ main = do -- Convert these to ByteStrings. let raw_delegates = map BS.pack (delegates cfg) + let normalize_function = + if (no_append_root cfg) + then normalize_case + else normalize + -- Normalize the given names and delegates - let nrml_domains = map normalize raw_domains - let nrml_delegates = map normalize raw_delegates + let nrml_domains = map normalize_function raw_domains + let nrml_delegates = map normalize_function raw_delegates rc <- case (server cfg) of Nothing -> return defaultResolvConf @@ -82,8 +88,8 @@ main = do rs <- makeResolvSeed rc let lookup_function = case cfg of - (NS _ _) -> lookupNS' - (MX _ _) -> lookupMX' + (NS _ _ _) -> lookupNS' + (MX _ _ _) -> lookupMX' _ <- withResolver rs $ \resolver -> do -- Bad stuff happens if we try to run these lookups in parallel -- 2.44.2