                                 NAME

   mararc - Format of the mararc zone file that MaraDNS uses

                          MARARC FILE FORMAT

   Mararc files use a syntax that is a subset of Python 2.2.3
   syntax. In particular, Python 2.2.3 (and possibly other
   versions of Python) can read a properly formatted mararc file
   without error.

   Unlike Python, however, a mararc file can only use certain
   variable names, and the variables can only be declared as
   described below.

                               COMMENTS

   Comments (lines ignored by the MaraDNS parser) start with the
   '#' character, like this:
# This is a comment

   The MaraDNS parser also ignores lines which contain only
   white space.

                              OPERATORS

   The MaraRC file supports two operators: = and +=

   The = operator can be used to assign both numeric and string
   values

   The += operator can only be used on string values, and
   concatenates the value to the right of the += operator to the
   string specified to the left of the += operator.

   Examples:
ipv4_bind_addresses = "10.2.19.83"
ipv4_bind_addresses += ",10.2.66.74"
ipv4_bind_addresses += ",10.3.87.13"

   ipv4_bind_addresses now has the value
   "10.2.19.83,10.2.66.74,10.3.87.13"
ipv4_alias["icann"] = "198.41.0.4"
ipv4_alias["icann"] += ",192.228.79.201"
ipv4_alias["icann"] += ",192.33.4.12,128.8.10.90"

                           MARARC VARIABLES

   Follows is a listing of variables that can be declared in the
   mararc file.

                      DICTIONARY VARIABLE FORMAT

   A dictionary variable is an array that can have multiple
   elements. Unlike a traditional array, these arrays are
   indexed by strings instead of numbers. These are analogous to
   associative arrays, or what Perl somewhat inaccurately calls
   hashes.

   The syntax of a dictionary variable is in the following form:
name["index"] = "value"

   Where name is the name of the dictionary variable, index is
   the index of the array, and value is the value stored at that
   index.

   Every time we have a dictionary-type variable (such as csv2),
   we must first initialize it using a line in the following
   form:
csv2 = {}

   Here, csv2 is the name of the "dictionary" variable that we
   are initializing.

                         DICTIONARY VARIABLES

   Here is a listing of all "dictionary"-style variables that
   MaraDNS uses:

csv2

   The csv2 dictionary variable stores all of the zone names and
   file names for the zone files that MaraDNS uses. Note that
   csv2 files are read after MaraDNS is chrooted. Hence the
   filename is relative to the chroot_dir. Example:
csv2["example.net."] = "db.example.net"

   See csv2(5) for a description of this file's format.

   The dictionary index (zone name) can not have a * in it. If
   it does, MaraDNS will terminate with an "Illegal zone name"
   error.

csv1

   csv1: Used to indicate the filename to use for a given zone
   stored in the legacy csv1 zone file format. This is primarily
   for compatibility with people who have maradns-1.0 zone
   files.
csv1["zone"] = "filename"

   csv1: A pipe-separated-file. See csv1(5).

   zone: the zone that file in question is authoritative for

   filename: the file with the CSV1 zone data

   Note that csv1 files are read after MaraDNS is chrooted, and,
   hence the filename is relative to the chroot_dir.

   See the csv1(5) man page for more information on this file
   format.

ipv4_alias

   ipv4_alias: Used to give nicknames or aliases for ip/netmask
   pairs for ipv4 (standard 32-bit) IP addresses.
ipv4_alias["name"] = "ip1/netmask,ip2/netmask,etc"

   name: The name of the alias in question

   ip: The ip portion of an ip/netmask pair

   netmask: the mask portion of an ip/netmask pair

   ,: Used to separate ip/netmask pairs. Spaces may be placed
   before or after this comma.

   An ip is in dotted-decimal format, e.g. "10.1.2.3".

   The netmask can be in one of two formats: A single number
   between 1 and 32, which indicates the number of leading "1"
   bits in the netmask, or a 4-digit dotted-decimal netmask.

   The netmask is used to specify a range of IPs.

ipv4_alias examples

   10.1.1.1/24 indicates that any ip from 10.1.1.0 to 10.1.1.255
   will match.

   10.1.1.1/255.255.255.0 is identical to 10.1.1.1/24

   10.2.3.4/16 indicates that any ip from 10.2.0.0 to
   10.2.255.255 will match.

   10.2.3.4/255.255.0.0 is identical to 10.2.3.4/16

   127.0.0.0/8 indicates that any ip with "127" as the first
   octet (number) will match.

   127.0.0.0/255.0.0.0 is identical to 127.0.0.0/8

   The netmask is optional, and, if not present, indicates that
   only a single IP will "match". e.g:

   10.9.9.9/32, 10.9.9.9/255.255.255.255, and 10.9.9.9 are all
   functionally identical, and indicate that only the ip
   10.9.9.9 will match.

   The significance of "match" depends on what we use the ipv4
   alias for.

   ipv4 aliases can nest. E.g:
ipv4_alias["susan"] = "10.6.7.8/24"
ipv4_alias["office"] = "susan,10.9.9.9"

   Where "susan" in the "office" alias matches the value of the
   ipv4_alias susan.

   Multiple levels of nesting are allowed. Self-referring nests
   will result in an error.

                        NORMAL VARIABLE FORMAT

   Normal variables. These are variables that can only take a
   single value.

   The syntax of a normal variable is in the form
name = "value"

   Where name is the name of the normal variable, and value is
   the value of the variable in question.

                           NORMAL VARIABLES

   Here is a listing of normal variables that MaraDNS uses:

ipv4_bind_addresses

   ipv4_bind_addresses: The IP addresses to give the MaraDNS
   server.

   This accepts one or more ipv4 IPs in dotted-decimal (e.g.
   "127.0.0.1") notation, and specifies what IP addresses the
   MaraDNS server will listen on. Multiple bind addresses are
   separated with a comma, like this: "10.1.2.3, 10.1.2.4,
   127.0.0.1"

admin_acl

   This is a list of ip/netmask pairs that are allowed to get
   certain administrative information about MaraDNS, including:
     * The version number of MaraDNS running
     * The number of threads MaraDNS has
     * MaraDNS' internal timestamp value

   Note that this information is not available unless the mararc
   variable debug_msg_level is sufficiently high. See the
   information on debug_msg_level below for details on this and
   on the TXT queries sent to get the above information.

bind_address

   bind_address: The IP address to give the MaraDNS server.

   This accepts a single IP in dotted-decimal (e.g. "127.0.0.1")
   notation, and specifies what IP address the MaraDNS server
   will listen on. Note that ipv4_bind_addresses has the same
   functionality. This name is included so that old MaraDNS
   configuration files will continue to work with new MaraDNS
   releases.

bind_star_handling

   In the case where there is both a star record for a given
   name and recordtype, a non-star record with the same name but
   a different recordtype, and no record for the given name and
   recordtype, MaraDNS will usually return the star record.
   BIND, on the other hand, will return a "not there" reply. In
   other words:
     * If a non-A record for foo.example.com exists
     * An A record for *.example.com exists
     * No A record for foo.example.com exists
     * And the user asks for the A record for foo.example.com
     * MaraDNS will usually return the A record attached to
       *.example.com
     * BIND, on the other hand, returns a "not there" for
       foo.example.com

   If the BIND behavior is desired, set bind_star_handling to 1.
   Otherwise, set this to 0. In MaraDNS 1.3, this has a default
   value of 1.

   In addition, if there is a star record that could match any
   given record type, when bind_star_handling is 1, it makes
   sure that MaraDNS does not incorrectly return a NXDOMAIN (RFC
   4074 section 4.2).

   Also, if bind_star_handling has a value of 2, MaraDNS will
   handle the following case exactly as per section 4.3.3 of
   RFC1034:
     * If a record for foo.example.com exists
     * An A record for *.example.com exists
     * And the user asks for the A record for
       bar.foo.example.com
     * MaraDNS will usually return the A record attached to
       *.example.com
     * RFC1034 section 4.3.3 says one should return a NXDOMAIN.

   MaraDNS will exit with a fatal error if bind_star_handling
   has any value besides 0, 1, or 2.

chroot_dir

   chroot_dir: The directory MaraDNS chroots to

   This accepts a single value: The full path to the directory
   to use as a chroot jail.

   Note that csv1 zone files are read after the chroot
   operation. Hence, the chroot jail needs to have any and all
   zone files that MaraDNS will load.

csv2_default_zonefile

   This is a special zone file that allows there to be stars at
   the end of hostnames. This file is similar to a normal csv2
   zone file, but has the following features and limitations:
     * Stars are allowed at the end of hostnames
     * A SOA record is mandatory
     * NS records are mandatory
     * Neither CNAME, FQDN4, nor FQDN6 records are permitted in
       the zone file
     * Delegation NS records are not permitted in the zone file
     * Default zonefiles may not be transferred via zone
       transfer
     * Both recursion and default zonefiles may not be enabled
       at the same time

csv2_synthip_list

   Sometimes the IP list of nameservers will be different than
   the nameservers one is bound to. This allows the synthetic
   nameserver list to have different IPs.

   Note that this may act in an unexpected manner if routable
   and non-routable (localhost and RFC1918) addresses are
   combined; in particular, a list with both routable and
   non-routable addresses will discard the non-routable IP
   addresses, and a list with rfc1918 and localhost addresses
   will discard the localhost addresses.

csv2_tilde_handling

   How the csv2 zone file parser handles tildes (the ~
   character) in csv2 zone files. This is a numeric record, with
   a possible value between 0 and 3 (four possible values). The
   way the csv2 parser acts at different csv2_tilde_handling
   levels:
     * 0) The csv2 parser behaves the same as it does in old
       MaraDNS releases: The tilde has no special significance
       to the parser.
     * 1) A tilde is not allowed anywhere in a csv2 zone file.
     * 2) A tilde is only allowed between records in a csv2 zone
       file. If a tilde is between the first record and the
       second record, a tilde is required to be between all
       records. Otherwise, a tilde is not allowed anywhere in a
       csv2 zone file. The first record can not be a TXT, WKS,
       or LOC record.
     * 3) A tilde is required to be between all records in a
       csv2 zone file.

   The default value for csv2_tilde_handling is 2; this allows
   compatibility with older zone files without tildes while
   allowing zone files to be updated to use the tilde to
   separate resource records.

debug_msg_level

   This is a number indicating what level of information about a
   running MaraDNS process should be made public. When set to 0,
   no information will be made public.

   When set to one (the default), or higher, a Tversion.maradns.
   (TXT query for "version.maradns.") query will return the
   version number of MaraDNS.

   When set to two or higher, a Tnumthreads.maradns. (TXT query
   for "numthreads.maradns.") query will return the number of
   threads that MaraDNS is currently running, and a
   Tcache-elements.maradns. query will return the number of
   elements in MaraDNS' cache.

   If MaraDNS is compiled with debugging information on, a
   Tmemusage.maradns. query will return the amount of memory
   MaraDNS has allocated. Note that the overhead for tracking
   memory usage is considerable and that compiling MaraDNS with
   "make debug" will greatly slow down MaraDNS. A debug build of
   MaraDNS is not recommended for production use.

   When set to three or higher, a Ttimestamp.maradns. query will
   return, in seconds since the UNIX epoch, the timestamp for
   the system MaraDNS is running on.

default_rrany_set

   This variable used to determine what kind of resource records
   were returned when an ANY query was sent. In MaraDNS, the
   data structures have since been revised to return any
   resource record type when an ANY query is sent; this variable
   does nothing, and is only here so that old MaraDNS mararc
   files will continue to work. The only accepted values for
   this variable were 3 and 15.

dns_port

   This is the port that MaraDNS listens on. This is usually 53
   (the default value), but certain unusual MaraDNS setups (such
   as when resolving dangling CNAME records on but a single IP)
   may need to have a different value for this.

dos_protection_level

   If this is set to a non-zero value, certain features of
   MaraDNS will be disabled in order to speed up MaraDNS'
   response time. This is designed for situations when a MaraDNS
   server is receiving a large number of queries, such as during
   a denial of service attack.

   This is a numeric variable; its default value is zero,
   indicating that all of MaraDNS' normal features are enabled.
   Higher numeric values disable more features:
     * A dos_protection_level between 1 and 78 (inclusive)
       disables getting MaraDNS status information remotely.
     * A dos_protection_level of 8 or above disables CNAME
       lookups.
     * A dos_protection_level or 12 or above disables delegation
       NS records.
     * A dos_protection_level of 14 or above disables ANY record
       processing.
     * A dos_protection_level of 18 or above disables star
       record processing at the beginning of hostnames (default
       zonefiles still work, however).
     * A dos_protection_level of 78 disables all authoritative
       processing, including default zonefiles.

   The default level of dos_protection_level is 0 when there are
   one or more zonefiles; 78 when there are no zone files.

ipv6_bind_address

   If MaraDNS is compiled with as an authoritative server, then
   this variable will tell MaraDNS which ipv6 address for the
   UDP server to; for this variable to be set, MaraDNS must be
   bound to at least one ipv4 address.

hide_disclaimer

   If this is set to "YES", MaraDNS will not display the legal
   disclaimer when starting up.

long_packet_ipv4

   This is a list of IPs which we will send UDP packets longer
   than the 512 bytes RFC1035 permits if necessary. This is
   designed to allow zoneserver, when used send regular DNS
   packets over TCP, to receive packets with more data than can
   fit in a 512-byte DNS packet.

   This variable only functions if MaraDNS is compiled as an
   authoritative only server.

maradns_uid

   maradns_uid: The numeric UID that MaraDNS will run as

   This accepts a single numerical value: The UID to run MaraDNS
   as.

   MaraDNS, as soon as possible drops root privileges,
   minimizing the damage a potential attacker can cause should
   there be a security problem with MaraDNS. This is the UID
   maradns becomes.

   The default UID is 99.

maradns_gid

   maradns_gid: The numeric GID that MaraDNS will run as.

   This accepts a single numerical value: The GID to run MaraDNS
   as.

   The default GID is 99.

max_ar_chain

   max_ar_chain: The maximum number of records to display if a
   record in the additional section (e.g., the IP of a NS server
   or the ip of a MX exchange) has more than one value.

   This is similar to max_chain, but applies to records in the
   "additional" (or AR) section.

   Due to limitations in the internal data structures that
   MaraDNS uses to store RRs, if this has a value besides one,
   round robin rotates of records are disabled.

   The default value for this variable is 1.

max_chain

   max_chain: The maximum number of records to display in a
   chain of records.

   With DNS, it is possible to have more than one RR for a given
   domain label. For example, "example.com" can have, as the A
   record, a list of multiple ip addresses.

   This sets the maximum number of records MaraDNS will show for
   a single RR.

   MaraDNS normally round-robin rotates records. Hence, all
   records for a given DNS label (e.g. "example.com.") will be
   visible, although not at the same time if there are more
   records than the value allowed with max_chain

   The default value for this variable is 8.

max_tcp_procs

   max_tcp_procs: The (optional) maximum number of processes the
   zone server is allowed to run.

   Sometimes, it is desirable to have a different number of
   maximum allowed tcp processes than maximum allowed threads.
   If this variable is not set, the maximum number of allowed
   tcp processes is "maxprocs".

max_total

   max_total: The maximum number of records to show total for a
   given DNS request.

   This is the maximum total number of records that MaraDNS will
   make available in a DNS reply.

   The default value for this variable is 20.

max_mem

   max_mem is the maximum amount of memory we allow MaraDNS to
   allocate, in bytes.

   The default value of this is to allocate 2 megabytes for
   MaraDNS' general use, and in addition, to allocate 3072 bytes
   for each element we can have in the cache or DNS record that
   we are authoritatively serving.

min_visible_ttl

   min_visible_ttl: The minimum value that we will will show as
   the TTL (time to live) value for a resource record to other
   DNS servers and stub resolvers. In other words, this is the
   minimum value we will ask other DNS server to cache (keep in
   their memory) a DNS resource record.

   The value is in seconds. The default value for this is 30;
   the minimum value this can have is 5.

   As an aside, RFC1123 section 6.1.2.1 implies that zero-length
   TTL records should be passed on with a TTL of zero. This,
   unfortunately, breaks some stub resolvers (such as Mozilla's
   stub resolver).

remote_admin

   remote_admin: Whether we allow verbose_level to be changed
   after MaraDNS is started.

   If remote_admin is set to 1, and admin_acl is set, any and
   all IPs listed in admin_acl will be able to reset the value
   of verbose_level from any value between 0 and 9 via a TXT
   query in the form of 5.verbose_level.maradns. What this will
   do is set verbose_query to the value in the first digit of
   the query.

   This is useful when wishing to temporarily increase the
   verbose_level to find out why a given host name is not
   resolving, then decreasing verbose_level so as to minimize
   the size of MaraDNS' log.

synth_soa_origin

   When a CSV2 zone file doesn't have a SOA record in it,
   MaraDNS generates a SOA record on the fly. This variable
   determines the host name for the "SOA origin" (which is
   called the MNAME in RFC1035); this is the host name of the
   DNS server which has the "master copy" of a given DNS zone's
   file.

   This host name is in human-readable format without a trailing
   dot, e.g.:
synth_soa_origin = "ns1.example.com"

   If this is not set, a synthetic SOA record will use the name
   of the zone for the SOA origin (MNAME) field.

synth_soa_serial

   This determines whether we strictly follow RFC1912 section
   2.2 with SOA serial numbers. If this is set to 1 (the default
   value), we do not strictly follow RFC1912 section 2.2 (the
   serial is a number, based on the timestamp of the zone file,
   that is updated every six seconds), but this makes it so that
   a serial number is guaranteed to be automatically updated
   every time one edits a zone file.

   If this is set to 2, the SOA serial number will be in
   YYYYMMDDHH format, where YYYY is the 4-digit year, MM is the
   2-digit month, DD is the 2-digit day, and HH is the 2-digit
   hour of the time the zone file was last updated (GMT;
   localtime doesn't work in a chroot() environment). While this
   format is strictly RFC1912 compliant, the disadvantage is
   that more than one edit to a zone file in an hour will not
   update the serial number.

   I strongly recommend, unless it is extremely important to
   have a DNS zone that generates no warnings when tested at
   dnsreport.com, to have this set to 1 (the default value).
   Having this set to 2 can result in updated zone files not
   being seen by slave DNS servers.

   Note that synth_soa_serial can only have a value of 1 on the
   native Windows port.

tcp_convert_acl

   This only applies to the zoneserver (general DNS-over-TCP)
   program.

   This is a list of IPs which are allowed to connect to the
   zoneserver and send normal TCP DNS requests. The zoneserver
   will convert TCP DNS requests in to UDP DNS requests, and
   send the UDP request in question to the server specified in
   tcp_convert_server. Once it gets a reply from the UDP DNS
   server, it will convert the reply in to a TCP request and
   send the reply back to the original TCP client.

   Whether the RD (recursion desired) flag is set or not when
   converting a TCP DNS request in to a UDP DNS request is
   determined by whether the TCP client is on the recursive_acl
   list. Since MaraDNS 2.0 does not have recursion, the maradns
   daemon ignores the RD bit (Deadwood will not process any
   queries without the RD bit set).

tcp_convert_server

   This only applies to the zoneserver (general DNS-over-TCP)
   program.

   This is the UDP server which we send a query to when
   converting DNS TCP queries in to DNS UDP servers. Note that,
   while this value allows multiple IPs, all values except the
   first one are presently ignored.

timestamp_type

   timestamp_type: The type of timestamp to display. The main
   purpose of this option is to suppress the output of
   timestamps. Since duende uses syslog() to output data, and
   since syslog() adds its own timestamp, this option should be
   set to 5 when maradns is invoked with the duende tool.

   This option also allows people who do not use the duende tool
   to view human-readable timestamps. This option only allows
   timestamps in GMT, due to issues with showing local times in
   a chroot() environment.

   This can have the following values:

   0
          The string "Timestamp" followed by a UNIX timestamp

   1
          Just the bare UNIX timestamp

   2
          A GMT timestamp in the Spanish language

   3
          A (hopefully) local timestamp in the Spanish language

   4
          A timestamp using asctime(gmtime()); usually in the
          English language

   5
          No timestamp whatsoever is shown (this is the best
          option when maradns is invoked with the duende tool).

   6
          ISO GMT timestamp is shown

   7
          ISO local timestamp is shown

   The default value for this variable is 5.

verbose_level

   verbose_level: The number of messages we log to stdout

   This can have five values:

   0
          No messages except for the legal disclaimer and fatal
          parsing errors

   1
          Only startup messages logged (Default level)

   2
          Error queries logged

   3
          All queries logged

   4
          All actions adding and removing records from the cache
          logged

   The default value for this variable is 1.

zone_transfer_acl

   zone_transfer_acl: List of ips allowed to perform zone
   transfers with the zone server

   The format of this string is identical to the format of an
   ipv4_alias entry.

                         EXAMPLE MARARC FILE

# Example mararc file (unabridged version)

# The various zones we support

# We must initialize the csv2 hash, or MaraDNS will be unable to
# load any csv2 zone files
csv2 = {}

# This is just to show the format of the file
#csv2["example.com."] = "db.example.com"

# The address this DNS server runs on.  If you want to bind
# to multiple addresses, separate them with a comma like this:
# "10.1.2.3,10.1.2.4,127.0.0.1"
ipv4_bind_addresses = "127.0.0.1"
# The directory with all of the zone files
chroot_dir = "/etc/maradns"
# The numeric UID MaraDNS will run as
maradns_uid = 99
# The (optional) numeric GID MaraDNS will run as
# maradns_gid = 99

# Normally, MaraDNS has some MaraDNS-specific features, such as DDIP
# synthesizing, a special DNS query ("erre-con-erre-cigarro.maradns.or
g."
# with a TXT query returns the version of MaraDNS that a server is
# running), unique handling of multiple QDCOUNTs, etc.  Some people
# might not like these features, so I have added a switch that lets
# a sys admin disable all these features.  Just give "no_fingerprint"
# a value of one here, and MaraDNS should be more or less
# indistinguishable from a tinydns server.
no_fingerprint = 0

# These constants limit the number of records we will display, in orde
r
# to help keep packets 512 bytes or smaller.  This, combined with roun
d_robin
# record rotation, help to use DNS as a crude load-balancer.

# The maximum number of records to display in a chain of records (list
# of records) for a given host name
max_chain = 8
# The maximum number of records to display in a list of records in the
# additional section of a query.  If this is any value besides one,
# round robin rotation is disabled (due to limitations in the current
# data structure MaraDNS uses)
max_ar_chain = 1
# The maximum number of records to show total for a given question
max_total = 20

# The number of messages we log to stdout
# 0: No messages except for fatal parsing errors and the legal disclai
mer
# 1: Only startup messages logged (default)
# 2: Error queries logged
# 3: All queries logged (but not very verbosely right now)
verbose_level = 1

# Here is a ACL which restricts who is allowed to perform zone transfe
r from
# the zoneserver program

# Simplest form: 10.1.1.1/24 (IP: 10.1.1.1, 24 left bits in IP need to
 match)
# and 10.100.100.100/255.255.255.224 (IP: 10.100.100.100, netmask
# 255.255.255.224) are allowed to connect to the zone server
# NOTE: The "maradns" program does not serve zones.  Zones are served
# by the "zoneserver" program.
#zone_transfer_acl = "10.1.1.1/24, 10.100.100.100/255.255.255.224"



                                 BUGS

   If one should declare the same the same index twice with a
   dictionary variable, MaraDNS will exit with a fatal error.
   This is because earlier versions of MaraDNS acted in a
   different manner than Python 2.3.3. With Python 2.3.3, the
   last declaration is used, while MaraDNS used to use the first
   declaration.

                           LEGAL DISCLAIMER

   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY
   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
   DAMAGE.
