Bootowanie systemu Live z wykorzystaniem PXE

Bootowanie po PXE jest stosunkowo prostym zagadnieniem, szybkim do omówienia. Temat jednak rozrasta się, gdy mówimy o wykorzystaniu PXE do jakiegoś konkretnego zastosowania, określonej aplikacji.

Postaram się tutaj omówić instalacje i konfiguracje systemu serwującego obraz systemu do klientów po PXE, oraz przygotowanie obrazu systemu który będzie bootowany. Może to znaleźć zastosowanie np. do szybkiego bootowania systemu operacyjnego opartego o jądro linuksa np. w szkolnej pracowni(co było moim ‚use casem’) 😉

Zanim przystąpimy do czegokolwiek, warto dowiedzieć sie, czym w zasadzie jest PXE, jak działa, i co wymaga do sprawnego swojego działania.
Linkuję dwa artykuły, warte dogłębnej analizy: jeden i drugi.

Przygotowanie całości będzie przebiegało mniej więcej tak:

  • 1.0 Przygotowanie serwera hostującego
    1.1 niezbędna do aplikacji konfiguracja systemu bazowego
    1.2 instalacja i konfiguracja dnsmasq
    1.3 instalacja i konfiguracja nginx
    1.4 (opcjonalne)instalacja i konfiguracja SSHD
  • 2.0 przygotowanie serwowanego obrazu systemu
    2.1 konfiguracja kont użytkowników
    2.2 odebranie zbędnych uprawnień użytkownikowi
    2.3 bezpieczna konfiguracja SSHD/wyłączenie SSHD

1.1 Konfiguracja systemu bazowego do serwowania systemu PXE

1.1.1 Ustawiamy statyczny adres IP:
w pliku

/etc/network/interfaces

Tworzymy wpis dla interfejsu na którym działał będzie serwer PXE:

auto eth0
  iface eth0 inet static
    address 192.168.1.10
    netmask 255.255.255.0
    gateway 192.168.1.1

Jako, że komputer w trakcie prac podłączony jest do mojej sieci lokalnej, wybrałem swoją bramę a komputerowi nadałem inny adres, który później będziemy musieli podać przy dalszej konfiguracji.(tym sposobem podłączając komputer do swojej sieci lokalnej komputer miał dostep do internetu -> zadziała to bardzo podobnie w kazdej innej sieci z tą samą bramą, z ewentualnymi drobnymi problemami jeśli ip jest zajęte).
Samo bootowanie po PXE powinno spokojnie działać przy adresie IP serwera pobieranym z DHCP, jednak w mojej aplikacji takowego nie ma, stąd ‚sztywne’ ustawienie.

1.1.2 modyfikacja /etc/fstab

Chodzi o to, aby obraz z systemem montował się od razu tam gdzie trzeba. Wystarczy dodać:

/ścieżka/do/obrazu/iso    /to/samo/co/tftp-root(patrz: dalej)    iso9660     ro,users,loop  0 0

1.1.3 BHP

Warto usunąć również zbędne oprogramowanie. Dla własnego komfortu pracy zainstalowałem również ssh(o konfiguracji daemona którego mowa będzie w kolejnych punktach) tmuxa oraz zsh -> dla wygody pracy.

1.2 Instalacja i konfiguracja dnsmasq

Instalacja przebiega bardzo łatwo, instalować możemy wersję dostępną w repozytorium.
Jako, że na serwer wybrałem system operacyjny Debian, zainstaluję dnsmasq korzystając z APT’a:

aptitude install dnsmasq -y

teraz pozostaje już nic innego jak stworzyć odpowiedni plik konfiguracyjny:

# nano /etc/dnsmasq.conf
port=0
interface=eth0
bind-interfaces
dhcp-range=192.168.0.50,192.168.0.150,12h
dhcp-boot=/arch/boot/syslinux/lpxelinux.0
dhcp-option-force=209,boot/syslinux/archiso.cfg
dhcp-option-force=210,/arch/
enable-tftp
tftp-root=/mnt/archiso

Wszystkie opcje są raczej zrozumiałe, uwagę trzeba zwrócić na:

tftp-root

gdzie zamontowany będzie obraz naszego serwowanego systemu.

1.3 instalacja i konfiguracja nginx

W związku z tym, że obraz naszego systemu będzie pobierany po HTTP, potrzebujemy serwer do tego. Oczywiście nginx ;]

aptitude install nginx -y

Domyślnie, uruchamiany jest on jako użytkownik

www-data

Nie lubie tego typu rozwiązań, bo sprawy mogą się skomplikować jeśli uruchomimy kilka serwerów http. Dla tego też usuwam tego użytkownia, i tworzę nowego, o nazwie nginx:

root@debian:~# deluser www-data
Usuwanie użytkownika "www-data" ...
Ostrzeżenie: grupa "www-data" nie ma już żadnych członków.
Gotowe.
root@debian:~# adduser nginx
Dodawanie użytkownika "nginx"...
Dodawanie nowej grupy "nginx" (1001)...
Dodawanie nowego użytkownika "nginx" (1001) w grupie "nginx"...
Tworzenie katalogu domowego "/home/nginx"...
Kopiowanie plików z "/etc/skel" ...
Proszę podać nowe hasło UNIX:
Proszę ponownie podać hasło UNIX:
Nie podano hasła
Proszę podać nowe hasło UNIX:
Proszę ponownie podać hasło UNIX:
passwd: Błąd podczas modyfikowania tokenu uwierzytelniania
passwd: password unchanged
Spróbować ponownie? [t/N] n
Zmieniam informację o użytkowniku nginx
Wpisz nową wartość lub wciśnij ENTER by przyjąć wartość domyślną
Imię i nazwisko []:
Numer pokoju []:
Telefon do pracy []:
Telefon domowy []:
Inne []:
Czy informacja jest poprawna? [T/n]

Dla bezpieczeństwa w pliku:

/etc/passwd

ustawiamy powłokę użytkownika nginx na:

/bin/false

uniemożliwiając mu dostęp do powłoki.

No i tworzymy odpowiedni plik konfiguracyjny, z kilkoma drobnymi optymalizacjami.

worker_processes 1;
user nginx nginx;
events {
  worker_connections 1024;
  }
  http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    server_tokens off; #ukrycie informacji o wersji nginx
    	###############
    ## KOMPRESJA ##
    ###############
    gzip on;
    gzip_min_length 0;
    gzip_http_version 1.0;
    gzip_types text/plain text/xml application/xml application/json text/css application/x-javascript text/javascript application/javascript;
    gzip_comp_level 9;
    gzip_proxied any;
    	###########
    ## PROXY ##
    ###########
    proxy_buffering on;
    proxy_cache_path /var/nginx levels=1:2 keys_zone=one:15m inactive=7d max_size=1000m;
    proxy_buffer_size 4k;
    proxy_buffers 100 8k;
    proxy_connect_timeout      60;
    proxy_send_timeout         60;
    proxy_read_timeout         60;
    	server {
      listen 80;
      server_name localhost;
      access_log /var/log/nginx/localhost.access.log;
      error_log /var/log/nginx/localhost.error.log;
      		location / {
        root /mnt/archiso;
        index index.php index.html index.htm;
        autoindex on;
      }
    }
  }
  

Jeśli nie istnieją jeszcze, trzeba utworzyć foldery wykorzystywane przez nginx i nadać im odpowiednie uprawnienia:

  mkdir /var/log/nginx
  mkdir /var/nginx
  chown nginx:nginx /var/log/nginx -R
  chown nginx:nginx /var/nginx -R
  

Uwaga! Główny folder serwera powinien być taki sam jak „tftp-root” w pliku konfiguracyjny dnsmasq.

1.4 instalacja i konfiguracja SSHD

aptitude install openssh-server

Jako, że komputer ten nie będzie podłączony do internetu, dla bezpieczeństwa jedynie wyłączymy logowanie użytkownika root, zmieniając w pliku:

/etc/ssh/sshd_config

wpis:

PermitRootLogin yes

na

PermitRootLogin no

(tak właściwie, serwer SSH nie jest potrzebny, by komputer spełniał swoją rolę -> zainstalowałem go jedynie dla wygody administracji. Można wyłączyć)

Teraz już nasz serwer jest gotowy! Jedyne czego nam brakuje to… obraz systemu, który będzie serwowany! Przejdźmy więc do pracy.

2.0 przygotowanie serwowanego obrazu systemu

Jako, ze bootloader obrazu LiveCD systemu ArchLinux posiada już gotową konfigurację do bootowania PXE, z obrazu tego właśnie systemu skorzystam. Pobieram więc obraz.

Teraz przyszła pora na zabawę. Domyślnie, obraz uruchamiając się sam loguje się jako root. A to w naszym scenariuszu jest bardzo, bardzo złą rzeczą..
Narzędzia, które będziemy potrzebować znajdują się w pakietach:

genisoimage squashfs-tools

Przydadzą się również skrypty instalacyjne ArchLinuksa
Potrzebujemy właściwy obraz systemu plików systemu. Czyli montujemy obraz *iso, i kopiujemy do osobnego folderu wszystkie pliki.

Wiedząc, że targetowane komputery to x86_64 możemy od razu usunąć folder:

arch/i686

natomiast folder x86_64 kopiujemy gdzieś, gdzie będziemy nad nim pracować(jeśli komputer, na którym pracujesz posiada dużo wolnej pamięci ram (~1GB) można rozważyć operacje na tym obrazie w RAM’ie -> znacznie przyspieszy to pakowanie/rozpakowanie).

Przejdźmy teraz do skopiowanego folderu x86_64. W środku znajduje się plik:

root-image.fs.sfs
  

Jest to cały system plików obrazu Live, spakowany. Żeby go zmodyfikować, musimy go rozpakować! Czas więc zabrać się do roboty:
Rozpakowujemy ten obraz poleceniem:

unsquashfs root-image.fs.sfs

Jeśli wszystko przebiegło pomyślnie, w nowo utworzonym folderze powinniśmy znaleźć plik *fs. Ten plik montujemy sobie w dowolnym miejscu. Tam będziemy mogli dowolnie go modyfikować. Niestety, jeśli host jest innej architektury niż obraz który modyfikujemy, nie uda nam się dostać do środowiska chroot(w prosty sposób)… upewnijmy się zatem, że komputer na którym chcemy zmieniać obraz jest oparty o tą samą architekturę, której obraz modyfikujemy.

2.1 konfiguracja kont użytkowników

ArchLinux live, automatycznie loguje użytkownika na konto root. W naszym przypadku zachowanie to nie jest korzystne, i musi to zostać wyłączone.
Przejdźmy więc do środowiska chroot rozpakowanego obrazu:

arch-chroot /miejsce/montowania/root-image.fs

w pliku:

/etc/systemd/system/[email protected]/autologin.conf

zmieniamy:

--autologin root

na:

--autologin arch

tym sposobem, po uruchomieniu komputera zalogowani będziemy jako zwykły użytkownik „arch”.

Ustawmy jeszcze tylko hasło root’a(to, za pomocą którego będzie można dostać uprawnienia na każdym komputerze, na którym uruchomiony jest system z tego właśnie obrazu):

passwd

2.2 Odebranie uprawnień zwykłemu użytkownikowi

Jednak to jeszcze nie wszystko. Użytkownik arch dopisany jest do pliku sudoers, w sposób umożliwiający mu uzyskanie uprawnień superużytkownika(roota) bez podawania hasła.

Usuńmy/zakomentujmy zatem z pliku /etc/sudoers linijkę:

arch ALL=(ALL) ALL

I upewnijmy się, że ten plik posiada odpowiednie uprawnienia:

chmod 440 /etc/sudoers

i usuńmy folder z innymi(zbędnymi dla naszej aplikacji) wpisami:

rm -rf /etc/sudoers.d

Ustalmy jeszcze prawa dostępu do su(tak, aby nikt nie mógł go wykonać -> na klientach nie ma takiej potrzeby):

chmod 660 /usr/bin/su*

Jednak to nie wszystko!

2.3 bezpieczna konfiguracja SSHD

Domyślnie, daemon SSH jest włączony. Poczatkowo myślałem, żeby po prostu zblacklistować zwykłego usera i wyłączyć logowanie po haśle. Po chwili pomyślałem, czemu by w ogóle nie wyłączyć serwera SSH? Przecież tutaj i tak do niczego nie będzie potrzebny.
Jak pomyślałem, tak też zrobiłem:

systemctl disable sshd.service && pacman -Rsc openssh-server

Wygląda na to, że to już prawie wszystko! Jedyne co pozostało nam do zrobienia to:

  • odmontowanie root-image.fs
  • spakowanie obrazu:
mksquashfs squashfs-root root-image.fs.sfs

  • zastąpienie nowospakowanym obrazem oryginalnego w miejscu, gdzie skopiowaliśmy pliki z *.iso
  • złożenie całości ponownie do pojedynczego obrazu *.iso:
# genisoimage -l -r -J -V "ARCH_201404" -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -c isolinux/boot.cat  -o ~/arch-custom.iso ~/arch
  I: -input-charset not specified, using utf-8 (detected in locale settings)
  Size of boot image is 4 sectors -> No emulation
  3.08% done, estimate finish Sun Apr  6 17:30:04 2014
  6.15% done, estimate finish Sun Apr  6 17:30:04 2014
  9.23% done, estimate finish Sun Apr  6 17:30:04 2014
  12.31% done, estimate finish Sun Apr  6 17:30:04 2014
  15.38% done, estimate finish Sun Apr  6 17:30:04 2014
  18.46% done, estimate finish Sun Apr  6 17:30:04 2014
  21.53% done, estimate finish Sun Apr  6 17:30:04 2014
  24.62% done, estimate finish Sun Apr  6 17:30:04 2014
  27.69% done, estimate finish Sun Apr  6 17:30:04 2014
  30.77% done, estimate finish Sun Apr  6 17:30:04 2014
  33.84% done, estimate finish Sun Apr  6 17:30:04 2014
  36.92% done, estimate finish Sun Apr  6 17:30:04 2014
  39.99% done, estimate finish Sun Apr  6 17:30:04 2014
  43.07% done, estimate finish Sun Apr  6 17:30:04 2014
  46.14% done, estimate finish Sun Apr  6 17:30:04 2014
  49.22% done, estimate finish Sun Apr  6 17:30:04 2014
  52.29% done, estimate finish Sun Apr  6 17:30:04 2014
  55.38% done, estimate finish Sun Apr  6 17:30:04 2014
  58.45% done, estimate finish Sun Apr  6 17:30:04 2014
  61.53% done, estimate finish Sun Apr  6 17:30:04 2014
  64.60% done, estimate finish Sun Apr  6 17:30:04 2014
  67.68% done, estimate finish Sun Apr  6 17:30:04 2014
  70.75% done, estimate finish Sun Apr  6 17:30:04 2014
  73.83% done, estimate finish Sun Apr  6 17:30:04 2014
  76.90% done, estimate finish Sun Apr  6 17:30:04 2014
  79.98% done, estimate finish Sun Apr  6 17:30:04 2014
  83.05% done, estimate finish Sun Apr  6 17:30:04 2014
  86.14% done, estimate finish Sun Apr  6 17:30:04 2014
  89.21% done, estimate finish Sun Apr  6 17:30:04 2014
  92.28% done, estimate finish Sun Apr  6 17:30:04 2014
  95.36% done, estimate finish Sun Apr  6 17:30:04 2014
  98.44% done, estimate finish Sun Apr  6 17:30:04 2014
  Total translation table size: 2048
  Total rockridge attributes bytes: 10701
  Total directory bytes: 33472
  Path table size(bytes): 176
  Max brk space used 27000
  162549 extents written (317 MB)
  

Gdzie:

~/arch

to miejsce, gdzie wypakowane są pliki z obrazu *.iso, a

~/arch-custom.iso

to plik, gdzie zapisany będzie otrzymany obraz.

Teraz wystarczy zrestartować serwery:

  /etc/init.d/nginx restart
  /etc/init.d/dnsmasq restart
  

I voila! Na klientach przestawiamy bootowanie na LAN(albo PXE, czy tam Network -> różnie jest ta opcja nazywana) i naszym oczom ukazać się powinno logo ArchLinuksa.

Po uruchomieniu naszego serwerka wystarczy podłączyć go do sieci do której podłączone są komputery 🙂 Jeśli siec jest podłączona do internetu, można dnsmasq dopisać opcję dhcp o adresie bramy i dodać jakieś serwery DNS, wtenczas każdy zabootowany komputer będzie miał dostep do internetu.

Ten artykuł nie wyczerpuje tematu. Istnieje jeszcze wiele sposobów na ulepszenia i zwiększenie możliwości tego typu aplikacji, jednak nie to było jego celem, a podstawowa konfiguracja serwowania systemu Live z wykorzystaniem PXE

Leave a Reply

Your email address will not be published. Required fields are marked *