Skip to main content

Ambiente


Vamos montar o servidor PXE usando algumas medidas de segurança, o servidor vai ter 2 interfaces de rede, uma interface para cada rede, uma das conexões vai ser para acesso na internet e a outra vai ser para comunicação com o os servidores da rede pxe.


Com isso, vamos habilitar o daemon do DHCP para escutar apenas na interface da rede do pxe assim como o daemon do tftp, ambos escutarão apenas na rede pxe.



A primeira instalação vai mostrar o método mais simples para subir um servidor pxe manual (existem algumas aplicações que sobem o servidor pxe como o cobbler), logo mais vamos fazer uma customização do servidor pxe, usando menu em boot para escolher qual sistema subir via pxe.



Introdução


PXELINUX é um derivado do Syslinux, usado para inicializar o Linux fora de um servidor de rede, usando uma ROM de rede em conformidade com a especificação Intel PXE (Pre-Execution Environment). O arquivo do pxelinux em sí é um bootloader para Linux que usa o protocolo de inicialização de rede PXE.


Existem alguma formas de configurar o "serviço do pxe", como expecificar o arquivo de configuração baseado no MAC do servidor cliente a nível de camada 1, apesar de nao ser muito complicado, usar o arquivo padrão para isso é muito mais fácil e prático, permitindo uma configuração que todos entendam e consigam dar manutenção rapidamente.


Para que o servidor pxe funcione, precisamos que algumas aplicações funcionem em conjunto; para que o nosso servidor pxe possa funcionar. Essas aplicações são (obrigatóriamente): DHCP, TFTP, NFS ou HTTP.


O que vai mudar é o método de configuração dependendo da aplicação escolhida, por exemplo, se usado o DHCP do ISC, o método de configração do DHCP vai ser diferente se usado o DHCP do DNSMASQ, a configuração do TFTPD é relativamente diferente do ATFTP e do TFTPD-HPA, e assim por diante, nos exemplos a seguir vamos usar o tftpd-hpa, isc-dhcp-server e NFS, não vou usar o pxe via http por uma questão de escolha, mas isso cabe ao gosto do freguês, assim como qual serviço de tftp usar.



Instalar o servidor PXE - Pre-Execution Environment


Vamos começar instalando os pacotes necessários para o funcionamento do pxelinux:

# Instalar as aplicações para o pxe server:
sudo apt install isc-dhcp-server nfs-kernel-server tftpd-hpa pxelinux -y

# isc-dhcp-server = Servidor DHCP;
# nfs-kernel-server = Servidor NFS;
# tftpd-hpa = Servidor TFTP-HPA;
# pxelinux = Pacote que contém os arquivos do PXE.

# Apenas para testar o TFTP, podemos instalar o pacote tftp-hpa.


Configurar o TFTP


Agora vamos configurar o daemon do tftpd para que ele possa fornecer os arquivos durante o boot.

# Edite o arquivo de configuração do tftpd:
sudo vim /etc/default/tftpd-hpa

###### Deixe como abaixo, mudando o necessário ######
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.100.2:69"
TFTP_OPTIONS="--secure"

# Você logo pode ver a diferença entre o meu arquivo e o seu,
# no meu foi modificado a pasta raiz do tftp e ao invés de deixar ele
# escutando em todas as interfaces, eu pedi para que ele escute apenas
# na interface 'enp0s8' que tem o IP '192.168.100.2'.

# Veja abaixo o ip na interface:
sudo ip addr show enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:54:a2:67 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 brd 192.168.100.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe54:a267/64 scope link
valid_lft forever preferred_lft forever

# Agora vamos criar a pasta do tftp:
sudo mkdir -p /srv/tftp

# Agora reinicie o serviço do tftpd e verifique o status:
sudo systemctl restart tftpd-hpa.service
sudo systemctl status tftpd-hpa.service


Configure o dhcp server


Agora vamos configurar o servidor DHCP, para uma configuração básica do dhcp, podemos usar o exemplo que está no arquivo /usr/share/doc/pxelinux/README.txt.gz caso você tenha o pacote pxelinux instalado, nosso exemplo foi baseado nesse arquivo, mudando apenas algumas coisas.

default-lease-time 600;
max-lease-time 7200;

allow booting;
allow bootp;

authoritative;
ignore client-updates;

log-facility local7;

subnet 192.168.100.0 netmask 255.255.255.0 {
range dynamic-bootp 192.168.100.20 192.168.100.253;
option broadcast-address 192.168.100.255;
option routers 192.168.100.2;
option domain-name-servers 8.8.8.8;
option subnet-mask 255.255.255.0;
default-lease-time 21600;
max-lease-time 43200;
}


group {
next-server 192.168.100.2;

host teste {
# Coloque o MAC da máquina cliente aqui em baixo!
hardware ethernet 52:54:00:20:35:ac;
fixed-address 192.168.100.177;
# Graças ao CHROOT usado pelo tftp-hpa, não precisamos colocar o caminho
# completo para o arquivo PXELINUX, pois o mesmo está no diretório raiz
# do tftp, caso contrário precisa colocar.
filename "pxe5254";

}
}

## Agora vamos configurar a interface do dhcp que ele vai ficar escutando
# Edite o arquivo abaixo:
sudo vim /etc/default/isc-dhcp-server

# Em INTERFACES, coloque o nome da interface que o daemon vai escutar, no meu caso
# a interface é 'enp0s8', segue meu exemplo:
INTERFACES="enp0s8"


# Agora reinicie o DHCP e veja o status do serviço:
sudo systemctl restart isc-dhcp-server
sudo systemctl status isc-dhcp-server


Baixando a ISO


Agora vamos baixar a imagem do sistema que será instalada pela rede e vamos criar uma pasta onde vamos deixar os arquivos da ISO para que possam ser disponibilizados via NFS:

# Crie a pasta onde vamos colocar a ISO (descompactada):
sudo mkdir -p /distros/ubuntu2004

# Baixe a ISO, no nosso caso será uma uma imagem do Ubuntu 20.04
wget https://cdimage.ubuntu.com/ubuntu-server/focal/daily-live/current/focal-live-server-amd64.iso

# Agora vamos montar a imagem em /mnt:
sudo mount focal-live-server-amd64.iso /mnt/

# Agora copie tudo da pasta /mnt para a pasta /distros/ubuntu2004
sudo find /mnt -maxdepth 1 -not -wholename "/mnt" -exec cp -Rv {} /distros/ubuntu2004/ \;


Configurar o NFS


Agora vamos compartilhar a pasta onde está nossa imagem do Ubuntu para que ela seja disponibilizada durante o boot:

# Edite o arquivo:
sudo vim /etc/exports

# Deixe como abaixo:
/distros/ubuntu2004 *(rw,sync,no_subtree_check)


# Exporte a configuração do NFS
sudo exportfs -a


Configuração do PXE


Toda a configuração do pxe (arquivos e binários) é colocada dentro do tftp, para que assim o tftp possa fornecer os arquivos como pxelinux.0, initrd, vmlinuz entre outros.

## Crie a pasta para colocarmos o pxelinux.0:
sudo mkdir /srv/tftp/pxe/

## Vamos pegar o pxelinux.0:
sudo cp -v /usr/lib/PXELINUX/pxelinux.0 /srv/tftp/pxe/

## Crie a pasta onde colocaremos o arquivo de configuração padrão:
sudo mkdir /srv/tftp/pxelinux.cfg

## Crie o arquivo de configuração padrão:
sudo touch /srv/tftp/pxelinux.cfg/default

## Edite o arquivo:
sudo vim /srv/tftp/pxelinux.cfg/default

#### Coloque a informação abaixo: ####
default install
prompt 0
timeout 1
label install
menu label Install
kernel vmlinuz
append initrd=initrd ip=dhcp nfsroot=192.168.100.2:/distros/ubuntu2004 netboot=nfs ---


## Vamos colar a imagem do kernel e o initrd:
sudo cp /mnt/casper/{vmlinuz,initrd} /srv/tftp/

# Agora vamos copiar para o tftp o arquivo de bios simples:
sudo cp -v /usr/lib/syslinux/modules/bios/ldlinux.c32 /srv/tftp/

## Crie o link para o pxelinux.0 na raiz do tftp:
sudo ln -sf pxe/pxelinux.0 /srv/tftp/pxe5254


Configuração do PXE com UEFI


Vamos começar instalando os pacotes necessários para o funcionamento do pxelinux:

# Instalar as aplicações para o pxe server:
sudo apt install isc-dhcp-server nfs-kernel-server tftpd-hpa pxelinux -y

# isc-dhcp-server = Servidor DHCP;
# nfs-kernel-server = Servidor NFS;
# tftpd-hpa = Servidor TFTP-HPA;
# pxelinux = Pacote que contém os arquivos do PXE.

# Apenas para testar o TFTP, podemos instalar o pacote tftp-hpa.


Configurar o TFTP


Agora vamos configurar o daemon do tftpd para que ele possa fornecer os arquivos durante o boot.

# Edite o arquivo de configuração do tftpd:
sudo vim /etc/default/tftpd-hpa

###### Deixe como abaixo, mudando o necessário ######
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.100.2:69"
TFTP_OPTIONS="--secure"

# Você logo pode ver a diferença entre o meu arquivo e o seu,
# no meu foi modificado a pasta raiz do tftp e ao invés de deixar ele
# escutando em todas as interfaces, eu pedi para que ele escute apenas
# na interface 'enp0s8' que tem o IP '192.168.100.2'.

# Veja abaixo o ip na interface:
sudo ip addr show enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:54:a2:67 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 brd 192.168.100.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe54:a267/64 scope link
valid_lft forever preferred_lft forever

# Agora vamos criar a pasta do tftp:
sudo mkdir -p /srv/tftp

# Agora reinicie o serviço do tftpd e verifique o status:
sudo systemctl restart tftpd-hpa.service
sudo systemctl status tftpd-hpa.service


Configure o dhcp server


Agora vamos configurar o servidor DHCP, para uma configuração básica do dhcp, podemos usar o exemplo que está no arquivo /usr/share/doc/pxelinux/README.txt.gz caso você tenha o pacote pxelinux instalado, nosso exemplo foi baseado nesse arquivo, mudando apenas algumas coisas.

default-lease-time 600;
max-lease-time 7200;

allow booting;
allow bootp;

authoritative;
ignore client-updates;

log-facility local7;

subnet 192.168.100.0 netmask 255.255.255.0 {
range dynamic-bootp 192.168.100.20 192.168.100.253;
option broadcast-address 192.168.100.255;
option routers 192.168.100.2;
option domain-name-servers 8.8.8.8;
option subnet-mask 255.255.255.0;
default-lease-time 21600;
max-lease-time 43200;
}


group {
next-server 192.168.100.2;

host teste {
# Coloque o MAC da máquina cliente aqui em baixo!
hardware ethernet 52:54:00:20:35:ac;
fixed-address 192.168.100.177;

if option pxe-system-type = 00:00 {
filename "pxelinux.0-nonexist";
} elsif option pxe-system-type = 00:09 {
filename "bootx64.efi";
} elsif option pxe-system-type = 00:07 {
filename "bootx64.efi";
}

}
}

## Agora vamos configurar a interface do dhcp que ele vai ficar escutando
# Edite o arquivo abaixo:
sudo vim /etc/default/isc-dhcp-server

# Em INTERFACES, coloque o nome da interface que o daemon vai escutar, no meu caso
# a interface é 'enp0s8', segue meu exemplo:
INTERFACES="enp0s8"


# Agora reinicie o DHCP e veja o status do serviço:
sudo systemctl restart isc-dhcp-server
sudo systemctl status isc-dhcp-server


Baixando a ISO


Agora vamos baixar a imagem do sistema que será instalada pela rede e vamos criar uma pasta onde vamos deixar os arquivos da ISO para que possam ser disponibilizados via NFS:

# Crie a pasta onde vamos colocar a ISO (descompactada):
sudo mkdir -p /distros/ubuntu2004

# Baixe a ISO, no nosso caso será uma uma imagem do Ubuntu 20.04
wget https://cdimage.ubuntu.com/ubuntu-server/focal/daily-live/current/focal-live-server-amd64.iso

# Agora vamos montar a imagem em /mnt:
sudo mount focal-live-server-amd64.iso /mnt/

# Agora copie tudo da pasta /mnt para a pasta /distros/ubuntu2004
sudo find /mnt -maxdepth 1 -not -wholename "/mnt" -exec cp -Rv {} /distros/ubuntu2004/ \;


Configurar o NFS


Agora vamos compartilhar a pasta onde está nossa imagem do Ubuntu para que ela seja disponibilizada durante o boot:

# Edite o arquivo:
sudo vim /etc/exports

# Deixe como abaixo:
/distros/ubuntu2004 *(rw,sync,no_subtree_check)


# Exporte a configuração do NFS
sudo exportfs -a


Configuração do PXE-UEFI


Vou demonstrar apenas os passos necessários para poder inicializar máquinas UEFI na rede usando um menu do Grub.

## Vamos colar a imagem do kernel e o initrd:
sudo cp /mnt/casper/{vmlinuz,initrd} /srv/tftp/

# Faça download dos pacotes necessários:
apt download shim-signed grub-efi-amd64-signed grub-common -y

# Descompacte cada um deles:
sudo dpkg-deb -xv shim-signed_1.40.7+15.4-0ubuntu9_amd64.deb shim-signed
sudo dpkg-deb -xv grub-efi-amd64-signed_1.167.2+2.04-1ubuntu44.2_amd64.deb grub-efi
sudo dpkg-deb -xv grub-common_2.04-1ubuntu26.13_amd64.deb grub-common

# Copie os arquivos necessários:
sudo cp shim-signed/usr/lib/shim/shimx64.efi.signed /srv/tftp/bootx64.efi
sudo cp grub-efi/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /srv/tftp/grubx64.efi
sudo cp grub-common/usr/share/grub/unicode.pf2 /srv/tftp/

# Aplique a permissão:
sudo chmod 644 /srv/tftp/{bootx64.efi,grubx64.efi,unicode.pf2}

# Reinicie o servidor TFTPD e DHCPD:
sudo systemctl restart isc-dhcp-server
sudo systemctl restart tftpd-hpa.service

# Edite o menu do grub:
mkdir /srv/tftp/grub
vim /srv/tftp/grub/grub.cfg

#########################################
########### Deixe como abaixo ###########
#########################################
set default="0"
set timeout="0"

if loadfont unicode ; then
set gfxmode=auto
set locale_dir=$prefix/locale
set lang=en_US
fi
terminal_output gfxterm

set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
if background_color 44,0,30; then
clear
fi

function gfxmode {
set gfxpayload="${1}"
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=7
else
set vt_handoff=
fi
}

set linux_gfx_mode=keep

export linux_gfx_mode

menuentry 'Install Ubuntu 20.04' {
gfxmode $linux_gfx_mode
linux vmlinuz ip=dhcp nfsroot=IP:FOLDER(NFS) netboot=nfs ro autoinstall ds=nocloud\;s=/cdrom/nocloud/ ---
initrd initrd
}


Configuração do PXE com UEFI


Vamos fazer a instalação do PXE com UEFI com duas mídias de instalação. Comece instalando os pacotes necessários para o funcionamento do pxelinux:

# Instalar as aplicações para o pxe server:
sudo apt install isc-dhcp-server nfs-kernel-server tftpd-hpa pxelinux -y

# isc-dhcp-server = Servidor DHCP;
# nfs-kernel-server = Servidor NFS;
# tftpd-hpa = Servidor TFTP-HPA;
# pxelinux = Pacote que contém os arquivos do PXE.

# Apenas para testar o TFTP, podemos instalar o pacote tftp-hpa.


Configurar o TFTP


Agora vamos configurar o daemon do tftpd para que ele possa fornecer os arquivos durante o boot.

# Edite o arquivo de configuração do tftpd:
sudo vim /etc/default/tftpd-hpa

###### Deixe como abaixo, mudando o necessário ######
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.100.2:69"
TFTP_OPTIONS="--secure"

# Você logo pode ver a diferença entre o meu arquivo e o seu,
# no meu foi modificado a pasta raiz do tftp e ao invés de deixar ele
# escutando em todas as interfaces, eu pedi para que ele escute apenas
# na interface 'enp0s8' que tem o IP '192.168.100.2'.

# Veja abaixo o ip na interface:
sudo ip addr show enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:54:a2:67 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 brd 192.168.100.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe54:a267/64 scope link
valid_lft forever preferred_lft forever

# Agora vamos criar a pasta do tftp:
sudo mkdir -p /srv/tftp

# Agora reinicie o serviço do tftpd e verifique o status:
sudo systemctl restart tftpd-hpa.service
sudo systemctl status tftpd-hpa.service


Configure o dhcp server


Agora vamos configurar o servidor DHCP, para uma configuração básica do dhcp, podemos usar o exemplo que está no arquivo /usr/share/doc/pxelinux/README.txt.gz caso você tenha o pacote pxelinux instalado, nosso exemplo foi baseado nesse arquivo, mudando apenas algumas coisas.

default-lease-time 600;
max-lease-time 7200;

allow booting;
allow bootp;

authoritative;
ignore client-updates;

log-facility local7;

subnet 192.168.100.0 netmask 255.255.255.0 {
range dynamic-bootp 192.168.100.20 192.168.100.253;
option broadcast-address 192.168.100.255;
option routers 192.168.100.1;
option domain-name-servers 8.8.8.8;
option subnet-mask 255.255.255.0;
default-lease-time 21600;
max-lease-time 43200;
}


group {
next-server 192.168.100.2;

host teste {
hardware ethernet 52:54:00:f3:f1:46;
fixed-address 192.168.100.177;
filename "bootx64.efi";
}
}

## Agora vamos configurar a interface do dhcp que ele vai ficar escutando
# Edite o arquivo abaixo:
sudo vim /etc/default/isc-dhcp-server

# Em INTERFACES, coloque o nome da interface que o daemon vai escutar, no meu caso
# a interface é 'enp0s8', segue meu exemplo:
INTERFACES="eth1"


# Agora reinicie o DHCP e veja o status do serviço:
sudo systemctl restart isc-dhcp-server
sudo systemctl status isc-dhcp-server


Baixando a ISO


Agora vamos baixar a imagem do sistema que será instalada pela rede e vamos criar uma pasta onde vamos deixar os arquivos da ISO para que possam ser disponibilizados via NFS:

## Baixe as imagens:
wget https://cdimage.ubuntu.com/ubuntu-server/jammy/daily-live/current/jammy-live-server-amd64.iso
wget https://cdimage.ubuntu.com/ubuntu-server/focal/daily-live/current/focal-live-server-amd64.iso

# Crie os diretórios onde vamos colocar as ISOs (descompactada):
sudo mkdir -p /srv/pxe_nfs/{ubuntu2004,ubuntu2204}

# Agora vamos montar a imagem em /mnt:
sudo mount focal-live-server-amd64.iso /mnt/

# Agora copie tudo da pasta /mnt para a pasta /distros/ubuntu2004
sudo find /mnt -maxdepth 1 -not -wholename "/mnt" -exec cp -Rv {} /srv/pxe_nfs/ubuntu2004/ \;

# Crie a pasta onde vamos manter o Kernel e o initrd para cada sistema:
sudo mkdir -p /srv/tftp/kernels/{ubuntu2004,ubuntu2204}

## Copie a imagem do kernel e o initrd:
sudo cp -v /mnt/casper/{vmlinuz,initrd} /srv/tftp/kernels/ubuntu2004/

## Desmonte o ISO:
sudo umount /mnt/

## Agora vamos montar a outra imagem em /mnt:
sudo mount jammy-live-server-amd64.iso /mnt/

## Agora copie tudo da pasta /mnt para a pasta /distros/ubuntu22004
sudo find /mnt -maxdepth 1 -not -wholename "/mnt" -exec cp -Rv {} /srv/pxe_nfs/ubuntu2204/ \;

## Copie a imagem do kernel e o initrd:
sudo cp -v /mnt/casper/{vmlinuz,initrd} /srv/tftp/kernels/ubuntu2204/

## Desmonte o ISO:
sudo umount /mnt/


Configurar o NFS


Agora vamos compartilhar a pasta onde está nossa imagem do Ubuntu para que ela seja disponibilizada durante o boot:

# Edite o arquivo:
sudo vim /etc/exports

# Deixe como abaixo:
/srv/pxe_nfs/ *(rw,sync,no_subtree_check)


# Exporte a configuração do NFS
sudo exportfs -a


Configuração do PXE-UEFI


Vou demonstrar apenas os passos necessários para poder inicializar máquinas UEFI na rede usando um menu do Grub.

## Faça download dos pacotes necessários:
apt download shim-signed grub-efi-amd64-signed grub-common -y

## Descompacte cada um deles:
sudo dpkg-deb -xv shim-signed_1.40.7+15.4-0ubuntu9_amd64.deb shim-signed
sudo dpkg-deb -xv grub-efi-amd64-signed_1.187.3~20.04.1+2.06-2ubuntu14.1_amd64.deb grub-efi
sudo dpkg-deb -xv grub-common_2.04-1ubuntu26.16_amd64.deb grub-common

## Copie os arquivos necessários:
sudo cp shim-signed/usr/lib/shim/shimx64.efi.signed /srv/tftp/bootx64.efi
sudo cp grub-efi/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed /srv/tftp/grubx64.efi
sudo cp grub-common/usr/share/grub/unicode.pf2 /srv/tftp/

# Aplique a permissão:
sudo chmod 644 /srv/tftp/{bootx64.efi,grubx64.efi,unicode.pf2}

# Reinicie o servidor TFTPD e DHCPD:
sudo systemctl restart isc-dhcp-server
sudo systemctl restart tftpd-hpa.service

# Edite o menu do grub:
mkdir /srv/tftp/grub
vim /srv/tftp/grub/grub.cfg

#########################################
########### Deixe como abaixo ###########
#########################################
# set default="0"
# set timeout="0"

if loadfont unicode ; then
set gfxmode=auto
set locale_dir=$prefix/locale
set lang=en_US
fi
terminal_output gfxterm

set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
if background_color 44,0,30; then
clear
fi

function gfxmode {
set gfxpayload="${1}"
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=7
else
set vt_handoff=
fi
}

set linux_gfx_mode=keep

export linux_gfx_mode

menuentry 'Install Ubuntu 20.04' {
gfxmode $linux_gfx_mode
linux kernels/ubuntu2004/vmlinuz ip=dhcp boot=casper netboot=nfs nfsroot=${IP}:${NFS_FOLDER}
initrd kernels/ubuntu2004/initrd

}

menuentry 'Install Ubuntu 22.04' {
gfxmode $linux_gfx_mode
linux kernels/ubuntu2204/vmlinuz ip=dhcp boot=casper netboot=nfs nfsroot=${IP}:${NFS_FOLDER}
initrd kernels/ubuntu2204/initrd
}

}

Se quiser um grub mais limpo pode usar a opção abaixo:

#set default="0"
#set timeout="20"

set timeout=30

loadfont unicode

set menu_color_normal=white/black
set menu_color_highlight=black/light-gray

menuentry 'Install Ubuntu 20.04' {
linux kernels/ubuntu2004/vmlinuz ip=dhcp boot=casper netboot=nfs nfsroot=192.168.100.2:/srv/pxe_nfs/ubuntu2004/ ---
initrd kernels/ubuntu2004/initrd

}

menuentry 'Install Ubuntu 22.04' {
set gfxpayload=keep
linux kernels/ubuntu2204/vmlinuz ip=dhcp boot=casper netboot=nfs nfsroot=192.168.100.2:/srv/pxe_nfs/ubuntu2204/ ---
initrd kernels/ubuntu2204/initrd
}

}


Instalação personalizada


Vamos instalar agora o pxe num modelo onde podemos configurar varios sistemas para boot, e quem escolhe qual sistema iniciar é quem está inicializando o sistema. Para evitar problemas vamos configurar do zero todos os passos, apenas alterando o que for necessário.



Instalar o servidor PXE - Pre-Execution Environment


Vamos começar instalando os pacotes necessários para o funcionamento do pxelinux:

# Instalar as aplicações para o pxe server:
sudo apt install isc-dhcp-server nfs-kernel-server tftpd-hpa pxelinux -y

# isc-dhcp-server = Servidor DHCP;
# nfs-kernel-server = Servidor NFS;
# tftpd-hpa = Servidor TFTP-HPA;
# pxelinux = Pacote que contém os arquivos do PXE.

# Apenas para testar o TFTP, podemos instalar o pacote tftp-hpa.


Configurar o TFTP


Agora vamos configurar o daemon do tftpd para que ele possa fornecer os arquivos durante o boot.

# Edite o arquivo de configuração do tftpd:
sudo vim /etc/default/tftpd-hpa

###### Deixe como abaixo, mudando o necessário ######
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="192.168.100.2:69"
TFTP_OPTIONS="--secure"

# Você logo pode ver a diferença entre o meu arquivo e o seu,
# no meu foi modificado a pasta raiz do tftp e ao invés de deixar ele
# escutando em todas as interfaces, eu pedi para que ele escute apenas
# na interface 'enp0s8' que tem o IP '192.168.100.2'.

# Veja abaixo o ip na interface:
sudo ip addr show enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:54:a2:67 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 brd 192.168.100.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe54:a267/64 scope link
valid_lft forever preferred_lft forever

# Agora vamos criar a pasta do tftp:
sudo mkdir -p /srv/tftp

# Agora reinicie o serviço do tftpd e verifique o status:
sudo systemctl restart tftpd-hpa.service
sudo systemctl status tftpd-hpa.service


Configure o dhcp server


Agora vamos configurar o servidor DHCP, para uma configuração básica do dhcp, podemos usar o exemplo que está no arquivo /usr/share/doc/pxelinux/README.txt.gz caso você tenha o pacote pxelinux instalado, nosso exemplo foi baseado nesse arquivo, mudando apenas algumas coisas.

default-lease-time 600;
max-lease-time 7200;

allow booting;
allow bootp;

authoritative;
ignore client-updates;

log-facility local7;

subnet 192.168.100.0 netmask 255.255.255.0 {
range dynamic-bootp 192.168.100.20 192.168.100.253;
option broadcast-address 192.168.100.255;
option routers 192.168.100.2;
option domain-name-servers 8.8.8.8;
option subnet-mask 255.255.255.0;
default-lease-time 21600;
max-lease-time 43200;
}


group {
next-server 192.168.100.2;

host teste {
# Coloque o MAC da máquina cliente aqui em baixo!
hardware ethernet 52:54:00:20:35:ac;
fixed-address 192.168.100.177;
# Graças ao CHROOT usado pelo tftp-hpa, não precisamos colocar o caminho
# completo para o arquivo PXELINUX, pois o mesmo está no diretório raiz
# do tftp, caso contrário precisa colocar.
filename "pxe5254";

}
}

## Agora vamos configurar a interface do dhcp que ele vai ficar escutando
# Edite o arquivo abaixo:
sudo vim /etc/default/isc-dhcp-server

# Em INTERFACES, coloque o nome da interface que o daemon vai escutar, no meu caso
# a interface é 'enp0s8', segue meu exemplo:
INTERFACES="enp0s8"


# Agora reinicie o DHCP e veja o status do serviço:
sudo systemctl restart isc-dhcp-server
sudo systemctl status isc-dhcp-server


Baixando a ISO


Agora vamos baixar a imagem do sistema que será instalada pela rede e vamos criar uma pasta onde vamos deixar os arquivos da ISO para que possam ser disponibilizados via NFS:

# Crie a pasta onde vamos colocar a ISO (descompactada):
sudo mkdir -p /distros/ubuntu2004

# Baixe a ISO, no nosso caso será uma uma imagem do Ubuntu 20.04
wget https://cdimage.ubuntu.com/ubuntu-server/focal/daily-live/current/focal-live-server-amd64.iso

# Agora vamos montar a imagem em /mnt:
sudo mount focal-live-server-amd64.iso /mnt/

# Agora copie tudo da pasta /mnt para a pasta /distros/ubuntu2004
sudo find /mnt -maxdepth 1 -not -wholename "/mnt" -exec cp -Rv {} /distros/ubuntu2004/ \;

# Crie a pasta onde vamos colocar a ISO (descompactada):
sudo mkdir /srv/tftp/ubuntu2004

## Vamos colar a imagem do kernel e o initrd:
sudo cp -v /mnt/casper/{vmlinuz,initrd} /srv/tftp/ubuntu2004/

## Desmonte o ISO:
sudo umount /mnt/


Agora vamos fazer isso com outra imagem:

# Crie a pasta onde vamos colocar a ISO (descompactada):
sudo mkdir -p /distros/ubuntu21_desktop

# Baixe a ISO, no nosso caso será uma uma imagem do Ubuntu 20.04
wget https://cdimage.ubuntu.com/ubuntu/daily-live/current/hirsute-desktop-amd64.iso

# Agora vamos montar a imagem em /mnt:
sudo mount hirsute-desktop-amd64.iso /mnt/

# Agora copie tudo da pasta /mnt para a pasta /distros/ubuntu2004
sudo find /mnt -maxdepth 1 -not -wholename "/mnt" -exec cp -Rv {} /distros/ubuntu21_desktop/ \;

# Crie a pasta onde vamos colocar a ISO (descompactada):
sudo mkdir /srv/tftp/ubuntu21_desktop

## Vamos colar a imagem do kernel e o initrd:
sudo cp -v /mnt/casper/{vmlinuz,initrd} /srv/tftp/ubuntu21_desktop/


Configurar o NFS


Agora vamos compartilhar a pasta onde está nossa imagem do Ubuntu para que ela seja disponibilizada durante o boot:

# Edite o arquivo:
sudo vim /etc/exports

# Deixe como abaixo:
/distros/ *(rw,sync,no_subtree_check)


# Exporte a configuração do NFS
sudo exportfs -a


Configuração do PXE


Toda a configuração do pxe (arquivos e binários) é colocada dentro do tftp, para que assim o tftp possa fornecer os arquivos como pxelinux.0, initrd, vmlinuz entre outros.

## Crie a pasta para colocarmos o pxelinux.0:
sudo mkdir /srv/tftp/pxe/

## Vamos pegar o pxelinux.0:
sudo cp -v /usr/lib/PXELINUX/pxelinux.0 /srv/tftp/pxe/

## Crie a pasta onde colocaremos o arquivo de configuração padrão:
sudo mkdir /srv/tftp/pxelinux.cfg

## Crie o arquivo de configuração padrão:
sudo touch /srv/tftp/pxelinux.cfg/default

## Edite o arquivo:
sudo vim /srv/tftp/pxelinux.cfg/default

#### Coloque a informação abaixo: ####
default vesamenu.c32

label install1
menu label ^Install Ubuntu 20.04 LTS Server to Desktop
menu default
kernel ubuntu2004/vmlinuz
append initrd=ubuntu2004/initrd ip=dhcp boot=casper netboot=nfs nfsroot=192.168.100.2:/distros/ubuntu2004/ ---

label install2
menu label ^Install Ubuntu 21.10 LTS Desktop
menu default
kernel ubuntu21_desktop/vmlinuz
append initrd=ubuntu21_desktop/initrd ip=dhcp boot=casper netboot=nfs nfsroot=1192.168.100.2:/distros/ubuntu21_desktop/ ---

# Agora vamos copiar para o tftp os arquivos de bios e menus necessários
# para criar o "grub" do pxe:
sudo cp -v /usr/lib/syslinux/modules/bios/{ldlinux.c32,libcom32.c32,libutil.c32,vesamenu.c32} /srv/tftp/

## Crie o link para o pxelinux.0 na raiz do tftp:
sudo ln -sf pxe/pxelinux.0 /srv/tftp/pxe5254

Abaixo segue uma foto de como é o "grub" do pxe que acabamos de configurar usando o módulo vesamenu.c32.

IPcbT4r067EhNA



Maneira alternativa


Existe outra forma de iniciar o PXE com UEFI, mas essa maneira o Auto Install do Ubuntu não funciona, mas você consegue fazer uma instalação manual, só precisa substituir os arquivos pxelinux.0 e ldlinux.c32 por ldlinux.e64 e syslinux.efi, veja o processo abaixo:

apt download syslinux-efi syslinux-common -y

sudo dpkg-deb -xv syslinux-efi_3%3a6.04~git20190206.bf6db5b4+dfsg1-2_all.deb syslinux-efi
sudo dpkg-deb -xv syslinux-common_3%3a6.04~git20190206.bf6db5b4+dfsg1-2_all.deb syslinux-common

sudo cp -r syslinux-efi/usr/lib/SYSLINUX.EFI/{efi32,efi64} /srv/tftp/
sudo cp syslinux-common/usr/lib/syslinux/modules/efi64/ldlinux.e64 /srv/tftp/

sudo chmod 644 /srv/tftp/ldlinux.e64
sudo chmod 644 /srv/tftp/{efi64,efi32}/syslinux.efi
sudo chmod 655 /srv/tftp/{efi64,efi32}

sudo systemctl restart tftpd-hpa.service isc-dhcp-server
sudo systemctl status tftpd-hpa.service isc-dhcp-server