動機

就是把windows與ubuntu的安裝整合在一起 (都是uefi)

Sol

整體結構

  • dhcp回dhcp-boot,讓client拉ipxe的執行檔
  • ipxe透過tftp拉真正的menu,ipxe在透過http拉需要的東西
    • general: kernel要知道怎麼透過網路去找安裝程式,所以下面就有兩種方式
      • 一個shell給你作事 (winpe)
      • 有魔改的kernel,裡面放url (netboot),或是透過kernel args傳nfs
    • windows:
      • 透過wimboot引導winpe
      • winpe再連到自己host windows iso的地方
    • ubuntu:
      • 就是load kernel與initrd
      • 之後裡面魔改後kernel與initrd會去ubuntu拉ubuntu iso
        • 也因為魔改過(應該是initrd),所以有自動回答文件

網路

這次是把 dhcp, tftp, web, router整合在同一台,只用一個網孔,因為我的respi2只有一個孔。

所以整個網路就是電腦一個孔要吃兩個網路,有兩個方式

  1. ip alias, vlan: 應該可以用,但我沒試
  2. 從現有的net分幾個ip給dhcp發: 這裡用這個方法
  • 假設dhcp的假子網路: 192.168.81.20~192.168.81.25

要處理snat,

iptables -P FORWARD ACCEPT
iptables -t nat -A POSTROUTING -m iprange --src-range 192.168.81.20-192.168.81.25 -j MASQUERADE

dhcpd

dhcpd.conf

ddns-update-style none;
ignore client-updates;
  
allow booting;
allow bootp;
  
subnet 192.168.81.0 netmask 255.255.255.0 {
        range 192.168.81.20 192.168.81.25;
        option broadcast-address 192.168.81.2;
        option subnet-mask 255.255.255.0;
        option domain-name-servers 8.8.8.8;
  
          class "pxeclients" {
                  match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
                  next-server 192.168.81.160;
                  filename "ipxe.efi";
          }
}

tftpd

tftpd.remap 都是因為window的斜線是反的!!

rg \\ /

nginx

/etc/nginx/nginx.conf 裡面的user要改成root,不然沒辦法掛在mnt

user  root;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

/etc/conf.d/default.conf

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                autoindex on;
                autoindex_exact_size off;
                autoindex_format html;
                autoindex_localtime on;
                root /mnt/;
        }
}

ipxe

clone code

sudo apt-get install -y git gcc make liblzma-dev
git clone https://github.com/ipxe/ipxe.git
cd ipxe/src

embed.ipxe

#!ipxe

dhcp
chain tftp://${next-server}/main.ipxe || shell

編ipxe

make bin-x86_64-linux/ipxe.pxe EMBED=embed.ipxe

main.ipxe

#!ipxe
# dhcp

set http-root           http://${next-server}

# Some menu defaults
set menu-timeout 5000
set submenu-timeout ${menu-timeout}
set menu-default ubuntu1804_inst

:start
menu iPXE boot menu
item --gap --                   ---------------------------- Installers ----------------------------------
item --key u    ubuntu_inst         Install Ubuntu
item --key e    windows10_uefi_inst          Install Windows 10
item --gap --                   ------------------------- Advanced options -------------------------------
item            shell                   Drop to iPXE shell
item            reboot                  Reboot
item
item --key x    exit                    Exit iPXE and continue BIOS boot
choose --timeout ${menu-timeout} --default ${menu-default} selected || goto cancel
set menu-timeout 0
goto ${selected}

:cancel
echo You cancelled the menu, dropping you to a shell

:shell
echo Type 'exit' to get the back to the menu
shell
set menu-timeout 0
set submenu-timeout 0
goto start

:reboot
reboot

:exit
exit

:windows10_uefi_inst
kernel ${http-root}/windows/wimboot
initrd ${http-root}/windows/BCD         BCD
initrd ${http-root}/windows/boot.sdi    boot.sdi
initrd ${http-root}/windows/boot.wim boot.wim
boot

:ubuntu_inst
kernel ${http-root}/ubuntu/linux initrd=initrd.gz
initrd ${http-root}/ubuntu/initrd.gz
boot

資料夾結構

  • /
    • files
      • web
        • windows
          • boot.wim: winpe的kernel
          • wimboot: ipxe用來load winpe的魔法
          • boot.sdi: winpe的ramdisk
          • BCD: windows的bootloader
        • ubuntu
      • tftpd
        • main.ipxe
        • ipxe.efi
    • confs
      • tftpd
        • tftpd.remap
      • nginx
        • nginx.conf
        • default.conf
      • dhcpd
        • dhcpd.conf

docker compose

docker的server一般要知道要開什麼port,但如果懶就用--net host,在compose就用network_mode: host

附上常用的docker指令

  • 創container (d是detach, v是volume)
    • docker run -d --name <container name> --net host -v <host path>:<container path> <image name>
  • debug需要 (f就是tail的f)
    • docker logs -f <container name>
    • docker-compose logs -f
  • 連進去確認container狀況
    • docker exec -it <container name> /bin/sh
  • 直接關掉與刪掉container (f是force)
    • docker rm -f <container name>
services:
  dhcpd:
    image: networkboot/dhcpd
    network_mode: host
    volumes:
      - /confs/dhcpd:/data
  tftpd:
    image: 3x3cut0r/tftpd-hpa
    ports:
      - "69:69/udp"
    volumes:
      - /files/tftpd:/tftpboot
      - /confs/tftpd/tftpd.remap:/mapfile
    environment:
      MAPFILE: /mapfile
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - /confs/nginx/nginx.conf:/etc/nginx/nginx.conf
      - /confs/nginx/default.conf:/etc/nginx/conf.d/default.conf
      - /files/web:/mnt

不要用dnsmasq

雖然說dhcp, tftp都有,但是不知道為什麼在winpe的uefi開機時都會出事

dhcp好像有錯,同時tftp不能remap,所以只能用別款

不要用virtualbox實驗

virtualbox的nat網路不是真正的nat,要自己創nat網路… 雖說原本的nat支援pxe,但實際上無法用自己網路來構成pxe開機,只能算是模擬

每次都重建一台vm

有遇到winpe一直卡在wpeinit的事,但是自從每次都重建要被裝os的vm來實驗後就沒遇過了

直接用iscsi掛iso去boot不work

因為轉到iscis之後,雖然是iso的執行環境, 但iso還要從iso載入其他檔案,會因為不知道iscsi的target在哪,就直接出事。

Ref

why-are-my-two-virtual-machines-getting-the-same-ip-address 解决Nginx出现403 forbidden is-it-possible-to-have-a-root-path-containing-spaces-in-my-nginx-conf build ipxe iPXE编译增加功能与自定义脚本 折腾网络启动(2)iPXE 篇