Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 54 additions & 72 deletions distrobuilder/lxc.generator
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,11 @@ is_lxc_privileged_container() {
grep -qw 4294967295$ /proc/self/uid_map
}

# is_incus_vm succeeds if we're running inside an Incus VM
is_incus_vm() {
[ -e /dev/virtio-ports/org.linuxcontainers.incus ]
}

# is_in_path succeeds if the given file exists in on of the paths
is_in_path() {
# Don't use $PATH as that may not include all relevant paths
for path in /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin; do
[ -e "${path}/$1" ] && return 0
[ -e "${path}/${1}" ] && return 0
done

return 1
Expand All @@ -34,8 +29,8 @@ is_in_path() {
## Fix functions
# fix_ro_paths avoids udevd issues with /sys and /proc being writable
fix_ro_paths() {
mkdir -p "/run/systemd/system/$1.d"
cat <<-EOF > "/run/systemd/system/$1.d/zzz-lxc-ropath.conf"
mkdir -p "/run/systemd/system/${1}.d"
cat <<-EOF > "/run/systemd/system/${1}.d/zzz-lxc-ropath.conf"
# This file was created by distrobuilder
[Service]
BindReadOnlyPaths=/sys
Expand All @@ -44,8 +39,8 @@ fix_ro_paths() {

# fix_ro_run is a workaround for units failing to write in /run due to ProtectSystem=strict
fix_ro_run() {
mkdir -p "/run/systemd/system/$1.d"
cat <<-EOF > "/run/systemd/system/$1.d/zzz-lxc-rorun.conf"
mkdir -p "/run/systemd/system/${1}.d"
cat <<-EOF > "/run/systemd/system/${1}.d/zzz-lxc-rorun.conf"
# This file was created by distrobuilder
[Service]
ReadWritePaths=/run
Expand All @@ -54,15 +49,17 @@ fix_ro_run() {

# fix_nm_link_state forces the network interface to a DOWN state ahead of NetworkManager starting up
fix_nm_link_state() {
[ -e "/sys/class/net/$1" ] || return 0
ip_path=
if [ -f /sbin/ip ]; then
ip_path=/sbin/ip
elif [ -f /bin/ip ]; then
ip_path=/bin/ip
[ -e "/sys/class/net/${1}" ] || return 0

ip=
if [ -f "/sbin/ip" ]; then
ip="/sbin/ip"
elif [ -f "/bin/ip" ]; then
ip="/bin/ip"
else
return 0
fi

cat <<-EOF > /run/systemd/system/network-device-down.service
# This file was created by distrobuilder
[Unit]
Expand All @@ -73,13 +70,14 @@ fix_nm_link_state() {
[Service]
# do not turn off if there is a default route to 169.254.0.1, i.e. the device is a routed nic
ExecCondition=/bin/sh -c '! /usr/bin/grep -qs 00000000.0100FEA9 /proc/net/route'
ExecStart=-${ip_path} link set $1 down
ExecStart=-${ip} link set ${1} down
Type=oneshot
RemainAfterExit=true

[Install]
WantedBy=default.target
EOF

mkdir -p /run/systemd/system/default.target.wants
ln -sf /run/systemd/system/network-device-down.service /run/systemd/system/default.target.wants/network-device-down.service
}
Expand All @@ -88,27 +86,28 @@ fix_nm_link_state() {
fix_systemd_override_unit() {
dropin_dir="/run/systemd/${1}.d"
mkdir -p "${dropin_dir}"

{
echo "[Service]";
[ "${systemd_version}" -ge 247 ] && echo "ProcSubset=all";
[ "${systemd_version}" -ge 247 ] && echo "ProtectProc=default";
[ "${systemd_version}" -ge 232 ] && echo "ProtectControlGroups=no";
[ "${systemd_version}" -ge 232 ] && echo "ProtectKernelTunables=no";
[ "${systemd_version}" -ge 239 ] && echo "NoNewPrivileges=no";
[ "${systemd_version}" -ge 249 ] && echo "LoadCredential=";
[ "${systemd_version}" -ge 254 ] && echo "PrivateNetwork=no";
[ "${systemd_version}" -ge 256 ] && echo "ImportCredential=";
[ "${SYSTEMD}" -ge 247 ] && echo "ProcSubset=all";
[ "${SYSTEMD}" -ge 247 ] && echo "ProtectProc=default";
[ "${SYSTEMD}" -ge 232 ] && echo "ProtectControlGroups=no";
[ "${SYSTEMD}" -ge 232 ] && echo "ProtectKernelTunables=no";
[ "${SYSTEMD}" -ge 239 ] && echo "NoNewPrivileges=no";
[ "${SYSTEMD}" -ge 249 ] && echo "LoadCredential=";
[ "${SYSTEMD}" -ge 254 ] && echo "PrivateNetwork=no";
[ "${SYSTEMD}" -ge 256 ] && echo "ImportCredential=";

# Additional settings for privileged containers
if is_lxc_privileged_container; then
echo "ProtectHome=no";
echo "ProtectSystem=no";
echo "PrivateDevices=no";
echo "PrivateTmp=no";
[ "${systemd_version}" -ge 244 ] && echo "ProtectKernelLogs=no";
[ "${systemd_version}" -ge 232 ] && echo "ProtectKernelModules=no";
[ "${systemd_version}" -ge 231 ] && echo "ReadWritePaths=";
[ "${systemd_version}" -ge 254 ] && [ "${systemd_version}" -lt 256 ] && echo "ImportCredential=";
[ "${SYSTEMD}" -ge 244 ] && echo "ProtectKernelLogs=no";
[ "${SYSTEMD}" -ge 232 ] && echo "ProtectKernelModules=no";
[ "${SYSTEMD}" -ge 231 ] && echo "ReadWritePaths=";
[ "${SYSTEMD}" -ge 254 ] && [ "${SYSTEMD}" -lt 256 ] && echo "ImportCredential=";
fi

true;
Expand All @@ -117,19 +116,19 @@ fix_systemd_override_unit() {

# fix_systemd_mask masks the systemd unit
fix_systemd_mask() {
ln -sf /dev/null "/run/systemd/system/$1"
ln -sf /dev/null "/run/systemd/system/${1}"
}

# fix_systemd_udev_trigger overrides the systemd-udev-trigger.service to match the latest version
# of the file which uses "ExecStart=-" instead of "ExecStart=".
fix_systemd_udev_trigger() {
cmd=
udev=
if [ -f /usr/bin/udevadm ]; then
cmd=/usr/bin/udevadm
udev=/usr/bin/udevadm
elif [ -f /sbin/udevadm ]; then
cmd=/sbin/udevadm
udev=/sbin/udevadm
elif [ -f /bin/udevadm ]; then
cmd=/bin/udevadm
udev=/bin/udevadm
else
return 0
fi
Expand All @@ -139,69 +138,52 @@ fix_systemd_udev_trigger() {
# This file was created by distrobuilder
[Service]
ExecStart=
ExecStart=-${cmd} trigger --type=subsystems --action=add
ExecStart=-${cmd} trigger --type=devices --action=add
ExecStart=-${udev} trigger --type=subsystems --action=add
ExecStart=-${udev} trigger --type=devices --action=add
EOF
}

# fix_systemd_sysctl overrides the systemd-sysctl.service to use "ExecStart=-" instead of "ExecStart=".
fix_systemd_sysctl() {
cmd=/usr/lib/systemd/systemd-sysctl
! [ -e "${cmd}" ] && cmd=/lib/systemd/systemd-sysctl
sysctl=/usr/lib/systemd/systemd-sysctl
[ ! -e "${sysctl}" ] && sysctl=/lib/systemd/systemd-sysctl

mkdir -p /run/systemd/system/systemd-sysctl.service.d
cat <<-EOF > /run/systemd/system/systemd-sysctl.service.d/zzz-lxc-override.conf
# This file was created by distrobuilder
[Service]
ExecStart=
ExecStart=-${cmd}
ExecStart=-${sysctl}
EOF
}

## Main logic
# Nothing to do in Incus VM but deployed in case it is later converted to a container
is_incus_vm && exit 0

# Exit immediately if not an Incus/LXC container
is_lxc_container || exit 0

# Check for NetworkManager
nm_exists=0

is_in_path NetworkManager && nm_exists=1

# Determine systemd version
SYSTEMD=""
for path in /usr/lib/systemd/systemd /lib/systemd/systemd; do
[ -x "${path}" ] || continue

systemd_version="$("${path}" --version | head -n1 | cut -d' ' -f2 | cut -d'~' -f1)"
SYSTEMD="$("${path}" --version | head -n1 | cut -d' ' -f2 | cut -d'~' -f1)"
break
done

# Determine distro name and release
ID=""
if [ -e /etc/os-release ]; then
# shellcheck disable=SC1091
. /etc/os-release
# Apply systemd overrides
if [ "${SYSTEMD}" -ge 244 ]; then
fix_systemd_override_unit system/service
else
# Setup per-unit overrides
find /lib/systemd /etc/systemd /run/systemd /usr/lib/systemd -name "*.service" -type f | sed 's#/\(lib\|etc\|run\|usr/lib\)/systemd/##g'| while read -r service_file; do
fix_systemd_override_unit "${service_file}"
done
fi

# Overriding some systemd features is only needed if security.nesting=false
# in which case, /dev/.lxc will be missing
if [ ! -d /dev/.lxc ]; then
# Apply systemd overrides
if [ "${systemd_version}" -ge 244 ]; then
fix_systemd_override_unit system/service
else
# Setup per-unit overrides
find /lib/systemd /etc/systemd /run/systemd /usr/lib/systemd -name "*.service" -type f | sed 's#/\(lib\|etc\|run\|usr/lib\)/systemd/##g'| while read -r service_file; do
fix_systemd_override_unit "${service_file}"
done
fi

# Workarounds for unprivileged containers.
if ! is_lxc_privileged_container; then
fix_ro_paths systemd-networkd.service
fix_ro_paths systemd-resolved.service
fi
# Workarounds for unprivileged containers.
if ! is_lxc_privileged_container; then
fix_ro_paths systemd-networkd.service
fix_ro_paths systemd-resolved.service
fi

# Ignore failures on some units.
Expand Down Expand Up @@ -240,7 +222,7 @@ if [ -d /etc/udev ]; then
fi

# Workarounds for NetworkManager in containers
if [ "${nm_exists}" -eq 1 ]; then
if is_in_path NetworkManager; then
fix_nm_link_state eth0
fi

Expand Down