From 05138dabc36ca8f2b3f5e2326e56f8952c481504 Mon Sep 17 00:00:00 2001 From: Bert Van Vreckem Date: Sun, 16 Jun 2024 14:05:11 +0200 Subject: [PATCH] Update module about BIND --- modules/dns_bind/030-content.md | 326 +++++++++- modules/dns_bind/040-practice.md | 35 +- .../assets/dns_authoritative_zone.jpg | Bin .../dns_bind/assets/dns_bind_lab_setup.png | Bin 0 -> 26651 bytes .../assets/dns_forwarder.jpg | Bin .../assets/dns_master_slave.jpg | Bin .../assets/dns_primary_secondary.jpg | Bin .../assets/dns_zone_transfer.jpg | Bin .../assets/dns_zone_transfer_pic.jpg | Bin modules/dns_bind/dns_old_theory.md | 579 ------------------ 10 files changed, 332 insertions(+), 608 deletions(-) rename modules/{dns => dns_bind}/assets/dns_authoritative_zone.jpg (100%) create mode 100644 modules/dns_bind/assets/dns_bind_lab_setup.png rename modules/{dns => dns_bind}/assets/dns_forwarder.jpg (100%) rename modules/{dns => dns_bind}/assets/dns_master_slave.jpg (100%) rename modules/{dns => dns_bind}/assets/dns_primary_secondary.jpg (100%) rename modules/{dns => dns_bind}/assets/dns_zone_transfer.jpg (100%) rename modules/{dns => dns_bind}/assets/dns_zone_transfer_pic.jpg (100%) delete mode 100644 modules/dns_bind/dns_old_theory.md diff --git a/modules/dns_bind/030-content.md b/modules/dns_bind/030-content.md index 857603b..35f5b18 100644 --- a/modules/dns_bind/030-content.md +++ b/modules/dns_bind/030-content.md @@ -2,17 +2,49 @@ There are several types of DNS servers, each with its own purpose. The most common types are: -- **Authoritative:** this type of server is the "source of truth" for a specific *DNS zone*. Authoritative servers can be **primary** or **secondary[^primary_secondary] servers**. A *primary server* has a *zone file* that contains all the resource records for the zone. A *secondary server* replicates the zone data from the primary server through a *zone transfer*. When a query is made for a record in the zone, the authoritative server returns the answer. +### Authoritative name server + +This type of server is the "source of truth" for a specific *DNS zone*. When a query is made for a record in the zone, the authoritative server returns the answer. **Authoritative** servers can be **primary** or **secondary[^primary_secondary] servers**. A *primary server* is the first authoritative DNS server for a domain, and it has a (human readable) *zone file* that contains all the resource records for the zone. + +For reasons of fault tolerance, performance or load balancing you may decide to set up another *DNS server* with authority over that zone. This is called a *secondary* dns server. A *secondary server* replicates the zone data from the primary server through a *zone transfer* (and stores it in a binary format). [^primary_secondary]: The old nomenclature of *master* and *slave* servers is being phased out due to its negative connotations. The terms *primary* and *secondary* are now preferred. -- **Caching:** this type of server caches responses to queries it receives. When a query is made, the caching server first checks its cache to see if it has the answer. If it does, it returns the cached response. If not, it starts a ***recursive query.*** In a recursive query, the resolver will query a root server for the DNS server responsible for the top-level domain of the query. It will then query that server for the DNS server responsible for the second-level domain, and so on, until it gets the answer to the original query. The caching server will cache the response to the original query for a certain amount of time (the *TTL* or *Time To Live* value of the record). +![](assets/dns_authoritative_zone.jpg) + +![](assets/dns_primary_secondary.jpg) + +### Caching name server + +This type of server is not authoritative, but passes on the query to another server and then caches responses to queries it receives. + +When a query is made, the caching server first checks its cache to see if it has the answer. If it does, it returns the cached response. If not, it starts an **iterative query.** In an iterative query, the resolver will query a root server for the DNS server responsible for the top-level domain of the query. It will then query that server for the authoritative DNS server for the second-level domain, and so on, until it gets the answer to the original query. The caching server will cache the response to the original query for a certain amount of time (the *TTL* or *Time To Live* value of the record). Subsequent queries for the same record will be answered from the cache. + +For example, a client queries for the A record on *www.linux-training.be* to its local server stored in `/etc/resolv.conf`. This is the first query ever received by this local server. The local server checks that it is not authoritative for the linux-training.be domain, nor for the *.be TLD*, and it is also not a root server. So the local server will use the root hints to send an *iterative* query to a root server. + +The root server will reply with a reference to the server that is authoritative for the .be domain (root DNS servers do not resolve fqdn's, and root servers do not respond to recursive queries). + +The local server will then send an iterative query to the authoritative server for the *.be tld*. This server will respond with a reference to the name server that is authoritative for the *linux-training.be* domain. + +The local server will then sent the query for *www.linux-training.be* to the authoritative server (or one of its slave servers) for the *linux-training.be* domain. When the local server receives the ip address for *www.linux-training.be*, then it will provide this information to the client that submitted this query. + +Besides caching the A record for *www.linux-training.be*, the local server will also cache the NS and A record for the *linux-training.be* name server and the .be name server. + +### Forwarding name server + +A **Forwarding name server** is not authoritative, but it forwards queries to other servers. The DNS server of a VirtualBox NAT interface is an example of a forwarding server that passes on queries of the VM to the DNS server of the physical machine. + +### Stealth name server + +This type of server is hidden from the public and is used for internal purposes. It is not listed in the publicly visible NS records for a domain. **Stealth servers** are used for DNS resolution of network services for internal use and are not accessible from the internet. + +For example, a company might have an intranet webserver with hostname `intranet.company.com` that is only accessible from within the company network. The RRs for this host would only be available from the internal stealth DNS server, but not from the public authoritative DNS server for `company.com`. -- **Forwarding:** this type of server is not authoritative, but it forwards queries to other servers. The DNS server of a VirtualBox NAT interface is an example of a forwarding server that passes on queries of the VM to the DNS server of the physical machine. +### Split horizon server -- **Stealth:** this type of server is hidden from the public and is used for internal purposes. It is not listed in the publicly visible NS records for a domain. Stealth servers are used for DNS resolution of network services for internal use and are not accessible from the internet. For example, a company might have an intranet webserver with hostname `intranet.company.com` that is only accessible from within the company network. The RRs for this host would only be available from the internal stealth DNS server, but not from the public authoritative DNS server for `company.com`. +This type of server provides different responses to queries based on the source of the query. For example, a **split horizon server** might return different IP addresses for a domain based on whether the query is coming from inside or outside the local network. -- **Split horizon:** this type of server provides different responses to queries based on the source of the query. For example, a split horizon server might return different IP addresses for a domain based on whether the query is coming from inside or outside the local network. +### Best practices A DNS server, depending on how it is configured, can have one or more properties from the above list. For example, a server can be both authoritative and caching, it can be caching and forwarding, or both primary and secondary (for different domains). @@ -34,11 +66,11 @@ The default installation of BIND is a caching ony name server without a forwarde #### caching only server without forwarder -A caching only server without forwarder will have to get information elsewhere. When it receives a query from a client, then it will consult one of the *root servers*. The *root server* will refer it to a *TLD* server, which will refer it to another *DNS* server. That last server might know the answer to the query, or may refer to yet another server. In the end, our hard working *DNS* server will find an answer and report this back to the client. +A caching only server without forwarder will have to get information elsewhere. When it receives a query from a client, then it will determine the response through a series of *iterative queries* (as described earlier). In the end, our hard working *DNS* server will find an answer and report this back to the client. In the picture below, the clients asks for the ip address of *linux-training.be*. Our caching only server will contact the root server, and be refered to the *.be* server. It will then contact the *.be* server and be refered to one of the name servers of Openminds. One of these name servers (in this cas *ns1.openminds.be*) will answer the query with the ip address of *linux-training.be*. When our caching only server reports this to the client, then the client can connect to this website. -![](assets/dns_06_caching_only.jpg) +![Caching name server resolving *linux-training.be*.](assets/dns_06_caching_only.jpg) Sniffing with `tcpdump` will give you this (the first 20 characters of each line are cut). @@ -70,7 +102,9 @@ forwarders { }; ``` -You can also configure your *dns server* to work with *conditional forwarder(s)*. The definition of a conditional forwarder looks like this. +![Example of a forwarded DNS query, captured by Wireshark.](assets/dns_forwarder.jpg) + +You can also configure your DNS server to work with *conditional forwarder(s)*. The definition of a conditional forwarder looks like this. ```nginx zone "someotherdomain.local" { @@ -137,7 +171,7 @@ The main differences are: ### troubleshooting commands -Before we start configuring BIND, we'll first introduce some useful commands for troubleshooting DNS issues. We'll show the commands on an EL system, but they work on Debian as well. +Before we start configuring BIND, we'll first introduce some useful commands to observe how BIND works, that can be used for troubleshooting configuration issues. We'll show the commands on an EL system, but they work on Debian as well. Checking the status of the BIND service: @@ -246,7 +280,7 @@ Change this to e.g.: The hosts that can send queries to the server are configured with the `allow-query` directive. By default, BIND only allows queries from localhost. To allow queries from any host, change the directive to: ```text - allow-query { localnets; }; + allow-query { any; }; ``` You can also specify a range of IP addresses (e.g. 192.168.56/24), a single IP address, special keywords like `localhost`, `localnets`, `any`, or a semicolon-separated list of these. @@ -352,7 +386,7 @@ This is exactly the information stored in the root hints file. In order to set up a forward lookup zone, you first need to create a zone file, and then add a zone definition to the main configuration file. -Let's say we want to set up a forward lookup zone for the domain `example.com`. The zone file will have the same name as the zone (`example.com`) and will be stored in the `/var/named` directory. We want to keep track of the following host names: +Let's say we want to set up a forward lookup zone for the domain `example.com`. The zone file will have the same name as the zone (`example.com`) and will be stored in the `/var/named` directory (`/etc/bind` on Debian). We want to keep track of the following host names: | Host | Alias | IP | Function | | :----- | :---- | :--------- | :-------------------- | @@ -366,18 +400,28 @@ Additionally, we want that `https://example.com/` will also point to the web ser A zone file for this domain could look like this: ```text -// Zone file /var/named/example.com +;; Zone file for example.com $ORIGIN example.com. $TTL 1W -@ IN SOA ns.example.com. hostmaster.example.com. ( - 24061601 1D 1H 1W 1D ) +@ IN SOA ns1.example.com. hostmaster.example.com. ( + 24061601 ; Serial + 1D ; Refresh time + 1H ; Retry time + 1W ; Expiry time + 1D ) ; Negative cache TTL + +; Name servers IN NS ns1 IN NS ns2 +; Mail server + IN MX 10 srv002 +; Hosts + ns1 IN A 192.0.2.1 ns2 IN A 192.0.2.2 @@ -399,9 +443,9 @@ Line 4 and 5 define the *Start of Authority* record. The `@` symbol is a shortha - `ns.example.com.` is the primary name server for the zone. - `hostmaster.example.com.` is the email address of the person responsible for the zone (to be interpreted as `hostmaster@example.com`, but the `@` is replaced with a dot because of the special meaning of the `@` symbol in the zone file). - `24061601` is a serial number that is chosen by the system administrator. It is an integer, but commonly it contains an encoded timestamp, e.g. `YYMMDDHH`. The serial number is used to determine whether a zone transfer is necessary. If the serial number of the primary server is higher than the serial number of the secondary server, a zone transfer will occur. That means that you need to increment the serial number every time you make a change to the zone file. -- `1D` is the refresh time. It is the time that a secondary server waits before checking if the serial number of the primary server has changed. -- `1H` is the retry time. It is the time that a secondary server waits before retrying a zone transfer if the previous attempt failed. -- `1W` is the expiry time. It is the time that a secondary server will keep the zone data if it can't contact the primary server. +- `1D` (one day) is the refresh time. It is the time that a secondary server waits before checking if the serial number of the primary server has changed. If it has, it requests a zone transfer. +- `1H` (one hour) is the retry time. It is the time that a secondary server waits before retrying a zone transfer if the previous attempt failed. +- `1W` (one week) is the expiry time. It is the time that a secondary server will keep the zone data if it can't contact the primary server. After this time has elapsed, the secondary server will stop answering queries for the zone. - `1D` determines how long a NAME ERROR result can be cached. The `NS` records on line 7 and 8 define the name servers for the zone, i.e. `ns1` and `ns2`. @@ -428,8 +472,6 @@ Next, add a zone definition to the main configuration file. The zone definition zone "example.com" IN { type primary; file "example.com"; - notify yes; - allow-update { none; }; }; ``` @@ -439,10 +481,6 @@ The `type` of this zone is `primary`, meaning that this server is the primary au The `file` directive specifies the location of the zone file, relative to the directory specified in the `directory` directive in the `options` section (`/var/named` on EL). -The `notify` directive tells the server to notify the secondary servers when the zone has changed. - -The `allow-update` directive specifies which hosts are allowed to update the zone. In this case, no hosts are allowed to update the zone. We'll change this later when we set up a secondary server. - Check the syntax, restart the service and test: ```console @@ -452,6 +490,248 @@ Check the syntax, restart the service and test: 192.0.2.10 ``` +Try to query the SOA record from the zone. This is a rare case where `nslookup` gives more information (specifically, the names of the timer fields) than `dig`: + +```console +[vagrant@el ~]$ dig @localhost SOA example.com +short +ns.example.com. hostmaster.example.com. 24061601 86400 3600 604800 86400 +[vagrant@el ~]$ nslookup +> server localhost +Default server: localhost +Address: ::1#53 +Default server: localhost +Address: 127.0.0.1#53 +> set type=SOA +> example.com +Server: localhost +Address: ::1#53 + +example.com + origin = ns.example.com + mail addr = hostmaster.example.com + serial = 24061601 + refresh = 86400 + retry = 3600 + expire = 604800 + minimum = 86400 +``` + ### reverse lookup zone +The example in the previous section is not sufficient to allow the DNS server to respond to *reverse lookup* queries, where the client provides the IP address and wants to know the associated host name. These are specified in a *reverse lookup zone*. + +Some domains have IP addresses over several IP subnets. In this case, you will need to create a separate reverse lookup zone for each subnet! + +The name of a reverse lookup zone has a special format. For the `example.com` domain, we used the 192.0.2.0/24 IP range. The reverse lookup zone name is constructed as follows: + +- Start with the IP addres for the address range: 192.0.2.0/24 +- Drop the host part, so only the network part remains: 192.0.2 +- Reverse the order of the octets: 2.0.192 +- Append `.in-addr.arpa.`: **2.0.192.in-addr.arpa.** + +The zone file for this reverse lookup zone could look like this: + +```text +;; Zone file for reverse lookup zone 2.0.192.in-addr.arpa. +$ORIGIN 2.0.192.in-addr.arpa. +$TTL 1W + +@ IN SOA ns1.example.com. hostmaster.example.com. ( + 24061601 ; Serial + 1D ; Refresh time + 1H ; Retry time + 1W ; Expiry time + 1D ) ; Negative cache TTL + +; Name servers + + IN NS ns1.example.com. + IN NS ns2.example.com. + +; Reverse lookup records + +1 IN PTR ns1.example.com. +2 IN PTR ns2.example.com. +10 IN PTR srv001.example.com. +20 IN PTR srv002.example.com. +``` + +In this file, we find the SOA record like in the forward lookup zone file. Next, the `NS` records define the name servers for the zone. Finally, the PTR records map an IP address to a host name. + +Remark that for the IP addresses, we only need to specify the host part, in this case the last octet. The network part is already defined in the zone name. + +Also remark that all host names are fully qualified and end with a dot. If we would only have specified the host name (e.g. `srv001`), the value of `$ORIGIN` would have been appended, resulting in the nonsensical `srv001.2.0.192.in-addr.arpa.`, which is not what we want! + +Saving the zone definition to the appropriate file, and check its syntax: + +```console +[student@el ~]$ sudo vi /var/named/2.0.192.in-addr.arpa +... edit the file ... +[student@el ~]$ sudo named-checkzone 2.0.192.in-addr.arpa /var/named/2.0.192.in-addr.arpa +zone 2.0.192.in-addr.arpa/IN: loaded serial 24061601 +OK +``` + +Next, we add a zone definition to the main configuration file. The zone definition could look like this: + +```text +zone "2.0.192.in-addr.arpa" IN { + type master; + file "2.0.192.in-addr.arpa"; +}; +``` + +At this time, you set up a DNS server that is authoritative for the `example.com` domain, and can respond to forward and reverse lookup queries. If you want to follow best practices, turn off recursion and any forwarders that you might have set up previously. + +After adding this section to the main configuration file, check the syntax, restart the service and test: + +```console +[student@el ~]$ sudo named-checkconf +[student@el ~]$ sudo systemctl restart named +[student@el ~]$ dig @localhost -x 192.0.2.10 +short +srv001.example.com. +``` + ## secondary server and zone transfer + +In this section, we'll set up a secondary server for the `example.com` domain. The secondary server will replicate the zone data from the primary server through a *zone transfer*. + +![Zone transfer from a primary to a secondary name server](assets/dns_zone_transfer_pic.jpg) + +Depending on expected network traffic and server load, a system administrator may want to set up multiple secondary name servers. Usually, the primary server sends notifications to all secondary servers, but sometimes a secondary server can be the primary server for another secondary server. + +![More elaborate setup of primary and secondary name servers. `ns1` notifies `ns2` and `ns3`, but `ns4` is notified by `ns2`.](assets/dns_master_slave.jpg) + +Zone transfers are requested by the secondary servers at regular intervals. Those intervals are defined in the *SOA record*. + +- Set up a new VM (we'll give it host name `el2`), install BIND and start the service, as shown above. +- Ensure the service is listening on all network interfaces and is available for other hosts on the network. Ensure recursion is turned off. + +```console +[student@el2 ~]$ sudo dnf install -y bind +... output omitted ... +[student@el2 ~]$ sudo systemctl enable --now named +Created symlink /etc/systemd/system/multi-user.target.wants/named.service → /usr/lib/systemd/system/named.service. +[student@el2 ~]$ sudo vi /etc/named.conf +... edit the file ... +[student@el2 ~]$ sudo named-checkconf +[student@el2 ~]$ sudo systemctl restart named +``` + +Before we can set up `el2` as a secondary server, we need to allow zone transfers from the primary server. This is done with the `allow-transfer` directive in the zone definition. Add the IP address of the secondary server to the list of allowed hosts: + +```text +// Zone definitions on theprimary server + +zone "example.com" IN { + type primary; + file "example.com"; + notify yes; + allow-transfer { 192.168.56.111; }; +}; + +zone "2.0.192.in-addr.arpa" IN { + type primary; + file "2.0.192.in-addr.arpa"; + notify yes; + allow-transfer { 192.168.56.111; }; +}; +``` + +The `notify` directive tells the server to notify the secondary servers when the zone has changed (or, rather, when the zone's serial has increased). + +The `allow-update` directive specifies which hosts are allowed to update the zone. + +Remark that the IP address here is the one given to the VM `el2`. It does not correspond with the IP addresses in the zone file, but that is actually not necessary. + +Save the file (on the primary server), check the syntax, and restart the service. Ensure query logging is turned on so you can observe the zone transfer in the logs. Follow the logs in real time: + +```console +[vagrant@el ~]$ sudo vi /etc/named.conf +[vagrant@el ~]$ sudo named-checkconf +[vagrant@el ~]$ sudo systemctl restart named +[vagrant@el ~]$ sudo rndc querylog on +[vagrant@el ~]$ sudo journalctl -flu named +``` + +Next, set up the secondary server: + +```text +// Zone definitions on the secondary server + +zone "example.com" IN { + type secondary; + primaries { 192.168.56.11; }; + file "slaves/example.com"; +}; + +zone "2.0.192.in-addr.arpa" IN { + type secondary; + primaries { 192.168.56.11; }; + file "slaves/2.0.192.in-addr.arpa"; +}; +``` + +Add these zone definitions for the forward and reverse lookup zones to the main configuration file. Change the IP address to the one of your primary server, if it differs. The secondary server will store the zone database in a file in binary format. On EL, the appropriate directory for these zone files is `/var/named/slaves`, on Debian it is `/var/cache/named`. + +Check the syntax and restart. Observe the zone transfer in the primary server logs! Or, additionaly, you can set up a network sniffer to capture the zone transfer. + +```console +[student@el2 ~]$ sudo vi /etc/named.conf +[student@el2 ~]$ sudo named-checkconf +[student@el2 ~]$ sudo systemctl restart named +[student@el2 ~]$ dig @localhost example.com +short +192.0.2.10 +``` + +The logs on the primary server should show something like this (for clarity, timestamps and other redundent information was removed): + +```text +query: 2.0.192.in-addr.arpa IN SOA -E(0) (192.168.56.11) +query: 2.0.192.in-addr.arpa IN AXFR -T (192.168.56.11) +transfer of '2.0.192.in-addr.arpa/IN': AXFR started (serial 24061601) +transfer of '2.0.192.in-addr.arpa/IN': AXFR ended: 1 messages, 8 records, 248 bytes, 0.001 secs (248000 bytes/sec) (serial 24061601) +query: example.com IN SOA -E(0) (192.168.56.11) +query: example.com IN AXFR -T (192.168.56.11) +transfer of 'example.com/IN': AXFR started (serial 24061601) +transfer of 'example.com/IN': AXFR ended: 1 messages, 13 records, 317 bytes, 0.001 secs (317000 bytes/sec) (serial 24061601) +``` + +![A zone transfer captured by Wireshark.](assets/dns_zone_transfer.jpg) + +The transfer was performed using an AXFR query, requesting a *full zone transfer*. You can run this query yourself from the command line on the secondary server: + +```console +[student@el2 ~]$ dig @192.168.56.11 AXFR example.com + +; <<>> DiG 9.16.23-RH <<>> @192.168.56.11 AXFR example.com +; (1 server found) +;; global options: +cmd +example.com. 604800 IN SOA ns.example.com. hostmaster.example.com. 24061601 86400 3600 604800 86400 +example.com. 604800 IN A 192.0.2.10 +example.com. 604800 IN NS ns1.example.com. +example.com. 604800 IN NS ns2.example.com. +example.com. 604800 IN MX 10 srv002.example.com. +imap.example.com. 604800 IN CNAME srv002.example.com. +ns1.example.com. 604800 IN A 192.0.2.1 +ns2.example.com. 604800 IN A 192.0.2.2 +smtp.example.com. 604800 IN CNAME srv002.example.com. +srv001.example.com. 604800 IN A 192.0.2.10 +srv002.example.com. 604800 IN A 192.0.2.20 +www.example.com. 604800 IN CNAME srv001.example.com. +example.com. 604800 IN SOA ns.example.com. hostmaster.example.com. 24061601 86400 3600 604800 86400 +;; Query time: 2 msec +;; SERVER: 192.168.56.11#53(192.168.56.11) +;; WHEN: Sun Jun 16 09:21:32 UTC 2024 +;; XFR size: 13 records (messages 1, bytes 356) +``` + +This returns all the records in the zone file for the `example.com` domain. We hope that this also illustrates the security risk of allowing zone transfers to any host! The `AXFR` query is quite useful for an attacker who is trying to enumerate all the hosts in a domain. So be careful with this and only allow zone transfers to secondary name servers. + +You can also force a refresh from a zone with `rndc`. The example below forces a transfer of the `example.com` zone: + +```console +[student@el2 ~]$ sudo rndc retransfer example.com +``` + +There also exists an *incremental zone transfer* (IXFR), which only transfers the changes since the last transfer. The decision on which of the two (AXFR/IXFR) depends on the size of the transfer that is needed to completely update the zone on the secondary server. An incremental zone transfer is prefered when the total size of changes is smaller than the size of the zone database. diff --git a/modules/dns_bind/040-practice.md b/modules/dns_bind/040-practice.md index b52d3fe..2801131 100644 --- a/modules/dns_bind/040-practice.md +++ b/modules/dns_bind/040-practice.md @@ -1,6 +1,23 @@ ## practice: BIND -1. Set up a Linux VM (Debian or EL-based) and install BIND. +Use Vagrant and VirtualBox to set up the following scenario for DNS domain `linuxtrn.lan` with IP range 172.16.76.0/24. The scenario is illustrated in the following diagram: + +![BIND practice lab](assets/dns_bind_lab_setup.png) + +Four VMs are attached to a common Host-Only or Internal network. The properties of the VMs are summarized in the following table: + +| Host | Alias | IP | Role | +| :------- | :------------- | :-------------- | :------------------- | +| `srv001` | `ns1` | `172.16.76.251` | Primary DNS server | +| `srv002` | `ns2` | `172.16.76.252` | Secondary DNS server | +| `srv003` | `smtp`, `imap` | `172.16.76.3` | Mail server | +| `srv004` | `www` | `172.16.76.4` | Webserver | + +If you used a Host-Only network, the host machine can play the role of a client. In the case of an internal network, add another VM (e.g. a ready-made Linux Mint or Kali Linux VM) to the network as a client. In this scenario, routing is not considered. The VMs will have internet access through their NAT interfaces. + +Remark that the VMS `srv003` and `srv004` should not necessarily exist in order to make te setup work. It could add to the realism of the scenario, though, since you can check whether entering `https://www.linuxtrn.lan` in a browser on a client will work. + +1. Set up `srv001` (Debian or EL-based) and install BIND. - Discover the default configuration files. Can you define the purpose of each file? - Turn on the query log and start `tcpdump` to capture any traffic for port 53 (inbound and outbound). @@ -14,20 +31,26 @@ - Repeat the queries from the previous step. Do you see a difference in behavior? -4. Create a *primary forward lookup zone* named `yourname.local` with a variety of resource records, e.g. NS, MX, A, AAAA, CNAME. Also add an A record for the `@` shorthand. Use 192.0.2.0/24 as IP range. +4. Create a *primary forward lookup zone* named `linuxtrn.lan` with a variety of resource records, e.g. NS, MX, A, CNAME. Also add an A record for the `@` shorthand. - Use `dig` and `nslookup` to verify all resource records. - Optionally, write a test script that runs these queries automatically and compares the results with the expected values. -5. Create a new VM, install BIND and set up a *secondary* server of your primary zone. +5. On the client machine, set the system DNS server to the IP address of `srv001` and test (from the terminal, or using your test script) whether you can: + + - Ping the VMs by their hostnames. + - Resolve the domain name `linuxtrn.lan` to an IP address. + - Query the name and mail servers for the domain `linuxtrn.lan`. + - Perform a reverse lookup for any of the IP addresses in the domain. + - Access the website on `srv004` by entering `https://www.linuxtrn.lan` in a browser (or alternatively use `curl` if your client VM does not have a graphical UI). + +6. Set up `srv002`, install BIND and set up a *secondary* server for your primary zone. - Rewrite your test script so it can also run queries against the secondary server. - Ensure that you have the query logs on the primary server turned on and that you are watching its logs before you start the secondary server. - Observe the zone transfer process when you start the secondary server. - Check that the secondary server responds to the same queries as the primary. + - Try an AXFR query from the secondary server to the primary server. Try the same from the client machine. Also try it from the primary server to the secondary server. Which work and which don't? - Make a change to one of the resource records on the primary server (e.g. change an IP address) and update your test script. Restart the primary server. Query both the primary and the secondary server to see if the change has been propagated. - It probably hasn't, unless you thought of incrementing the seral number in the zone file. Do that now and repeat the previous step. Check whether the zone transfer happens and that both primary and secondary server respond with the updated information. -6. Set up two primary zones on two servers and implement a -*conditional forwarder* (you can use the two servers from before). - diff --git a/modules/dns/assets/dns_authoritative_zone.jpg b/modules/dns_bind/assets/dns_authoritative_zone.jpg similarity index 100% rename from modules/dns/assets/dns_authoritative_zone.jpg rename to modules/dns_bind/assets/dns_authoritative_zone.jpg diff --git a/modules/dns_bind/assets/dns_bind_lab_setup.png b/modules/dns_bind/assets/dns_bind_lab_setup.png new file mode 100644 index 0000000000000000000000000000000000000000..f60c3a1638c18614da4e8d86ddf9885dd858bf9c GIT binary patch literal 26651 zcmXuK1yoz#(={C2-5rX%yB7BV#VPI-cZwG;4#kQ?acyyTcWZG7?!gKE<@bNTXJxG< zYvtaYduH~Y+2_oh7!7p=3{+B7004lYq$sNe0Kk|-zmFgzLf=QHc9NhUFdkY8(tz4& z@?!vi8lWWmQQOz#ED$9?d#URk%+X-;2OORh9*CojPs>DjI&UF&ifgpC<1CB)-2U>s zc^YZA_D_PS@hJef=n%W4{23*hY0=CIPXk$$&T7kshc_#*;~_6NnAc+fn`f*#E6Wvp zXsKj7E&Q+!e#`~uJR315aiG9JU!g*@^*dJ>4akL+mjdC~;}4v^?`rq4Ma(1bwW|-m zT=J?=)Wx@Z%FFU`sbyb(%mZ*?abZ#9wn0lx!8Cve22Whg_0O(tE}o6xN~4zAM5Lq} zz!wBS?|V{GaXTGu0;)tsLwHEI6caLAaKJ7S-UzdciKnJ6(^P8Z6l->S-|=rfs+B)= z0<;4cV`DV6KYs=Y_BwD7GFrrhr#iHij42|=DZ!WT10Acg1x&n_2pV_`3ks;|DN_#p zW>4=fR}Y*wZGKC*oh)a7na)w82Ko$Cl+W&el1?Mkr$6LJ(*`lbgwsZ#H_skgCvTcrD&#CI$|G|DCo@J1;P*A$5PnKqd~w@ig1@+~2SE z+i2$_>UGdol65RdRTMgw`}ngUTxy&)gwCZw_8hLyG72 zy8S~$rs#ZXjN(l4#W?Eu5*S7gWMeTlyLrQ1rV=ACOF;cu+@JG=>IlZ^%OZb-VIQei`iUjFS`R*M+xv9G1dU+cc1<=ZYY#VcibI5Plk%%k6j{h1uZb zk{w~qS;aN9|Dh;EpU%_9VDLKO6Dv%j;>IIlUdgm+iTb=LOxtVc@e3{Z5uELh$d7mD ziF10I^5ss;Ltv>&K()ZW@~)Ki+U#>4Do5vK{|{g6>?y>NM5?IVC^gr{m33d=kpvye zyb~h3k0Z=dMzZU}Q`yFtAx%X+uCg-(_cqZ-99m`Jw3iE#&H+oHP%vI-Ii5t8kXlG- zU*GJW%gp=90u|gI^%W|hN^YV_cF?Uq@Rxap`28k=)EMT*TYLc1q*@pnN2}Q{4yCKE z0Z>S>LSlb69-)x${NmE((6s3&eol-xZq3Kq*#o!1R1g(H9VUq60PsE}W%z^yt6~uaIzg zoh<&4LZUsuBo_iG7&+FTMy~{2-kf7GTQwTEB8#M3`}>)gC;iXezf)x?xN4Go0>LK% zih5=6NCSIgsWiO2c&ZF|d;$WPfM~+IoE&n_kG$w`>SYUS!xq2M8-Fhg`#$qhH0Fvl zEf;|uJ+22+4%Ax~mq^Ipju^P%bS;PuUfM+OE?p!$bGdGxkh(vi8yFaH+0Xy_;rI0V z{2*gl1{d$K-k0n3FovSfgjGiyexj!G=}6E?Yx!5I>o}XO1w;Fpj?p4ZFvPuS6^ zzkrFSXnkyWuo7PG0bHO!^6Z|wFcbcF-a(t+zH9Iz%a*2ea%sx^vzT6X;n*5gGv&F- zOyZP@8A3x7`|dE^CkR22PW9|25fKp~W#(ah0OF?b4Ef?v4q7R56M@N`0EUO&i!dkZ z;?DrehL+rov4QNh##!&PMXdAJTqiLE#QN*uq7NKan*-p$?KDsYr`#ZkG{)uG=F?ft$B?lIGBEu}aSr##Nd==Lf`yr1SL=67Sxf+-q znBF1XTQDuAk_&6qO%w2I4^6$3F@9WL((Mm^YyvG0bn9Osm&#EUb#Op-p3Mc7g*XXa z6g}LQpUi%?Cxtp>L8*o2!H->4X!vq+avEA%DLh#2d!slBpY8cv}s zD0CWE{Xrj4kfssG_%%3Vw_+mswf&=saD^*B2w`rp1ZF7qD-Q1PJFW7$d?Vr;r}@2$ z1)I_}1q!W8^a@+LK#Vs;Jm0Ws^_AyV%|8+y+pQ?sI=f79o%k&y*-Y{*5^D2A95st( zc3f5EVFY91Gx7n+(W=VLkHFDY0AJe* ziTe%@WRDEW&Ir#=qSfFg)DZv9Qn>Z z_G#09U|*OgKxKSp21sJXWl^i}56i{*JYw^{dF!F6iITc;R$;Bp)qa}%Abnw-%;z7*>pIx-R!-- zLQd07xNg10H#U|Vjb6-=l1@)fJJ{b^SYyIJS!*iz=Y`V6ZQ?)-6J^&I7vW!DUrm}| z468KN<~BDawli3r)2FA^kB+b8;EFMc)^^`VX0D`Z(MXMEQw!VLR-Q>V;dGEghXtLQ9e?|l!`JHSj(Fs? z0T(GOh9c@2$&rUmTj-aoLPPwAyi<*%Oq>*h>MD}t{7&WWx$QHl!+MEcr(g-)`Krt3 zO#bblOqQ95Nb4V#Y;IQbUrZe(y*m?1iN))vyJTlh16=eZ?ChIav2<}F zJ9Ry8Pi(l9XIOEjJ6%_F2};_RNz=zZ#v~EMf)?)RCN?FMOR3gq?vt#*m&N*{ZO256?W0ftCd|4&M3<{xB z9g{j;{A3stuHY}Hbs3~HQ?0jesC{olc<|9#{+e-KK3Y@!o3r~7MJQu(FPaXX;z7B> zFjbfo7{jql(0}{&Ny2Wut88`O+Yp*fKSccX!R_8|pTL^VPS+8$)gqnD6Bng-M~N*5 zt&w-ryzS<9<*0wDc6xiNYT^DZs&>;Q3;L@zsr|F4rj{l*9FMuU*u&-P&~DR+jkX;s zXMXZU?4n{QYbK4$uL{fIsz`>^``&4a_i6XRi$JemZ4ye1Vz};CkDCtGN7o4dn%Fb5 z(u9lIyzn6AF~t`bZ#8B2;CEKwZg!f2O2yu)8)}vCs-kL4_%5yg7#~a5nI3pkb?@5e zhL>2yJ5rj%^5fVQ{1aE1+ILgGEFLowR3S>SK>4x-J4R9u;6Jo7vP5v|)ejvrW;knF z!?IL?9~o=a{QPl9z4R5d^41%%%mBEiovYKSU9_}oZ9hCR)Sr0g-WFW?ErJ)X*Co9t zqa`laiLl|G*1~2r_c#Eifj_Je*e_29o3jmcXL$L&v5+>=) zw9*_Z%pUVMyb~&ACYLPo^Cc(yYKtDXmz-yj60~wSeHd(5Vy@_}yg#ENHz9UBo?EqXGNP^CRhTDP_J%P8R#>;0kW+Y24noFOtTyu-i&2wMF?b z+fgg`$^4-FsfR+YiH&L%exI>PEv`6O_Rt%v;$VhMl~~2 zmX4s;flmHhbq*u`{wE}j@XMVoP%WIC|40FR=&~mw`v7)X_N+Gv24<9$uzuUNwy;6R z(n&o5A6pnQgU>k?}uNW_pAPXvD4j1%I!;MH%MYs#tU#8g&$d)PUux7i0kI( zL{dh>-#$R@)T<+?)}5(%H9a>uxeBQbhgm396UXeSWIZd0uNN?=1Tak9ki)y?CP!yg zvgEEi>W-d!7uEk_CLr-H8>g}4b5FP1b2enJrzW!djwl_$Mn>5}UsZh78&5&e;mpQd z@dA&xr;lLNS1r8tbd$Wn|DI+b^vav6BRFPt{!^mR?r-T80a38@4L%SDn+Y3PgAa%4 zy9NlCM-G`CJM^IUJRQwjP{BZla??SVmEu^SOr@suGYJWYkD6MyFD#~inBpIN2H0>7 z*1YA$h&0Wu&euvY`4TfkM6MNI7cMmx6JZh_jnM!j*a^F?_XrbLQ3@l>^Q~tvEX}Yd zmi0>e(nXvsJI=Mdirn@u;rs|dE&oXr2|)0ZPKnL=J$jbz1nc|)%@q4Ce|4-5iuf)|-pt*F2?v-h0=zwF5dt zQyu3-UuFLNNXQ!y4C|^ZFF)${X&9b*47Y*LW1ybpqt)14sKN7nXZHDZH*jx)>&@$| z-Y2|AIqdK|q^2OmtzyY0v93EO=ixN8$X{v z=h5f-eHA#N^S}IR9rvB8$hWq(6E!d{pJ^ttW&63YJMl^TfrE;}RkMN7ZO060P+zh- zx;L;)so~?(Tl#LQ?egOEqcc-+WN6^RdTN`F!~-HRoc?&xlu={uJ=7N6ZbXPoVGZ6$XIQMh$ zNX|XIQJh#1i)%8?!~dM#7HGgnYJz8F-4%7AhDk&%KfF;(7k>i{;dA+yrd3+$ArkM@ zOJuL){bY$YI~6XJf;q}h_y=9m{i^x5e`5FLsr%e>#QdWo?@~#aIJr!&Z2#fS^i?He zXPJfAiW+xBc8y#VV?-Ms4{$>;$leBA#8qtgL?Wd%>)ozWrxDyr} z7vuN@qnMt_+lDwx+Q(i;TmETSm>(n(xV84k(!j&E}IQ$oUsb@TZFPYg>eqm+%Z&Xr}T#kH%BO3}#f?bW%22zQt4P7ms(|-s= z)9-8}5iA%PdL?sp+O90=SF?>VXUmr@Gb8cYcTvX+b?fSy=-fD#cZPlYJD3!!O|O*b$-owy?9&s& zTtHnhhmC$16qnpa-?@3Q$7M+YFN^P6q5$4JgmTAl`u$rA^%+#yiPdxE;p4r|QgD~Q zX&|PQWu_q5ziNL7|J>U>j{1-(T@N)*$<@}jfihd|qk7)UNR6?vxMY^k>#LxdWLwJq z#)fRtSak0Vr84#&{)A!X@Ngp4+_51g!l<9+bPig+y&cmRahbs?IZ4$R*Ho#!^qShh z+@kGTebOB^OiFdH9OfQ^(~%zy_@6aGKTvj5HOwGT1=`b5mK7gB`ow|Q%I1?h1``KU z+qWI^h=HQeTP*Ntu~n@M!whVM%Q2{D~wVpLIbz`lFa>_S7`-eLvtl$C{}(`o*f z3z%kb+^~j?HRBWCOhf1Ayn|YmvULedlJ1nIKc7m;doC9%Hu7gO-A)7IZM5{{BR6C; zN!4o@zK!e_kSCD;>|4#jBnY!|@+!e7*#1-QN+5o9&6rS)OMX$HT%AjA!k z>>tOko+Dq$g=pbpqcY_&egoYW)@@2tX+*{G+KB3u))=KFnBinw5@u=|g)VmDoVX_k zXo8N~~AdYm`NCSbmHW4O-va9zR`U(SAl1=g{oh0TnPUO%65>;W#Y zfz?MbeHM!*YE!WoB_$bee;PgKBo`L^rioS}?HT4K`lNEjGk95&Ha9sroW6*@A&30# zY;A=cU$DM!k!e_7Gwvsk`r;2I!|DTNbfN;1r*ja^#*6Gn-84N*b4nH|LsLG%rnnv@ zXA}!Pw61?ILZ;yxvV6nELJ}at{zS@24CDCf^|;`q!Ml0Bg=X8;q(n!av9GxL(XC7F z`jxSF(H7=HEIOz^44AK23c)Y;?o9=gT%Yg4cu&I!wc(ka&}%fE?KKUXv`xrO%xRQq z|2g`4u=&&Y2$PAEO0gfkl72XT?JlggHcx?t6>JdqFl)D0JC$v;0kAG_zcfXZUsQ-4 zmTFm3FP3O8J8Y0UKaWoYV9VLt4=q*={*um$e+~Avs z%o6JdZMve%nIlWQU2BL9Xz91Cm)?gcVXHz*E4z%*6?}i}T%Xs=Zn|!yAbYViz5h@F zK8rB;T^Jg7Jo4)+jsn6b-?&?0flU(p;VTq$pEK_x)j3HR!&VPBnVCj6jWvJo(QBKc zkKcsAi(s!D(ps8Ip?tNWCZUBmIjv=Q`Uuv+7u;G~X8~K9O}d(pK+t|_o;)!vTog|LG zhskW_jm7c2SZN(+Jc;TsJA3xU*}2nal%&Ac&d!&t^mMcb$fz$N7`Vfc>~<#SwvFVK z95K4#oSidXY%mSi*z0k~-ZG1>qECX{J-%7w);@v9_T#Y=f#v=>)06fsdut7(5~B14 z5Y)&C*rbrNY_7PUVUcV~#1m8CKMYG~Z(Jz&`m_D%cGcdT{jesOfydb$Nb34{T;D zqS#368sU=UmPlpSN{F`gG>ET=W#e4 z^i)+hE=otW+d6ty@Jqw3O#v0_tFG%@lH}XrE2l1M-Nkl=cZjBT_d}%L!7tJMncB;&0^Mms{67PaEc8*OqJ)f5QzVUH? zXYGnVerd|!&CZn_N(QC-f*hh6z7+0AEu<&nHAivbC@k=BNTLHeM8Dn)lq%|zAoz$H zSephbVZr)>n*l%K0f`IwZH#2!2v1$V4(yJC8P7*(^|z&dL`=cW)4!6OoADuT8Zawt zyEBD=i_t<_+O@V zi)rE3LD%A#8qJ8?c@%x4f|q-u-==-aP0z>yb^xX-#8&&YouL9(q0jD`7&zZS=ETuR zah`aL7dbvpw{M9y)14kc&dzP#Ny*Nmip4aGWZjOgGQ^bJ^D}14ybTq{T!;aatZZzb z7yMTSIF(?iDmq|>$0zA=)w|NF?^9ihO%IKz7_SME{onxY0NqzZw)k)dMja6iSVo4Vf(y`_MJl) zWr^X67M$VnIOq_$X#uk?u3xTB16oG10&udP-{pFj09CcU4pT>wp7I!=Z5@^fQy81wdNlFII7?kT0Dl&O|+_(`M!xCt;9TgkpwQzUUq&aV4_0+rN3lv zJP*I+FDYB)h>%%SPilVv?U^dkN#EX`1DH(VTpw(UrMjcX>GDY}=I;P#51b}B97Is8 zgNC`>fyP0lU!u!f6|pI}<_QP_-CTf)7Z?9Qi)8W(`2TtVFy|DB&Vpcc{cpK-XH_y- zmJ0*o)>fOh7B@Ctm;g(sSP+ORDkR#9q(mZ_nmXB)t~_2n-~ZJi%DHFSXN@Vj4&s>& zFhlCCER*Gz4ep^96=j*u&ao95Fc4BiAUzhqC)f|*aoee>%Z=%cg_wkm3i8bT$7lQiwDAq39Ki2T1^1Am0ka@}0+hrt8 zzr|Z?qnXNC6JwzD0lLE&!YLTqjc*7T2BJRQTN;L6{k-gt(>iGR z<|CwrEs_@s;Uw4yoi^u+MfCuUn~5+~XhbHj+JS+|22g)_SCqVcfW<{&R42T+O|8Qy zxHSlQmQdz;{D9l@K(bevVF8eXAM>*awFyafK7YLRF zI>9HTaq8#;TfW5MU*g2>rw=D7`rcY^KL@!W5%of#I$}#GGhk*1O z-|>QiE`XTxKJ{ust5<=qUL_E^*CkHUYj~cil>*1)N4On|q2zi^kWV>5P65vpNWR?x z#wv+KriHo#8zcJHvjymQ!SvnoVx7u3FJ0H+n)FzDVv%r6ED{64mCbyws`WU-y0!+a zhR6Q?0z>tl6c9%n`uT)5+4aSG+gtMSTYi8ffY|Uo`V$VTL0tcs;N_UwigDVam}!Y%BOOukp)wTXg4jg`A6LUP+ORd)Ed{@aZ$I#jE) z{LQ>Y1a_lK9eV&Cx&$)=kg6#5+#5pDqIRpjiC+eNrGwE6PH@YAV%aht_LaBpD5l=X z#-2f40qU1&ySoEZu&^4r`Y4Tk>w?kA*?1GHv3UGt2NuRBi9Jcift5JvKCQa^=#!C= zA-**4esxdWiaPw{_vzk1;KCzGcZ5yq!K|EvG*SUY!$I??s@vu zqGrEX*32`G^@PqWgiH(E=BM8JI}iT;>2WllzO3-i`jw=u?f*hj8Dp8 zG^u-~EtFhVY$>Vd0_Q5Fc0b$X#Cy^vxhcX>O*F1999ed{4aeC7DMbaEG(YSnr$4{E zn0x>o{d<+~S*2O1y9x9cx|Yl3tfcUjNc^uIf&05_>>e}a6A{c7hQ=#K+;_Y$;W6~5 z3Xi{p*IxolmJ0LOIk$qmR8$5|Jr2aUBzbwaNNs61kUjeO>Sd4u%zgp~=k|FjFv%h4 za1vZk7yGdsKOYuD;pD`jxTD(<@qSjMBY#}o+?ISifQ&uV5GQd?GZ51B(uyx>o4V&Q zZvk3&ws(fC-J^=vvT21d$Nc1fsxWOKksiOH7l2q;T@3h@<=e4GeW9@+wW4YpawX0R zSiOK5HT9U{kIi3gW?x`I2nhdkYuOVo+YhR{YI)r=0&razgdn|BDt3pV0lzy$;iz{P z%XRN81fc`o;q~v>DrwLWmED}jo}%#%!V`~1#i5bz=HQ%Vz2hM@Y=8d-OfGowy-ood z$VEtym|08yQDrVK`;xK-drq2rw~ZVC2(FwLCA0=4t4 z?!`VlCkEqO>HwAm6D{2HW;HQ4d8kur-;(nvUooKg*z#*mzVKT#j&0htaGP-*A?Dd0 z$k5*GEf7RU41gx0oQ?H>TO7cyqa;bsf0IMITejy+z8wAHSCb#00`ol|q5RG0dkUw7 zeF+#o05k+3YKeDu&r43G>>i?~-Iy>!LqpsA$#;AZOgE}XQ zu!BbgI0;DO#{XyVWpU*?!-}4r}1KqL27RamH5yc zAP0zV`g7d@qzg@U7UIEV-Y#ysYcTTvYN!j#bxuHF4dfRz)#gM97?ie3@rN>Jrg}#3 zWlxl%zz(BVrtZTdhw;x5^!*>f34QE-p4~D^bH>0SR#>`q7 z44TWM9B6|2{hetn?*F*@3PVLTnIrsKQLIqLr({KrcBNFyJ#CBI-4E<0g2k6WbG>^DH;NUzcmZJ&Z z_Kt%kQZ54|A5C@`w}_GhMxs~E>#fXpAf~X|GZB@?XKm2Lru9ccb6yM@>DV{C1N}RW zBOY&px$>e{_>Vab7QH`+}pbfkBHtjoaF-j0BSMegwHhb^>MtrjPqHZthcOYJP|bKSy&(arsyiVaAFqX|D~-L- zn$SW89-4z{o={mw+>i%+0=Hu?Qe-;Xx19Oo?$-K}eIckMW@2G6T;O$C`2vk^)fpC^ z!(CmnDa4~>}$suqLZc7R{~@6cFT!R<)# zo+Km&wHRdN&LQCn^AXQEG)MuSKL6N{j(StM$L^5=7NJTX)StV2Zwc+~c>;EC-TI5Z zR0X`W)!Jn4qrR(f>osWnvMvQ;aG$$}JVphM`7yN(n5+KX6Dt(^#8h`xy``vU`uTHr zbJ0%wgVv~`U=AZf(4pQZbfU|vp%zh5GVbjGekena|6{2Bhh00lFP=|{^tjzne*Swz zcaF`MLmnyba}qj+-~%KO_3r|{L*-M%FR0mu6Svx1iw9mjt@pcbKFuP1g>sa8+w%Eb zTpURk)=ChVqyM&eyg+o31YJ4NSX_}=vL#)TOFnYkCxfkLVE0fJy8{F5?;#6r4_=S^#=}yoUMQ{)Tb#d9B z>jOy)_W>1c_a}XETVetU2k`N+a6Al^Xqjr(({0741uW=N;G0n<(jU6nz#F8*ttAlzqH?%tAI=JXs!LSl5{V~*DC2Bj#h z;Glw{oyybiv7DlL{qpTN>cay_0R=F1CHuJqA{2kSCjuY7q1lLgK`sYvVxWoK`8OFY zffBJ--jRcM?93V{Ql07>l8zq7gD4P})|5bXbk8mNTeP(i|0m-vjtn)VaA0*mJ}t5H6@sn$*g-7^|Y>!Q>N7? zsGyr)UAXa{hcJYP5MsTLv|(20vs2%d_V1p$Qi1u-`Y2|Q$gL5GA5{IjeaN1q6B`0{ zOTvfn1OAC2X*iI5572y|PsMS8nQCk#&ohU24tv1a`a*QwwQiECpBc`se8Y`0A9d)0gYIBfk1 zQRtXoJ^j;YsU0+XBDZfTwxr|=-&Bn$Bwh#!+0P5sv9RT=2_eRN7N%a|ejh@m`qqo- zi%vu0;}z&#GBc8C_2Y-#Ur!FmifBrr8`~gPBX>$nIP1%ve@|inYd&12`S+xN8Kl?0 zT2v-g9C9*?#46KxKW{O&Sb7y7`h)G7hGU^Nt)v`)qF0Rh@{1}i9by2scm1=CzyB+S zv9TKQr8z6RT5$X8b$-ByWH&ZhHwbr1X!ry)MPmcR;OZ}D0I6|(qZy?evL)jO3-dXh z)XR`5M-HL_Zy~BtB0bMePL|p;fsiU61mH9;L%c@e#djE53dEYl#m?XU>#a&NKQc@k z+~UZN86t_HV(*joFt*!C$9h`EzR8S$vI%oYZ8BDmt&*@Jd zqScql;1@|a)di%d$D#5{A8zuUMj{&_$Iby>*d9;J$-}CU1 zZB!;opZ)zc)sjC+dY$|#Q_susvP0$}bd#j2N6R;tIl|#b;q*W2f>lokQABxkFtv>- zg+85$?!NPTRJTk`pVtvkZQVS|03x4Z-2bW9z5HcusC#byc<`rzFHQc2GSbT(GyT5R z9zeq68_LH|emwk7F@5SDpXg@2-7D}#|H=)WsHdm%Z5yt@E3o5aE~BST7n!GQ>Vpq2 zrZ9*^S-#3I;-}Y|4ohN+#}%cn{IzgiC*)aF6i!!moz2o>0X>Rpq>Wj9Sc4P^n2l1l zeEVcMGe>f=pl95$L!euFHHuG}C>4e@|3hrxIy~7L)2!cL)x>WKCgf1>z5EOM&LREo zbI_G84&#CbW;z#XM#TOd`DuY4VRRG@d>+py-KQ$xR_i~@qc$MJ#JYyW^Za|R?=gEW zw1S1r3qT4%4M`r0dBA%2qTD8e?TY+MXMt~JD=XTg`! z+S(z^Sv5c{ffk8qK(*o(8cAbFq$N&|>C5qwXLiHo1L(pOrAHB)xEm--_i}lH1-7v} z$g1|#H4vti$;}!b46=E{Q4^r_rfL#W)lD3*_jzl#25$_r}f`dy`$nm={ai74mb6L47K~{({=uL#DXa@$Z$LS^k8cAmn~2=_AcOCg3nPS z#yur3N_gbV`PZAeCdPa6)#{2%sVTQKWPKW}~Sd;jZVsQW4WGK5jliE@_U!)HLXW1ffVmXNs-(w)s&B5=s@U&ooi^ z4y~1n{@2@;osNmm|G_qK6%S9^42*)t$F~xKC&ph&d2ac)nU*5Et8RHy3&?klJ7NunuUDaq5Zg-XT)jPEZn16Cp@*SyBisuaX) zs0hR{UpRB}FnhAvgx?#+O~Mv~h~s;4Zkg}&9usbA70crQQF<2qgP@#ZviM&W9(;AV znq4;<##bV!Hqcw5%_3E(;rrgR0D{k0JAW0`%#RAonquya5`8M@cwE$>2xPA@z}#$B z%LRuR?j+FTY&AH1N=_kccQMYyQXbNPjJ-nI5J7@Z(EIWi=zIO|M2^mdn#yZBO8l^c zxK%JYK}6G)IcvJBJ#(N8^sb7Ipcbgms1gZsRf9qQ3p4YRAMJ;7zRGGctwQgy=ht`j z#lt?pfUpA}>9!wboP2Q$$w~CqdTGRT>8CCJd+$bl=C+EY)=8sg;&VWq|I5Bp5vIES zea9Vr2*lV3`Q#&A4pYvz4MDb-&#;|sO+<}qBQ8t#-ucbk+QBfK`gAYTa+(|&GV=0> ztsBl<*;5jaWb`k;UbE5pNH@sKpLGL;)YTVq!<2+rS}}&^FrH#l^kVmww~{!$u}>D+=@X`~FO^ zG#4=nBWju10|uF7)r3mFF(cN-LfwL(2hX?^ccXbuze6qb@Xc_gwpQhCl;j(<{eZ%C zOLpb-=!lpab8?{m`qRcstd47ODU`yDKgD&i9h6qJNenLJT|>$b z$BXz>{~Q^gKXyS6YPO7``ujk-I?q&_ScD&l8)Qpsps5KXENshIB;vXa&_B!5>;ta$ zDD@RC!Lbxa+WIct8IF{0HFHz;b;H`3j z;5d;_53f4|Zr6^n@4*M#@TmCwGbc@D_tTTJN~fZbrVv7h%OK+rtFD>YrKdLJs+YYk%*izfuLSC z@$6G1k%$kNldHMA>`T*4ZDTZ{V{?X`lbec4ovE4GcgN~?xs^=BmxNxizg$SQhW=`N z^}!sPp!7!nK~4WZ4t16ERq46t1L3@kcvP86J+Rj?qP)-jB1@zBO-_(GgA$jzRX@3! zsvhRShqaM6Kc$)m-c?3Zbt}z!rgNm9kfZdJ6B(}dXv$>-s!-MR#D8nDZO4qGaBNJ1Ee?!Fv~AlCZDsrVdQsb4O3Q{N zP*9k7#nlyldwP1Z&b@#_8-(?8h@>}*>L83=R0{u*8QbI|d=ltJQwcwhJfR!~@T~;+ zU|{=vjK>pt{T7|u2Q-gKGyl}jnWIDUr=~HuIFjo(oUaljdCTc+Y{E>*JF=7d_d?9Z z#*{!}!^rjyrt|v?4T*|T-~L}b={uJHPP9Zc45i4XOaAWTvd=LbnAJY95+j9iFu@Kl z<>;s~_kV?prrJMvf)BN$f00g|n;V20vam+!PjeCC=jzDlOfo^|^^iJOJ-vU>_aX@_ zBw22Y+Semc)Kg<*!rVRHa2vz_=!+)VV_tiHlx+RArrWrmll*pCb~2tcX#NeuB{Zd+ z|L%XMX-3S#KE{szVT1NnkC34Zx{>qo@tGa)DMG^wV zucboev)7Y10SKLK;%NPXZ`Tg~3*G-8EhJHP6EjWzZPg;SnDo2Y;Y085;>fidy*N9A z&z=&%<|cCaFLuc~l7h6q$xoUyxoT=A`{?6W=jBoUFDfkG5D*dh19NsF3MYjaytkgdXd=jxh*h6uy5jc{Ew0Y!!uyUI2@1Ht|xEd!aLlc!y+O5H`x|- zZXemsD>OpxjO*(|peQyJ;WRG8jcZ9b9_RzTXDbab?{ZqAo<~U!TmOpyz&tS$9$wxV zhi_%x$>Bx`l%GL7S)w8Crv~b?^L)jLCF;KA(QW@fI~ftbkPBZ&uPq*8cqd=wnV|GE z%%QUc7l&_Y;CTEO4Cu(A<9!l{cjY>%HLc;)oS2y|iexl!S$ z$gS;E*UqcddzbLZ4B3t8m`oW8u9I(?Ezu%oVmd|YLYn!B;RFYw9Bgd2Cwp8o2yb>~ ze`qur+2q;G>xb>a+5Z>aHgP7-o1x+>|(` zmMcJr*=s@++*PdC1+q*1Eb)BFZ1$j9ZpmM5@u`7ImH8w0I7}#;;vEB1N{H@y!IErN!tIQN5fTgh_ENmv zqsFmAsNc3#{*hJn7l1+plH_VY8ckznN79mdKN&>QzH<-G1AScy>wATt@>I%AQ25Lhs|mCE}js28E^rPhftdn{2~31Tz5xLya?qX|cztj z!|@2XGnD@mjSL7VNU^ObEgIHl;h0ay7JX`+{S=Jr(rLth#N2iUVc41s*&AD0u#)OC zMWy31$!bXLK@vXmpp5NxoQiK-ifQ~ixuVjmJ!4YEb5k@75fX5LcyKqW+lv-Dmpsds z>X}?H*EcsaPo!w64$rEaX7QoX*+SNuv2ukozXpLW_lRHkEC+K|W-05~94ZpF6!{N! z;!W950~tzQ;-R)pkg!}3h5qaBRW?*wlTbef3msS2Rt1WfaBhp~P21bZjbYk+*Z;1k z4+_E^j^;EiT!if5se8T1e}IY+qFCvCCFbBD+=Pd>c#L>?L1k6cK+Mj`x|@aJ`<7*n(Q$Q}&`F_tgCM1p85Xkqs`DIr5ev$k5}(4XYV z(eC6G@_!#wEJ){fb#=|o&4F?as!=f`uQLaj?{_H#L^5TI{4Rd=b3*x55xu3)e4C|x z?IR&KIrK+^nqdYcv^kOen+2T|6$NXFfdDOV)$#r#M9!3$PwPeN_w3`E3rGUPrClm^?o>wu9B zB*^2vY*9^g;$NC;|9`yz@egkp82gZBH5Gn$WzJypgM={`#YKHUOPR3an- z5x#{P$87c#&RGQ*l>`(5*@oy+#}GBHeZ@9YRCkp0(Tx~-$$m+v9io2Hc#)Mfub4fo z7v-9Rlzc6mkp*u-=D*k#mjx8gTwlA7PEAqx8cr7dg;vGnDR4B7QoX};S+xC{&ESWi zvha#SJL@DuLP6v|O{mRzn|1U`MyfX4qBBnPG&wp7hzlGEP7cwez^R_K73-J()TLpq z@dEXW$;O4^KSdFcuYzOg{~I*9TPUR0dOQx@ykbRrSmz)v$yq{gZJbIw+g|4zm%{;Pppv3kk-j}5#x z56SmVnqd0wTko&Oc-F@;5vscH^E6>Ag?%Xw0e3Pjkd6FDJUNdqXm>~Kwo8#WC_=82 z?U1+p!Qg4bx43uTa1)>SZb{dH`<;0c`#k;z(Ve^kU#~U6bLzcQ@+ZH{`6!#h8C`;Z z=zOXIGlaUw^Cldg!z^ZO>0uuSKB1F3zBq%Gh9vWM_i!9vEC$)r!$fD^*PQ+_T;(u{ z>c0m+z>H3+@M1z`g841Bv+w84F>8X3$)G`x>UIrHPLL%@?t1R`>MA&)URxgjmvIR> z7Yrg#GAH5w4`QqkS>`=E)*XJrcLN(J_df|;pMyJtoA zf|%U!f3b{v2au}&YyV~sr}-Zy#At;=wa$QQR3Ah##uaW%&--Cdxp;CIsh&@k{{tZg z-*NnBWjYY;Vy04Se6nawh(Btd_)#$v*nSZ`x00ooEQdMe3Gc_Kp~L zfkc(c|1V-er8GMqoF+4QqJzx79CL5 zBf9*zOZqI3gsT3L@HrM~Yb^dhz%nd6I61;tDmUsf6~S0=7~}p$JSFYSPrlK$Z$qM{ z7Ztn2jaf)U)m8hR;X(zs3lXx}nhWXF|YbVojVxS}%TqCjQKohR} zyLayzk-g&c`@g8l;w%-t3qsc!ZTK5`;Z;#5T@rjS4*aOkP`oHS(ir;v*do)K&aD96 z$V4~%76{*wUHali+&*)n`EP_vcR;S+oKg%+DwgeA=}a;hO%EULP_3WcVg->j{yp*z zFyp)oqEm*cHmj_3A5Tx`QISQ=HnrS1`ADisuFkrZF!+y-e4i1Si(FE*0;US;hyN(FYgf}69Fk}^eD516yE@PZ;crj*~+D4%`ee3uQ8yJnvQ2sf%=usD2&%n9BCY&SI zV0I!>zw{{A+uQc#?-XK&F+tF6{LscLv23`p0fjJP$X>hRqYS1+<<2|HA6*vE7Ljo+ z0W8e}?(DS)*ym4f^ukZffui|)-a6=aef2*)t@k-%gE?a3!G09^`L+ADw!~QCn3Mxw z!GWk?NS_lmk~7ljAM*@1{OFT(&yC;3kFQPMW1_tHeJtXA zC0nmliN^gbQ&+xkH56h9;!rLCJ}fq#z>bmbvfpHj(3(OU@ z`Wx5CLo8*#;b{0C-y2IRwE#r;$5O8^=;W}!KnR^Z^MJZX>Y<7!Z$rqiyMSl-?#u^6I;5>N#sQv!opz=Q&z&?rr#^xpfmmF(fQjAdIzS zNIev%+=dEZ3ERs`m#XV4JV-V$m(oCCbF~oV zTVdo&0Kz6y8s2-nw_3jVImjIb8A3z+B9EB7w1 zvI&{cJ+nOh{}R2p#0-EQW)YB5Q6k!Ywbl*AN*bz5;^A!-eRn%U&b-05<$R{zZ9)Us3fB!%dopptY@z- zq^z`MxL**2>P=@}O?J+Zf_xW;2{DXN-BkxX&?9B9`l_Ys*~_oWYAYg&04JE|`}R$3 zpCbe>KaO~>t}i~1xhn5U1tg}wr=_f`TD$e4pSx`)VDcW+|DUT>+1?=Y8wTBed{fRxTUtHpsyk;a00}<;f@#jxy+U^iMwkGZq3W z7`={J>wYwC|Ft-D%gUZn)^_%uK?c!8Y2knOvv{BNkW_8y!+7rNCH{E(@?U#UUb@vERbBSgA zvwK(4^m1KCboZ?rK=JE134hZBT3)5Sae@y&HZXoo|Gw*oOR$53-c|Fb>M@3b-m9Fa zu9=CPS23190Y0-;TRbS2lgb%xw|~jerQ#KKryu2e0v6zRbk^>!8F^@FyAaX{%Cd@d z&?1kfnAfn3{|bvYa$(Eo_daoi>dN5`Q;fs!MQ|N2S#bF(I_icD$13@3Jqu2-Af)zn z3a{0__cTiT$CU|yw3q+Zj|MKMM=|nMJN@vPc<>=v#Yi)}5c@+R+anblNLX{OAg_j^|v{Vysz^}irp{9Pq5pW4h|I} zSt1VW{A6OSkwpUi9OO?w_u>Q61!E^-+}AO8-5R+%>WX(R15|fZ#AcQqtg+!qO6tLm zVUniX|A}5rwSNor3UgRUg3p*BON+S;v10LftUX!ot^?nx^;M}+e61{ivPDkm$v4~pc@v$=1O4-xbn{RI1h-rF-%6( zeG7QjPI3E81IuY57 zuYJZ)*Bs{0=7)|ab5}V#P5*pgG1$~XSo=`+kh%rcz_Bvq?|2QtijVKHktk!`_sVd0 zXqUt!X9rWDsyPUuRzjKcLIsBv=DSe6zB63Nqu{DygVs97+b*IZM2xE*VjsB{Ka|Be z(j;@_B{GLha34F+2rAG?JT?&;^%Nz1XX_ZfS?%HqN!u1O9cvVqcpJ*)O(?D|8$<9S zR1@NJICY`BWAO+E7jF_KD@~9jARW`n@QNE5x5y&7@0p3bu2hR)5uouU4ittG4u5p(yF^%!%oA)av^PjG-|ngXzg zTIcAl_taafVU7E(BALtK0d~e4UGk*QUFgoythEIa7oi9uRR=CIb?>bZI|sR+LEne# zo%Nh(OJNd<4s#{h3OL*0j+B)Ni-l{J%T-SRmXaPOuhP6{Y2iWoxYG+B(sY=;xH`ST<1PuXn|z<~Efl(1!(E zKyd_DVya!3G-I+&Chz3m*+KHEWUe|yolpbwU3Dp*mc2g48CjJ~*ve|OFNU(cqhO0m zarmm#p%+Yi*nWsUqVb!`8GnGuhEs?(FVv852qto(;Crjd;)p- z?5~S(Th9H`4mNzcM;n(-SU;VGMe7DH?^F4Ln&*IlBp6SD*kvGv3_82(Lvnzg@H`od zUNV1Vy2l$!Cy0{J4Z-M)8WR`Sir0ZcK6_~77He~}^(ZQ*_F4P}Gb%$nk=VjN^uouv zK9S4pODLHp3Vj`}Bl)ZozQ~o6Qb(jzO{1Yzl9D}z+Sb=Qej;qV=Y=mn7X!1IM=ZND zi#2PlY-PaqEuK-wJxbDxo6hQ8h~2SC@_R(e8$%jsn?A9)mBQYhj{vHfb0)_Hf9G5F z#qEx2;Pw=fnXvF|(EGZpKrJ?)F{D=U54gO1l8OUa|CPku3Ipbe6-)mezM)v!B` z8=yCJB0ve$CJgz+aaAX2dY{ZR@iB6$l!}A|bBjoNjt1}(ue`FLsvxQU+pSI3qy!f? zf~jFoxF&NG4=&FLbC;Wm9-~H8RN!D-A1S6BX56KtKq)&>UGA-n*Y2X?K(gza7Zzkv zpPu$9gcqWvEQ=>5jm9a>nyZQy2hDmUaSV(_@BdHh&pzX7a04H~7FF1!90{q=q$)Un z)-=WcG|mdj%dp!2%CJHof5T|TvjEkqKo5QZ9B$SETD@G}_Vc?<;`Vd4K0AL#y2o#tg35X;N7>jM~JKWADABhK&i63{s8}Vi%!ngVuGXjPAd+lzq#64bt zfICt^@M^a%;8Xzn0S|m*mmNWcrtyduXUy|JX$f(z+`^OFNi!hZ3F>NrQ=#UD&nV#* zBRv}L4SAtJimr-i%5cH}j=IHJEWVKU3NrQ^*PLJXV93TunW4L2o%fIvH=r1`{{+lh zEp$*m^q_=pz^2v%mW-_KK=(V{M1eGfxeO9?=T} zVwvuwaJ;#+RDZXP)>Q>;KLpjNrVGEfw-<{|hp1Eqs=+?{#v3OeQ^M1+#lHi82Wt}@6MRQ`u>V)g$NM8>wkB< z6rmKh{C74(x&I1XyU@g?nLI~j5bLrEDIG!q_1Z79LcGhfm|@VPGcB{hgk@R_bw$=B=RP^8~&xWaPUqQv2s!G0 zb~szWww!!_=o?G5OwX&ECW6(z@D2A!hYUIA>)S=Hw;#UD+DQJXc@6nN-q-;q9aThN zWGAYmQ4|&SEI?0qRt86SYtzHh*lT&nJVQ(D^s?i!rlup1h*ScFN&>b&ySi`mj7%L9 zB^qARYc+5eBPJ;W6B-M#5hblp}7AX zXJoF98RGMFYPdt~{sdN69*5i~J-67J``SP2N|nw{L-8NtXvA^9%!fbgL!iq)XMjAf zJ`~6Pw%2ijZVSu||GZ5|;6_bgvdH1DCrS#)e8m9Xn8*u3BVDLKGo-9HT8=?vagGfb z`VIXwBVEC56sjIHt}J-zzk3pXHQzVe9h^rJLZ}4}oO;E%MzK-gfAnE^^@n3s?QB(( z&vN#_>XnM)2k*=f1n)F>YZO>PQMqE(t*5xo1MiHhVUXnpD{YNJcr9g9lh{Y|2ikR@ zh*&i_Fq#iaXuuXe?94p9>pnP)v8*L7hVw>cCdIuf!<);{HZ?$9qd$fwl=Sl&WsnN} z6e@~FFrUc*4}c?x&M6{%z>Z3I4f%O+If#0UYK)7+Laci8+RgIW+42u=;;NQ-AWW8k zcrr!UvKK{2nqCilmNEjYIpEk7aR1GDB4+0zHzE~?_0thn;bZt+?XL(VZ73$-F8~{s z%MateR1Sa1gDMN>Cy}Y)VZOh&Hbr?ziPhW71t6T918>^K*SvD`k~gx@^z#93PCZ*| zZPMIS`}N>(PI8h`9>Pa{M)~PvTYumsc)DE>hfz$#-?=}T{p(<}Oz}mSrLoMW@Kdbl z!Fz#ojIz>{(Zdnv<@?Qym*09}4c`65`IjYl+G!>tlV$xeZ;!?FZqf?n*lR+fCdcv zj=bQNYP=m6i-GW#gn=%WhQQ?#DZ4QxY`zPTf*VJm`7&7|UU5hybGGLuyS^?Mzr7M_z)^D?!Ud!>vVKdoLnjbdj5{(Iev<8f4WY^Y^^LrJ>aYA1v=bg5V z(_NQQvnN$X1-i}{Ws6zKqk9gm_;zHar21a5h4?9B{6b!1ItEp{peBD>VOj1VGJCp) zaNtIhO%|`-9OVy#aXthaDm`I|J4^-Pce86iyo0pnfrjj|!0AM^ngqEJ(C|l-)t6ok zev)%GoN&fBR0~{~JA|rU4qAK~$#^NHeJ11tBUD@ixLN{XfI4&EcmxQBi@Q`v>|++^ z?Ptt>yHF#D-CY}3TT>)KEylgX{0>qYu+R_DpZMY0B$ueU_c*IAHC z$#<`FYj2^sLBw7uLN_N*0|P+N8aAqfPwqWmw5oL_rdknCNE)|CbrX(K4H<-OsIb3p z$^Utw(0*<5qw0P-^S=M|HQiT~^vn^|u1eIL`p~ZQB^&itv~i;yhgcp45aC2MSqDfK zDuy&=$INFq#p4ZOEHywxTJL*kE|((C(Yb{UtzT+W{4_-a{kUY4@57=T5SW`q$}s8K zycbkkBLF|213$)6oYZ75j?1t+9z6bwO%b9TEJ-@tC5d8GNs>v?$BO-hn&qxTtH$v6 zw>^-9{k+?c>INC0H-#1Pl%-cs-NW0#_6{b5}2P~Y5$wqOuT24yUUj|U~w1M_hN5*^= zdnAZyj-{7X@qns1a}lrILI&rXhx?@WaS3-kK=_~rxj&A^RYbY#^wTEI+^xnG9zu z@=GU$5?{2C95)l9OhrOkY3EuTeJr(Y$nPLc>5ISe44$@>r2#u85lIKC9jXBjO&-SV zvDope4-7{K-^y9UrkgKBSQAEnl6EmPjvYg)pJG-zw&GJhZ^hPp+K7k@GFQ0GP-4wb zeRkNY6&WyVOW%q5Y6qO>0f01M9o{NpI8|(684knu^(ltqv|7{F3AyMwf8MG4$9YVL zcxE*zHwDy@UWL5HD(w>;4*Q6--R0~uMj4IZDU?MkD#=iK5>mvlb|#BWq7@ak)9ldvK}EYv*xngka(B%6MM78 zReb8;9>+|}S)9j+gZ)2`frRjHMtol%5bdO(9f-p_i$WK9p`q%_^e|Lc84wYM>Ju;1 zPyN{md>IVWwaOmaGZahDClyPPHq2?mkFbr$kg1i^u8x>54cqmR7fx}uPe&s|OEQ-G z>(i6GE$Qh2=53;FiutXLLI$V(=A6N|{QI`|pcPW#HNR0|*9nhbWsXAFd=PqWkBdmB zjr6l5ImEOf6_D7MqLJYRBGKEZyY&7j!?XwKbtM-2zcwdw7}xsT<1NYp$<5CG*~(`O z3kS8Bd*;FSBdWgavghMu{tN-;avTJR-ug8OW%a^O554`c1@7CSYY?%5C_Y&=GGjv0 z7uLY@JiU5rWu->GlWZ1rqiVezUnbfOTi{`$!r zL?$kpPSY%!t=V?RQNplg)!&^|M~A@tz^c@0Q=>uz{nHwMdJbOm-*z8VuGbDP6JA2y z@DM*RNh}oo=IYem-r)RU#+R-Mm#xwN@2R}*JeD!yu`Ue-06?n$?~Q<1w(a_6 zi-n5_+VWOI8fAAfCCTc`<{o3M7nkd(N4GL9?@+p^k= zi#7~l5-Wm06@$GuaPxtd_w>jPt2&GR?waWcm@j&B;INlsITP9{&rvpNH49Iw5V_!M{q5n%&IK@FAJm(R&pUR;5_1D$OxD&vE>KE1?KKV!rml zKs{&TaIh~XrmU@kL%kEt#G-fTA8%m&b7e|bjm`t3-5@BK)7`veaf*7VZ0d*=;g3$O z5{h$(j5R}}_-DCH8J{^!03+mwJnqm}WJ|?Ot2=rgQ96nu2Ev^7V=7s9dN@mwl>k_cL7Q*m8+v6Ah9HnKEW1LhyIZmy=|(Gf-~{a zORy8~%a3XC_p+l$=KL%hF8J=uuX6#Li~^7PAA>=}rG|v3ak!F}&X|IOV;|XX>u7%m zAIR(_E51qI5E;$mjrl5kpr5BiyFaNtIhwCj`&73{wL!Ta_UGEeDA)n+&8M+C;=Q@Z z6#TkI0;g-VM7ilKhmV(gd3Z(wQYNl{Yy_d<}IxkM>n zL%2!}U(2GcJJufl4<{p_=-d?H8V2T;g}XO%!k}bM|3I52JU{i2`h{FMz33!1rvh`? zanO^@fcEfj&^dEy;U3eXghl~h(4qF7cHHu1!o*2za(g=pjA(A|C)S#R)0;2dWOPHW zT&@wmM@Uz-&&c!R(W3UhT+x>;xd}M28O{T6Uq)?%lonv8v_-6O3shl79+_+lak~XQ z1dtiSzEVtmJHjug8XZr;F?KB<6+dY8aiAb2u*65ark8uOciWNjNLhTRaZLV4^RPC) zE8%sd&YEF}As>jRz8-!xf0q|LMMZPSlQ5VozM*PGKr`@(C|22C6^tDa zjes~%>Q3}}dV0E+=gtwU>MgO+_F?x9nF`Q28&${jHJAvx)P-LA`J5sf-9~o@ z;edSXe%bCe)#INjl)1@ENZ@EDf3|Vv&{F+E1Rv!kpxmjbYO(sAUQ9PX=t+WIyn)6@ z2lE+&x}V;y{7U9=(CY)rOWcN>HrhsYAt{^atFw)Qb6wZVRXl9G#Bl;8QwR@VT4p#8 zgN8faMs?5v`yk@!oy4Dqx{V_m3$odQO$!bcF@))PEBzaw1&WPt(J_tun)xaN;W~04 z!K?u+B{)*$pASNjQ5k+&;#_BTM_lK+G6W9pu0t_*pfyz%H#Xz~TLojlWKG1yA6^0y ze+?!Lm)gHB)JDq1^&~XBG#HfR5u2nWE$lN%z8>|C7#OX@mnO%j9-GzSgFAT@njy1j zGOo1L8H;*9EwNei6S``VKZahO#5F*bH161R9QTZ3K^A<*q+E^*?SA*jk7ToetUASJ zTT@dIov&BsR|TS^wCL66<{yaI3t(G*%PBS8Gb+(!QV;~5x22ddK#~5GsrR!-%Z50+ zAEmlgSLEPA68fog$(a|&&d3|Y`^MX}*J{^)5~72w75;BI(j9I%3qBdN1)?+A!-rgtr))1nnz{j` zuEr;K^hN=^ns5KMN$@SCT}eueS<@b^lbQ}IZ__Oa{Ycl?<@}pv{Teus>j>RAHt set type=SOA -> server ns1.openminds.be -> linux-training.be -Server: ns1.openminds.be -Address: 195.47.215.14#53 - -linux-training.be - origin = ns1.openminds.be - mail addr = hostmaster.openminds.be - serial = 2321001133 - refresh = 14400 - retry = 3600 - expire = 604800 - minimum = 3600 -``` - -Zone transfers only occur when the zone database was updated (meaning when one or more resource records were added, removed or changed on the master server). The slave server will compare the *serial number* of its own copy of the SOA record with the serial number of its master's SOA record. When both serial numbers are the same, then no update is needed (because no records were added, removed or deleted). When the slave has a lower serial number than its master, then a zone transfer is requested. - -Below a zone transfer captured in wireshark. - -![](assets/dns_zone_transfer.jpg) - -## full or incremental zone transfers - -When a zone tranfer occurs, this can be either a full zone transfer or an incremental zone transfer. The decision depends on the size of the transfer that is needed to completely update the zone on the slave server. An incremental zone transfer is prefered when the total size of changes is smaller than the size of the zone database. Full zone transfers use the *axfr* protocol, incremental zone transfer use the *ixfr* protocol. - -## DNS cache - -DNS is a caching protocol. - -When a client queries its local DNS server, and the local DNS server is not authoritative for the query, then this server will go looking for an authoritative name server in the DNS tree. The local name server will first query a root server, then a *TLD* server and then a domain server. When the local name server resolves the query, then it will relay this information to the client that submitted the query, and it will also keep a copy of these queries in its cache. So when a(nother) client submits the same query to this name server, then it will retrieve this information form its cache. - -For example, a client queries for the A record on *www.linux-training.be* to its local server. This is the first query ever received by this local server. The local server checks that it is not authoritative for the linux-training.be domain, nor for the *.be tld*, and it is also not a root server. So the local server will use the root hints to send an *iterative* query to a root server. - -The root server will reply with a reference to the server that is authoritative for the .be domain (root DNS servers do not resolve fqdn's, and root servers do not respond to recursive queries). - -The local server will then sent an iterative query to the authoritative server for the *.be tld*. This server will respond with a reference to the name server that is authoritative for the linux-training.be domain. - -The local server will then sent the query for *www.linux-training.be* to the authoritative server (or one of its slave servers) for the linux-training.be domain. When the local server receives the ip address for *www.linux-training.be*, then it will provide this information to the client that submitted this query. - -Besides caching the A record for *www.linux-training.be*, the local server -will also cache the NS and A record for the linux-training.be name -server and the .be name server. - -## forward lookup zone example - -The way to set up zones in `/etc/bind/named.conf.local` is to create a zone entry with a reference to another file (this other file contains the *zone database*). - -Here is an example of such an entry in `/etc/bind/named.conf.local`: - -```text -// -// Do any local configuration here -// - -// Consider adding the 1918 zones here, if they are not used in your -// organization -//include "/etc/bind/zones.rfc1918"; - -zone "paul.local" IN { - type master; - file "/etc/bind/db.paul.local"; - allow-update { none; }; -}; -``` - -To create the zone file, the easy method is to copy an existing zone file (this is easier than writing from scratch). - -```console -root@linux:/etc/bind# cp db.empty db.paul.local -root@linux:/etc/bind# vi db.paul.local -``` - -Here is an example of a zone file. - -```console -root@linux:/etc/bind# cat db.paul.local -; zone for classroom teaching -$TTL 86400 -@ IN SOA debianpaul.paul.local. root.paul.local ( - 2014100100 ; Serial - 1h ; Refresh - 1h ; Retry - 2h ; Expire - 86400 ) ; Negative Cache TTL -; -; name servers -; - IN NS ns1 - IN NS debianpaul - IN NS debian10 -; -; servers -; -debianpaul IN A 10.104.33.30 -debian10 IN A 10.104.33.30 -ns1 IN A 10.104.33.30 -;www IN A 10.104.33.30 -``` - -## example: caching only DNS server - -1. installing DNS software on Debian - - student@debian:~# apt update && apt upgrade - ... - student@debian:~$ aptitude install bind9 - ... - student@debian:~$ dpkg -l | grep bind9 | tr -s ' ' - ii bind9 1:9.8.4.dfsg.P1-6+nmu2+deb7u2 amd64 Internet Domain Name Server - ii bind9-host 1:9.8.4.dfsg.P1-6+nmu2+deb7u2 amd64 Version of 'host' bundled... - ii bind9utils 1:9.8.4.dfsg.P1-6+nmu2+deb7u2 amd64 Utilities for BIND - ii libbind9-80 1:9.8.4.dfsg.P1-6+nmu2+deb7u2 amd64 BIND9 Shared Library use... - student@debian:~$ - -2. Discover the default configuration files. Can you define the purpose -of each file ? - - student@debian:~$ ls -l /etc/bind - total 52 - -rw-r--r-- 1 root root 2389 Sep 5 20:25 bind.keys - -rw-r--r-- 1 root root 237 Sep 5 20:25 db.0 - -rw-r--r-- 1 root root 271 Sep 5 20:25 db.127 - -rw-r--r-- 1 root root 237 Sep 5 20:25 db.255 - -rw-r--r-- 1 root root 353 Sep 5 20:25 db.empty - -rw-r--r-- 1 root root 270 Sep 5 20:25 db.local - -rw-r--r-- 1 root root 3048 Sep 5 20:25 db.root - -rw-r--r-- 1 root bind 463 Sep 5 20:25 named.conf - -rw-r--r-- 1 root bind 490 Sep 5 20:25 named.conf.default-zones - -rw-r--r-- 1 root bind 374 Oct 1 20:01 named.conf.local - -rw-r--r-- 1 root bind 913 Oct 1 13:24 named.conf.options - -rw-r----- 1 bind bind 77 Oct 1 11:14 rndc.key - -rw-r--r-- 1 root root 1317 Sep 5 20:25 zones.rfc191 - -3. Setup caching only dns server. This is normally the default setup. A -caching-only name server will look up names for you and cache them. Many -tutorials will tell you to add a *forwarder*, but we first try without -this! - -Hey this seems to work without a *forwarder*. Using a sniffer you can -find out what really happens. Your freshly install dns server is not -using a cache, and it is not using your local dns server (from -/etc/resolv.conf). So where is this information coming from ? And what -can you learn from sniffing this dns traffic ? - -4. Explain in detail what happens when you enable a caching only dns -server without forwarder. This wireshark screenshot can help, but you -learn more by sniffing the traffic yourself. - -![](assets/wireshark_org_server.jpg) - -You should see traffic to a *root name server* whenever you try a new -*TLD* for the first time. Remember that *DNS* is a caching protocol, -which means that repeating a query will generate a lot less traffic -since your *dns server* will still have the answer in its memory. - - - -## example: caching only with forwarder - -5. Add the public Google *dns server* as a *forwarder*. The ip address -of this server is 8.8.8.8 . - -Before the change: - - student@debian:~$ grep -A2 'forwarders {' /etc/bind/named.conf.options - // forwarders { - // 0.0.0.0; - // }; - -changing: - - student@debian:~$ vi /etc/bind/named.conf.options - -After the change: - - student@debian:~$ grep -A2 'forwarders {' /etc/bind/named.conf.options - forwarders { - 8.8.8.8; - }; - -Restart the server: - - student@debian:~$ service bind9 restart - Stopping domain name service...: bind9. - Starting domain name service...: bind9. - -6. Explain the purpose of adding the *forwarder*. What is our -*dns server* doing when it receives a query ? - - student@debian:~$ nslookup - > server - Default server: 10.104.33.30 - Address: 10.104.33.30#53 - > linux-training.be - Server: 10.104.33.30 - Address: 10.104.33.30#53 - - Non-authoritative answer: - Name: linux-training.be - Address: 188.93.155.87 - > - -This is the output of `tcpdump udp port 53` while executing the above -query for `linux-training.be` in `nslookup`. - - student@debian:~$ tcpdump udp port 53 - tcpdump: verbose output suppressed, use -v or -vv for full protocol decode - listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes - -You should find the following two lines in the output of `tcpdump`: - - 10.104.33.30.19381 > google-public-dns-a.google.com.domain: 18237+% [1au] A? \ - linux-training.be. (46) - google-public-dns-a.google.com.domain > 10.104.33.30.19381: 18237 1/0/1 A 188\ - .93.155.87 (62) - -Below is an (old) wireshark screenshot that can help, you should see -something similar (but with different ip addresses). - -![](assets/dns_forwarder.jpg) - -7. What happens when you query for the same domain name more than once -? - -8. Why does it say \"non-authoritative answer\" ? When is a dns server -authoritative ? - -9. You can also use `dig` instead of `nslookup`. - - student@debian:~$ dig @10.104.33.30 linux-training.be +short - 188.93.155.87 - student@debian:~$ - -10. How can we avoid having to set the server in dig or nslookup ? - -Change this: - - student@debian:~$ cat /etc/resolv.conf - nameserver 10.46.101.1 - student@debian:~$ - -into this: - - student@debian:~$ cat /etc/resolv.conf - nameserver 10.104.33.30 - student@debian:~$ - -11. When you use `dig` for the first time for a domain, where is the -answer coming from ? And the second time ? How can you tell ? - -## example: primary authoritative server - -1. Instead of only cachng the information from other servers, we will -now make our server authoritative for our own domain. - -2. I choose the top level domain `.local` and the domain `paul.local` -and put the information in `/etc/bind/named.conf.local`. - - student@debian:~$ cat /etc/bind/named.conf.local - // - // Do any local configuration here - // - - // Consider adding the 1918 zones here, if they are not used in your - // organization - //include "/etc/bind/zones.rfc1918"; - - zone "paul.local" IN { - type master; - file "/etc/bind/db.paul.local"; - allow-update { none; }; - }; - -3. Also add a *zone database file*, similar to this one (add some A -records for testing). Set the *Refresh* and *Retry* values not too high -so you can sniff this traffic (this example makes the slave server -contact the master every hour). - - student@debian:~$ cat /etc/bind/db.paul.local - ; zone for classroom teaching - $TTL 86400 - @ IN SOA debianpaul.paul.local. root.paul.local ( - 2014100101 ; Serial - 1h ; Refresh - 1h ; Retry - 2h ; Expire - 900 ) ; Negative Cache TTL - ; - ; name servers - ; - IN NS ns1 - IN NS debianpaul - IN NS debian10 - ; - ; servers - ; - debianpaul IN A 10.104.33.30 - debian10 IN A 10.104.33.30 - ns1 IN A 10.104.33.30 - ;www IN A 10.104.33.30 - student@debian:~$ - -Note that the *www* record is commented out, so it will not resolve. - -### using your own DNS server - -If you are confident that your *dns server* works, then set it as -default and only dns server in `/etc/resolv.conf`. - - student@debian:~$ cat /etc/resolv.conf - nameserver 10.104.33.30 - student@debian:~$ - -In case you also use `dhclient`, you will need to add your dns server to -`/etc/dhcp/dhclient.conf`. - - student@debian:~$ diff /etc/dhcp/dhclient.conf /etc/dhcp/dhclient.conf.original - 21c21 - < prepend domain-name-servers 10.104.33.30; - --- - > #prepend domain-name-servers 127.0.0.1; - 23,24c23 - < # domain-name, domain-name-servers, domain-search, host-name, - < domain-name, domain-search, host-name, - --- - > domain-name, domain-name-servers, domain-search, host-name, - student@debian:~$ - -The above screenshot shows that 10.104.33.30 is now a default option -that the *dhcp client* should no longer request from the *dhcp server*. - -Adjust `/etc/hosts` to reflect your *domain name* and verify with -`hostname` and `dnsdomainname`. - - student@debian:~$ grep debian10 /etc/hosts - 127.0.1.1 debian10.paul.local debian10 - student@debian:~$ hostname - debian10 - student@debian:~$ hostname --fqdn - debian10.paul.local - student@debian:~$ dnsdomainname - paul.local - -### using your own domain - -Consider the following screenshot: - - student@debian:~$ cat /etc/resolv.conf - nameserver 10.104.33.30 - student@debian:~$ ping -c1 www - ping: unknown host www - student@debian:~$ vi /etc/resolv.conf - student@debian:~$ cat /etc/resolv.conf - nameserver 10.104.33.30 - domain paul.local - student@debian:~$ ping -c1 www - PING www.paul.local (10.104.33.31) 56(84) bytes of data. - 64 bytes from 10.104.33.31: icmp_req=1 ttl=64 time=0.021 ms - - --- www.paul.local ping statistics --- - 1 packets transmitted, 1 received, 0% packet loss, time 0ms - rtt min/avg/max/mdev = 0.021/0.021/0.021/0.000 ms - student@debian:~$ - -Adding the *domain paul.local* directive to `/etc/resolv.conf` allows -omitting the domain when using hostnames. - -You can accomplish this feature automatically by adjusting -`dhclient.conf`. - - student@debian:~$ grep paul.local /etc/dhcp/dhclient.conf - prepend domain-name "paul.local"; - prepend domain-search "paul.local"; - student@debian:~$ - -4. Restart the DNS server and check your zone in the error log. - - student@debian:~$ service bind9 restart - Stopping domain name service...: bind9. - Starting domain name service...: bind9. - student@debian:~$ grep paul.local /var/log/syslog - Oct 6 09:22:18 debian10 named[2707]: zone paul.local/IN: loaded seria\ - l 2014100101 - Oct 6 09:22:18 debian10 named[2707]: zone paul.local/IN: sending noti\ - fies (serial 2014100101) - -5. Use `dig` or `nslookup` (or even `ping`) to test your A records. - - student@debian:~$ ping -c1 ns1.paul.local - PING ns1.paul.local (10.104.33.30) 56(84) bytes of data. - 64 bytes from 10.104.33.30: icmp_req=1 ttl=64 time=0.006 ms - - --- ns1.paul.local ping statistics --- - 1 packets transmitted, 1 received, 0% packet loss, time 0ms - rtt min/avg/max/mdev = 0.006/0.006/0.006/0.000 ms - student@debian:~$ ping -c1 www.paul.local - ping: unknown host www.paul.local - -Note that the *www* record was commented out, so it should fail. - - student@debian:~$ dig debian10.paul.local - - ; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> debian10.paul.local - ;; global options: +cmd - ;; Got answer: - ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50491 - ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 2 - - ;; QUESTION SECTION: - ;debian10.paul.local. IN A - - ;; ANSWER SECTION: - debian10.paul.local. 86400 IN A 10.104.33.30 - - ;; AUTHORITY SECTION: - paul.local. 86400 IN NS ns1.paul.local. - paul.local. 86400 IN NS debian10.paul.local. - paul.local. 86400 IN NS debianpaul.paul.local. - - ;; ADDITIONAL SECTION: - ns1.paul.local. 86400 IN A 10.104.33.30 - debianpaul.paul.local. 86400 IN A 10.104.33.30 - - ;; Query time: 4 msec - ;; SERVER: 10.104.33.30#53(10.104.33.30) - ;; WHEN: Mon Oct 6 09:35:25 2014 - ;; MSG SIZE rcvd: 141 - - student@debian:~$ - -6. Our primary server appears to be up and running. Note the -information here: - - server os : Debian 7 - ip address : 10.104.33.30 - domain name: paul.local - server name: ns1.paul.local - -## example: a DNS slave server - -1. A slave server transfers zone information over the network from a -master server (a slave can also be a master). A primary server maintains -zone records in its local file system. As an exercise, and to verify the -work of all students, set up a slave server of all the master servers in -the classroom. - -2. Before configuring the slave server, we may have to allow transfers -from our zone to this server. Remember that this is not very secure -since transfers are in clear text and limited to an ip address. This -example follows our demo from above. - -Imagine a student named *Jesse* having completed the setup as shown -before, with the domain name *jesse.local* and the ip address -10.104.15.20. The goal is to have a slave server of paul.local on -Jesse's computer and a slave zone of jesse.local on my computer. - -Below is an example of an `allow-transfer` statement. Careful, maybe the -default allows transfer to any. - - root@linux:/etc/bind# cat named.conf.local - // - // Do any local configuration here - // - - // Consider adding the 1918 zones here, if they are not used in your - // organization - //include "/etc/bind/zones.rfc1918"; - - zone "paul.local" IN { - type master; - file "/etc/bind/db.paul.local"; - allow-update { none; }; - allow-transfer { 10.104.15.20; }; - }; - -3. With the configuration below I can make my server a slave for the -`jesse.local` zone. - - root@linux:/etc/bind# tail -6 named.conf.local - zone "jesse.local" IN { - type slave; - file "/var/cache/named/db.jesse.local"; - masters { 10.104.15.20; }; - }; - - root@linux:/etc/bind# mkdir /var/cache/named/ - root@linux:/etc/bind# chown bind:bind /var/cache/named/ - root@linux:/etc/bind# ls -ld /var/cache/named/ - drwxr-xr-x 2 bind bind 4096 Oct 1 20:01 /var/cache/named/ - -Note that we put the *slave zones* in `/var/cache/named` and not in -`/etc/bind`. - -4. Restarting bind on the slave server should transfer the zone -database file. Verify this in `/var/log/syslog`. (time and date are -truncated from the screenshot, and Jesse did not use the current date in -the serial number...) - - root@linux:/etc/bind# grep jesse /var/log/syslog - named[2731]: zone jesse.local/IN: Transfer started. - named[2731]: transfer of 'jesse.local/IN' from 10.104.15.20#53: connected u\ - sing 10.104.33.30#44719 - named[2731]: zone jesse.local/IN: transferred serial 20110516 - named[2731]: transfer of 'jesse.local/IN' from 10.104.15.20#53: Transfer co\ - mpleted: 1 messages, 8 records, 239 bytes, 0.001 secs (239000 bytes/sec) - -And the contents of the *slave zone*: - - root@linux:/etc/bind# cat /var/cache/named/db.jesse.local - $ORIGIN . - $TTL 604800 ; 1 week - jesse.local IN SOA ns.jesse.local. root.jesse.local.jesse.local. ( - 20110516 ; serial - 300 ; refresh (5 minutes) - 200 ; retry (3 minutes 20 seconds) - 2419200 ; expire (4 weeks) - 604800 ; minimum (1 week) - ) - NS ns.jesse.local. - $ORIGIN jesse.local. - anya A 10.104.15.1 - mac A 10.104.15.30 - ns A 10.104.15.20 - ubu1010srv A 10.104.15.20 - www A 10.104.15.25 - root@linux:/etc/bind# -