Explain the answer/authority section handling in the man page.
authorMichael Orlitzky <michael@orlitzky.com>
Sun, 28 Jul 2013 20:42:16 +0000 (16:42 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 28 Jul 2013 20:42:16 +0000 (16:42 -0400)
Add the no-append-root option.

doc/man1/haeredes.1
haeredes.cabal
src/CommandLine.hs
src/DNS.hs
src/Main.hs

index facf5cc1f3d076bd1df3bd5f6a4d6816dcfae692..31eeff72981584441d4d998a2ebc6cfb25f0d75f 100644 (file)
@@ -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]
index 8c6754a725933a25220e6da96fc7824e0a3597bf..b53cb947f904983ba3aac0c7385f51f41821d2b9 100644 (file)
@@ -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/:
   .
index 42fcd616a4766ce4950063783ed492d2282663fa..0ea89a0173c56456162c10ab882dc1dc35e84341 100644 (file)
@@ -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"
index a1ed2bdf718790d5fce2aaa77cda275da77eb3f1..02e5a5524b866eb646102a544bcc0719a154080c 100644 (file)
@@ -3,6 +3,7 @@ module DNS (
   lookupMX',
   lookupNS',
   normalize,
+  normalize_case,
   resolve_address )
 where
 
index 4aa0c326de6f5ebbc81bd371a1c46c31dac10bd0..5c6f401f7a5e839b6f5545bd4e4bba91cd6b3195 100644 (file)
@@ -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