--- title: Basic Configuration of dnsmasq in an Incus Container on Debian with Netplan --- # Introduction This guide provides step-by-step instructions for setting up `dnsmasq` as a DNS and DHCP server in an Incus container running Debian. The network configuration is managed using Netplan to ensure proper network integration. # Prerequisites Before proceeding, ensure the following: - Incus is installed on the host system (`sudo apt install incus`). - A Debian-based container is created in Incus. - Basic knowledge of Linux networking and container management. - Root or sudo access to the host and container. # Step-by-Step Configuration ## Creating and Setting Up the Incus Container Create a Debian container named `dnsmasq-container` using the following commands on the host: ``` {.bash language="bash"} incus create images:debian/12 dnsmasq-container incus config set dnsmasq-container security.syscalls.intercept.mount true incus config set dnsmasq-container security.nesting true incus config set dnsmasq-container security.privileged true incus start dnsmasq-container ``` The `security.syscalls.intercept.mount`, `security.nesting`, and `security.privileged` settings are required for `dnsmasq` and Docker to function correctly in the container. ## Firewall Configuration To allow traffic forwarding between the `incusbr0` bridge and the `wlo1` wireless interface, the following iptables rules are applied: sudo iptables -A FORWARD -i incusbr0 -o wlo1 -j ACCEPT sudo iptables -A FORWARD -i wlo1 -o incusbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT ## Installing Additional Packages Install the necessary packages inside the container: ``` {.bash language="bash"} incus exec dnsmasq-container -- apt update incus exec dnsmasq-container -- apt install -y \ netplan.io \ sudo vim nano git tmux mc zip unzip curl wget htop lynx \ iproute2 termshark bridge-utils \ python3 python3-ipython python3-pyroute2 python3-scapy \ docker.io docker-compose ``` ## Configuring Users and Permissions Configure user access and permissions within the container. ### Changing the Root Password Set the root password to \"passroot\": ``` {.bash language="bash"} incus exec dnsmasq-container -- bash -c 'echo "root:passroot" | chpasswd' ``` ### Adding a New User Add a new user named \"user\" with the password \"pass\" and add them to the \"sudo\" and \"docker\" groups: ``` {.bash language="bash"} sudo useradd -m -s /bin/bash -G sudo user && echo 'user:pass' | sudo chpasswd ``` ## Accessing the Container Access the container's shell: ``` {.bash language="bash"} incus exec dnsmasq-container -- su - user ``` # Setting Up a Veth Pair Between Container and Network Namespace To enable direct communication between a container and a network namespace, a virtual Ethernet (`veth`) pair is created. The following Python script (`link.py`) is used to create a `veth` pair between the `dnsmasq-container` (an Incus container) and the `ns1` network namespace, with interfaces named `vA` and `vB`. sudo python3 link.py -n1 vA -t2 incus -ns2 dnsmasq-container -n2 vB This command: - Creates a `veth` pair with one end (`vA`) in the default namespace and the other end (`vB`) in the `dnsmasq-container`'s network namespace. - Ensures the interfaces are set up and operational, allowing network traffic to flow between the container and the `ns1` namespace (or default namespace if `ns1` is not explicitly created). The script uses the `pyroute2` library to manage network interfaces and namespaces, and supports container types such as Incus, LXC, LXD, and Docker. Ensure the `dnsmasq-container` is running in Incus before executing the command. ## Configuring the Network with Netplan Configure the container's network using Netplan to assign a static IP address. Create or edit the Netplan configuration file at `/etc/netplan/01-netcfg.yaml`: ``` {.bash language="bash"} incus exec dnsmasq-container -- nano /etc/netplan/01-netcfg.yaml ``` Add the following configuration: ``` {.yaml language="yaml"} network: version: 2 ethernets: vB: dhcp4: no addresses: - 192.168.1.10/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: [8.8.8.8, 8.8.4.4] ``` Apply the configuration: ``` {.bash language="bash"} incus exec dnsmasq-container -- netplan apply ``` ## Installing dnsmasq Update the package list and install `dnsmasq`: ``` {.bash language="bash"} incus exec dnsmasq-container -- apt update incus exec dnsmasq-container -- apt install dnsmasq -y ``` ## Configuring dnsmasq Edit the `dnsmasq` configuration file at `/etc/dnsmasq.conf`: ``` {.bash language="bash"} incus exec dnsmasq-container -- nano /etc/dnsmasq.conf ``` Add or modify the following settings to enable DNS and DHCP: # DNS settings domain-needed bogus-priv no-resolv server=8.8.8.8 server=8.8.4.4 local=/example.local/ domain=example.local # DHCP settings dhcp-range=192.168.1.100,192.168.1.200,12h dhcp-option=3,192.168.1.1 dhcp-option=6,8.8.8.8,8.8.4.4 **Explanation:** - `domain-needed`: Prevents incomplete domain names from being sent to upstream DNS. - `bogus-priv`: Blocks reverse DNS lookups for private IP ranges. - `no-resolv`: Disables reading `/etc/resolv.conf`. - `server`: Specifies upstream DNS servers (Google DNS in this case). - `local` and `domain`: Configures a local domain. - `dhcp-range`: Defines the IP range for DHCP clients (from 192.168.1.100 to 192.168.1.200, lease time 12 hours). - `dhcp-option`: Sets the default gateway (option 3) and DNS servers (option 6). ## Starting and Enabling dnsmasq Restart and enable the `dnsmasq` service: ``` {.bash language="bash"} incus exec dnsmasq-container -- systemctl restart dnsmasq incus exec dnsmasq-container -- systemctl enable dnsmasq ``` Verify that `dnsmasq` is running: ``` {.bash language="bash"} incus exec dnsmasq-container -- systemctl status dnsmasq ``` ## Testing the Configuration Test DNS resolution from within the container: ``` {.bash language="bash"} incus exec dnsmasq-container -- nslookup example.local 192.168.1.10 ``` To test DHCP, connect a client device to the same network and verify that it receives an IP address in the range `192.168.1.100–192.168.1.200`. # Troubleshooting If `dnsmasq` fails to start: - Check the logs: `incus exec dnsmasq-container – journalctl -u dnsmasq`. - Ensure no other service is using port 53 (DNS) or 67 (DHCP). - Verify the network configuration with `incus exec dnsmasq-container – ip a` and `incus exec dnsmasq-container – ping 8.8.8.8`. # Conclusion This guide configures `dnsmasq` as a DNS and DHCP server in an Incus container on Debian. The Netplan configuration ensures proper network setup. For advanced configurations, refer to the `dnsmasq` documentation (`man dnsmasq`).