Customizar a Instalação do Linux Debian com Preseed
Entenda como customizar/personalizar a imagem ISO, configurar o arquivo /etc/network/interfaces, /etc/sudoers (além de outros), acoplar programas, etc, em suma: customizar a ISO para instalar seu Debian personalizado tanto em um único computador quanto em rede.
[ Hits: 415 ]
Por: Buckminster em 28/07/2025
#!/bin/bash
set -e
### === VERIFICAÇÃO DE ROOT ===
if [ "$EUID" -ne 0 ]; then
echo "Este script deve ser executado usando sudo)."
exit 1
fi
### === CONFIGURAÇÕES ===
### ALTERE para o teu ambiente ###
##PRESEED_PATH="/home/aristotles/0-Montagem_de_Cluster/PXE/preseed.cfg"
PRESEED_PATH="/home/kluster/0-Montagem_de_Cluster/PXE/preseed.cfg"
INTERFACE="enp3s0"
SERVER_IP="192.168.1.3"
DHCP_SUBNET="192.168.1.0"
DHCP_NETMASK="255.255.255.0"
DHCP_RANGE_START="192.168.1.4"
DHCP_RANGE_END="192.168.1.12"
DHCP_ROUTER="192.168.1.3"
### === INSTALAR PACOTES NECESSÁRIOS ===
echo "Instalando pacotes..."
apt update
#aptitude safe-upgrade -y
apt install -y isc-dhcp-server tftpd-hpa apache2 syslinux syslinux-common pxelinux wget cpio unzip
### === CONFIGURAR PXE COM NETBOOT E TFTP ===
echo "Configurando PXE com netboot e TFTP..."
mkdir -p /var/lib/tftpboot
mkdir -p /var/lib/tftpboot/{pxelinux.cfg,EFI/boot,grub,clonezilla}
# Baixar os arquivos netboot do Debian (amd64)
NETBOOT_BASE_URL="http://deb.debian.org/debian/dists/bookworm/main/installer-amd64/current/images/netboot/debian-installer/amd64"
wget -q --show-progress "$NETBOOT_BASE_URL/linux" -O /var/lib/tftpboot/vmlinuz
wget -q --show-progress "$NETBOOT_BASE_URL/initrd.gz" -O /var/lib/tftpboot/initrd.gz
# Personalizar initrd.gz para incluir DNS dentro do initrd
echo "Personalizando initrd.gz para incluir DNS..."
cd /var/lib/tftpboot
mkdir -p initrd-temp
cd initrd-temp
gzip -dc ../initrd.gz | cpio -id --no-absolute-filenames
cat <etc/resolv.conf
nameserver 1.1.1.1
nameserver 9.9.9.9
EOF
# Recriar o initrd.gz customizado
find . | cpio -o -H newc | gzip -c > ../initrd-custom.gz
cd ..
rm -rf initrd-temp
mv initrd-custom.gz initrd.gz
echo "initrd.gz customizado com DNS inserido."
# Copiar arquivos PXELINUX essenciais
cp /usr/lib/PXELINUX/pxelinux.0 /var/lib/tftpboot/
cp /usr/lib/syslinux/modules/bios/libutil.c32 /var/lib/tftpboot/
cp /usr/lib/syslinux/modules/bios/libcom32.c32 /var/lib/tftpboot/
cp /usr/lib/syslinux/modules/bios/menu.c32 /var/lib/tftpboot/
cp /usr/lib/syslinux/modules/bios/ldlinux.c32 /var/lib/tftpboot/
### === BAIXAR E CONFIGURAR MEMTEST86+ 7.20 ===
TMPDIR="/var/lib/tftpboot/tmp"
rm -rf "$TMPDIR"
mkdir -p "$TMPDIR"
echo "Baixando Memtest86+ 7.20..."
wget -q --show-progress https://www.memtest.org/download/v7.20/mt86plus_7.20.binaries.zip -O "$TMPDIR/memtest.zip" || { echo "❌ Falha no download do Memtest86+"; exit 1; }
unzip -o "$TMPDIR/memtest.zip" -d "$TMPDIR"
if [[ -f "$TMPDIR/memtest64.bin" ]]; then
cp "$TMPDIR/memtest64.bin" /var/lib/tftpboot/memtest86+
echo "Memtest86+ copiado como 'memtest86+' (usando memtest64.bin)"
else
echo "Arquivo memtest64.bin não encontrado após extração."
exit 1
fi
rm -rf "$TMPDIR"
### === BAIXAR E INSTALAR CLONEZILLA ===
### Verifique em https://clonezilla.org/downloads/download.php?branch=stable a versao atual e altere abaixo nos wget o numero da versao se for o caso.
CLONEZILLA_ZIP="/var/lib/tftpboot/clonezilla.zip"
CLONEZILLA_DIR="/var/lib/tftpboot/clonezilla"
TMP_CLONEZILLA_DIR="/var/lib/tftpboot/tmp/clonezilla-files"
echo "Verificando Clonezilla..."
# Verifica se já está tudo copiado para o destino final
if [[ -f "$CLONEZILLA_DIR/vmlinuz" && -f "$CLONEZILLA_DIR/initrd.img" && -f "$CLONEZILLA_DIR/filesystem.squashfs" ]]; then
echo "Clonezilla já está configurado em $CLONEZILLA_DIR. Pulando extração e cópia."
else
# Verifica se o zip existe e/ou se está corrompido antes de baixar
if [ -f "$CLONEZILLA_ZIP" ]; then
if unzip -tq "$CLONEZILLA_ZIP" >/dev/null 2>&1; then
echo "Arquivo $CLONEZILLA_ZIP existe e é válido. Pulando download."
else
echo "Arquivo $CLONEZILLA_ZIP está corrompido. Baixando novamente..."
rm -f "$CLONEZILLA_ZIP"
# Baixa o arquivo
wget -q --show-progress https://downloads.sourceforge.net/project/clonezilla/clonezilla_live_stable/3.2.2-15/clonezilla-live-3.2.2-15-amd64.zip -O "$CLONEZILLA_ZIP" || { echo "❌ Falha no download do Clonezilla"; exit 1; }
fi
else
echo "Baixando Clonezilla..."
wget -q --show-progress https://downloads.sourceforge.net/project/clonezilla/clonezilla_live_stable/3.2.2-15/clonezilla-live-3.2.2-15-amd64.zip -O "$CLONEZILLA_ZIP" || { echo "❌ Falha no download do Clonezilla"; exit 1; }
fi
# Garante que o diretório temporário exista antes de extrair
mkdir -p "$TMP_CLONEZILLA_DIR"
# Extrai o zip na pasta temporária
unzip -o "$CLONEZILLA_ZIP" -d "$TMP_CLONEZILLA_DIR"
# Detecta o diretório que contém o subdiretório "live/"
EXTRACTED_DIR=$(find "$TMP_CLONEZILLA_DIR" -type d -name live -exec dirname {} \; | head -n1)
if [ -z "$EXTRACTED_DIR" ]; then
echo "Diretório com subdiretório 'live' não encontrado após extração."
exit 1
fi
echo "Diretório detectado: $EXTRACTED_DIR"
# Verifica se os arquivos essenciais existem dentro do subdiretório "live"
if [[ -f "$EXTRACTED_DIR/live/vmlinuz" && -f "$EXTRACTED_DIR/live/initrd.img" && -f "$EXTRACTED_DIR/live/filesystem.squashfs" ]]; then
mkdir -p "$CLONEZILLA_DIR"
cp "$EXTRACTED_DIR/live/"{vmlinuz,initrd.img,filesystem.squashfs} "$CLONEZILLA_DIR/"
echo "Clonezilla copiado para $CLONEZILLA_DIR"
else
echo "Arquivos do Clonezilla não encontrados após extração."
exit 1
fi
# Limpeza opcional dos temporários
rm -rf "$TMP_CLONEZILLA_DIR"
fi
# Criar Menu PXE BIOS
echo "Configurando o menu PXE..."
cat </var/lib/tftpboot/pxelinux.cfg/default
DEFAULT debian
UI menu.c32
PROMPT 1
TIMEOUT 100
MENU TITLE PXE Boot Menu
LABEL debian-pxe
MENU LABEL Instale o Debian (PXE)
KERNEL vmlinuz
APPEND initrd=initrd.gz auto=true priority=critical netcfg/get_hostname=no01 netcfg/get_domain=localdomain preseed/url=http://$SERVER_IP/debianiso/preseed.cfg ---
LABEL memtest
MENU LABEL Teste de RAM (Memtest86+ 7.20)
KERNEL memtest86+
LABEL clonezilla
MENU LABEL Clonezilla Live (Backup/Restore)
KERNEL clonezilla/vmlinuz
APPEND initrd=clonezilla/initrd.img boot=live union=overlay username=user config components noswap edd=on nomodeset ocs_live_run="ocs-live-general" ocs_live_keymap="none" ocs_live_batch="no" vga=788 fetch=tftp://$SERVER_IP/clonezilla/filesystem.squashfs
LABEL debian-ipxe
MENU LABEL Instalar Debian via iPXE
KERNEL ipxe.lkrn
APPEND dhcp && chain http://$SERVER_IP/boot/debian.ipxe
EOF
### === CONFIGURAR UEFI PXE COM GRUB ===
echo "Configurando suporte a UEFI PXE com GRUB..."
# Instala o GRUB para gerar arquivos UEFI PXE (apenas se ainda não instalado)
apt install -y grub-efi-amd64-bin
# Cria diretório EFI/boot para UEFI PXE boot
#mkdir -p /var/lib/tftpboot/EFI/boot
# Copia o GRUB EFI executável padrão
cp /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /var/lib/tftpboot/EFI/boot/bootx64.efi 2>/dev/null || \
cp /usr/lib/grub/x86_64-efi/grubnetx64.efi /var/lib/tftpboot/EFI/boot/bootx64.efi
# Cria diretório de configuração do GRUB
#mkdir -p /var/lib/tftpboot/grub
cat </var/lib/tftpboot/grub/grub.cfg
set default=0
set timeout=10
menuentry "Instalação Automática Debian (PXE)" {
linux /vmlinuz auto=true priority=critical preseed/url=http://$SERVER_IP/debianiso/preseed.cfg ---
initrd /initrd.gz
}
menuentry "Teste de Memória RAM (Memtest86+ UEFI)" {
chainloader /memtest86+.efi
}
EOF
### === CONFIGURAR APACHE ===
echo "Configurando Apache para servir preseed.cfg..."
# Detecta o DocumentRoot do Apache
DOCROOT=$(grep -i "DocumentRoot" /etc/apache2/sites-enabled/000-default.conf | grep -v '#' | awk '{print $2}')
# Se não encontrou, usa padrão seguro
if [ -z "$DOCROOT" ]; then
echo "DocumentRoot não detectado. Usando /var/www/html como padrão."
DOCROOT="/var/www/html"
fi
# Cria diretório e copia o preseed
mkdir -p "$DOCROOT/debianiso"
cp "$PRESEED_PATH" "$DOCROOT/debianiso/"
# Ajusta permissões
chmod 644 "$DOCROOT/debianiso/preseed.cfg"
chown www-data:www-data "$DOCROOT/debianiso/preseed.cfg"
# Reinicia o Apache
systemctl restart apache2
### === CONFIGURAR TFTP ===
echo "Configurando tftpd-hpa..."
/etc/default/tftpd-hpa
cat </dev/null TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure --blocksize 512"
EOF
### === CONFIGURAR DHCP ===
echo "Configurando DHCP Server..."
# Define interface de rede onde o DHCP deve escutar (ajuste conforme necessário)
echo "INTERFACESv4=$INTERFACE" > /etc/default/isc-dhcp-server
# Backup do dhcpd.conf original, se ainda não existir
cp -n /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.bak
# Comentar opções DNS padrão, se existirem
sed -i -E 's/^(option domain-name.*|option domain-name-servers.*)/# &/' /etc/dhcp/dhcpd.conf
# Adiciona opção de arquitetura PXE global, se não existir ainda
if ! grep -qF "option arch code 93 = unsigned integer 16;" /etc/dhcp/dhcpd.conf; then
echo "option arch code 93 = unsigned integer 16;" >> /etc/dhcp/dhcpd.conf
fi
MARKER="# BEGIN SUBNET $DHCP_SUBNET"
# Adicionar subnet 192.168.1.0/24 com marcador único, se ainda não estiver configurada
if ! grep -qF "$MARKER" /etc/dhcp/dhcpd.conf; then
cat <> /etc/dhcp/dhcpd.conf
MARKER
# Definir opção de arquitetura PXE (REQUIRED for conditional checks)
option arch code 93 = unsigned integer 16;
subnet $DHCP_SUBNET netmask $DHCP_NETMASK {
range $DHCP_RANGE_START $DHCP_RANGE_END;
option routers $DHCP_ROUTER;
option domain-name-servers 1.1.1.1, 9.9.9.9;
if option arch = 00:07 {
filename "EFI/boot/bootx64.efi"; # UEFI 64-bit
} else {
filename "/pxelinux.0"; # BIOS
}
next-server $DHCP_ROUTER;
}
# END SUBNET $DHCP_SUBNET
EOF
echo "Subnet adicionada no dhcpd.conf."
else
echo "Subnet já configurada, pulando adição."
fi
### === REINICIAR SERVIÇOS ===
ifup "$INTERFACE"
systemctl restart isc-dhcp-server
systemctl restart tftpd-hpa
systemctl restart apache2
echo "Servidor PXE configurado com sucesso!"
echo "Menu PXE: Debian | Memtest86+ | Clonezilla | iPXE"
echo "Configure os clientes para bootar via PXE pela rede."
#!/bin/bash
set -e
### === CONFIGURAÇÕES ===
HTTP_ROOT="/var/www/html" # Caminho do servidor Apache
BOOT_DIR="$HTTP_ROOT/boot"
SERVER_IP="192.168.1.3" # IP do servidor PXE/HTTP
TFTP_DIR="/var/lib/tftpboot"
PRESEED_DIR="/home/kluster/0-Montagem_de_Cluster/PXE"
NETBOOT_URL="https://deb.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/netboot.tar.gz"
echo "Criando diretório de boot em $BOOT_DIR..."
sudo mkdir -p "$BOOT_DIR"
cd "$BOOT_DIR"
echo "Baixando netboot.tar.gz..."
if [ ! -f "netboot.tar.gz" ]; then
sudo wget -q --show-progress "$NETBOOT_URL"
else
echo "netboot.tar.gz já existe, pulando download."
fi
echo "Extraindo netboot.tar.gz..."
if [ ! -d "$BOOT_DIR/debian-installer/amd64" ]; then
sudo tar -xzf netboot.tar.gz
sudo rm -f netboot.tar.gz
else
echo "Arquivos já extraídos, pulando extração."
fi
#echo "Copiando preseed.cfg para $BOOT_DIR..."
#if [ -f "$PRESEED_DIR/preseed.cfg" ]; then
# sudo cp "$PRESEED_DIR/preseed.cfg" "$BOOT_DIR"
#else
# echo "Arquivo preseed.cfg não encontrado em $PRESEED_DIR" >&2
# exit 1
#fi
echo "Criando PRESEED em $BOOT_DIR/preseed.cfg..."
sudo tee "$BOOT_DIR/preseed.cfg" > /dev/null <<'EOF'
#_preseed_V1
###Preseed para boot PXE sem Interface Grafica###
###Este é o preseed###
###Locale e linguagem###
d-i debian-installer/locale string pt_BR.UTF-8
d-i console-setup/ask_detect boolean false
### Configuracoes de teclado ###
d-i console-keymaps-at/keymap select br-abnt2
d-i keyboard-configuration/xkb-keymap select br
d-i keyboard-configuration/layout select br
d-i keyboard-configuration/model select abnt2
d-i keyboard-configuration/variant select abnt2
d-i keyboard-configuration/options string lv3:alt_switch,compose:rctrl
d-i keyboard-configuration/store_defaults_in_debconf_db boolean true
d-i time/zone string America/Sao_Paulo
### Hostname e rede ###
d-i netcfg/use_autoconfig boolean true
d-i netcfg/disable_dhcp_hostname boolean true
d-i netcfg/get_nameservers string 1.1.1.1 9.9.9.9
d-i netcfg/choose_interface select auto
### Repositorio Debian ###
d-i mirror/country string manual
d-i mirror/http/hostname string deb.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
### Usuario e senha ###
d-i passwd/root-password password cluster
d-i passwd/root-password-again password cluster
d-i passwd/user-fullname string Kluster User
d-i passwd/username string kluster
d-i passwd/user-password password cluster
d-i passwd/user-password-again password cluster
d-i passwd/user-default-groups string sudo
### Popularidade ###
popularity-contest popularity-contest/participate boolean false
### Pre-carrega os modulos necessarios ###
d-i anna-install string btrfs-modules xfs-modules
### Garante que os módulos btrfs e xfs estarao disponiveis antes do particionamento ###
d-i preseed/early_command string \
modprobe btrfs || true; \
modprobe xfs || true
### Configura o particionamento automatico ###
d-i partman-auto/method string regular
d-i partman-auto/choose_recipe select boot-root
d-i partman-auto/expert_recipe string \
boot-root :: \
40 50 512 ext4 \
$primary{ } $bootable{ } \
method{ format } format{ } \
use_filesystem{ } filesystem{ ext4 } \
mountpoint{ /boot } . \
4096 4096 4096 linux-swap \
$primary{ } \
method{ swap } format{ } . \
51200 51200 51200 btrfs \
$primary{ } \
method{ format } format{ } \
use_filesystem{ } filesystem{ btrfs } \
mountpoint{ / } . \
512 512 -1 xfs \
$primary{ } \
method{ format } format{ } \
use_filesystem{ } filesystem{ xfs } \
mountpoint{ /orangefs } .
### Confirma as acoes do particionador ###
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
### Pacotes ###
tasksel tasksel/first multiselect standard, ssh-server
d-i pkgsel/include string sudo vim curl wget net-tools aptitude libu2f-udev console-setup keyboard-configuration console-data
### GRUB ###
d-i grub-installer/bootdev string default
### Finalizacao ###
d-i finish-install/reboot_in_progress note
### Comandos pos-instalacao ###
### Substitua a chave ssh publica que deverá ser gerada no servidor e copiada do arquivo ###
### /home/kluster/.ssh/id_ed25519.pub para o primeiro echo abaixo entre aspas ###
d-i preseed/late_command string \
mkdir -p /target/root/.ssh; \
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFcx6e2Zcm4agOhhb0h2hgHKEAYPCsHnTyOsipaNySEu kluster@cservidor" > /target/root/.ssh/authorized_keys; \
chmod 700 /target/root/.ssh; \
chmod 600 /target/root/.ssh/authorized_keys; \
in-target bash -c 'echo "XKBMODEL=\"abnt2\"" > /etc/default/keyboard; \
echo "XKBLAYOUT=\"br\"" >> /etc/default/keyboard; \
echo "XKBVARIANT=\"abnt2\"" >> /etc/default/keyboard; \
echo "XKBOPTIONS=\"lv3:alt_switch,compose:rctrl\"" >> /etc/default/keyboard; \
echo "BACKSPACE=\"guess\"" >> /etc/default/keyboard'; \
in-target dpkg-reconfigure -f noninteractive keyboard-configuration; \
in-target setupcon --force; \
in-target update-initramfs -u; \
in-target bash -c 'set -e; \
apt-get clean || true; \
apt-get update || true; \
sed -i "s/^allow-hotplug/auto/" /etc/network/interfaces; \
update-grub || true; update-initramfs -u || true; \
mkdir -p /etc/sudoers.d; \
echo "kluster ALL=(ALL:ALL) ALL" > /etc/sudoers.d/klustoer; \
chmod 0440 /etc/sudoers.d/klustoer'
EOF
echo "Criando script iPXE em $BOOT_DIR/debian.ipxe..."
sudo tee "$BOOT_DIR/debian.ipxe" > /dev/null <<'EOF'
#!ipxe
dhcp
echo "Obtido IP via DHCP!"
kernel http://192.168.1.3/boot/debian-installer/amd64/linux auto=true priority=critical netcfg/get_hostname=no01 netcfg/get_domain=localdomain ---
initrd http://192.168.1.3/boot/debian-installer/amd64/initrd-custom.gz
boot
EOF
echo "Baixando ipxe.lkrn para $TFTP_DIR..."
if [ ! -f "$TFTP_DIR/ipxe.lkrn" ]; then
sudo wget -q --show-progress https://boot.ipxe.org/ipxe.lkrn -O "$TFTP_DIR/ipxe.lkrn"
else
echo "ipxe.lkrn já existe em $TFTP_DIR, pulando download."
fi
echo ""
echo "Tudo pronto!"
echo ""
#!/bin/bash
set -e
### Use: sudo ./embed-preseed.sh
# === CONFIGURAÇÕES ===
BOOT_DIR="/var/www/html/boot/debian-installer/amd64"
WORK_DIR="/tmp/initrd-work"
PRESEED_SOURCE="/var/www/html/boot/preseed.cfg"
OUTPUT_INITRD="$BOOT_DIR/initrd-custom.gz"
# === CHECAGENS INICIAIS ===
INITRD_ORIGINAL="$BOOT_DIR/initrd.gz"
if [ ! -f "$INITRD_ORIGINAL" ]; then
echo "Arquivo initrd.gz não encontrado em: $INITRD_ORIGINAL"
exit 1
fi
if [ ! -f "$PRESEED_SOURCE" ]; then
echo "Arquivo preseed.cfg não encontrado em: $PRESEED_SOURCE"
exit 1
fi
echo "Preparando diretório de trabalho..."
rm -rf "$WORK_DIR"
mkdir -p "$WORK_DIR"
cd "$WORK_DIR"
echo "Fazendo backup do initrd original..."
cp "$INITRD_ORIGINAL" "${INITRD_ORIGINAL}.bak"
echo "Extraindo initrd.gz..."
gzip -dc "$INITRD_ORIGINAL" | cpio -id --quiet
echo "Copiando preseed.cfg para raiz do initrd..."
cp "$PRESEED_SOURCE" ./preseed.cfg
echo "Reempacotando initrd com preseed embutido..."
##find . | cpio --quiet -o -H newc | gzip -9 > "$OUTPUT_INITRD"
find . | cpio --quiet -o -H newc --owner=0:0 | gzip -9 > "$OUTPUT_INITRD"
echo "Novo initrd com preseed embutido criado com sucesso!"
echo "Local: $OUTPUT_INITRD"
echo
Resolver problemas de Internet
Criar entrada (menuentry) ISO no Grub
Instalar e configurar o Nftables com exemplos básicos de configurações
Arch BSD - Instalação em VirtualBox
Configurando uma placa de rede no Linux
Instalação do CACTI no Debian Sarge
Instalação automatizada de servidores com kickstart
Customizar a Instalação do Linux Debian com Preseed
Atualizando o Passado: Linux no Lenovo G460 em 2025
aaPanel - Um Painel de Hospedagem Gratuito e Poderoso
Um modo leve de ouvir/ver áudio/vídeo da internet em máquinas pererecas
Resolver algumas mensagens de erro do SSH
Instalar módulo de segurança do Banco do Brasil Warsaw do tipo .run
Bora fazer um teste? mbti (10)
Instalação de Certificados .Cer no Ubuntu 24.04 (0)
O que você está ouvindo agora? [2] (193)
Procrastinação e autossabotagem são problemas muito comuns na sociedad... (8)