KVM-02 DNS Configuration
Context
Adding kvm-02 (10.50.1.111) and ipmi-02 (10.50.1.201) to BIND zones. Replacing decommissioned netscaler entries with hypervisor records.
Pre-flight: Inspect Zone Files
Forward Zone Structure
awk '{print NR": "$0}' <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone") | less
grep -n "kvm\|netscaler\|Hypervisor\|Load Balancer" <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
awk 'NR>=74 && NR<=90 {print NR": "$0}' <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
Reverse Zone Structure
cat <(ssh bind-01 "sudo cat /var/named/10.50.1.rev")
grep -n "110\|111\|200\|201" <(ssh bind-01 "sudo cat /var/named/10.50.1.rev")
Forward Zone Modifications
Step 1: Backup
ssh bind-01 "sudo cp /var/named/inside.domusdigitalis.dev.zone /var/named/inside.domusdigitalis.dev.zone.bak-$(date +%Y%m%d)"
Verify backup (no output = identical = success)
diff <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone") <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone.bak-$(date +%Y%m%d)")
Step 2: Replace Load Balancers with Hypervisors
ssh bind-01 "sudo sed -i '
/; Load Balancers/c\; Hypervisors (.110-119)
/netscaler-01/d
/netscaler-02/c\kvm-02 IN A 10.50.1.111
' /var/named/inside.domusdigitalis.dev.zone"
Validate Step 2
grep -n "Hypervisor\|kvm-02" <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
grep -n "netscaler\|Load Balancer" <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
Step 3: Add ipmi-02
ssh bind-01 "sudo sed -i '/ipmi-01.*10.50.1.200/a\ipmi-02 IN A 10.50.1.201' /var/named/inside.domusdigitalis.dev.zone"
Validate Step 3
grep -n "ipmi" <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
Step 4: Remove stale lb CNAME
ssh bind-01 "sudo sed -i '/lb.*CNAME.*netscaler/d' /var/named/inside.domusdigitalis.dev.zone"
Validate Step 4
grep -n "CNAME" <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
Step 5: Increment serial
ssh bind-01 "sudo sed -i 's/2026022401/2026030101/' /var/named/inside.domusdigitalis.dev.zone"
Validate Step 5
awk 'NR>=2 && NR<=4 {print NR": "$0}' <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
Step 6: Final verification
Diff backup vs current (shows what changed)
diff <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone.bak-$(date +%Y%m%d)") <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
View modified section
awk 'NR>=74 && NR<=92 {print NR": "$0}' <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
Confirm new records exist
grep -n "kvm-02\|ipmi-02\|Hypervisor" <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
Confirm stale records removed
grep -n "netscaler\|Load Balancer" <(ssh bind-01 "sudo cat /var/named/inside.domusdigitalis.dev.zone")
Reverse Zone Modifications
Step 7: Backup reverse zone
ssh bind-01 "sudo cp /var/named/10.50.1.rev /var/named/10.50.1.rev.bak-$(date +%Y%m%d)"
Validate backup (no output = identical = success)
diff <(ssh bind-01 "sudo cat /var/named/10.50.1.rev") <(ssh bind-01 "sudo cat /var/named/10.50.1.rev.bak-$(date +%Y%m%d)")
Inspect current reverse zone structure
cat <(ssh bind-01 "sudo cat /var/named/10.50.1.rev")
grep -n "110\|111\|200\|201\|netscaler\|ipmi" <(ssh bind-01 "sudo cat /var/named/10.50.1.rev")
Step 8: Add ipmi-02 PTR
ssh bind-01 "sudo sed -i '/^200.*ipmi-01/a\201 IN PTR ipmi-02.inside.domusdigitalis.dev.' /var/named/10.50.1.rev"
Validate Step 8
grep -n "200\|201\|ipmi" <(ssh bind-01 "sudo cat /var/named/10.50.1.rev")
Step 9: Replace netscaler PTRs with kvm-02
ssh bind-01 "sudo sed -i '/^110.*netscaler-01/d' /var/named/10.50.1.rev"
ssh bind-01 "sudo sed -i '/^111.*netscaler-02/c\111 IN PTR kvm-02.inside.domusdigitalis.dev.' /var/named/10.50.1.rev"
Validate Step 9
grep -n "110\|111\|kvm\|netscaler" <(ssh bind-01 "sudo cat /var/named/10.50.1.rev")
Step 10: Final reverse zone verification
Diff backup vs current
diff <(ssh bind-01 "sudo cat /var/named/10.50.1.rev.bak-$(date +%Y%m%d)") <(ssh bind-01 "sudo cat /var/named/10.50.1.rev")
Confirm no stale records
grep -n "netscaler" <(ssh bind-01 "sudo cat /var/named/10.50.1.rev")
Reload and Validate
Step 10: Reload BIND
ssh bind-01 "sudo rndc reload"
Step 11: Test forward resolution
dig +short kvm-02.inside.domusdigitalis.dev @10.50.1.90
dig +short ipmi-02.inside.domusdigitalis.dev @10.50.1.90
Step 12: Test reverse resolution
dig +short -x 10.50.1.111 @10.50.1.90
dig +short -x 10.50.1.201 @10.50.1.90
pfSense DNS Overrides
Load credentials
dsource d000 dev/network
Pre-flight: View current state
netapi pfsense dns list | grep -E "netscaler|kvm|ipmi"
Remove stale netscaler entries
Use --id from list output. IDs may shift after each delete - re-check!
|
netapi pfsense dns list | grep -E "netscaler"
netapi pfsense dns delete --id 30
Validate delete (no output = both gone)
netapi pfsense dns list | grep -E "netscaler"
Add kvm-02
netapi pfsense dns add -h kvm-02 -d inside.domusdigitalis.dev -i 10.50.1.111 --descr "KVM hypervisor 02"
Validate add
netapi pfsense dns list | grep -E "kvm-02"
Add ipmi-02
netapi pfsense dns add -h ipmi-02 -d inside.domusdigitalis.dev -i 10.50.1.201 --descr "KVM-02 BMC"
Validate add
netapi pfsense dns list | grep -E "ipmi-02"
Final pfSense verification
netapi pfsense dns list | grep -E "kvm|ipmi"
Expected output
β 12 β ipmi-01 β inside.domusdigitalis.dev β 10.50.1.200 β KVM Host IPMI/BMC β β 13 β ipmi-02 β inside.domusdigitalis.dev β 10.50.1.201 β KVM-02 BMC β β 26 β kvm-01 β inside.domusdigitalis.dev β 10.50.1.99 β KVM Hypervisor Host β β 27 β kvm-01-lan β inside.domusdigitalis.dev β 192.168.1.225 β β β 28 β kvm-02 β inside.domusdigitalis.dev β 10.50.1.111 β KVM hypervisor 02 β
dig +short kvm-02.inside.domusdigitalis.dev @10.50.1.1
dig +short ipmi-02.inside.domusdigitalis.dev @10.50.1.1
Validation Loops and Patterns
Loop through hosts with dig
for host in kvm-02 ipmi-02; do
echo "=== $host ==="
dig +short "$host.inside.domusdigitalis.dev" @10.50.1.90
done
Validate both BIND and pfSense resolve same
for host in kvm-02 ipmi-02; do
bind=$(dig +short "$host.inside.domusdigitalis.dev" @10.50.1.90)
pf=$(dig +short "$host.inside.domusdigitalis.dev" @10.50.1.1)
echo "$host: BIND=$bind pfSense=$pf $([ "$bind" = "$pf" ] && echo 'β' || echo 'MISMATCH')"
done
Reverse lookup validation
for ip in 10.50.1.111 10.50.1.201; do
echo "$ip -> $(dig +short -x $ip @10.50.1.90)"
done
Check all hypervisor IPs (.110-.119)
for i in {110..119}; do
result=$(dig +short -x "10.50.1.$i" @10.50.1.90)
[ -n "$result" ] && echo "10.50.1.$i -> $result"
done
Regex with actual input
netapi pfsense dns list | grep -E "10\.50\.1\.11[0-9]"
netapi pfsense dns list | awk '$4 ~ /10\.50\.1\.11[0-9]/'
Compare DNS servers with process substitution
diff <(dig +short kvm-02.inside.domusdigitalis.dev @10.50.1.90) <(dig +short kvm-02.inside.domusdigitalis.dev @10.50.1.1)
Triple DNS validation (BIND + pfSense + local)
for host in kvm-02 ipmi-02; do
fqdn="$host.inside.domusdigitalis.dev"
bind=$(dig +short "$fqdn" @10.50.1.90)
pf=$(dig +short "$fqdn" @10.50.1.1)
local=$(dig +short "$fqdn")
printf "%-10s BIND=%-15s PF=%-15s LOCAL=%-15s %s\n" \
"$host" "$bind" "$pf" "$local" \
"$([ "$bind" = "$pf" ] && [ "$pf" = "$local" ] && echo 'β ALL MATCH' || echo 'β MISMATCH')"
done
Parallel dig with process substitution (no temp files)
paste <(dig +short kvm-02.inside.domusdigitalis.dev @10.50.1.90) \
<(dig +short kvm-02.inside.domusdigitalis.dev @10.50.1.1) \
<(dig +short kvm-02.inside.domusdigitalis.dev) | \
awk '{printf "BIND: %s | PF: %s | LOCAL: %s\n", $1, $2, $3}'
Full hypervisor range scan (.110-.119)
echo "=== Forward (.110-.119) ==="
for i in {110..119}; do
for srv in "10.50.1.90:BIND" "10.50.1.1:PF" ":LOCAL"; do
ip="${srv%%:*}"; name="${srv##*:}"
[ -n "$ip" ] && result=$(dig +short -x "10.50.1.$i" @"$ip") || result=$(dig +short -x "10.50.1.$i")
[ -n "$result" ] && printf ".%-3s %-6s %s\n" "$i" "$name" "$result"
done
done
Array-based multi-host validation
hosts=(kvm-02 ipmi-02 kvm-01 ipmi-01)
servers=("10.50.1.90" "10.50.1.1" "")
for h in "${hosts[@]}"; do
echo "=== $h ==="
for s in "${servers[@]}"; do
[ -n "$s" ] && r=$(dig +short "$h.inside.domusdigitalis.dev" @"$s") || r=$(dig +short "$h.inside.domusdigitalis.dev")
printf " %-12s %s\n" "${s:-LOCAL}" "$r"
done
done
One-liner: all new records across all DNS
for h in kvm-02 ipmi-02; do echo "$h:"; for s in 10.50.1.90 10.50.1.1 ""; do printf " %s: %s\n" "${s:-local}" "$(dig +short $h.inside.domusdigitalis.dev ${s:+@$s})"; done; done
Diff all three DNS servers at once
diff3 <(dig +short kvm-02.inside.domusdigitalis.dev @10.50.1.90) \
<(dig +short kvm-02.inside.domusdigitalis.dev @10.50.1.1) \
<(dig +short kvm-02.inside.domusdigitalis.dev)
SSH Access Troubleshooting
Problem: "Too many authentication failures"
SSH agent offers too many keys before trying password.
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no kvm-02
Problem: "Permission denied" with root
Rocky Linux 9 defaults PermitRootLogin no in /etc/ssh/sshd_config.
Try non-root user first
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no evanusmodestus@kvm-02
If successful, verify root SSH config
sudo grep -n "PermitRootLogin" /etc/ssh/sshd_config
Enable root login (if needed)
sudo sed -i 's/^#PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
sudo systemctl restart sshd
If all SSH fails: Console access needed
Options: 1. Physical console (keyboard/monitor on kvm-02) 2. IPMI/BMC console (requires BMC on reachable network) 3. Boot from USB rescue mode
Current BMC status
BMC likely on DHCP (172.x.x.x) - unreachable from 10.50.1.0/24. Need to configure IPMI to 10.50.1.201 first via physical access or ipmitool from kvm-01.
Post-SSH: Initial Verification
SSH Access (from workstation)
ssh evanusmodestus@kvm-02.inside.domusdigitalis.dev
Fix hostname (if wrong from install)
Check current hostname
hostnamectl
Set correct hostname
sudo hostnamectl set-hostname kvm-02.inside.domusdigitalis.dev
Verify change
hostnamectl
Reload shell to see new prompt
exec bash
Remove typo user accounts (if any)
List all users with UID >= 1000
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3}' /etc/passwd
Check if typo user exists before deleting
id evanusmodesus 2>/dev/null && echo "User exists - safe to delete" || echo "User does not exist"
Delete typo user (only if exists)
sudo userdel -r evanusmodesus
Verify deletion
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3}' /etc/passwd
Verify IP configuration
ip -4 -o addr show | awk '{print $2, $4}'
Vault SSH CA Configuration
From workstation: Get Vault CA public key
If CA not cached locally
scp vault-01:/tmp/vault-ssh-ca.pub /tmp/vault-ca.pub
Copy CA to kvm-02
scp /tmp/vault-ca.pub kvm-02:/tmp/
On kvm-02: Install Vault CA
Move to trusted location
sudo mv /tmp/vault-ca.pub /etc/ssh/vault-ca.pub
Set permissions
sudo chmod 644 /etc/ssh/vault-ca.pub
Verify installation
ls -la /etc/ssh/vault-ca.pub && awk '{print "Type:", $1}' /etc/ssh/vault-ca.pub
Configure sshd to trust Vault CA
Add TrustedUserCAKeys directive
echo "TrustedUserCAKeys /etc/ssh/vault-ca.pub" | sudo tee -a /etc/ssh/sshd_config
Restart sshd
sudo systemctl restart sshd
Verify sshd running
systemctl is-active sshd && echo "sshd running"
Test from workstation (new terminal)
Fresh connection (bypass mux)
ssh -o ControlPath=none kvm-02 'hostname && whoami'
Verify certificate was used
ssh -o ControlPath=none -v kvm-02 'hostname' 2>&1 | grep -E "CERT|Server accepts"
Expected output
debug1: Server accepts key: .ssh/id_ed25519_vault-cert.pub ED25519-CERT
Check sshd logs on kvm-02
sudo journalctl -u sshd -n 10 | awk '/Accepted.*CERT/'