Welcome to my website

Configure static ip (for pi-hole)

How to Configure a Static IP and Pi-hole DNS on Ubuntu Server with Netplan



A Current Guide for Ubuntu Server, systemd-resolved, cloud-init and IPv6



Introduction

A static IP address is important for a server running services such as Pi-hole. It ensures that the server and its DNS service remain available at a predictable address.

Modern Ubuntu Server versions use Netplan for network configuration. Netplan normally uses systemd-networkd on servers. Ubuntu Desktop installations often use NetworkManager instead.

This guide explains how to configure a static IPv4 address and configure the Ubuntu server itself to use its local Pi-hole service for DNS.

Important: This guide assumes Pi-hole is installed on this server and can answer DNS requests on 127.0.0.1:53.

Prerequisites



  • Ubuntu Server: A recent Ubuntu Server installation using Netplan.
  • Access: SSH access or local console access to the server.
  • Static IP address: An address outside the router's normal DHCP range, or an address reserved in the router's DHCP configuration.
  • Gateway: Your router or gateway IP address.
  • Network interface: The name of the active network interface.
  • Pi-hole: Pi-hole installed and running on this server.


Example values used in this guide:

  • Server IP address: 192.168.178.10
  • Network prefix: /24
  • Subnet mask: 255.255.255.0
  • Gateway/router: 192.168.178.1
  • Network interface: eno2


Replace these example values with the values for your own network.

Step 1: Identify Your Network Interface Name



First, identify the network interface that is currently connected to your local network.


ip -brief address


Look for the interface with your current local IP address.

Example:


lo               UNKNOWN        127.0.0.1/8 ::1/128
eno2             UP             192.168.178.25/24


In this example, the active interface is eno2.

Check the current default gateway:


ip route


Example:


default via 192.168.178.1 dev eno2 proto dhcp src 192.168.178.25 metric 100


Step 2: Inspect and Back Up Existing Netplan Configuration



Check which Netplan files currently exist:


ls -la /etc/netplan/
sudo cat /etc/netplan/*.yaml


Common file names include:

  • 00-installer-config.yaml: Often created during the Ubuntu Server installation.
  • 50-cloud-init.yaml: Often created by cloud-init on cloud images.
  • 01-network-manager-all.yaml: May be present on systems using NetworkManager.


Important: Netplan reads and merges all files ending in `.yaml` in `/etc/netplan/`. Avoid keeping multiple conflicting configurations for the same network interface.

Create a backup before making changes:


sudo mkdir -p /root/netplan-backup
sudo cp -a /etc/netplan/. /root/netplan-backup/


Step 3: Check Which Network Service Manages the Interface



Ubuntu Server normally uses systemd-networkd. Check the status of the network services:


systemctl is-active systemd-networkd
systemctl is-active NetworkManager


Check whether systemd-networkd manages your network interface:


networkctl status eno2


If NetworkManager is active, check whether it manages the interface:


nmcli device status


Important: Do not configure NetworkManager and systemd-networkd to manage the same interface.

This guide uses:


renderer: networkd


This is normally the preferred option for Ubuntu Server.

Step 4: Handle cloud-init Configuration, If Applicable



Some Ubuntu Server cloud images use cloud-init to create a Netplan file during startup. This is often:


/etc/netplan/50-cloud-init.yaml


If you want to manage the server network configuration manually, disable cloud-init networking:


sudo mkdir -p /etc/cloud/cloud.cfg.d
sudo tee /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg >/dev/null <<'EOF'
network: {config: disabled}
EOF


If the cloud-init Netplan file exists, rename it so Netplan no longer loads it:


sudo mv /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.disabled


Note: Only run this command if `50-cloud-init.yaml` exists and you intentionally want to replace its configuration with a manually managed Netplan file.

Step 5: Create Your Static Netplan Configuration



Create a new Netplan configuration file:


sudo nano /etc/netplan/10-static-ip.yaml


Paste the following configuration. Replace eno2, the IP address and the gateway with the values for your own network.


# /etc/netplan/10-static-ip.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eno2:
      dhcp4: false
      addresses:
        - 192.168.178.10/24
      routes:
        - to: default
          via: 192.168.178.1
      nameservers:
        addresses:
          - 127.0.0.1


Save the file in Nano:

  • Ctrl+O: Save the file.
  • Enter: Confirm the file name.
  • Ctrl+X: Exit Nano.


Explanation of Key Settings:

  • renderer: networkd: Uses systemd-networkd to manage the network interface.
  • dhcp4: false: Prevents the server from receiving an IPv4 address, DNS settings and routes through DHCP.
  • addresses: Sets the static IPv4 address and network prefix.
  • routes: Sets the default route through the router or gateway.
  • nameservers: Defines the DNS resolver used by this Ubuntu server.
  • 127.0.0.1: Sends the server's DNS requests to the Pi-hole service running locally.


Why is there no public fallback DNS server?

Do not add a public DNS resolver, such as 1.1.1.1 or 8.8.8.8, to the Netplan configuration if you want all DNS traffic from this server to go through Pi-hole.

A fallback DNS server can bypass Pi-hole blocking and query logging.

Configure reliable upstream DNS servers inside Pi-hole instead. Pi-hole can forward allowed DNS queries to the upstream DNS providers that you select.

Step 6: Optional - Disable IPv6 Configuration



Only use this step if you intentionally do not want IPv6 connectivity on this server.

Some routers advertise IPv6 addresses, routes and DNS servers through IPv6 Router Advertisements or DHCPv6.

To stop the server from accepting this IPv6 configuration, add these lines below `dhcp4: false`:


      dhcp6: false
      accept-ra: false


The full configuration then becomes:


# /etc/netplan/10-static-ip.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eno2:
      dhcp4: false
      dhcp6: false
      accept-ra: false
      addresses:
        - 192.168.178.10/24
      routes:
        - to: default
          via: 192.168.178.1
      nameservers:
        addresses:
          - 127.0.0.1


Warning: These settings do more than stop router DNS configuration.

  • dhcp6: false: Stops DHCPv6 configuration.
  • accept-ra: false: Stops IPv6 Router Advertisements.
  • Result: The server may not receive an IPv6 address, IPv6 default route or IPv6 DNS server.


Do not use these settings if the server requires IPv6 connectivity.

Step 7: Set Correct File Permissions



Netplan warns if active YAML files are readable or writable by non-root users.

Set secure permissions on active Netplan files:


sudo chmod 600 /etc/netplan/*.yaml


Verify the permissions:


ls -l /etc/netplan/


The active YAML file should normally look similar to this:


-rw------- 1 root root


Step 8: Validate and Apply the Netplan Configuration



Important for SSH users: An incorrect interface name, IP address, subnet prefix or gateway can disconnect the server.

First validate the configuration:


sudo netplan generate


If no errors appear, test the configuration safely:


sudo netplan try


`netplan try` temporarily applies the new configuration. If the server loses network connectivity, or if you do not confirm the change, Netplan restores the previous configuration automatically.

When the server remains reachable, apply the configuration permanently:


sudo netplan apply


Step 9: Verify the Static IP Address and Default Route



Check the configured IP address:


ip -brief address show eno2


Expected result:


eno2             UP             192.168.178.10/24


Check the default route:


ip route


Expected result:


default via 192.168.178.1 dev eno2


Test the connection to the router:


ping -c 4 192.168.178.1


Step 10: Verify DNS Configuration Correctly



On current Ubuntu versions, `/etc/resolv.conf` is often managed by systemd-resolved.

It may show this entry:


nameserver 127.0.0.53


This is normal. `127.0.0.53` is the local systemd-resolved DNS stub. It does not necessarily mean that Ubuntu is ignoring Pi-hole.

Check the DNS server configured for the interface:


resolvectl status eno2


Look for an entry similar to this:


Link 2 (eno2)
    Current Scopes: DNS
         DNS Servers: 127.0.0.1


Test DNS resolution through the normal system resolver:


resolvectl query example.com


Test Pi-hole directly:


dig @127.0.0.1 example.com


If `dig` is not installed, install the DNS utilities package:


sudo apt update
sudo apt install dnsutils


You can also test Pi-hole with:


nslookup example.com 127.0.0.1


Step 11: Confirm Pi-hole Is Listening on Port 53



Check whether a DNS service is listening on port 53:


sudo ss -lntup '( sport = :53 )'


You should see Pi-hole listening on port 53, either on 127.0.0.1, the server's static IP address, or both.

Check the Pi-hole service status:


sudo systemctl status pihole-FTL


If Pi-hole does not answer DNS queries:

  • Check the service: Run `sudo systemctl status pihole-FTL`.
  • Check port 53: Run `sudo ss -lntup '( sport = :53 )'`.
  • Test DNS locally: Run `dig @127.0.0.1 example.com`.
  • Check Pi-hole settings: Confirm that Pi-hole listens on localhost or on the required network interface.


Step 12: Reboot and Verify Persistence



After the live test succeeds, reboot the server:


sudo reboot


After reconnecting, run:


ip -brief address show eno2
ip route
resolvectl status eno2
resolvectl query example.com
dig @127.0.0.1 example.com


If the static IP address, default route and local DNS settings remain correct after rebooting, the configuration is persistent.

Common Problems and Solutions



Problem: Netplan Reports YAML or Indentation Errors

  • Spaces: Use spaces and never use tabs in YAML files.
  • Indentation: Check that each YAML level uses consistent indentation.
  • Interface name: Confirm that the interface name matches the output of `ip -brief address`.
  • Validation: Run `sudo netplan generate` to identify errors.


Problem: SSH Connection Is Lost After Applying the Configuration

  • Interface: Check that the interface name is correct.
  • IP address: Check the configured static IP address and network prefix.
  • Gateway: Confirm that the gateway address is correct.
  • Safe testing: Use `sudo netplan try` before applying future changes.
  • Recovery: Restore the backup in `/root/netplan-backup/` through local console access if required.


Problem: resolv.conf Shows 127.0.0.53 Instead of 127.0.0.1

  • Expected behaviour: This is normal when Ubuntu uses systemd-resolved.
  • Check DNS: Run `resolvectl status eno2` to view the configured DNS server.
  • Test Pi-hole: Run `dig @127.0.0.1 example.com` to query Pi-hole directly.


Problem: DNS Servers From the Router Still Appear

  • Netplan files: Check all active configurations with `sudo cat /etc/netplan/*.yaml`.
  • cloud-init: Check whether cloud-init recreates a Netplan configuration.
  • NetworkManager: Check whether it manages the interface with `nmcli device status`.
  • IPv6 disabled: If IPv6 is intentionally disabled, use `dhcp6: false` and `accept-ra: false`.
  • IPv6 required: Configure IPv6 explicitly instead of blocking Router Advertisements.


Problem: Public Fallback DNS Bypasses Pi-hole

  • Remove fallback resolvers: Remove public DNS addresses, such as `1.1.1.1`, from the Netplan nameserver configuration.
  • Use local Pi-hole: Keep `127.0.0.1` as the DNS resolver for this server.
  • Configure upstream DNS: Configure reliable upstream resolvers inside Pi-hole.


Conclusion



Your Ubuntu server should now have:

  • Static IPv4: A persistent static IPv4 address.
  • Default route: A configured gateway through the router.
  • Local DNS: DNS resolution through the local Pi-hole service.
  • Current Ubuntu support: A configuration compatible with Netplan and systemd-resolved.
  • Optional IPv6 control: The option to stop unwanted IPv6 router configuration when IPv6 is not required.


Tip: Keep a copy of the working Netplan configuration and document the server IP address, gateway, interface name and Pi-hole upstream DNS settings.

Back to Knowledge Base