카테고리 없음

[Network] PXE 부팅 개념과 서버 구축하기

devyong 2026. 10. 28. 20:47

여러 대의 PC에 OS를 설치해야 할 때 USB를 하나씩 꽂아가며 설치하는 건 꽤 번거로운 일입니다. 이럴 때 네트워크로 부팅해서 설치할 수 있게 해주는 게 PXE입니다. 이 글에서는 PXE가 어떤 흐름으로 동작하는지 정리하고, Ubuntu에서 간단하게 PXE 서버를 구축하는 방법까지 공유하고자 합니다.

PXE란?

PXE(Preboot eXecution Environment)는 로컬 디스크 없이 네트워크에서 부팅 파일을 받아 실행하는 방식입니다. 대부분의 유선 랜카드에는 PXE 기능이 내장되어 있어서, BIOS/UEFI 부팅 순서에서 Network Boot를 선택하면 바로 사용할 수 있습니다.

새로운 프로토콜이 따로 있는 건 아니고, 기존의 DHCP와 TFTP를 조합해서 동작합니다.

  • DHCP 서버 : IP 할당 + 어떤 서버에서 어떤 파일을 받을지 알려줌
  • TFTP 서버 : 부팅 파일(NBP) 전송
  • NBP : 처음 실행되는 부팅 프로그램 (pxelinux.0, grubx64.efi, ipxe.efi 등)
  • HTTP 서버 (선택) : 커널, initrd, ISO처럼 큰 파일 전송

PXE 부팅 흐름

  1. 클라이언트가 DHCP 요청을 보냅니다. 이때 PXE 요청이라는 걸 알리기 위해 Option 60(PXEClient)과 Option 93(펌웨어 종류)을 같이 보냅니다.
  2. DHCP 서버는 IP와 함께 next-server(TFTP 서버 주소), filename(부팅 파일 이름)을 응답합니다.
  3. 클라이언트는 TFTP로 부팅 파일(NBP)을 받아서 실행합니다.
  4. NBP가 설정 파일을 읽고 커널(vmlinuz)과 initrd를 받아 부팅합니다.

여기서 Option 93 값이 중요한데, 이 값으로 클라이언트가 BIOS인지 UEFI인지 구분해서 서로 다른 부팅 파일을 내려줘야 합니다.

  • 0 : BIOS (Legacy) → undionly.kpxe, pxelinux.0
  • 7, 9 : x64 UEFI → ipxe.efi, grubx64.efi

BIOS 머신에 efi 파일을 주거나 반대로 주면 부팅이 바로 실패합니다.

iPXE를 쓰는 이유

TFTP는 블록 단위로 하나씩 ACK를 기다리면서 전송하기 때문에 속도가 매우 느립니다. 수백 MB짜리 ISO를 TFTP로 받는 건 현실적이지 않습니다.

그래서 보통 iPXE를 같이 사용합니다. iPXE는 HTTP 전송과 스크립트를 지원하는 오픈소스 부트 펌웨어인데, 랜카드의 PXE로 iPXE만 먼저 받고(체인로딩) 나머지 큰 파일은 HTTP로 받는 방식입니다.

랜카드 PXE → (TFTP) iPXE → (HTTP) boot.ipxe 스크립트 → (HTTP) 커널/initrd

다만 주의할 점이 있습니다. iPXE도 실행되면 다시 DHCP 요청을 보내는데, 서버가 또 iPXE 파일을 주면 무한 루프에 빠지게 됩니다. 그래서 DHCP 서버에서 iPXE가 보낸 요청인지(User Class = iPXE) 구분해서, iPXE에게는 스크립트 URL을 줘야 합니다.

PXE 서버 구축하기

  • 서버 OS : Ubuntu 24.04
  • 서버 IP : 192.168.100.1 (인터페이스 eth1)
  • 부팅 대상 : Ubuntu 24.04 Live Server
  • 사용 패키지 : dnsmasq (DHCP + TFTP), ipxe, nginx (HTTP)

DHCP 서버를 띄우기 때문에 회사망이나 공유기 망에서 그대로 실습하면 다른 기기에 영향을 줄 수 있습니다. 꼭 VM의 내부 네트워크나 별도 스위치처럼 분리된 네트워크에서 진행하는 것을 추천드립니다.

1. 패키지 설치

sudo apt update
sudo apt install -y dnsmasq ipxe nginx

sudo mkdir -p /srv/tftp
sudo cp /usr/lib/ipxe/undionly.kpxe /srv/tftp/
sudo cp /usr/lib/ipxe/ipxe.efi /srv/tftp/

ipxe 패키지를 설치하면 /usr/lib/ipxe/ 에 BIOS용(undionly.kpxe), UEFI용(ipxe.efi) 파일이 생기는데, 이걸 TFTP 루트로 복사해줍니다.

2. dnsmasq 설정

port=0
interface=eth1
bind-interfaces

dhcp-range=192.168.100.100,192.168.100.200,255.255.255.0,12h

# BIOS / UEFI 구분
dhcp-match=set:bios,option:client-arch,0
dhcp-match=set:efi64,option:client-arch,7
dhcp-match=set:efi64,option:client-arch,9

# iPXE에서 온 요청인지 구분
dhcp-userclass=set:ipxe,iPXE

# 랜카드 PXE → iPXE
dhcp-boot=tag:!ipxe,tag:bios,undionly.kpxe,,192.168.100.1
dhcp-boot=tag:!ipxe,tag:efi64,ipxe.efi,,192.168.100.1

# iPXE → 부팅 스크립트
dhcp-boot=tag:ipxe,http://192.168.100.1/boot.ipxe

enable-tftp
tftp-root=/srv/tftp
log-dhcp

/etc/dnsmasq.d/pxe.conf

port=0은 DNS 기능을 끄는 설정입니다. Ubuntu에서는 systemd-resolved가 53번 포트를 사용하고 있어서 이걸 안 해주면 dnsmasq가 실행되지 않습니다.

처음 요청에는 ipxe 태그가 없으니 iPXE 파일을 주고, iPXE가 다시 요청하면 ipxe 태그가 붙어서 boot.ipxe URL을 주는 구조입니다.

sudo systemctl restart dnsmasq

3. 부팅 파일 준비

Ubuntu Live Server ISO에서 커널과 initrd를 꺼내서 nginx 경로에 넣어줍니다. ISO 파일명은 받은 버전에 맞게 변경해주세요.

sudo mkdir -p /var/www/html/ubuntu && cd /var/www/html/ubuntu
sudo wget https://releases.ubuntu.com/24.04/ubuntu-24.04.3-live-server-amd64.iso -O ubuntu.iso

sudo mount -o loop,ro ubuntu.iso /mnt
sudo cp /mnt/casper/vmlinuz /mnt/casper/initrd .
sudo umount /mnt

4. iPXE 부팅 스크립트

#!ipxe

set base http://192.168.100.1/ubuntu

kernel ${base}/vmlinuz initrd=initrd ip=dhcp url=${base}/ubuntu.iso cloud-config-url=/dev/null
initrd --name initrd ${base}/initrd
boot

/var/www/html/boot.ipxe

  • ip=dhcp url=... : 부팅 후 네트워크를 잡고 ISO 전체를 HTTP로 받아서 메모리에 올립니다. 그래서 클라이언트 RAM은 4GB 이상 필요합니다.
  • initrd=initrd : UEFI에서 initrd를 찾을 수 있도록 이름을 맞춰주는 부분입니다.
  • cloud-config-url=/dev/null : ISO를 한 번 더 다운로드하는 걸 막아줍니다.

5. 방화벽

sudo ufw allow in on eth1 to any port 67 proto udp
sudo ufw allow in on eth1 to any port 69 proto udp
sudo ufw allow in on eth1 to any port 80 proto tcp

DHCP(67), TFTP(69), HTTP(80) 포트를 열어줍니다.

이제 클라이언트를 같은 네트워크에 연결하고 Network Boot로 부팅하면 Ubuntu 설치 화면까지 진입하게 됩니다. 진행 상황은 아래 명령어로 확인할 수 있습니다.

sudo journalctl -u dnsmasq -f

자주 발생하는 오류

  • PXE-E51 (No DHCP offers) : DHCP 응답이 없는 경우입니다. dnsmasq 인터페이스 설정과 67번 포트를 확인해주세요.
  • PXE-E32 (TFTP open timeout) : TFTP 요청이 막힌 경우입니다. 69번 포트와 tftp-root 경로를 확인해주세요.
  • UEFI에서 부팅이 바로 넘어가는 경우 : Secure Boot가 켜져 있으면 서명되지 않은 ipxe.efi가 차단됩니다. 테스트할 때는 Secure Boot를 꺼주세요.
  • iPXE 화면이 계속 반복되는 경우 : 체인로딩 무한 루프입니다. dhcp-userclass와 tag:!ipxe 설정을 확인해주세요.

정리

  • PXE는 DHCP로 부팅 정보를 받고, TFTP로 부팅 파일을 받아서 실행하는 구조.
  • BIOS/UEFI는 Option 93으로 구분해서 다른 파일을 내려줘야 함.
  • TFTP는 느리기 때문에 iPXE로 체인로딩 후 HTTP로 받는 방식을 많이 사용.

[Network] PXE 부팅 개념과 서버 구축하기여기에 Ubuntu autoinstall을 붙이면 설치 과정까지 자동화할 수 있는데, 이 부분은 다음에 정리해보겠습니다.

iPXE 공식 문서

dnsmasq man page