Dnsmasqのproxydhcp機能を使ってiPXE chainloading

PXEサーバーというのはご存知だろうか。
ネットワーク上からBootしてLinuxをインストールしたり、Memtestを走らせたりするサーバーである。

今回はiPXEでchainloadingをやってみたい。

通常はtftpだけを使いNetworkBootを行う。
しかし、tftpはとても遅く少しのデータしか転送できない。
httpからBootできれば早くそしてより重いデータも転送することができる。

PXEbootはhttpをいきなりブート出来ない。
iPXEはhttpからのBootが可能である。

そこで、
下図のように

1. LANからPXEでtftpからiPXE(undionly.kpxe)をロードさせる。
2. undionly.kpxeがWebサーバーにあるbootメニューを読み込む
3. インターネット上にあるubuntuやCentOSのインストーラーを読み込む

とやればhttpからbootすることが可能になる。
これをchainloadingと呼ぶ。

```
LAN Boot > undionly.kpxe from tftpd > boot_menu.ipxe from local httpd > global httpd boot

```

## 環境
僕はネットワーク管理者ではない。
DHCPサーバーの設定を変更することはできない。
だから、ProxyDHCPを使う。

proxyDHCPはその名の通り、DHCPサーバーの代理を行う。
実際のIP配布はDHCPサーバーに行ってもらう。

proxyDHCPから先の仕事はtftpサーバーが行ってくれる。
proxyDHCPはDHCPサーバーへのIPの配布の代理と、
tftpへのブートの受け渡しをやってくれるようである。

> The proxyDHCP server providing TFTP server IP address and name of the NBP only to PXE identified booting clients. [^1]

proxyDHCP機能のあるソフトウェアは少ない。
有名どころだとDnsmasqしかない。
DnsmasqはDNS, DHCP,NetworkBoot等のネットワークインフラ機能を提供する。
DnsmasqのTFTPとproxyDHCPの機能を使う。

Dnsmasqはyumやapt-getでインストールすることができる。

以下環境です。

- Server
  - Debian Wheezy (Linux pxeserver 3.2.0-4-amd64 #1 SMP Debian 3.2.78-1 x86_64 GNU/Linux)
  - ECS 945GCT-M
  - Intel(R) Pentium(R) Dual CPU E2160 @1.80GHz
  - Dnsmasq 2.62-3+deb7u3
  - Proxy DHCP
  - iPXE (undionly.kpxe)
- Clilent
  - Desktop PC
  - ECS G45T-M5
  - Realtec PCIe GBE Family Controller
  - Intel UNDI,PXE-2.0 (bulid 082)
  - Realtek RTL8139(A/B/C)/RTL8130 PCI Fast Ethernet Controller v2.11
- Network
  - 172.20.0.0/16
  - GW
    - 172.20.0.254
  - DHCP-Server
    - 172.20.0.70


## 設定

1. dnsmasqをインストール
2. dnsmasqを設定
3. git repositoryからiPXEのSourceを取得
4. iPXE Sourceからundionly.kpxeをbuild
5. undionly.kpxeをtftpサーバーに置く
6. boot.ipxeをWebサーバーに置く
7. NetworkBoot

### Dnsmasq

最初に、dnsmasqをインストールします。
僕はDebianを使うのでDebianで説明します。
CentOS/RedHatのdnsmasqも同じパッケージ名で設定ファイルの場所も同じです。


#### dnsmasqのインストール

Debian/Ubuntu

```bash:dnsmasqをインストール
$ sudo apt-get install dnsmasq

```


#### dnsmasqの設定

dnsmasqの設定を行う。
エディタで下記のように編集します。

```bash:dnsmasq.conf
$ vi /etc/dnsmasq.conf
# DHCP-Proxyを使う
dhcp-range=172.20.0.0,proxy
# dhcpが175オプションを持っていたときipxeというタグをSetする
dhcp-match=set:ipxe,175 # gPXE/iPXE sends a 175 option.
# ipxeタグでないときはundionly.kpxeをbootする
dhcp-boot=tag:!ipxe,undionly.kpxe
# bootするipxeのメニューのファイル名,Server名,サーバーのIPアドレス
# これをBootすることでipxeメニューを表示する。
dhcp-boot=http://172.20.0.225/a.ipxe,172.20.0.225,172.20.0.225
# pxe-serviceを使う設定
# 自らがDHCP-Serverである場合は設定する必要はないのだが、
# Proxy-DHCPの場合は設定する必要がある。
pxe-service=tag:!ipxe,x86PC,"splash",undionly.kpxe
# tftpを使う
enable-tftp
# tftpで公開するフォルダ
tftp-root=/var/ftpd
log-queries
conf-dir=/etc/dnsmasq.d
```

そして保存します。

### iPXE

[undionly.kpxe](http://boot.ipxe.org/undionly.kpxe)からダウンロードするのが簡単なんだが、一年前のSourceからもbuildして使いたい。

sourceからbuildしたundionly.kpxeは、chainloading時にparent codeを表示する。
Parentハッシュコードもチェックしておきたい。

だからSourceを[git repository](http://git.ipxe.org/ipxe.git)から取得してbuildすることにする。

#### iPXEのSourceを取得

gitをインストールする必要がある。
下記のようにするとインストールできる。

```bash
$ sudo apt-get install git-core

```

iPXEをbuildするためには下記のパッケージが必要です。

- gcc
- binutils
- make
- perl
- syslinux
- liblzma
- xz

下記のようにインストールする、

```bash
$ sudo apt-get install gcc,binutils,make,perl
$ sudo apt-get install syslinux,lzma-dev,liblzma5
```

自分のCurrentディレクトリーにipxeのsourceを取得します。
下記のように実行します。

```bash
$ cd ~
$ git clone git://git.ipxe.org/ipxe.git

```

#### iPXEをbuild

1. currentディレクトリーにあるipxeフォルダに入る。
2. undionly.kpxeをbuildする。

下記のように行えばいい。

```bash
$ cd ~/ipxe/source
$ make bin/undionly.kpxe
```

## 配置

下記のように/var/ftpdフォルダにundionly.kpxeを配置する。

```bash
$ cd ~/ipxe/source
$ mv bin/undionly.kpxe /var/ftpd

```

## Webサーバー
Apache2を用意する。

nginxを用意してもいいし、
perlやpythonのワンライナーで実行できるsimpleなWebサーバーを実行してもいいだろう。
[ワンライナーWebサーバを集めてみた](http://qiita.com/sudahiroshi/items/e74d61d939f18779970d)

### Apache2をInstall

debianだと下記のようにサラっとインストールできる。

```bash:apache2_Install
$ sudo apt-get install apache2

```

### DocumentRoot

Debian系のapache2はバーチャルホストが標準で有効化されている。
標準のDocumentRootは/var/wwwである。

下記のコマンドでバーチャルホストがonになっているのかをチェック

```bash
$ cat /etc/apache2/apache2.conf | grep sites-enabled
#       `-- sites-enabled
# * Configuration files in the mods-enabled/ and sites-enabled/ directories
Include sites-enabled/

```

site-enabledのファイルからDocumentRootの場所を確認

```bash
$ cat /etc/apache2/sites-enabled/000-default | grep DocumentRoot
        DocumentRoot /var/www
```

### Bootメニュー
/var/www/フォルダーに移動して
boot.ipxeを作成し、エディターで以下のように入力します。
エディタは普通Vimだよね !？

下記のように書き込みます。

```bash
$ sudo cd /var/www
$ sudo vi boot.ipxe
#!ipxe
menu install menu
item ubuntu Ubuntu installation
item centos7 Centos7 installation
item --gap
item back install menu
choose --timeout 20000 --default back target && goto ${target} || goto menu

:ubuntu
set ubuntu http://archive.ubuntu.com/ubuntu/dists/trusty/main/installer-amd64/current/images/netboot/ubuntu-installer/amd64
initrd ${ubuntu}/initrd.gz
kernel ${ubuntu}/linux tasks=standard vga=788 -- quiet
boot

:centos7
set centos7 http://mirror.centos.org/centos/7/os/x86_64
initrd ${centos7}/image/pxeboot/initrd.img
kernel ${centos7}/image/pxeboot/vmlinuz vga=788 repo=${centos7}
boot

:back
exit

```
そして保存します。

## PXE Boot

PXEServerの準備完了。

クライアントPCを起動します。

BIOS画面が出てきます。
BIOS Boot Screenを表示したいので、
起動時にすかさずF11キーを押します。

```
American
Megatrends

AMIBIOS(C) 2008 American Megatrends. Inc.
G43T-M5 BIOS Release 09/28/2009 for MCJ
CPU : Intel(R) Celeron(R) CPU E3300 @ 2.5GHz

Press DEL to run Setup
Press F11 for BBS POPUP
The MCH is operation with DDR2 800
DRAM Timing: Tcl:6/Tras:18/Trcd:6/Twr:6/Trfc:52/Twtr:3/Trrd:3/Trtp:3
Single Chanel Mode
2048MB OK (64MB Shared Memory SIze Used)
Auto-Detecting Pri Slave...IDE Hard Disk
Auto-Detecting 3rd Master..ATAPI CDROM
Pri Slave : SAMSUNG HD252HJ 1AC01118
            Ultra DMA Mode-5, S.M.A.R.T. Capable and Status OK
3rd Master: HL-DT-ST DVDDAM GH24NS50 XP01
            Ultra DMA Mode-5
```
BIOS Boot Screenが表示されます。
Realtec Boot Agentを↑↓で選んでEnterキーを押します。

```
Press select boot device:
---------------------------
   SAMSUNG HD252HJ
   HL-DT-ST DVDRAM GH24NS50
   Genetic USB SD Reader
   Genetic USB CF Reader
   Genetic USB SM Reader
   Genetic USB MS Reader
-> Realtec Boot Agent

---------------------------
↑ and ↓ to menu selection
ENTER to select boot device
ESC to boot using defaults

```

表示が下記のように変わった後に

```
Realtec RTL8111B/8111C Gigabit Boot Agent
Press Shift-F10 to configure ..........
```

PXE Bootが始まります。

```
Intel UNDI. PXE-2.1 (build 002)
Copyright (C) 1997-2000 Intel Corporation

For RealTek RTL8111B/8111C Gigabyte Ethernet Controller v2.14(000225)

CLIENT MAC ADDR: 00 25 11 CB 41 1B GUID 00020003-0004-0005-0006-00700080009
CLIENT IP: 172.20.10.83 MASK 255.255.0.0
DHCP IP: 172.20.0.70 PROXY IP:172.20.0.225
GATEWAY IP: 172.20.0.254

Auto-Select:
     splash

BOOT SERVER IP : 172.20.0.225

PXE-EB: !PXE at 9C3E:0070,entry point at 9C3E:0109
             UNDI code segment 9C3E:1A7A, data segment 923D:A010 (584-632kB)
             UNID device is PCI 02:00.0, type DIX+802.3
             584kB free base memory after PXE unload
iPXE initialising devices...ok

iPXE 1.0.0+ (55e4) -- Open Source Network Boot Firmware -- http://ipxe.org
Features: DNS HTTP iSCSI TFTP AoE ELF MBOOT PXE bzImage Menu PXEXT

Press Ctrl+B for the iPXE command line...
```

WebサーバーからBoot Menuが表示されます。
UbuntuかCentOS7かどちらかを↑↓で選択してEnterキーを押します。

Linuxインストーラーがネット上のリソースからBootされます。

```
            Install Menu

-> Ubuntu installation
   CentOS7 installation

```

どちらかを選んでEnter押せば、
OSのインストーラーが起動します。
バッチリ、OSインストールできますよ。

## References

- [Dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html)
  - PXEやproxyDHCPのためのPackage Software
- [iPXE chainloading](http://ipxe.org/howto/chainloading)
  - iPXE chainloadingのやり方
- [iPXE Download](http://ipxe.org/download)
  - Source codeセクションにSourceからどうやってbuildするかが書かれている。
- [Preboot_Execution_Environment](https://en.wikipedia.org/wiki/Preboot_Execution_Environment)
  - Preboot eXecution Environment(PXE)の説明
  - IntegrationセクションにproxyDHCPの説明がある。
- [How To Install Git on Debian 8](https://www.digitalocean.com/community/tutorials/how-to-install-git-on-debian-8)
  - gitのインストール方法
- [iPXE - The Versatile Boot Loader](http://blog.schlomo.schapiro.org/2014/07/ipxe-versatile-boot-loader.html)
  - 簡単なiPXE Bootメニュー




-----

[^1]: [Preboot_Execution_Environment](https://en.wikipedia.org/wiki/Preboot_Execution_Environment) Integration Section