infra:systemd-nspawn

Systemd nspawn on Debian

https://people.netfilter.org/pablo/netdev0.1/papers/IPVLAN-The-beginning.pdf

As described by above paper, ipvlan does not allow traffic between virtual and physical interfaces. If this is required, easiest solution is to create a ipvlan interface for the host system (default namespace).

Update the host to use systemd-networkd instead of standard debian ifupdown. Comment out all config lines in /etc/network/interfaces and disable NetworkManager/ifupdown.

systemctl disable NetworkManager
systemctl disable networking
systemctl disable wpa_supplicant.service
 
systemctl stop NetworkManager
systemctl stop networking
systemctl stop wpa_supplicant.service

Then create networkd and wpa_supplicant config files and enable associated services. Configure wpa_supplicant to associate our physical wireless interface to our accesspoint

/etc/wpa_supplicant/wpa_supplicant-wlp3s0.conf
network={
  ssid="XXX"
  psk="XXX"
}

Configure the physical (wireless) interface to have a ipvlan virtual interface attached.

/etc/systemd/network/wlp3s0.network
[Match]
Name=wlp3s0

[Network]
IPVLAN=ipv-wlp3s0

Configure the actual virtual ipvlan interface

/etc/systemd/network/ipv-wlp3s0.netdev
[Match]
Host=*

[NetDev]
Name=ipv-wlp3s0
Kind=ipvlan

[IPVLAN]
Mode=L2

Configure the hosts networking on the created ipvlan interface

/etc/systemd/network/ipv-wlp3s0.network
[Match]
Name=ipv-wlp3s0

[Network]
#DHCP=yes
Address=192.168.42.253/24
Gateway=192.168.42.254

Enable and start required services

systemctl enable wpa_supplicant@wlp3s0.service
systemctl enable systemd-networkd
systemctl start wpa_supplicant@wlp3s0.service
systemctl start systemd-networkd

Default nspawn uses veth networking. Simpler alternatives are macvlan & ipvlan, where ipvlan is the only possibility you are sharing a wireless card. (macvlan adds mac addresses on the host interface for each guest interface. ipvlan adds ip addresses on the hosts macaddress for each guest interface).

Create a systemd override for nspawn to use ipvlan and share the wlp3s0 interface with guests:

/etc/systemd/system/systemd-nspawn\@.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-ipvlan=wlp3s0 -U --settings=override --machine=%i

Reload systemd to active the overrid.

systemctl daemon-reload

Create a btrfs subvolume to host the template, bootstrap it and set defaults

btrfs subvolume create /var/lib/machines/Debian9
export http_proxy=http://aptproxy:3142
debootstrap --include dbus,sudo,vim,openssh-server,wget --exclude=ifupdown,nano stretch /var/lib/machines/Debian9
cp /etc/apt/apt.conf.d/00proxy /var/lib/machines/Debian9/etc/apt/apt.conf.d/00proxy
mkdir -m0700 /var/lib/machines/Debian9/root/.ssh
cat /root/.ssh/id_rsa.pub > /var/lib/machines/CentOS7/root/.ssh/authorized_keys
 
systemd-nspawn --directory=/var/lib/machines/Debian9

Install and configure yum

apt-get install yum
echo 'proxy=http://aptproxy:3142' >> /etc/yum/yum.conf

Configure repo's in /etc/yum/repos.d/centos.repo

/etc/yum/repos.d/centos.repo
[base]
baseurl = http://mirror.centos.org/centos/7/os/x86_64/
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
name = CentOS-7 - Base

[extras]
baseurl = http://mirror.centos.org/centos/7/extras/x86_64/
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
name = CentOS-7 - Extras

[updates]
baseurl = http://mirror.centos.org/centos/7/updates/x86_64/
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
name = CentOS-7 - Updates

[epel]
baseurl = http://download.fedoraproject.org/pub/epel/7/x86_64
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
name = Extra Packages for Enterprise Linux 7 - x86_64

Create a btrfs subvolume to host the template, bootstrap it and set defaults

btrfs subvolume create /var/lib/machines/CentOS7
yum groupinstall base  --skip-broken --nogpgcheck --installroot=/var/lib/machines/CentOS7
yum install sudo openssh-server vim dbus systemd-networkd --skip-broken --nogpgcheck --installroot=/var/lib/machines/CentOS7
rm -f /var/lib/machines/CentOS7/etc/yum.repos.d/*.repo
cp /etc/yum/repos.d/centos.repo /var/lib/machines/CentOS7/etc/yum.repos.d
wget -O /var/lib/machines/CentOS7/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-EPEL-7 https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
echo 'proxy=http://aptproxy:3142' >> /var/lib/machines/CentOS7/etc/yum/yum.conf
mkdir -m0700 /var/lib/machines/CentOS7/root/.ssh
cat /root/.ssh/id_rsa.pub > /var/lib/machines/CentOS7/root/.ssh/authorized_keys
 
systemd-nspawn --directory=/var/lib/machines/CentOS7

see: http://lukeluo.blogspot.nl/2015/09/how-to-bootstrap-different-linux.html

debootstrap --no-check-gpg jessie ./debian/  http://mirrors.aliyun.com/debian
debootstrap --no-check-gpg vivid ubuntu http://mirrors.aliyun.com/ubuntu
cat > /etc/yum/repos.d/fedora.repo << 'EOF'
[fedora]
name=fedora
baseurl=http://mirrors.aliyun.com/fedora/releases/22/Server/x86_64/os/
enabled=1
EOF
yum groupinstall minimal-environment  --skip-broken --nogpgcheck --installroot=/tmp/bootstrap/fedora/

Continue configuration from inside the bootstrapped container. (Start it using systemd-nspawn –directory xxx)

Create the file /etc/systemd/network/iv-wlp3s0.network on the template

/etc/systemd/network/iv-wlp3s0.network
[Match]
Name=iv-wlp3s0

[Network]
DHCP=yes

DUIDType=vendor
ClientIdentifier=duid

Update the root password, remove hostname, machine-id & enable networking & ssh key generation

rm -f /etc/{hostname,machine-id}
rm -rf /etc/ssh/*key*
passwd 
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password changed
 adduser toor
Adding user `toor' ...
Adding new group `toor' (1000) ...
Adding new user `toor' (1000) with group `toor' ...
Creating home directory `/home/toor' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for toor
Enter the new value, or press ENTER for the default
	Full Name []: 
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] y
systemctl disable network NetworkManager
systemctl enable systemd-networkd systemd-resolved

Create a service to generate ssh host-keys on container start /lib/systemd/system/ssh_generate_host_keys.service

lib/systemd/system/ssh_generate_host_keys.service
[Unit]
Description=Generate SSH host keys
Before=ssh.service

[Service]
Type=oneshot
ExecStartPre=-/bin/dd if=/dev/hwrng of=/dev/urandom count=1 bs=4096
ExecStart=/usr/bin/ssh-keygen -A -v
ExecStartPost=/bin/systemctl disable ssh_generate_host_keys.service

[Install]
WantedBy=multi-user.target
systemctl enable ssh_generate_host_keys
usermod -aGadm,cdrom,sudo,dip,plugdev toor
usermod -aGadm,cdrom,wheel,dip,plugdev toor

Start the guest for the first time from the template. This will give you a root shell.

systemd-nspawn --template=/var/lib/machines/Debian9 --machine=mynewdebian

This will create a new btrfs subvolume /var/lib/machine/mynewdebian and leave you in a root shell. Due to the absence of /etc/hostname this will be automagically set to mynewdebian. Also a new machine-id will be generated. This should enable a dhcp server to issue multiple IP's per mac address based on the DUID. When exiting the root shell, the container will shutdown again.

Configure the container to run at host boot and start it

systemctl enable systemd-nspawn@mynewdebian.service
systemctl start systemd-nspawn@mynewdebian.service
  • List running containers: machinectl
  • Connect to a container: machinectl login mynewdebian
  • Disconnect from container: <ctrl>]]]
  • infra/systemd-nspawn.txt
  • Last modified: 20/11/2021 01:58
  • by harm