Unlike Python, however, a mararc file can only use certain variable names, and the variables can only be declared as described below.
# This is a commentThe MaraDNS parser also ignores lines which contain only white space.
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"
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.
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["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["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.
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.
root_servers["."] = "list_of_servers"In this example, "." indicates that this is a listing of root_servers that will resolve any name not otherwise listed as a root_servers entry.
list_of_servers is a list of root name servers in the exact same format as ipv4_aliases.
The root_servers dictionary array can have multiple elements. Like csv2 elements, the names must be valid domain names that end with the '.' character. When there are multiple root_servers elements, the element with the most domain name labels that matches the end of the hostname one is searching for is used.
For example, let us suppose we have the following root_servers entries:
root_servers["."] = "198.41.0.4" root_servers["com."] = "192.5.6.30" root_servers["example.net."] = "10.1.2.3,10.2.3.4"In this example, we use use the name server with the IP 10.1.2.3 or 10.2.3.4 to start resolving "www.example.net", the name server with the IP 192.5.6.30 to start resolving "www.google.com", and the name server with the IP 198.41.0.4 to start resolving "www.maradns.org".
Note that, while ips in a listing of root name servers can have netmasks, the netmask portion is ignored.
The root_servers should point to root servers. If one wishes to use MaraDNS as a forwarding name server, which forwards DNS requests on to another server, use the upstream_servers variable instead.
Note that one can not have both root_servers and upstream_servers set in a given mararc file; MaraDNS will return with a fatal error if one attempts to do this.
Like root_servers, this is a dictionary variable that can have multiple elements. For example:
upstream_servers["."] = "10.5.6.7" upstream_servers["cl."] = "10.2.19.83"Here, we use 10.2.19.83 to resolve host names that end in "cl", and 10.5.6.7 to resolve all other host names.
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.
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"
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.
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:
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.
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.
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.
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:
This variable only functions if MaraDNS is compiled as an authoritative only server.
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.
This accepts a single numerical value: The GID to run MaraDNS as.
The default GID is 99.
This cache of recursive queries is used to store entries we have previously obtained from recursive queries.
If we approach this limit, the "custodian" kicks in to effect. The custodian removes elements at random from the cache (8 elements removed per query) until we are at the 99% or so level again.
The default value for this variable is 1024.
This variable is used to minimize the impact on the server when MaraDNS is heavily loaded. When this number is reached, it is impossible for MaraDNS to spawn new threads/processes until the number of threads/processes is reduced.
The default value for this variable is 64.
The maximum value this can have is 500.
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.
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.
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".
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.
The default value of this is to allocate 1 megabyte for MaraDNS' general use, and in addition, to allocate 1536 bytes for each element we can have in the cache or DNS record that we are authoritatively serving.
Setting this value changes the minimum amount of time MaraDNS' recursive server will keep a record in the cache. The value is in seconds.
The default value of this is 300 (5 minutes); the minimum value for this is 180 (2 minutes).
Setting this value changes the amount of time a CNAME record stays in the cache. The value is in seconds.
The default value for this is the value min_ttl has; the minimum value for this is 180 (2 minutes).
The value is in seconds. The default value for this is 30; the minimum value this can have is 5. People running highly loaded MaraDNS servers may wish to increase this value to 3600 (one hour) in order to reduce the number of queries recursively processed by MaraDNS.
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).
For example, if one wishes to send the IP 10.11.12.13 to clients whenever MaraDNS' recursive resolver gets a "this host does not exist" reply, set notthere_ip thusly:
notthere_ip = "10.11.12.13"
If one also wishes to have this IP returned when there is no reply from remote DNS servers, set handle_noreply thusly:
handle_noreply = 2
This parameter only affects the recursive resolver, and doesn't affect authoritative zones that MaraDNS serves. This parameter only affects A queries, and doesn't affect other DNS query types.
The location of this file is relative to the root of the filesystem, not MaraDNS' chroot directory.
This is ideally a file which is a good source of random numbers (e.g. /dev/urandom), but can also be a fixed file if your OS does not have a decent random number generator. In that case, make sure the contents of that file is random and with 600 perms, owned by root. We read the file before dropping root privileges.
When recurse_delegation has a value of 1, we recurse in this case. Otherwise, we do not.
This parameter has a default value of 0.
recurse_min_bind_port is the lowest port number that MaraDNS will bind to when making recursive queries. The default value for this is 15000.
This number must be a power of 2 between 256 and 32768. In other words, this must have the value 256, 512, 1024, 2048, 4096, 8192, 16384, or 32768. The default value for this is 4096.
The sum of the values for recurse_min_bind_port + recurse_number_ports must fit within the 16-bit value used for UDP ports. In other words, these two parameters, added together, can not be greater than 65534.
The format of this string is identical to the format of an ipv4_alias entry.
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.
This is mainly used to not allow spam-friendly domains to resolve, since spammers are starting to get in the habit of using spam-friendly DNS servers to resolve their domains, allowing them to hop from ISP to ISP.
The format of this string is identical to the format of an ipv4_alias entry.
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.
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.
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.
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.
The amount of time, in seconds, to wait for a reply from a remote DNS server before giving up and trying the next server on this list. The default value is 2 seconds.
This is for setups where a recursive MaraDNS server is on a slow network which takes more than two seconds to send and receive a DNS packet.
Note that, the larger this value is, the slower MaraDNS will process recursive queries when a DNS server is not responding to DNS queries.
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:
The default value for this variable is 5.
This can have five values:
The default value for this variable is 1.
This is mainly used for debugging.
The format of this string is identical to the format of an ipv4_alias entry.
# 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 # The maximum number of threads (or processes, with the zone server) # MaraDNS is allowed to run maxprocs = 96 # It is possible to specify a different maximum number of processes that # the zone server can run. If this is not set, the maximum number of # processes that the zone server can have defaults to the 'maxprocs' value # above # max_tcp_procs = 64 # Normally, MaraDNS has some MaraDNS-specific features, such as DDIP # synthesizing, a special DNS query ("erre-con-erre-cigarro.maradns.org." # 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 # Normally, MaraDNS only returns A and MX records when given a # QTYPE=* (all RR types) query. Changing the value of default_rrany_set # to 15 causes MaraDNS to also return the NS and SOA records, which # some registrars require. The default value of this is 3 default_rrany_set = 3 # These constants limit the number of records we will display, in order # to help keep packets 512 bytes or smaller. This, combined with round_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 disclaimer # 1: Only startup messages logged (default) # 2: Error queries logged # 3: All queries logged (but not very verbosely right now) verbose_level = 1 # Initialize the IP aliases, which are used by the list of root name servers, # the ACL for zone transfers, and the ACL of who gets to perform recursive # queries ipv4_alias = {} # Various sets of root name servers # Note: Netmasks can exist, but are ignored when specifying root name server # ICANN: the most common and most controversial root name server # http://www.icann.org # This list can be seen at http://www.root-servers.org/ ipv4_alias["icann"] = "198.41.0.4, 192.228.79.201, 192.33.4.12, 128.8.10.90," ipv4_alias["icann"] += "192.203.230.10, 192.5.5.241, 192.112.36.4," ipv4_alias["icann"] += "128.63.2.53, 192.36.148.17, 192.58.128.30," ipv4_alias["icann"] += "193.0.14.129, 199.7.83.42, 202.12.27.33" # OpenNIC: http://www.opennic.unrated.net/ # Current as of 2005/11/30; these servers change frequently so please # look at their web page ipv4_alias["opennic"] = "157.238.46.24, 209.104.33.250, 209.104.63.249," ipv4_alias["opennic"] += "130.94.168.216, 209.21.75.53, 64.114.34.119," ipv4_alias["opennic"] += "207.6.128.246, 167.216.255.199, 62.208.181.95," ipv4_alias["opennic"] += "216.87.153.98, 216.178.136.116" # End of list of root name server lists # Here is a ACL which restricts who is allowed to perform zone transfer 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" # More complex: We create two aliases: One called "office" and another # called "home". We allow anyone in the office or at home to perform zone # transfers #ipv4_alias["office"] = "10.1.1.1/24" #ipv4_alias["home"] = "10.100.100.100/255.255.255.224" #zone_transfer_acl = "office, home" # More complex then the last example. We have three employees, # Susan, Becca, and Mia, whose computers we give zone transfer rights to. # Susan and Becca are system administrators, and Mia is a developer. # They are all part of the company. We give the entire company zone # transfer access #ipv4_alias["susan"] = "10.6.7.8/32" # Single IP allowed #ipv4_alias["becca"] = "10.7.8.9" # also a single IP #ipv4_alias["mia"] = "10.8.9.10/255.255.255.255" # Also a single IP #ipv4_alias["sysadmins"] = "susan, becca" #ipv4_alias["devel"] = "mia" #ipv4_alias["company"] = "sysadmins, devel" # This is equivalent to the above line #ipv4_alias["company"] = "susan, becca, mia" #zone_transfer_acl = "company" # If you want to enable recursion on the loopback interface, uncomment # the relevant lines in the following section # Recursive ACL: Who is allowed to perform recursive queries. The format # is identical to that of "zone_transfer_acl", including ipv4_alias support #ipv4_alias["localhost"] = "127.0.0.0/8" #recursive_acl = "localhost" # Random seed file: The file from which we read 16 bytes from to get the # 128-bit random Rijndael key. This is ideally a file which is a good source # of random numbers, but can also be a fixed file if your OS does not have # a decent random number generator (make sure the contents of that file is # random and with 600 perms, owned by root, since we read the file *before* # dropping root privileges) #random_seed_file = "/dev/urandom" # The maximum number of elements we can have in the cache. If we have more # elements in the cache than this amount, the "custodian" kicks in to effect, # removing elements not recently accessed from the cache (8 elements removed # per query) until we are at the 99% level or so again. #maximum_cache_elements = 1024 # It is possible to change the minimal "time to live" for entries in the # cache; this is the minimum time that an entry will stay in the cache. # Value is in seconds; default is 300 (5 minutes) #min_ttl = 300 # CNAME records generally take more effort to resolve in MaraDNS than # non-CNAME records; it is a good idea to make this higher then min_ttl # default value is to be the same as min_ttl #min_ttl_cname = 900 # The root servers which we use when making recursive queries. # The following line must be uncommented to enable custom root servers # for recursive queries #root_servers = {} # You can choose which set of root servers to use. Current values (set above) # are: icann, osrc, alternic, opennic, pacificroot, irsc, tinc, and # superroot. #root_servers["."] = "icann" # If you prefer to contact other recursive DNS servers instead of the ICANN # root servers, this is done with the upstream_servers mararc variable: #upstream_servers["."] = "192.168.0.1, 192.168.0.2" # You can tell MaraDNS to *not* query certain DNS servers when in recursive # mode. This is mainly used to not allow spam-friendly domains to resolve, # since spammers are starting to get in the habit of using spam-friendly # DNS servers to resolve their domains, allowing them to hop from ISP to # ISP. The format of this is the same as for zone_transfer_acl and # recursive_acl # For example, at the time of this document (August 12, 2001), azmalink.net # is a known spam-friendly DNS provider (see doc/detailed/spammers/azmalink.net # for details.) Note that this is based on IPs, and azmalink.net constantly # changes IPs (as they constantly have to change ISPs) # 2002/10/12: Azmalink changed ISP again, this reflect their current ISP ipv4_alias["azmalink"] = "12.164.194.0/24" # As of September 20, 2001, hiddenonline.net is a known spam-friendly # DNS provider (see doc/detailed/spammers/hiddenonline for details). ipv4_alias["hiddenonline"] = "65.107.225.0/24" spammers = "azmalink,hiddenonline" # It is also possible to change the maximum number of times MaraDNS will # follow a CNAME record or a NS record with a glue A record. The default # value for this is ten. #max_glueless_level = 10 # In addition, one can change the maximum number of total queries that # MaraDNS will perform to look up a host name. The default value is 32. #max_queries_total = 32 # In addition, one can change the amount of time that MaraDNS will wait # for a DNS server to respond before giving up and trying the next DNS # server on a list. Note that, the larger this value is, the slower # MaraDNS will process recursive queries when a DNS server is not # responding to DNS queries. The default value is two seconds. #timeout_seconds = 2 # And that does it for the caching at this point