
Objetivo:
En este artículo la finalidad es crear una forma de instalar automáticamente
un sistema Debian 12 (en este caso), de manera que la instalación no sea interactiva
, es decir, que el usuario final no tenga que hacer nada ni tener conocimientos previos avanzados para poder tener el sistema operativo preparado para usar. Esto es útil para la creación de máquinas nuevas automáticamente.
Pasos Previos:
-
Para comenzar, parto de una
máquina cualquiera en local
que hará deservidor
(por ejemplo usando Virt Manager). -
Obtener mediante la página oficial de Debian, o por internet el archivo
preseed.cfg
que es el encargado de indicarle al sistema en el momento que se esta instalando, las configuraciones necesarias. En este caso, he dejado el que he usado ya configurado, al final del artículo (Ve abajo del todo.) -
El siguiente paso que he hecho ha sido
crear una red llamada "px2"
y le he añadido unainterfaz
al servidor que conecta con esta red (desde ajustes de Virt manager de la propia máquina). -
Las
direcciones ips
de mi máquina que hace de servidor son:
La que sale a internet: enp1s0: 192.168.122.22/24 La que conecta con la red px2: enp7s0: 10.0.0.30/24

Empezamos!
Bien, con la red configurada el primer paso es instalar el paquete dnsmasq
que incluye el paquete dhcp necesario para que las máquinas clientes puedan obtener una configuración de red. Para instalarlo y ver el estado es con:
sudo apt install dnsmasq
sudo systemctl status dnsmasq

El siguiente paso es configurar dnsmasq
pero antes, hay que crear el directorio que se va a usar (o dará error) que en este caso es /srv/tftp
.
Hecho esto ahora hay que ir al archivo /etc/dnsmasq.conf
añadiendo al final esta configuración:
#Servidor DHCP
dhcp-range=10.0.0.10,10.0.0.100,255.255.255.0,12h
#Preseed
dhcp-boot=pxelinux.0
#Servidor TFTP
enable-tftp
#directorio archivos
tftp-root=/srv/tftp
Donde indico el `rango de red para dhcp` acorde a mi red px2 que use las direcciones de la `10.0.0.10 a la 10.0.0.100` (esto es completamente configurable, si hubiese más equipos, se amplia el rango, es decir, en vez de poner 100 puedo poner por ejemplo 200). También como dije antes, hay que indicar el directorio de trabajo, donde después habrá que introducir unos archivos que ahora veremos.
Y reinicio el servicio para que cargue la nueva configuración con:
sudo systemctl restart dnsmasq
Ahora entro a mi directorio /srv/tftp
y descargo netboot
, para ello uso la herramienta wget
para obtener el archivo (la url puede variar con el paso del tiempo):
sudo wget http://ftp.debian.org/debian/dists/bookworm/main/installer-amd64/current/images/aso/netboot/netboot.tar.gz
En la imagen de abajo muestro los pasos anteriores. Si falla, recordad usar sudo (pero con cuidado!, sólo si es necesario). La orden mkdir -p
crea el directorio junto con los subdirectorios que le indico, para que sea más rápido que hacer varias veces mkdir, cd, etc. Cuando termina de descargar, obtenemos un archivo llamado netboot.tar.gz
.

Y descomprimo los archivos con:
sudo tar -xvf netboot.tar.gz

El siguiente paso es instalar apache2
para poder brindar a cualquier equipo cliente que necesite mi preseed para poder hacer la instalación automatizada. El archivo preseed.cfg
hay que copiarlo
al directorio /var/www/html
de la máquina servidor, es decir, con la que estamos trabajando todo el tiempo (lo especifico para que no haya dudas si es cliente o servidor, etc), para que pueda brindarlo por red usando apache.
sudo apt install apache2
Copio mi archivo preseed.cfg que lo tengo en /home/debian/ a /var/www/html/:
sudo cp /home/debian/preseed.cfg /var/www/html/

Ahora toca modificar el archivo /srv/tftp/debian-installer/amd64/boot-screens/txt.cfg
(/srv/tftp es mi directorio que he elegido) que por si acaso, hice una copia de seguridad del archivo, el archivo txt.cfg
le he especificado una entrada llamada Desatendida 2 andres
(a modo de ejemplo) que luego aparecerá en el grub de arranque.
Se puede configurar para que arranque directamente, pero he preferido hacerlo de esta manera para que realmente se aplique la entrada que he creado. Mi configuración es la siguiente:
default install label install menu label ^Install kernel debian-installer/amd64/linux append vga=788 initrd=debian-installer/amd64/initrd.gz --- quiet label unattended-gnome menu label ^Desatendida 2 andres kernel debian-installer/amd64/linux append vga=788 hostname=debian domain='' initrd=debian-installer/amd64/initrd.gz url=http://192.168.122.22/preseed.cfg locale=es_ES console-setup/ask_detect=false keyboard-configuration/xkb-keymap=es ---
Donde especifico la ip de mi servidor
donde esta el preseed, y un par de parámetros extra de entrada, para evitar errores ocasionales (hice una copia del archivo como se ve también en la imagen de más abajo).
Una vez modificado el archivo txt.cfg reinicio dnsmasq para que se apliquen los cambios reiniciando el servicio:
sudo systemctl restart dnsmasq
Y compruebo que no haya errores en la configuración con:
sudo systemctl status dnsmasq

Antes de terminar con el servidor hay que activar el bitforwarding
para el reenvio de paquetes, modificando el archivo /etc/sysctl.conf
y descomentando la linea (así quedará permanente):
# Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1
Y para que se aplique:
sudo sysctl -p

En el siguiente paso (ya quedan pocos!) hay que añadir una regla con iptables al servidor
para permitir que los clientes tenga internet y pueda descargar paqueteria
y para ello hay que instalar iptables (si no se tuviese ya):
sudo apt install iptables
Una vez instalado, como superusuario le especifico la regla para los equipos en mi red, que como recordatorio es la 10.0.0.0/24 y mi interfaz es enp1s0
. Esto permitirá a los clientes que se conecten y obtengan ip del rango que especifiqué antes, tengan salida a internet.
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o enp1s0 -j MASQUERADE

En el cliente:
Para crear un cliente usando virtmanager, hay que ir a nueva y a manual:

Luego como es Debian, elijo Debian 11 (porque en mi versión de virtmanager es la mas reciente, pero funciona igualmente en Debian 12), luego le asigno un disco, ram, etc y cuando me pregunte el nombre para terminar, hay que darle a personalizar antes de instalar
.

En opciones de arranque
hay que indicarle que primero compruebe por red
(poniendo la opción NIC como la primera):

Luego al iniciar la máquina aparece información varia de lo que esta ocurriendo:

Cuando termina y aparece el grub
de Debian 12, aparece Desatendida 2 andres
que es la entrada que puse en el archivo de configuración del txt.cfg de antes.

Y cuando termina la instalación, hay que parar la máquina
e indicarle que arranque desde el disco duro
volviendo a poner en primer lugar la opción Virt para poder cargar el sistema:

Hecho esto ya hemos terminado!, como se ve en la máquina cliente tiene salida a internet y tambien se resuelven los nombres de dominio (resolución DNS):

Solución de Posibles Errores:
Al reiniciar el servidor, hay que asegurarse que el bitforwarding sigue activado (aunque esta puesto como permanente) y volver a introducir la regla de iptables
(ya que no esta permanente, buscad información si interesa para hacerlo permanente a reinicios) y comprobar si dnsmasq esta activo
.
Si al probar dias despues, pasara algo extraño, como que se empiezan a descargar los paquetes, pero para algunos salta un error de réplica, lo tengo puesto en el presed a deb.debian.org y lo he modificadlo a ftp.debian.org. Es un error extraño porque haciendo alt+f2 y entrar en el modo consola, la máquina hace ping tanto a los dns de google 8.8.8.8, a google.com y a debian. Lo curioso es que al darle a reintentar, la instalación continua y acaba bien. Es muy extraño, buscando informacion en internet puede ser una caida puntual de internet. Dejo una captura del mensaje:

Justo despues funciona bien y se sigue instalando.

Si os pasa, ocurre cuando descarga el paquete liblzo2-2udeb
que sirve para el instalador de debian con el algoritmo LZ0, aunque no deberia de ocurrir.
Nota Importante:
Mi preseed.cfg contiene un usuario llamado andres
y una clave cifrada, para poder adaptar esto a otros usuarios, hay que modificar el nombre (obvio) y el campo de password por una contraseña cifrada que TÚ elijas. Si usas mi preesed directamente sin modificarlo, cuando termines no podrás iniciar sesión ya que estará el usuario andres y mi contraseña. Lo mismo aplica para root
.
Para introducir otra contraseña, puede ser en texto claro o cifrada como yo hice. Usé el algoritmo SHA-512, por eso empieza por $6$.
Con el paquete whois
se puede generar otra password así:
mkpasswd -m sha-512
Esto pedirá que se introduzca una contraseña y la devolverá ya cifrada. Eso es lo que hay que poner en el preseed en vez de la mia que empieza por $6$ en la parte de Accounts
Preseed.cfg
# Local
d-i debian-installer/language string en_GB:en
d-i debian-installer/country string ES
d-i debian-installer/locale string en_GB.UTF-8
# Keyboard
d-i keyboard-configuration/xkb-keymap select es
# Network
d-i netcfg/choose_interface select auto
d-i netcfg/get_hostname string andres
d-i netcfg/get_domain string unassigned-domain
d-i netcfg/wireless_wep string
# Mirror
d-i mirror/country string manual
d-i mirror/http/hostname string ftp.es.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
d-i mirror/suite string stable
# Accounts
d-i passwd/root-password-crypted password $6$bfZ4HnT1IB3XFz3s$w20.nob/mS71wYqyVFen3V4H6VY8no7j30roJYQ3s0OLHBNDhfPqrMRYDpeRga9/sclRvLNh5eC4rwiXZsAwA0
d-i passwd/user-fullname string andres
d-i passwd/username string andres
d-i passwd/user-password-crypted password $6$bfZ4HnT1IB3XFz3s$w20.nob/mS71wYqyVFen3V4H6VY8no7j30roJYQ3s0OLHBNDhfPqrMRYDpeRga9/sclRvLNh5eC4rwiXZsAwA0
# Clock and time zone
d-i clock-setup/utc boolean true
d-i time/zone string Europe/Madrid
d-i clock-setup/ntp boolean true
# Partitioning
d-i partman-auto/disk string /dev/vda
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-auto/method string lvm
d-i partman-lvm/confirm boolean true
d-i partman-auto/choose_recipe select mypartitioning
d-i partman-auto-lvm/new_vg_name string vg00
d-i partman-auto-lvm/guided_size string max
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-auto/expert_recipe string \
mypartitioning :: \
512 1 512 xfs \
$primary{ } $bootable{ } \
method{ format } format{ } \
use_filesystem{ } filesystem{ xfs } \
mountpoint{ /boot } \
. \
1024 1 1024 linux-swap \
$defaultignore{ } \
$lvmok{ } \
lv_name{ swap } \
in_vg { vg00 } \
method{ swap } format{ } \
. \
3072 1 3072 xfs \
$defaultignore{ } \
$lvmok{ } \
lv_name{ root } \
in_vg { vg00 } \
method{ format } format{ } \
use_filesystem{ } filesystem{ xfs } \
mountpoint{ / } \
. \
6144 1 6144 xfs \
$defaultignore{ } \
$lvmok{ } \
lv_name{ var } \
in_vg { vg00 } \
method{ format } format{ } \
use_filesystem{ } filesystem{ xfs } \
mountpoint{ /var } \
. \
8192 1 1000000000 xfs \
$defaultignore{ } \
$lvmok{ } \
lv_name{ home } \
in_vg { vg00 } \
method{ format } format{ } \
use_filesystem{ } filesystem{ xfs } \
mountpoint{ /home } \
.
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
# Base system
d-i base-installer/kernel/image string linux-image-amd64
# Apt
d-i apt-setup/services-select multiselect security, updates
d-i apt-setup/security_host string security.debian.org
# Package selection
tasksel tasksel/first multiselect standard, ssh-server
popularity-contest popularity-contest/participate boolean false
# Boot loader
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i grub-installer/bootdev string default
# Finishing up
d-i finish-install/reboot_in_progress note
Espero que os haya servido, un saludo y no useis ChatGPT que os piyarán! :)