Creazione dell’immagine cloud-init

A partire da FUSS 10 (Debian Buster) si genereranno delle immagini complete per macchina virtuale del server nel formato dei dump della piattaforma Proxmox adottata dal progetto, in modo da semplificare l’installazione e la configurazione iniziale di un FUSS server.

Le immagini si appoggiano a cloud-init in modo da consentire la gestione della rete direttamente dall’interfaccia web, una volta che le si siano importate e gli si sia associato un volume per cloud-init (i dettagli sono illustrati nella fuss-tech-guide.

Creazione macchina virtuale

Si crei una nuova macchina virtuale (VM) su Proxmox, in fase iniziale è sufficiente l’interfaccia di rete singola creata dal wizard, si usi il bridge associato alla rete esterna.

Sulla macchina virtuale si deve fare una installazione ordinaria di Debian con netinstall (ci si procuri l’ultima versione della ISO e la si carichi dentro /var/lib/vz/template/iso):

# cd /var/lib/vz/template/iso/
# wget
https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-13.0.0-amd64-netinst.iso

Nella creazione si utilizzi la precedente immagine come CDROM e per il resto si usino i valori di default per tutto, compresi i 32 G di dimensione del disco. Se si vuole ottenere una immagine del disco da impiegare eventualmente in altre piattaforme si abbia cura di fare installare quest’ultimo sullo storage local in formato qcow (che consente eventualmente di distribuire direttamente il file che si otterrà in /var/lib/vz/images/VMID/).

Una volta completato il wizard, aggiungere la seconda interfaccia per la rete interna, ed assicurarsi che sia questa che la prima interfaccia non abbiano spunta per l’uso del firewall. Non è necessario aggiungere subito le ulteriori due reti WiFi per gli ospiti (WiFi Guest) e per gli apparati (WiFi Devices), potranno essere aggiunte in un secondo tempo in fase di installazione dell’immagine.

Nota

non è detto che nella macchina Proxmox in cui si esegue questa preparazione siano presenti ulteriori bridge su cui attestarle.

Inoltre, occorrerà assicurarsi di attivare la spunta di Discard nella configurazione del disco, ed una volta terminata l’installazione occorrerà rimuovere l’uso dell’immagine del CD di installazione.

In sostanza una volta creata la macchina virtuale (si assuma con VMID 107) occorrerà eseguire i comandi (alcuni saranno inutili se si sono messe le relative impostazioni in fase di creazione):

qm set 107 -net0 virtio,bridge=vmbr0      # to remove firewall
qm set 107 -net1 virtio,bridge=vmbr1      # to remove firewall
qm set 107 -scsi0 local:107/vm-107-disk-0.qcow2,iothread=1,size=32G,discard=on
# qm set 107 -net2 virtio,bridge=vmbr2    # optional for WiFi Guest
# qm set 107 -net3 virtio,bridge=vmbr3    # optional for WiFi Devices
# qm set 107 -ide2 none                   # do after installation

Nota

per l’impostazione del discard (terza riga) occorre verificare su quale storage:pathname è stato creato il disco, nel casi dell’esempio con grep ^scsi0 /etc/pve/qemu-server/107.conf, ma è più semplice operare dall’interfaccia web

Installare Debian

Si esegua l’installazione in maniera ordinaria; per la rete si può anche usare un eventuale DHCP, la configurazione scelta in fase di installazione verrà comunque sovrascritta da quella che si imposterà in fase di deploy con cloud-init.

Le operazioni specifiche che occorre fare in fase di installazione sono:

  • si usi Italia / Italiano per la selezione di lingua, località e tastiera

  • come hostname e dominio si usi un valore qualunque (verranno sovrascritti) ad esempio trixie e fusslab.blz

  • si imposti per root la password di default: fuss

  • si usi un utente normale: fuss (o altro, andrà comunque cancellato)

  • si configuri la rete nella maniera più semplice per accedere sulla macchina (verrà comunque cancellata)

  • scegliere il partizionamento manuale del disco,

    • creare una prima partizione primaria di 4G come swap

    • creare una seconda partizione primaria con resto del disco come radice

  • si usino i default per la configurazione delle fonti di APT e il sondaggio sui pacchetti installati

  • nella schermata Selezione del software scegliere solo Server SSH e Utilità di sistema standard (il resto si installerà dopo).

  • installare grub sul disco

Preparazione dell’installazione base

Una volta completata l’installazione base si potrà passare a preparare il server. Dato che l’installazione di default blocca l’accesso in SSH a root, o si usa l’utente normale provvisorio creato in fase di installazione e si usa su o sudo, o ci si collega sulla console via web. Tutte le operazioni seguenti sono da eseguirsi dall’utente root.

Il primo passo è abilitare da subito l’accesso di SSH a root, inserendo dentro /etc/ssh/sshd_config.d/root.conf:

# enable root password access
PermitRootLogin yes

e riavviare sshd con systemctl restart ssh; non è necessario configurare in questa fase l’uso di chiavi in authorized_keys, queste possono essere impostate in qualunque momento successivo tramite cloud-init. Se ci si è collegati inizialmente con l’utente fuss si esca.

Ci si ricolleghi poi come root, e si rimuova l’utente creato in fase di installazione con:

# userdel -r fuss

Occorrerà anzitutto installare cloud-init ed alcuni programmi:

  • resolvconf per poter gestire la configurazione del DNS attraverso cloud-init;

  • bind9 per poter configurare da subito la macchina in modalità compatibile con la configurazione che verrà impostata da fuss-server

  • quotatool per attivare le quote nel caso si aggiunga un disco separato per le home;

  • qemu-guest-agent per l’integrazione con Proxmox

# apt install cloud-init resolvconf bind9 quotatool

Per evitare i problemi di risoluzione con indirizzi IPv6 che si sono verificati in alcuni casi, è opportuno che Bind sia configurato da subito per usare solo IPv4, pertanto si modifichi in /etc/default/named l’ultima riga in:

OPTIONS="-4 -u bind"

e si riavvii Bind con systemctl restart named.

Se è ancora in uso /etc/apt/sources.list si esegua apt modernize-sources che genera /etc/apt/sources.list.d/debian.sources, e si rimuova /etc/apt/sources.list.bak. Altrimenti si può configurare direttamente le fonti in /etc/apt/sources.list.d/ per usare i repository di fuss, si utilizzino contenuti analoghi ai seguenti; per /etc/apt/sources.list.d/debian.sources si usi:

Types: deb deb-src
URIs: http://deb.debian.org/debian/
Suites: trixie
Components: main non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb deb-src
URIs: http://deb.debian.org/debian/
Suites: trixie-updates
Components: main non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb deb-src
URIs: http://security.debian.org/debian-security/
Suites: trixie-security
Components: main non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

e per /etc/apt/sources.list.d/fuss.sources si usi:

Types: deb deb-src
URIs: http://archive.fuss.bz.it/
Suites: trixie
Components: main
Signed-By: /usr/share/keyrings/fuss-keyring.gpg

inoltre si deve installare il pacchetto con le chiavi GPG di firma dei pacchetti, con:

# wget https://archive.fuss.bz.it/pool/main/f/fuss-archive-keyring/fuss-archive-keyring_0.20250620_all.deb
# apt install ./fuss-archive-keyring_0.20250620_all.deb
# rm ./fuss-archive-keyring_0.20250620_all.deb

Con il passaggio a Debian Buster e seguenti di default le interfacce di rete assumono i nuovi nomi dipendenti dall’hardware, per cui al posto di eth0 ed eth1 si avranno nomi come ens18 o ens19. La configurazione delle stesse con cloud-init riporta però automaticamente in uso i nomi tradizionali, per cui non serve preoccuparsi di questo cambiamento nelle configurazioni, con una eccezione: le eventuali interfaccia dedicate alle reti WiFi Guest e WiFi Devices.

Queste non devono essere configurate da cloud-init per cui prenderanno il nome di default, variando rispetto a quello che si sarebbe ottenuto con una Debian Jessie. Si può però evitare il cambiamento (consentendo il riutilizzo senza cambiamenti dei nomi usati in un precedente fuss-server.yaml) configurando opportunamente le opzioni di avvio del kernel, inserendo in /etc/default/grub la riga:

GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"

ed eseguendo update-grub; in questo modo le interfacce verranno comunque chiamate eth0, eth1, eth2, ecc. Questa configurazione non è comunque necessaria.

Infine per evitare che la voce di configurazione per lo presente in /etc/network/interfaces sovrascriva la stessa voce che cloud-init configura con un suo file sotto /etc/network/interfaces.d (50-cloud-init.cfg) si sposti la riga che include le configurazioni da questa directory in fondo al file, in sostanza /etc/network/interfaces dovrà essere qualcosa del tipo:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

source /etc/network/interfaces.d/*

Nota

si tenga presente che con questo /etc/network/interfaces non verrà configurata automaticamente nessuna interfaccia di rete, e se non si configura la stessa via cloud-init la macchina risulterà raggiungibile solo sulla console, pertanto se vi si deve accedere via rete per lavorarci sopra prima di creare l’immagine di cloud-init si lasci presente la configurazione dell’interfaccia che si intende utilizzare, rimuovendola nella fase di pulizia.

Nota

si tenga presente che con questa configurazione si gestisce il contenuto di /etc/resolv.conf con cloud-init, ma questo file viene anche gestito direttamente dal comando fuss-server, per cui si abbia cura di impostare via cloud-init lo stesso nome a dominio che si imposterà poi nel fuss-server e di indicare sempre come server DNS 127.0.0.1.

Infine, qualora fosse presente, occorre modificare /etc/aliases per rimuovere l’eventuale presenza del reinoltro della posta dell’utente root all’utente di installazione fuss; in sostanza qualora presenta va rimossa la riga:

root: fuss

Configurazione di cloud-init

La configurazione di default installata da cloud-init prevede la creazione di un utente di default ed il blocco dell’accesso come root. La scelta del progetto è di fornire un accesso diretto a root a chiavi, con la possibilità di usare una password, per questo vanno fatte alcune modifiche in /etc/cloud/cloud.cfg. Anzitutto si devono cambiare le due righe relative alla gestione degli utenti locali creati di default come nell’esempio seguente:

# A set of users which may be applied and/or used by various modules
# when a 'default' entry is found it will reference the 'default_user'
# from the distro configuration specified below
users:
   - name: root

e poi bisogna evitare che venga applicata la configurazione che disabilita l’uso dell’utente root, configurando disable_root a false come in:

# If this is set, 'root' will not be able to ssh in and they
# will get a message to login instead as the above $user (debian)
disable_root: false

infine si aggiungano poi in coda al file la ulteriore configurazione che consente a cloud-init di gestire /etc/hosts:

manage_etc_hosts: true

Si aggiunga poi sotto /etc/cloud/cloud.cfg.d/ il file 10_fuss.cfg, con il contenuto seguente (attenzione: le spaziature non devono contenere tabulazioni):

apt:
    preserve_sources_list: true
packages:
  - fuss-server

Pulizia

Una volte effettuate le configurazioni precedenti si proceda a ripulire l’immagine da tutti i dati spuri, ci si sconnetta e ci si riconnetta eseguendo il comando:

# set +o history

per disabilitare la history.

Si verifichi se è stato installato un nuovo kernel con un uname -a per verificare la versione presente ed un controllo in /boot, e si cancellino eventuali immagini relative a versioni precedenti, con qualcosa come:

apt purge linux-image-6.12.38+deb13-amd64

Se si è lasciato la configurazione dell’interfaccia di rete principale usata in fase di installazione dentro /etc/network/interfaces la si rimuova.

Si eseguano poi (come root) i comandi:

> .bash_history
apt clean
apt purge os-prober
find /etc -name "*~" -delete
journalctl --rotate
journalctl --vacuum-time=1s
cd /var/log/
> dpkg.log
> installer/syslog
> wtmp
> btmp
> lastlog
fstrim /

per fare una pulizia finale, compreso ricreare vuoti i file modificati dal sistema mentre era in uso. Non installando più di default rsyslog i file di log tradizionali dovrebbero essere assenti.

Generazione dell’immagine

Una volte effettuate le configurazioni precedenti, si fermi la macchina virtuale e se ne esegua un backup, chiedendo la compressione (coi valori predefiniti in formato zst). Si troverà il file del backup sotto /var/lib/vz/dump (o nella directory che si è configurato come storage di backup) nella forma:

vzdump-qemu-VMID-ANNO_ME_GI-OR_MI_SE.vma.zst

Pubblicazione

Dopo eventuali test, caricare il file sulla macchina dove verrà pubblicato, ad esempio nella home dell’utente root con il comando:

$ scp /var/lib/vz/dump/vzdump-qemu-106-2023_06_05-16_06_42.vma.zst \
      root@iso.fuss.bz.it:

quindi collegarsi alla macchina stessa (ssh root@iso.fuss.bz.it) e lanciare il comando:

# cd /root
# ./release_cloud_image.sh vzdump-qemu-107-2025_08_29-15_06_14.vma.zst

che provvede a spostare il file nella destinazione corretta e generarne checksum e relative firme.

Quindi aggiornare il file /var/www/iso/cloud-init/changelog.txt con l’elenco delle modifiche presenti nella release corrente.

L’immagine è ora disponibile per lo scaricamento su https://iso.fuss.bz.it/cloud-init/