Skip to content

Instantly share code, notes, and snippets.

@lamafab
Last active September 8, 2024 11:47
Show Gist options
  • Save lamafab/a626cfe7be5e3c1ecfe06251ddab4130 to your computer and use it in GitHub Desktop.
Save lamafab/a626cfe7be5e3c1ecfe06251ddab4130 to your computer and use it in GitHub Desktop.
Assign static IP address to systemd-nspawn container (private networking mode)

Assign static IP address to systemd-nspawn container (private networking mode)

(Originally posted here)

On the host

Configure the host interface which will be exposed to the container.

$ sudo cp /lib/systemd/network/80-container-ve.network /etc/systemd/network/80-container-<MY_CONTAINER>.network

Modify the new file as desired:

$ cat /etc/systemd/network/80-container-<MY_CONTAINER>.network
[Match]
Name=ve-my-container
Driver=veth

[Network]
Address=192.100.100.1/24
LinkLocalAddressing=yes
DHCPServer=yes
IPMasquerade=yes
LLDP=yes
EmitLLDP=customer-bridge

Note that Name in [Match] must match the container interface displayed to you by ip link (remove the @if2 suffix):

$ ip link
1: ...
2: ...
3: ...
4: ve-my-container@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether f2:93:48:9b:99:8c brd ff:ff:ff:ff:ff:ff link-netnsid 0

Then specify your desired, static IP address in [Network], which represents the GATEWAY exposed to the container, NOT the container itself. I chose 192.100.100.1/24. Some other fields could probably be removed, but I'm leaving it as is.

Finally, restart the networking service:

$ sudo systemctl restart systemd-networkd

In the container

Set the static IP address of the container, and specify the Host/Gateway IP.

NOTE: Make sure that host0 matches the network interface displayed by ip link.

$ sudo cp /lib/systemd/network/80-container-host0.network /etc/systemd/network/80-container-host0.network

Modify the new file as desired:

$ cat /etc/systemd/network/80-container-host0.network
[Match]
Virtualization=container
Name=host0

[Network]
DNS=1.1.1.1
Address=192.100.100.10/24
Gateway=192.100.100.1

Address specifies the static IP address of the container, where I chose 192.100.100.10 (*.10 is the container IP, *.1 is the host/gateway IP). Set a custom DNS, such as 8.8.8.8 (Google) or 1.1.1.1 (Cloudflare). Note that Gateway MUST match the IP address as specified in the host, as described above. Now, exit the container and restart it (from the host):

$ sudo machinectl reboot my-container

The container should now have a static IP address. For convenience, add it to /etc/hosts (which simplifies SSH access, for example):

192.100.100.10 my-container

Note about firewalls:

If your host has a (passive) firewall enabled, an additional rule is required (compatible with ufw). Make sure you persist that rule:

$ sudo iptables -A FORWARD -i ve-+ -o internet0 -j ACCEPT

Note that internet0 is the interface to the internet, from the host. In my case, it's enp82s0.

More info: https://wiki.archlinux.org/index.php/Systemd-nspawn#Use_a_virtual_Ethernet_link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment