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: 369 ]
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
Redes de Computadores · IPtables · Endereços IPs - Explicações básicas
Manutenção de sistemas Linux Debian e derivados com apt-get, apt, aptitude e dpkg
Configuração do sistema, DHCP, compartilhamento e DNS no Debian Squeeze
Criar entrada (menuentry) ISO no Grub
Antivírus ClamAV com proteção em tempo real
Ubuntu 12.04 - Integração com Active Directory do Windows 2008
Instalando KDE 3.4 no Kurumin/Debian
Criação de usuário, grupo e permissão
Configurando DHCP com DNS (Bind9) na rede local - Debian Linux
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
O que você está ouvindo agora? [2] (193)
Procrastinação e autossabotagem são problemas muito comuns na sociedad... (8)