diff --git a/source/network_boot.rst b/source/network_boot.rst index 7d9efd3b..ec85a99e 100644 --- a/source/network_boot.rst +++ b/source/network_boot.rst @@ -11,9 +11,17 @@ this environment is to automatically install an operating system. The PXE extension known as `iPXE`_\* adds support for additional protocols such as HTTP, iSCIS, :abbr:`AoE (ATA over Ethernet)`, and :abbr:`FCoE (Fiber Channel over Ethernet)`. iPXE can also be used to enable -network-booting computers which lack built-in PXE support. +network booting computers which lack built-in PXE support. -This guide covers how to boot |CL| with iPXE using +Figure 1 depicts the flow of information between a PXE server and a PXE +client that needs to be created for network booting |CL|. + +.. figure:: _static/images/network-boot-flow.png + :alt: PXE information flow + + Figure 1: PXE information flow + +This guide covers how to network boot |CL| with iPXE using :abbr:`NAT (network address translation)`. Prerequisites @@ -28,42 +36,46 @@ made: * Your PXE server and PXE clients are connected to a switch on a private network. * Your PXE server has the secure boot option disabled. +* Your PXE clients have a boot order where the network boot option is + prioritized before the disk boot option. .. note:: The secure boot option must be disabled because the UEFI binaries used to - boot the |CLOSIA| are not signed. + boot |CL| are not signed. -The required computer and network setup are depicted in figure 1. +The required computer and network setup is depicted in figure 2. .. figure:: _static/images/network-boot-setup.png :alt: NAT network topology - Figure 1: NAT network topology + Figure 2: NAT network topology Configuration ============= -The configuration to boot using iPXE has been automated with the -:file:`configure-ipxe.sh` script which ran during the installation of the -`Ister Cloud Init Service`_, thus quickly enabling a bulk provisioning -setup. Before running the configuration script, modify -:file:`parameters.conf` with your specific configurations. - -Figure 2 depicts the information flow enabled by the configuration script. - -.. figure:: _static/images/network-boot-flow.png - :alt: PXE information flow - - Figure 2: PXE information flow +The configuration process to boot using iPXE has been automated with the +:file:`configure-ipxe.sh` script included with +:abbr:`ICIS (Ister Cloud Init Service)`, thus quickly enabling a bulk +provisioning setup. For additional instructions on how to get started with +the script, refer to the guide on the `ICIS GitHub repository`_. #. Define the variables used to parameterize the configuration of an iPXE boot. .. code-block:: console + uwsgi_app_dir=/usr/share/uwsgi + uwsgi_socket_dir=/run/uwsgi + icis_app_name=icis + ipxe_app_name=ipxe + + ipxe_port=50000 + icis_port=60000 + web_root=/var/www - ipxe_root=$web_root/ipxe + ipxe_root=$web_root/$ipxe_app_name + icis_root=$web_root/$icis_app_name tftp_root=/srv/tftp external_iface=eno1 @@ -71,27 +83,21 @@ Figure 2 depicts the information flow enabled by the configuration script. pxe_subnet=192.168.1 pxe_internal_ip=$pxe_subnet.1 pxe_subnet_mask_ip=255.255.255.0 - pxe_subnet_bitmask=24 -#. Add the ``pxe-server`` bundle to your system. This bundle has all the - packages needed run a PXE server. +#. Add the ``pxe-server`` bundle to your system. This bundle has all of the + files needed run a PXE server. .. code-block:: console swupd bundle-add pxe-server -#. Create an iPXE hosting directory. - - .. code-block:: console - - rm -rf $ipxe_root - mkdir -p $ipxe_root - -#. Download the latest network-bootable release of |CL|, and extract the +#. Download the latest network-bootable release of |CL| and extract the files. .. code-block:: console + rm -rf $ipxe_root + mkdir -p $ipxe_root curl -o /tmp/clear-pxe.tar.xz https://download.clearlinux.org/current/clear-$(curl https://download.clearlinux.org/latest)-pxe.tar.xz @@ -105,9 +111,8 @@ Figure 2 depicts the information flow enabled by the configuration script. actual kernel file. #. Create an iPXE boot script. During an iPXE boot, the iPXE boot script - directs the PXE client to the files needed to network-boot the latest - release. Use the names given to the initial ramdisk and kernel - files. + directs the PXE client to the files needed to network boot |CL|. Use the + names previously given to the initial ramdisk and kernel files. .. code-block:: console @@ -121,23 +126,29 @@ Figure 2 depicts the information flow enabled by the configuration script. EOF #. The ``pxe-server`` bundle contains a lightweight web-server known as - ``nginx``. Create a configuration file for ``nginx`` to serve the latest - release to PXE clients. + ``nginx``. Create a configuration file for ``nginx`` to serve |CL| to PXE + clients. .. code-block:: console mkdir -p /etc/nginx - cat > /etc/nginx/nginx.conf << EOF + cat > /etc/nginx/$ipxe_app_name.conf << EOF server { - listen 80; + listen $ipxe_port; server_name localhost; - location / { - root $ipxe_root; + location /$ipxe_app_name/ { + root $web_root; autoindex on; } } EOF + .. note:: + + Creating a separate configuration file for ``nginx`` to serve network- + bootable images on a non-standard port number preserves existing nginx + configurations. + #. Start ``nginx`` and enable startup on boot. .. code-block:: console @@ -145,45 +156,9 @@ Figure 2 depicts the information flow enabled by the configuration script. systemctl start nginx systemctl enable nginx -#. The ``pxe-server`` bundle contains iPXE firmware images which allow - computers without an iPXE implementation to perform an iPXE boot. Create a - TFTP hosting directory and populate it with the iPXE firmware images. - - .. code-block:: console - - rm -rf $tftp_root - mkdir -p $tftp_root - ln -sf /usr/share/ipxe/ipxe-x86_64.efi $tftp_root/ipxe-x86_64.efi - ln -sf /usr/share/ipxe/undionly.kpxe $tftp_root/undionly.kpxe - -#. The ``pxe-server`` bundle contains a lightweight TFTP server known as - ``dnsmasq``. Create a configuration file for ``dnsmasq`` to serve iPXE - firmware images to PXE clients over TFTP. - - .. code-block:: console - - cat > /etc/dnsmasq.conf << EOF - enable-tftp - tftp-root=$tftp_root - EOF - -#. Enable ``dnsmasq`` to start automatically on boot. - - .. code-block:: console - - systemctl enable dnsmasq - - .. note:: - - At this point in the configuration process, ``dnsmasq`` is only being - enabled to start automatically on boot but it is not started because - its DNS server conflicts with the DNS stub listener of - ``systemd-resolved``. - -#. Set ``dnsmasq`` to listen on a dedicated IP address. PXE clients on the - private network will use this IP address for DNS resolution. Disable - the DNS stub listener included with ``systemd-resolved`` to avoid a - conflict with the ``dnsmasq`` DNS server. +#. The ``pxe-server`` bundle contains a lightweight DNS server which + conflicts with the DNS stub listener provided by ``systemd-resolved``. + Disable the DNS stub listener and temporarily stop ``systemd-resolved``. .. code-block:: console @@ -193,47 +168,15 @@ Figure 2 depicts the information flow enabled by the configuration script. DNSStubListener=no EOF - cat >> /etc/dnsmasq.conf << EOF - listen-address=$pxe_internal_ip - EOF - - .. note:: - - ``dnsmasq`` is a lightweight implementation of a DNS server, a DHCP - server, and a TFTP server. For the purposes of this guide, the DHCP - server included with ``dnsmasq`` is not being used. - - .. important:: - - Using the ``dnsmasq`` DNS server allows ``systemd-resolved`` to - dynamically update the list of DNS servers for the private network from - the public network. This setup effectively creates a pass-through DNS - server which relies on the DNS servers listed in ``/etc/resolv.conf``. - -#. Start ``dnsmasq`` and avoid conflicts with ``systemd-resolved``. - - .. code-block:: console - systemctl stop systemd-resolved - systemctl restart dnsmasq - systemctl start systemd-resolved -#. Assign a static IP address to the network adapter for the private network. +#. Assign a static IP address to the network adapter for the private network + and restart ``systemd-networkd``. .. code-block:: console mkdir -p /etc/systemd/network - - ln -sf /dev/null /etc/systemd/network/80-dhcp.network - - cat > /etc/systemd/network/80-external-dynamic.network << EOF - [Match] - Name=$external_iface - [Network] - DHCP=yes - EOF - - cat > /etc/systemd/network/80-internal-static.network << EOF + cat > /etc/systemd/network/70-internal-static.network << EOF [Match] Name=$internal_iface [Network] @@ -241,138 +184,11 @@ Figure 2 depicts the information flow enabled by the configuration script. Address=$pxe_internal_ip/$pxe_subnet_bitmask EOF - systemctl restart systemd-networkd - - .. note:: - - By default, ``systemd-networkd`` uses DHCP for all network adapters. - This functionality must be disabled prior to assigning a static IP - address. Consequently, DHCP functionality for the network adapter - connected to the public network is also disabled. Thus, this functionality must be explicitly re-enabled for the network adapter. - -#. The ``pxe-server`` bundle contains a full DHCP server implementation - compliant with the specifications defined by the - :abbr:`ISC (Internet Systems Consortium)` known as ``dhcpd``. Configure - ``dhcpd`` to dynamically allocate IP addresses to PXE clients on the - private network. - - .. code-block:: console - - cat > /etc/dhcpd.conf << EOF - option space ipxe; - option ipxe-encap-opts code 175 = encapsulate ipxe; - option ipxe.priority code 1 = signed integer 8; - option ipxe.keep-san code 8 = unsigned integer 8; - option ipxe.skip-san-boot code 9 = unsigned integer 8; - option ipxe.syslogs code 85 = string; - option ipxe.cert code 91 = string; - option ipxe.privkey code 92 = string; - option ipxe.crosscert code 93 = string; - option ipxe.no-pxedhcp code 176 = unsigned integer 8; - option ipxe.bus-id code 177 = string; - option ipxe.bios-drive code 189 = unsigned integer 8; - option ipxe.username code 190 = string; - option ipxe.password code 191 = string; - option ipxe.reverse-username code 192 = string; - option ipxe.reverse-password code 193 = string; - option ipxe.version code 235 = string; - option iscsi-initiator-iqn code 203 = string; - option ipxe.pxeext code 16 = unsigned integer 8; - option ipxe.iscsi code 17 = unsigned integer 8; - option ipxe.aoe code 18 = unsigned integer 8; - option ipxe.http code 19 = unsigned integer 8; - option ipxe.https code 20 = unsigned integer 8; - option ipxe.tftp code 21 = unsigned integer 8; - option ipxe.ftp code 22 = unsigned integer 8; - option ipxe.dns code 23 = unsigned integer 8; - option ipxe.bzimage code 24 = unsigned integer 8; - option ipxe.multiboot code 25 = unsigned integer 8; - option ipxe.slam code 26 = unsigned integer 8; - option ipxe.srp code 27 = unsigned integer 8; - option ipxe.nbi code 32 = unsigned integer 8; - option ipxe.pxe code 33 = unsigned integer 8; - option ipxe.elf code 34 = unsigned integer 8; - option ipxe.comboot code 35 = unsigned integer 8; - option ipxe.efi code 36 = unsigned integer 8; - option ipxe.fcoe code 37 = unsigned integer 8; - option ipxe.vlan code 38 = unsigned integer 8; - option ipxe.menu code 39 = unsigned integer 8; - option ipxe.sdi code 40 = unsigned integer 8; - option ipxe.nfs code 41 = unsigned integer 8; - - class "PXE-Chainload" { - match if substring(option vendor-class-identifier, 0, 9) = "PXEClient"; - - next-server $pxe_internal_ip; - if exists user-class and option user-class = "iPXE" { - filename "http://$pxe_internal_ip/ipxe_boot_script.txt"; - } - elsif substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00007" or substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00008" or substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00009" { - filename "ipxe-x86_64.efi"; - } - elsif substring(option vendor-class-identifier, 0, 20) = "PXEClient:Arch:00000" { - filename "undionly.kpxe"; - } - } - - subnet $pxe_subnet.0 netmask $pxe_subnet_mask_ip { - authoritative; - option routers $pxe_internal_ip; - option domain-name-servers $pxe_internal_ip; - - pool { - allow members of "PXE-Chainload"; - range $pxe_subnet.128 $pxe_subnet.253; - default-lease-time 600; - max-lease-time 3600; - } - - pool { - deny members of "PXE-Chainload"; - range $pxe_subnet.2 $pxe_subnet.127; - default-lease-time 3600; - max-lease-time 21600; - } - } - EOF - - This configuration provides the following important functions: - - * Enables ``dhcpd`` to be iPXE-aware with `iPXE-specific options`_. - * Directs PXE clients without an iPXE implementation to the TFTP server - for acquiring architecture-specific iPXE firmware images to allow them - to perform an iPXE boot. - * Is only active on the network adapter which has an IP address on the - defined subnet. - * Directs PXE clients to the DNS server. - * Directs PXE clients to the PXE server for routing via NAT. - * Divides the private network into two pools of IP addresses, one for - network booting and another for usage after boot; each with their own - lease times. - - .. important:: - - There are three providers of a DHCP server on the system at this point: - ``systemd-networkd``, ``dnsmasq``, and ``dhcpd``. ``dhcpd`` is used - because it is maintained by ISC and is more flexible for iPXE booting. - -#. Create a file where ``dhcpd`` can record the IP addresses it hands - out to PXE clients. - - .. code-block:: console - - mkdir -p /var/db - touch /var/db/dhcpd.leases - -#. Start ``dhcpd`` and enable startup on boot. - - .. code-block:: console - - systemctl enable dhcp4 - systemctl restart dhcp4 + systemctl restart systemd-networkd #. Configure NAT to route traffic from the private network to the public - network, effectively turning the PXE server into a router. + network, effectively turning the PXE server into a router. To keep these + changes in spite of reboots, save the changes to the firewall. .. code-block:: console @@ -389,7 +205,7 @@ Figure 2 depicts the information flow enabled by the configuration script. coming from the PXE server. Thus, it hides the PXE clients from the public network. -#. Tell the Linux kernel to forward network packets on to different +#. Tell the kernel to forward network packets on to different interfaces. Otherwise, NAT will not work. .. code-block:: console @@ -398,17 +214,107 @@ Figure 2 depicts the information flow enabled by the configuration script. echo net.ipv4.ip_forward=1 > /etc/sysctl.d/80-nat-forwarding.conf echo 1 > /proc/sys/net/ipv4/ip_forward -#. Power on the PXE client and watch it boot the latest release of the - |CLOSIA| +#. The ``pxe-server`` bundle contains iPXE firmware images which allow + computers without an iPXE implementation to perform an iPXE boot. Create a + TFTP hosting directory and populate it with the iPXE firmware images. -Congratulations you have successfully installed and configured PXE network-booting for |CL|. + .. code-block:: console + + rm -rf $tftp_root + mkdir -p $tftp_root + ln -sf /usr/share/ipxe/undionly.kpxe $tftp_root/undionly.kpxe + +#. The ``pxe-server`` bundle contains a lightweight TFTP, DNS, and DHCP + server known as ``dnsmasq``. Create a configuration file for ``dnsmasq`` + to listen on a dedicated IP address for those functions. PXE clients on + the private network will use this IP address to access those functions. + + .. code-block:: console + + cat > /etc/dnsmasq.conf << EOF + listen-address=$pxe_internal_ip + EOF + +#. Add the options to serve iPXE firmware images to PXE clients over TFTP to + the ``dnsmasq`` configuration file. + + .. code-block:: console + + cat >> /etc/dnsmasq.conf << EOF + enable-tftp + tftp-root=$tftp_root + EOF + +#. Add the options to host a DHCP server for PXE clients to the ``dnsmasq`` + configuration file. + + .. code-block:: console + + cat >> /etc/dnsmasq.conf << EOF + dhcp-leasefile=/var/db/dnsmasq.leases + + dhcp-authoritative + dhcp-option=option:router,$pxe_internal_ip + dhcp-option=option:dns-server,$pxe_internal_ip + + dhcp-match=set:pxeclient,60,PXEClient* + dhcp-range=tag:pxeclient,$pxe_subnet.2,$pxe_subnet.253,$pxe_subnet_mask_ip,15m + dhcp-range=tag:!pxeclient,$pxe_subnet.2,$pxe_subnet.253,$pxe_subnet_mask_ip,6h + + dhcp-match=set:ipxeboot,175 + dhcp-boot=tag:ipxeboot,http://$pxe_internal_ip:$ipxe_port/$ipxe_app_name/ipxe_boot_script.txt + dhcp-boot=tag:!ipxeboot,undionly.kpxe,$pxe_internal_ip + EOF + + This configuration provides the following important functions: + + * Directs PXE clients without an iPXE implementation to the TFTP server + for acquiring architecture-specific iPXE firmware images to allow them + to perform an iPXE boot. + * Activates only on the network adapter which has an IP address on the + defined subnet. + * Directs PXE clients to the DNS server. + * Directs PXE clients to the PXE server for routing via NAT. + * Divides the private network into two pools of IP addresses, one for + network booting and another for usage after boot, each with their own + lease times. + +#. Create a file where ``dnsmasq`` can record the IP addresses it hands + out to PXE clients. + + .. code-block:: console + + mkdir -p /var/db + touch /var/db/dnsmasq.leases + +#. Start ``dnsmasq`` and enable startup on boot. + + .. code-block:: console + + systemctl enable dnsmasq + systemctl restart dnsmasq + +#. Start ``systemd-resolved``. + + .. code-block:: console + + systemctl start systemd-resolved + + .. important:: + + Using the ``dnsmasq`` DNS server allows ``systemd-resolved`` to + dynamically update the list of DNS servers for the private network from + the public network. This setup effectively creates a pass-through DNS + server which relies on the DNS servers listed in ``/etc/resolv.conf``. + +#. Power on the PXE client and watch it boot |CL|. + +**Congratulations!** You have successfully installed and configured a PXE +server that can network boot PXE clients with |CL|. .. _iPXE: http://ipxe.org/ -.. _Ister Cloud Init Service: +.. _ICIS GitHub repository: https://github.com/clearlinux/ister-cloud-init-svc - -.. _iPXE-specific options: - http://www.ipxe.org/howto/dhcpd#ipxe-specific_options