# DNS Self-Resolver Setup
## Make the Server Use Itself for DNS

This lesson configures the DNS server to resolve queries through its own local BIND instance.
The target state is simple:
- Applications on the server send DNS queries locally.
- Local resolver (BIND9) handles recursion/forwarding.
- The server no longer depends on external DNS configured directly on the host.

Network profile for this setup:
- Server IP: `10.10.10.250`
- Home subnet: `10.10.10.0/24`
- Local domain: `codeandcore.home`

Design intent:
- This server is authoritative for the local zone `codeandcore.home`.
- Clients on `10.10.10.0/24` should use `10.10.10.250` as DNS.
- Example expected hostname: `iphone.codeandcore.home`.

---

## Lesson 1: Confirm BIND Can Answer Locally
Objective: verify BIND9 is listening on loopback and can answer direct local queries.

Interpret:
- This lesson teaches that self-resolution only works if BIND is reachable on local addresses.
- You verify local query path first before changing host resolver settings.

Run:
```bash
sudo named-checkconf
sudo systemctl restart bind9
sudo systemctl status bind9 --no-pager
dig @127.0.0.1 google.com A
```

Checkpoint:
- `bind9` is active.
- `dig @127.0.0.1 ...` returns `NOERROR` with valid answers.

---

## Lesson 2: Configure Authoritative Local Zone (codeandcore.home)
Objective: make this server authoritative for your home namespace.

Interpret:
- This lesson teaches the difference between recursive internet lookups and authoritative local answers.
- You verify local hostnames are served from your own zone file.

Run:
```bash
sudo tee /etc/bind/named.conf.local >/dev/null <<'EOF'
zone "codeandcore.home" {
	type master;
	file "/etc/bind/db.codeandcore.home";
	allow-update { none; };
};
EOF

sudo tee /etc/bind/db.codeandcore.home >/dev/null <<'EOF'
$TTL 86400
@   IN  SOA ns1.codeandcore.home. admin.codeandcore.home. (
		2026051201 ; serial
		3600       ; refresh
		1800       ; retry
		1209600    ; expire
		86400 )    ; minimum

@       IN  NS  ns1.codeandcore.home.
ns1     IN  A   10.10.10.250
dns     IN  A   10.10.10.250
router  IN  A   10.10.10.10
iphone  IN  A   10.10.10.50
EOF

sudo named-checkconf
sudo systemctl restart bind9
dig @10.10.10.250 iphone.codeandcore.home A
```

Checkpoint:
- `iphone.codeandcore.home` resolves from `10.10.10.250` with `NOERROR`.
- Zone loads without syntax errors.

---

## Lesson 3: Make Clients Use 10.10.10.250 as DNS
Objective: ensure the whole `10.10.10.0/24` network uses this server for DNS.

Interpret:
- This lesson teaches DHCP-based DNS distribution to clients.
- You verify each client receives DNS server `10.10.10.250` and domain `codeandcore.home`.

Run:
1. Set router DHCP DNS option to `10.10.10.250`.
2. Set DHCP domain/search suffix to `codeandcore.home`.
3. Renew client DHCP leases.

MikroTik example:
```bash
/ip dhcp-server network set [find address="10.10.10.0/24"] \
	gateway=10.10.10.10 dns-server=10.10.10.250 domain=codeandcore.home
```

Checkpoint:
- Client lease shows DNS `10.10.10.250`.
- Client can resolve `iphone.codeandcore.home`.

---

## Lesson 4: Point Ubuntu Resolver to Local BIND
Objective: configure `systemd-resolved` to forward DNS to `127.0.0.1`.

Interpret:
- This lesson teaches safe host-level DNS redirection without breaking modern Ubuntu resolver flow.
- You verify that the host resolver now forwards requests to local BIND instead of public resolvers directly.

Run:
```bash
sudo cp /etc/systemd/resolved.conf /etc/systemd/resolved.conf.bak
sudo tee /etc/systemd/resolved.conf >/dev/null <<'EOF'
[Resolve]
DNS=127.0.0.1
FallbackDNS=
Domains=~.
EOF
sudo systemctl restart systemd-resolved
resolvectl status
```

Checkpoint:
- `resolvectl status` shows DNS server as `127.0.0.1` for the host.
- No resolver restart errors are shown.

---

## Lesson 5: Verify End-to-End Self-Resolution
Objective: prove default host DNS requests now use local resolver path.

Interpret:
- This lesson teaches validation at two levels: default resolver behavior and BIND query logging.
- You verify that host queries generate entries in BIND logs, proving local dependency.

Run:
```bash
getent hosts cloudflare.com
dig cloudflare.com A
dig @10.10.10.250 iphone.codeandcore.home A
sudo tail -n 20 /var/log/named/queries.log
```

Checkpoint:
- `getent` and `dig` succeed without specifying an external nameserver.
- `iphone.codeandcore.home` resolves through `10.10.10.250`.
- Query lines appear in `/var/log/named/queries.log` for those tests.

---

## Troubleshooting

### Symptom: `dig @127.0.0.1 ...` fails
Interpret:
- BIND is not healthy or not listening locally.

Run:
```bash
sudo systemctl status bind9 --no-pager
sudo journalctl -u bind9 -n 50
sudo named-checkconf
```

### Symptom: host lookup fails but `dig @127.0.0.1 ...` works
Interpret:
- Host resolver path is wrong, even though BIND itself works.

Run:
```bash
resolvectl status
sudo systemctl status systemd-resolved --no-pager
sudo journalctl -u systemd-resolved -n 50
```

### Symptom: no query lines in `/var/log/named/queries.log`
Interpret:
- Logging block or directory permissions are incorrect.

Run:
```bash
ls -ld /var/log/named
sudo journalctl -u bind9 -n 50
```

---

## Completion Standard
Setup is complete when all are true:
1. `dig @127.0.0.1 google.com A` succeeds.
2. `resolvectl status` shows DNS as `127.0.0.1`.
3. `dig google.com A` (no `@server`) succeeds.
4. Clients in `10.10.10.0/24` use `10.10.10.250` as DNS.
5. `dig @10.10.10.250 iphone.codeandcore.home A` succeeds.
6. Host-generated queries appear in `/var/log/named/queries.log`.
