Site icon Gioxx.org

Proxmox: open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied (LXC) (Aggiornato)

Proxmox: uno script per connettersi alla shell dei LXC

Durante il fine settimana ho avuto la malaugurata sempre buona idea di andare a fare un po’ di manutenzione sul nodo Proxmox di casa e, tra le varie, aggiornare anche tutti i i LXC attivi.

In seguito all’aggiornamento, Uptime Kuma mi ha prontamente segnalato che alcuni container Docker erano KO, cosa che di solito non accade perché, nel post-aggiornamento di Docker e delle sue componenti, tutti i compose vengono fatti ripartire e i container tornano operativi in autonomia. Il nodo ha in pancia un paio di LXC che sono dedicati ad altrettanti servizi che girano – appunto – via Docker, esposti e isolati. Provando a fare un salto su Portainer e forzando l’avvio degli stack, ottengo questo errore:

Failed to deploy a stack: compose up operation failed: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied

Dato che volevo rapidamente riportare up&running i servizi, ho chiesto a ChatGPT di spiegarmi e cercare cosa stesse accadendo:

Con gli ultimi update il runtime tenta di impostare il sysctl net.ipv4.ip_unprivileged_port_start=0 all’avvio di ogni container, cosa che in un LXC unprivileged viene ora bloccata da AppArmor/cgroup → “permission denied”. Prima questo passaggio era più permissivo; una recente modifica in runc (per una fix di sicurezza) ha cambiato il modo in cui il sysctl viene applicato, e dentro LXC unprivileged ora salta fuori l’errore.

Perché “proprio oggi”?

  • runc/containerd aggiornati: c’è un bug/regressione recente in runc 1.3.x che, in LXC non privilegiati, fa fallire l’accesso al sysctl durante l’init del container. È correlato a un hardening introdotto per una CVE e impatta chi esegue Docker dentro LXC.
  • Docker tende a settare quel sysctl a 0 di default per i container (così anche gli utenti non root possono aprire porte <1024). In LXC unprivileged, questa scrittura ora viene negata.
  • Molti hanno visto il problema dopo “apt upgrade” su Proxmox LXC negli ultimi giorni; alcuni hanno risolto downgradando containerd.io a una build precedente.

Se sei curioso e vuoi approfondire, ti ho lasciato qualche riferimento (link) in fondo all’articolo.

Per poter rimettere in piedi il tutto, ho scelto di non effettuare un downgrade di containerd.io (vedi anche questa discussione sul forum di Proxmox), ho preferito modificare il comportamento del LXC e abilitare i permessi extra, così da permettere a sysctl di non rimanere bloccato. Per farlo, ho recuperato l’ID del LXC interessato e poi ho eseguito (occhio: 801, qui di seguito, è l’ID che ho usato io, nel tuo caso dovrai recuperarlo lanciando un pct list sulla console del tuo nodo Proxmox):

pct set 801 -features nesting=1,keyctl=1
echo "lxc.apparmor.profile: unconfined" >> /etc/pve/lxc/801.conf
echo "lxc.cgroup2.devices.allow: a" >> /etc/pve/lxc/801.conf
echo "lxc.cap.drop:" >> /etc/pve/lxc/801.conf
pct restart 801

Dato che avrei dovuto ripetere da lì a poco la medesima operazione, ho scritto due righe di bash (che poi sono diventate ben più di due revisionando il codice con VSCode e Copilot, ma vabbè) per farlo più agilmente:

#!/usr/bin/env bash
# Proxmox LXC tuning script
# Usage: sudo ./tune-pct.sh <CTID>
# Applies:
# - pct set <CTID> -features nesting=1,keyctl=1
# - AppArmor unconfined
# - Allow all devices via cgroup2
# - Empty cap drop line
# - pct restart <CTID>
set -euo pipefail
# --- Helpers ---------------------------------------------------------------
usage() {
echo "Usage: sudo $0 <CTID>"
echo "Example: sudo $0 801"
exit 1
}
require_root() {
if [[ ${EUID} -ne 0 ]]; then
echo "Error: this script must be run as root." >&2
exit 1
fi
}
ensure_ct_exists() {
local ctid="$1"
if ! pct config "$ctid" >/dev/null 2>&1; then
echo "Error: container $ctid does not exist." >&2
exit 1
fi
}
ensure_line_in_file() {
# Appends the exact line to the file if it does not already exist.
local line="$1"
local file="$2"
if ! grep -qF -- "$line" "$file"; then
echo "$line" >>"$file"
fi
}
# --- Main ------------------------------------------------------------------
main() {
[[ $# -eq 1 ]] || usage
require_root
local CTID="$1"
[[ "$CTID" =~ ^[0-9]+$ ]] || { echo "Error: CTID must be numeric."; exit 1; }
ensure_ct_exists "$CTID"
local CFG="/etc/pve/lxc/${CTID}.conf"
# Safety backup before editing
if [[ -f "$CFG" ]]; then
cp -a "$CFG" "${CFG}.bak.$(date +%Y%m%d-%H%M%S)"
else
echo "Error: config file $CFG not found." >&2
exit 1
fi
echo ">> Enabling features nesting=1,keyctl=1 on CT $CTID…"
pct set "$CTID" -features nesting=1,keyctl=1
echo ">> Ensuring required lines are present in $CFG…"
ensure_line_in_file "lxc.apparmor.profile: unconfined" "$CFG"
ensure_line_in_file "lxc.cgroup2.devices.allow: a" "$CFG"
# An empty value after the colon is intentional
ensure_line_in_file "lxc.cap.drop:" "$CFG"
echo ">> Restarting CT $CTID…"
pct reboot "$CTID"
echo "Done."
}
main "$@"
view raw tune-pct.sh hosted with ❤ by GitHub

Puoi scaricarlo sul tuo nodo Proxmox direttamente da GitHub:

wget https://gist.github.com/gioxx/b1b714956ad0dee685c1de52f65e4238/raw/9fb1c98fdb227a51a389b96d7008a00f76d01381/tune-pct.sh -O tune-pct.sh

A quel punto rendilo eseguibile (chmod +x tune-pct.sh) e lancialo così: ./tune-pct.sh 801

Salvo problemi, in console sul tuo nodo Proxmox dovresti vedere un messaggio simile a questo:

explicitly configured lxc.apparmor.profile overrides the following settings: features:nesting

A conferma che il container LXC sta ripartendo rispettando però i tuoi nuovi settaggi. Ora, sperando di non portare iella, dovresti riuscire a far ripartire tutto senza problemi.

Aggiornato

Aggiornamento del 12/11/29025
Nel caso in cui tu ottenga comunque un errore di avvio del tuo Compose – Error response from daemon: Could not check if docker-default AppArmor profile was loaded: open /sys/kernel/security/apparmor/profiles: permission denied – dovrai mettere mano allo stesso e aggiungere / modificare l’opzione apparmor così:

security_opt:
   - apparmor=unconfined

Così facendo, dovresti finalmente riuscire ad avviare il tuo Compose / Stack e permettere al container di partire.

Un grande grazie a Matteo per la segnalazione.

In caso di dubbi, come al solito, hai l’area commenti a tua disposizione.

#KeepItSimple


Immagine di copertina: proxmoxcentral.com
riferimenti:
forums.docker.com/t/non-root-user-able-to-bind-to-port-80-why/140524
github.com/opencontainers/runc/issues/4972
help.nextcloud.com/t/error-during-container-init-open-sysctl-net-ipv4-ip-unprivileged-port-start-file-reopen-fd-8-permission-denied-unknown/235301
reddit.com/r/docker/comments/1op6e1a/impossible_to_run_docker/

Correzioni, suggerimenti? Lascia un commento nell'apposita area qui di seguito o contattami privatamente.
Ti è piaciuto l'articolo? Offrimi un caffè! ☕ :-)

Exit mobile version