PXE boot: Difference between revisions

From Alpine Linux
m (Marked article as obsolete.)
 
(25 intermediate revisions by 13 users not shown)
Line 1: Line 1:
{{Obsolete|These directions were written for an ancient version of Alpine that still had grsecurity, please update.}}
'''This functionality is still largely prototypal. Some things could still be broken.'''
'''This functionality is still largely prototypal. Some things could still be broken.'''


Line 13: Line 15:
:* A relative path, interpreted relative to the root of the <code>alpine_dev</code>.
:* A relative path, interpreted relative to the root of the <code>alpine_dev</code>.
:* If not specified, a file matching <code>*.apkovl.tar.gz</code> is searched for in the root of the <code>ovl_dev</code>. (If more than one exists in the root of a device, all are ignored.)
:* If not specified, a file matching <code>*.apkovl.tar.gz</code> is searched for in the root of the <code>ovl_dev</code>. (If more than one exists in the root of a device, all are ignored.)
; alpine_dev
 
: '''Required.'''
; alpine_dev (this parameter is no longer used)
: The <code>alpine_dev</code> specifies a device used for reference data which must reside on a filesystem; currently, this is only the case for kernel modules.
: The <code>alpine_dev</code> specifies a device used for reference data which must reside on a filesystem; currently, this is only the case for kernel modules.
: This is also used to obtain APKs if a repository is not explicitly specified; see below.
: This is also used to obtain APKs if a repository is not explicitly specified; see below.
Line 22: Line 24:
:* <code>LABEL=<em>filesystem-label</em></code>
:* <code>LABEL=<em>filesystem-label</em></code>
:* <code>nfs:<em>ip-address</em>:<em>path</em></code>, specifying an NFS export to use as the device. You may need to add modules to the initrd.
:* <code>nfs:<em>ip-address</em>:<em>path</em></code>, specifying an NFS export to use as the device. You may need to add modules to the initrd.
; ovl_dev
 
; ovl_dev (this parameter is no longer used)
: Valid forms include:
: Valid forms include:
:* <code><em>device_name</em>[:<em>fs_type</em>]</code>
:* <code><em>device_name</em>[:<em>fs_type</em>]</code>
:* If not specified, various devices are searched for a file matching <code>*.apkovl.tar.gz</code> in the root directory.
:* If not specified, various devices are searched for a file matching <code>*.apkovl.tar.gz</code> in the root directory.
: This argument can contain the fields <code>{MAC}</code> and <code>{UUID}</code>, which will be substituted with the MAC address of the NIC used by Alpine and the system's DMI "Product UUID" respectively. If these substitutions are used, the value passed to ovl_dev must be enclosed in quotes. e.g. <code>ovl_dev="<nowiki>http://.../</nowiki>{MAC}.apkovl.tar.gz"</code>.
: This argument can contain the fields <code>{MAC}</code> and <code>{UUID}</code>, which will be substituted with the MAC address of the NIC used by Alpine and the system's DMI "Product UUID" respectively. If these substitutions are used, the value passed to ovl_dev must be enclosed in quotes. e.g. <code>ovl_dev="<nowiki>http://.../</nowiki>{MAC}.apkovl.tar.gz"</code>.
; alpine_repo
; alpine_repo
: If set, <code>/etc/apk/repositories</code> will be filled with this. May be an URL. Otherwise, try and find a directory containing the marker file <code>.boot_repository</code> on the <code>alpine_dev</code>.
: '''Required.'''
: <code>/etc/apk/repositories</code> will be filled from this. May be a URL. Otherwise, try and find a directory containing the marker file <code>.boot_repository</code> on the <code>alpine_dev</code>. Please note that although "auto" might appear documented as a valid value, it will not work when PXE booting.


; modloop
; modloop
: if the specified file is of http/ftp or https (if wget is installed), the modloop file will be downloaded to the /lib directory and will be mounted afterwards
: If the specified file protocol is http/ftp or https (if wget is installed), the modloop file will be downloaded to the /lib directory and will be mounted afterwards
: ie modloop=http://192.168.1.1/pxe/alpine/grsec.modloop.squashfs in the append section of your bootloader
: e.g. modloop=<nowiki>http://192.168.1.1/pxe/alpine/grsec.modloop.squashfs</nowiki> in the append section of your [[Bootloaders|bootloader]]
 
; console
: Examples:
:* <code>tty0</code>
:* <code>ttyS1 </code>
:* <code>ttyAMA0</code>
 
; acpi
: Valid forms include:
:* <code>force</code>
 
; ssh_key
: Valid forms include:
:* An HTTP, HTTPS or FTP URL to a public SSH key which will be retrieved and added to the list of authorized SSH keys.
 
; modules


=HOWTO=
=HOWTO=
Line 53: Line 74:


==Set up a TFTP server to serve the PXE bootloader==
==Set up a TFTP server to serve the PXE bootloader==
Install a TFTP server (package "tftp-hpa"). You will need to place a gPXE image at <code>/var/tftproot/gpxe.kpxe</code>. You can generate an image online at [http://rom-o-matic.net/ ROM-o-matic.net]. Select the ".kpxe" output format and the "undionly" driver. You will need to specify a custom boot script. Select "Customize". The following boot script works well:
Install a TFTP server (package "tftp-hpa"). You will need to place a gPXE image at <code>/var/tftproot/gpxe.kpxe</code>. You can generate an image online at [https://rom-o-matic.eu/ ROM-o-matic.eu]{{Dead link}}. Select the ".kpxe" output format and the "undionly" driver. You will need to specify a custom boot script. Select "Customize". The following boot script works well:
   dhcp net0
   dhcp net0
   chain http://${net0/next-server}/gpxe-script
   chain <nowiki>http://${net0/next-server}/gpxe-script</nowiki>
You can include <code>${net0/mac}</code> and <code>${uuid}</code> in the URL for the interface MAC address and machine UUID respectively.
You can include <code>${net0/mac}</code> and <code>${uuid}</code> in the URL for the interface MAC address and machine UUID respectively.


Line 63: Line 84:
Suppose you have an HTTP server configured to serve from <code>/srv/http</code>. Place an appropriate gPXE script, such as the following, at <code>/srv/http/prov/gpxe-script</code>:
Suppose you have an HTTP server configured to serve from <code>/srv/http</code>. Place an appropriate gPXE script, such as the following, at <code>/srv/http/prov/gpxe-script</code>:
   #!gpxe
   #!gpxe
   kernel http://${net0/next-server}/prov/grsec ip=dhcp alpine_dev=nfs:${net0/next-server}:/srv/nfs/depot alpine_repo=http://nl.alpinelinux.org/alpine/v2.5/main/
   kernel <nowiki>http://${net0/next-server}/prov/grsec</nowiki> ip=dhcp alpine_dev=nfs:${net0/next-server}:/srv/nfs/depot alpine_repo=<nowiki>http://nl.alpinelinux.org/alpine/v2.5/main/</nowiki>
   initrd http://${net0/next-server}/prov/pxerd
   initrd <nowiki>http://${net0/next-server}/prov/pxerd</nowiki>
   boot
   boot


Line 77: Line 98:


  DEFAULT alpine
  DEFAULT alpine
  LINUX http://ipaddr/grsec
  LINUX <nowiki>http://ipaddr/grsec</nowiki>
  INITRD http://ipaddr/grsec.gz
  INITRD <nowiki>http://ipaddr/grsec.gz</nowiki>
  APPEND ip=dhcp modules=loop,squashfs,sd-mod,usb-storage alpine_repo=http://repo-url modloop=http://ipaddr/grsec.modloop.squashfs apkovl=http://ipaddr/localhost.apkovl.tar.gz
  APPEND ip=dhcp modules=loop,squashfs,sd-mod,usb-storage alpine_repo=<nowiki>http://repo-url</nowiki> modloop=<nowiki>http://ipaddr/grsec.modloop.squashfs</nowiki> apkovl=<nowiki>http://ipaddr/localhost.apkovl.tar.gz</nowiki>


==Using pxelinux instead of gPXE==
==Using pxelinux instead of gPXE==
Line 85: Line 106:
Since recent version of syslinux, pxelinux also has support to boot over tftp.<br/>
Since recent version of syslinux, pxelinux also has support to boot over tftp.<br/>
The pxelinux.cfg/default file (or specific MAC address file name) should be in the same format as with regular syslinux.<br/>
The pxelinux.cfg/default file (or specific MAC address file name) should be in the same format as with regular syslinux.<br/>
You will need to use a copy of the '''pxelinux.0''' found when installing syslinux on alpine: /usr/share/syslinux/pxelinux.0 and copy it to your tftp server.<br/>
You will need to use a copy of the '''pxelinux.0''' found when installing syslinux on alpine: {{path|/usr/share/syslinux/pxelinux.0}} and copy it to your tftp server.<br/>
Don't forget to also copy ldlinux.c32, as its a dependency of syslinux variants (see documentation).  
Don't forget to also copy ldlinux.c32, as its a dependency of syslinux variants (see documentation).  


Line 94: Line 115:
  LINUX alpine-vmlinuz-grsec
  LINUX alpine-vmlinuz-grsec
  INITRD alpine-pxerd
  INITRD alpine-pxerd
  APPEND ip=dhcp alpine_dev=nfs:192.168.1.1:/srv/boot/alpine modloop=http://192.168.1.1/modloop-grsec nomodeset quiet apkovl=http://192.168.1.1/localhost.apkovl.tar.gz
  APPEND ip=dhcp alpine_dev=nfs:192.168.1.1:/srv/boot/alpine modloop=<nowiki>http://192.168.1.1/modloop-grsec</nowiki> nomodeset quiet apkovl=<nowiki>http://192.168.1.1/localhost.apkovl.tar.gz</nowiki>


''vmlinuz-grsec'' is taken from a system running in memory from usb.<br/>
''vmlinuz-grsec'' is taken from a system running in memory from usb.<br />
''pxerd'' is generated on a system running in memory from usb. With network nfs and virtio_net added.<br/>
''pxerd'' is generated on a system running in memory from usb. With network nfs and virtio_net added.<br />
''/srv/boot/alpine'' is a copy of /media/usb from a system running in memory from usb.<br/>
''{{path|/srv/boot/alpine}}'' is a copy of {{path|/media/usb}} from a system running in memory from usb.<br />
''modules=loop,squashfs,sd-mod,usb-storage'' is not needed as loop and squashfs are hard coded into the init script and we do not use sd nor usb.<br/>
''modules=loop,squashfs,sd-mod,usb-storage'' is not needed as loop and squashfs are hard coded into the init script and we do not use sd nor usb.<br />
''modloop=http://ipaddr/grsec.modloop.squashfs'' does not seems to work. Without neither...(*)<br/>
''modloop=<nowiki>http://ipaddr/grsec.modloop.squashfs</nowiki>'' does not seems to work. Without neither...(*)<br />
''apkovl=http://ipaddr/localhost.apkovl.tar.gz''.<br/>
''apkovl=<nowiki>http://ipaddr/localhost.apkovl.tar.gz</nowiki>''.<br/>


(*) about the modloop problem: /etc/init.d/modloop tries to load the file from /media/nfs instead of /media/alpine and starts trying to mount it! (unsuccessfully) A fix to it is (a proposal) see http://bugs.alpinelinux.org/issues/4015
(*) about the modloop problem: {{path|/etc/init.d/modloop}} tries to load the file from {{path|/media/nfs}} instead of {{path|/media/alpine}} and starts trying to mount it! (unsuccessfully) A fix to it is (a proposal) see {{issue|4015}}


==Set up an NFS server from which Alpine can load kernel modules==
==Set up an NFS server from which Alpine can load kernel modules==
Line 116: Line 137:
==Configure mkinitfs to generate a PXE-bootable initrd==
==Configure mkinitfs to generate a PXE-bootable initrd==


NOTE: There is currently a mkinitfs profile just for networking called: network.
{{note|There is currently a mkinitfs profile just for networking called: network.
Using it will automatically add pxe support and all ethernet drivers to the initramfs.
Using it will automatically add pxe support and all ethernet drivers to the initramfs.}}


You need to add drivers for any Ethernet cards with which you might PXE boot to your initrd. To do this, create <code>/etc/mkinitfs/features.d/network.modules</code>. List any kernel drivers you require for your Ethernet card. If you are using an Intel E1000 card (this is used by VMware and VirtualBox, and so is good for testing), add
You need to add drivers for any Ethernet cards with which you might PXE boot to your initrd. To do this, create {{path|/etc/mkinitfs/features.d/network.modules}}. List any kernel drivers you require for your Ethernet card. If you are using an Intel E1000 card (this is used by VMware and VirtualBox, and so is good for testing), add
   kernel/drivers/net/ethernet/intel/e1000/*.ko
   kernel/drivers/net/ethernet/intel/e1000/*.ko


Line 129: Line 150:
   /etc/mkinitfs/features.d/nfs.modules, containing:
   /etc/mkinitfs/features.d/nfs.modules, containing:
     kernel/fs/nfs/*
     kernel/fs/nfs/*
Finally edit <code>/etc/mkinitfs/mkinitfs.conf</code> and add features '''squasffs, network, dhcp and nfs'''.
Finally edit {{path|/etc/mkinitfs/mkinitfs.conf}} and add features '''squashfs, network, dhcp and nfs'''.


Generate a PXE-capable initrd by running
Generate a PXE-capable initrd by running
  mkinitfs -o /srv/http/prov/pxerd
{{cmd|mkinitfs -o /srv/http/prov/pxerd}}


You should now be able to PXE-boot Alpine Linux. This feature is still in development and non-fatal post-initrd boot errors (regarding modloop, etc.) are to be expected.
You should now be able to PXE-boot Alpine Linux. This feature is still in development and non-fatal post-initrd boot errors (regarding modloop, etc.) are to be expected.


==Specifying an apkovl==
==Specifying an apkovl==
If you wish to specify an apkovl, simply add
  apkovl=http://..../file.apkovl.tar.gz
to the kernel arguments. {MAC} and {UUID} in this parameter will be substituted with the MAC address of the boot interface and the machine UUID respectively. If you use these parameters, ensure you place the URL in quotes.


You can also use ovl_dev= if you want to obtain an apkovl from a device. Use either apkovl or ovl_dev, not both.
The location of the .apkovl to load can be specified using the kernel parameters `apkovl`. (Full definitions above.)
 
For example, to have the apkovl loaded from the device sda5 add to the kernel arguments:
apkovl=sda5
 
Or, to load a specific apkovl from a HTTP server:
  apkovl=<nowiki>http://example.net/file.apkovl.tar.gz</nowiki>
 
All string occurences of {MAC} and {UUID} in this parameter will be substituted with the MAC address of the boot interface and the machine UUID respectively. If you use these strings, ensure you place the URL in quotes.
 
==A note about UEFI==
If you are booting a uefi system you will need to append initrd=initrdname to the kernel options to boot correctly.
 
[[Category:Booting]]

Latest revision as of 02:12, 4 September 2023

This material is obsolete ...

These directions were written for an ancient version of Alpine that still had grsecurity, please update. (Discuss)

This functionality is still largely prototypal. Some things could still be broken.

Guide to options

ip
Required for PXE.
Set ip=dhcp to get an IP via DHCP. (Requires af_packet.ko in the initrd, in addition to the modules needed for your NIC.)
Set ip=client-ip::gateway-ip:netmask::[device]: to specify an IP manually. device is a device name (e.g. eth0). If one is not specified, one is chosen automatically.
apkovl
Valid forms include:
  • An HTTP, HTTPS or FTP URL to an apkovl.tar.gz file which will be retrieved and applied.
  • device_name[:fs_type]:path, where device_name does not include /dev (e.g., sda). fs_type is optional (e.g. ext4). path expresses the path on the device to the apkovl.tar.gz file.
  • A relative path, interpreted relative to the root of the alpine_dev.
  • If not specified, a file matching *.apkovl.tar.gz is searched for in the root of the ovl_dev. (If more than one exists in the root of a device, all are ignored.)
alpine_dev (this parameter is no longer used)
The alpine_dev specifies a device used for reference data which must reside on a filesystem; currently, this is only the case for kernel modules.
This is also used to obtain APKs if a repository is not explicitly specified; see below.
Valid forms include:
  • A device name, not including /dev/.
  • UUID=filesystem-uuid
  • LABEL=filesystem-label
  • nfs:ip-address:path, specifying an NFS export to use as the device. You may need to add modules to the initrd.
ovl_dev (this parameter is no longer used)
Valid forms include:
  • device_name[:fs_type]
  • If not specified, various devices are searched for a file matching *.apkovl.tar.gz in the root directory.
This argument can contain the fields {MAC} and {UUID}, which will be substituted with the MAC address of the NIC used by Alpine and the system's DMI "Product UUID" respectively. If these substitutions are used, the value passed to ovl_dev must be enclosed in quotes. e.g. ovl_dev="http://.../{MAC}.apkovl.tar.gz".
alpine_repo
Required.
/etc/apk/repositories will be filled from this. May be a URL. Otherwise, try and find a directory containing the marker file .boot_repository on the alpine_dev. Please note that although "auto" might appear documented as a valid value, it will not work when PXE booting.
modloop
If the specified file protocol is http/ftp or https (if wget is installed), the modloop file will be downloaded to the /lib directory and will be mounted afterwards
e.g. modloop=http://192.168.1.1/pxe/alpine/grsec.modloop.squashfs in the append section of your bootloader
console
Examples:
  • tty0
  • ttyS1
  • ttyAMA0
acpi
Valid forms include:
  • force
ssh_key
Valid forms include:
  • An HTTP, HTTPS or FTP URL to a public SSH key which will be retrieved and added to the list of authorized SSH keys.
modules

HOWTO

Alpine can be PXE booted starting with Alpine 2.6-rc2. In order to accomplish this you must complete the following steps:

  • Set up a DHCP server and configure it to support PXE boot.
  • Set up a TFTP server to serve the PXE bootloader.
  • Set up an HTTP server to serve the rest of the boot files.
  • Set up an NFS server from which Alpine can load kernel modules.
  • Configure mkinitfs to generate a PXE-bootable initrd.

This article describes a setup using gpxe as a PXE bootloader, but you could also use PXELINUX.

Standard setup of all involved services is not covered here; advice on setting up basic DHCP/TFTP/HTTP/NFS/etc. is widely available.

Set up a DHCP server and configure it to support PXE boot

If you use the ISC DHCP server (package "dhcp"), amend your subnet block like so:

 next-server 10.0.0.1;
 filename "gpxe.kpxe";

Set up a TFTP server to serve the PXE bootloader

Install a TFTP server (package "tftp-hpa"). You will need to place a gPXE image at /var/tftproot/gpxe.kpxe. You can generate an image online at ROM-o-matic.eu[Dead Link]. Select the ".kpxe" output format and the "undionly" driver. You will need to specify a custom boot script. Select "Customize". The following boot script works well:

 dhcp net0
 chain http://${net0/next-server}/gpxe-script

You can include ${net0/mac} and ${uuid} in the URL for the interface MAC address and machine UUID respectively.

Note that as of writing, ROM-o-matic appears to produce a buggy image unless it is used with the "undionly" driver. If you require a different driver, consider building gPXE yourself, especially if you experience inexplicable connectivity issues. Common symptoms are a seemingly correctly configured, randomly functional network connection which appears to suffer from extreme packet loss.

Set up an HTTP server to serve the rest of the PXE boot files

Suppose you have an HTTP server configured to serve from /srv/http. Place an appropriate gPXE script, such as the following, at /srv/http/prov/gpxe-script:

 #!gpxe
 kernel http://${net0/next-server}/prov/grsec ip=dhcp alpine_dev=nfs:${net0/next-server}:/srv/nfs/depot alpine_repo=http://nl.alpinelinux.org/alpine/v2.5/main/
 initrd http://${net0/next-server}/prov/pxerd
 boot

ip=dhcp instructs the initrd to obtain an IP via DHCP. The NFS share specified by alpine_dev will be mounted. alpine_repo specifies an apk repository to use.

Using lpxelinux instead of gPXE

Since recent version of syslinux, pxelinux also has support to boot over ftp/http.
The pxelinux.cfg/default file (or specific MAC address file name) should be in the same format as with regular syslinux.
You will need to use a copy of the lpxelinux.0 found when installing syslinux on alpine: /usr/share/syslinux/lpxelinux.0 and copy it to your tftp server.
Don't forget to also copy ldlinux.c32, as its a dependency of syslinux variants (see documentation).

DEFAULT alpine
LINUX http://ipaddr/grsec
INITRD http://ipaddr/grsec.gz
APPEND ip=dhcp modules=loop,squashfs,sd-mod,usb-storage alpine_repo=http://repo-url modloop=http://ipaddr/grsec.modloop.squashfs apkovl=http://ipaddr/localhost.apkovl.tar.gz

Using pxelinux instead of gPXE

Since recent version of syslinux, pxelinux also has support to boot over tftp.
The pxelinux.cfg/default file (or specific MAC address file name) should be in the same format as with regular syslinux.
You will need to use a copy of the pxelinux.0 found when installing syslinux on alpine: /usr/share/syslinux/pxelinux.0 and copy it to your tftp server.
Don't forget to also copy ldlinux.c32, as its a dependency of syslinux variants (see documentation).

PROMPT 0
TIMEOUT 3
default alpine
LABEL alpine
LINUX alpine-vmlinuz-grsec
INITRD alpine-pxerd
APPEND ip=dhcp alpine_dev=nfs:192.168.1.1:/srv/boot/alpine modloop=http://192.168.1.1/modloop-grsec nomodeset quiet apkovl=http://192.168.1.1/localhost.apkovl.tar.gz

vmlinuz-grsec is taken from a system running in memory from usb.
pxerd is generated on a system running in memory from usb. With network nfs and virtio_net added.
/srv/boot/alpine is a copy of /media/usb from a system running in memory from usb.
modules=loop,squashfs,sd-mod,usb-storage is not needed as loop and squashfs are hard coded into the init script and we do not use sd nor usb.
modloop=http://ipaddr/grsec.modloop.squashfs does not seems to work. Without neither...(*)
apkovl=http://ipaddr/localhost.apkovl.tar.gz.

(*) about the modloop problem: /etc/init.d/modloop tries to load the file from /media/nfs instead of /media/alpine and starts trying to mount it! (unsuccessfully) A fix to it is (a proposal) see #4015

Set up an NFS server from which Alpine can load kernel modules

NOTE: by adding modloop with http support, this is no need for modules.

Set up an NFS share at /srv/nfs/depot and export it via /etc/exports:

 /srv/nfs/depot  *(ro,no_root_squash,no_subtree_check)

This export does not currently need to contain anything, unless you wish to use it to serve apks, in which case ensure that a file ".boot_repository" is created in the directory containing architecture subdirectories and remove alpine_repo from the kernel arguments. The repository will be autodetected by searching for ".boot_repository". Eventually Alpine will be able to load kernel modules from this export.

Configure mkinitfs to generate a PXE-bootable initrd

Note: There is currently a mkinitfs profile just for networking called: network. Using it will automatically add pxe support and all ethernet drivers to the initramfs.

You need to add drivers for any Ethernet cards with which you might PXE boot to your initrd. To do this, create /etc/mkinitfs/features.d/network.modules. List any kernel drivers you require for your Ethernet card. If you are using an Intel E1000 card (this is used by VMware and VirtualBox, and so is good for testing), add

 kernel/drivers/net/ethernet/intel/e1000/*.ko

You also must create the following files so that the modules and scripts necessary for DHCP and NFS are inserted into the initrd.

 /etc/mkinitfs/features.d/dhcp.files, containing:
   /usr/share/udhcpc/default.script
 /etc/mkinitfs/features.d/dhcp.modules, containing:
   kernel/net/packet/af_packet.ko
 /etc/mkinitfs/features.d/nfs.modules, containing:
   kernel/fs/nfs/*

Finally edit /etc/mkinitfs/mkinitfs.conf and add features squashfs, network, dhcp and nfs.

Generate a PXE-capable initrd by running

mkinitfs -o /srv/http/prov/pxerd

You should now be able to PXE-boot Alpine Linux. This feature is still in development and non-fatal post-initrd boot errors (regarding modloop, etc.) are to be expected.

Specifying an apkovl

The location of the .apkovl to load can be specified using the kernel parameters `apkovl`. (Full definitions above.)

For example, to have the apkovl loaded from the device sda5 add to the kernel arguments:

apkovl=sda5

Or, to load a specific apkovl from a HTTP server:

 apkovl=http://example.net/file.apkovl.tar.gz

All string occurences of {MAC} and {UUID} in this parameter will be substituted with the MAC address of the boot interface and the machine UUID respectively. If you use these strings, ensure you place the URL in quotes.

A note about UEFI

If you are booting a uefi system you will need to append initrd=initrdname to the kernel options to boot correctly.