Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | .. Copyright (c) 2018 Heinrich Schuchardt |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 3 | |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 4 | iSCSI booting with U-Boot and iPXE |
| 5 | ================================== |
| 6 | |
| 7 | Motivation |
| 8 | ---------- |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 9 | |
| 10 | U-Boot has only a reduced set of supported network protocols. The focus for |
| 11 | network booting has been on UDP based protocols. A TCP stack and HTTP support |
| 12 | are expected to be integrated in 2018 together with a wget command. |
| 13 | |
| 14 | For booting a diskless computer this leaves us with BOOTP or DHCP to get the |
| 15 | address of a boot script. TFTP or NFS can be used to load the boot script, the |
| 16 | operating system kernel and the initial file system (initrd). |
| 17 | |
| 18 | These protocols are insecure. The client cannot validate the authenticity |
| 19 | of the contacted servers. And the server cannot verify the identity of the |
| 20 | client. |
| 21 | |
| 22 | Furthermore the services providing the operating system loader or kernel are |
| 23 | not the ones that the operating system typically will use. Especially in a SAN |
| 24 | environment this makes updating the operating system a hassle. After installing |
| 25 | a new kernel version the boot files have to be copied to the TFTP server |
| 26 | directory. |
| 27 | |
| 28 | The HTTPS protocol provides certificate based validation of servers. Sensitive |
| 29 | data like passwords can be securely transmitted. |
| 30 | |
| 31 | The iSCSI protocol is used for connecting storage attached networks. It |
| 32 | provides mutual authentication using the CHAP protocol. It typically runs on |
| 33 | a TCP transport. |
| 34 | |
| 35 | Thus a better solution than DHCP/TFTP/NFS boot would be to load a boot script |
| 36 | via HTTPS and to download any other files needed for booting via iSCSI from the |
| 37 | same target where the operating system is installed. |
| 38 | |
| 39 | An alternative to implementing these protocols in U-Boot is to use an existing |
Heinrich Schuchardt | 76a472d | 2018-07-29 13:50:50 +0200 | [diff] [blame] | 40 | software that can run on top of U-Boot. iPXE[1] is the "swiss army knife" of |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 41 | network booting. It supports both HTTPS and iSCSI. It has a scripting engine for |
| 42 | fine grained control of the boot process and can provide a command shell. |
| 43 | |
| 44 | iPXE can be built as an EFI application (named snp.efi) which can be loaded and |
| 45 | run by U-Boot. |
| 46 | |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 47 | Boot sequence |
| 48 | ------------- |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 49 | |
| 50 | U-Boot loads the EFI application iPXE snp.efi using the bootefi command. This |
| 51 | application has network access via the simple network protocol offered by |
| 52 | U-Boot. |
| 53 | |
| 54 | iPXE executes its internal script. This script may optionally chain load a |
| 55 | secondary boot script via HTTPS or open a shell. |
| 56 | |
| 57 | For the further boot process iPXE connects to the iSCSI server. This includes |
| 58 | the mutual authentication using the CHAP protocol. After the authentication iPXE |
| 59 | has access to the iSCSI targets. |
| 60 | |
| 61 | For a selected iSCSI target iPXE sets up a handle with the block IO protocol. It |
| 62 | uses the ConnectController boot service of U-Boot to request U-Boot to connect a |
| 63 | file system driver. U-Boot reads from the iSCSI drive via the block IO protocol |
| 64 | offered by iPXE. It creates the partition handles and installs the simple file |
Heinrich Schuchardt | 76a472d | 2018-07-29 13:50:50 +0200 | [diff] [blame] | 65 | protocol. Now iPXE can call the simple file protocol to load GRUB[2]. U-Boot |
| 66 | uses the block IO protocol offered by iPXE to fulfill the request. |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 67 | |
Heinrich Schuchardt | 76a472d | 2018-07-29 13:50:50 +0200 | [diff] [blame] | 68 | Once GRUB is started it uses the same block IO protocol to load Linux. Via |
| 69 | the EFI stub Linux is called as an EFI application:: |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 70 | |
Heinrich Schuchardt | 76a472d | 2018-07-29 13:50:50 +0200 | [diff] [blame] | 71 | +--------+ +--------+ |
| 72 | | | Runs | | |
| 73 | | U-Boot |========>| iPXE | |
| 74 | | EFI | | snp.efi| |
| 75 | +--------+ | | DHCP | | |
| 76 | | |<===|********|<========| | |
| 77 | | DHCP | | | Get IP | | |
| 78 | | Server | | | Address | | |
| 79 | | |===>|********|========>| | |
| 80 | +--------+ | | Response| | |
| 81 | | | | | |
| 82 | | | | | |
| 83 | +--------+ | | HTTPS | | |
| 84 | | |<===|********|<========| | |
| 85 | | HTTPS | | | Load | | |
| 86 | | Server | | | Script | | |
| 87 | | |===>|********|========>| | |
| 88 | +--------+ | | | | |
| 89 | | | | | |
| 90 | | | | | |
| 91 | +--------+ | | iSCSI | | |
| 92 | | |<===|********|<========| | |
| 93 | | iSCSI | | | Auth | | |
| 94 | | Server |===>|********|========>| | |
| 95 | | | | | | | |
| 96 | | | | | Loads | | |
| 97 | | |<===|********|<========| | +--------+ |
| 98 | | | | | GRUB | | Runs | | |
| 99 | | |===>|********|========>| |======>| GRUB | |
| 100 | | | | | | | | | |
| 101 | | | | | | | | | |
| 102 | | | | | | | Loads | | |
| 103 | | |<===|********|<========|********|<======| | +--------+ |
| 104 | | | | | | | Linux | | Runs | | |
| 105 | | |===>|********|========>|********|======>| |=====>| Linux | |
| 106 | | | | | | | | | | | |
| 107 | +--------+ +--------+ +--------+ +--------+ | | |
| 108 | | | |
| 109 | | | |
| 110 | | ~ ~ ~ ~| |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 111 | |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 112 | Security |
| 113 | -------- |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 114 | |
| 115 | The iSCSI protocol is not encrypted. The traffic could be secured using IPsec |
| 116 | but neither U-Boot nor iPXE does support this. So we should at least separate |
| 117 | the iSCSI traffic from all other network traffic. This can be achieved using a |
| 118 | virtual local area network (VLAN). |
| 119 | |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 120 | Configuration |
| 121 | ------------- |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 122 | |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 123 | iPXE |
| 124 | ~~~~ |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 125 | |
Heinrich Schuchardt | 76a472d | 2018-07-29 13:50:50 +0200 | [diff] [blame] | 126 | For running iPXE on arm64 the bin-arm64-efi/snp.efi build target is needed:: |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 127 | |
| 128 | git clone http://git.ipxe.org/ipxe.git |
| 129 | cd ipxe/src |
| 130 | make bin-arm64-efi/snp.efi -j6 EMBED=myscript.ipxe |
| 131 | |
| 132 | The available commands for the boot script are documented at: |
| 133 | |
| 134 | http://ipxe.org/cmd |
| 135 | |
| 136 | Credentials are managed as environment variables. These are described here: |
| 137 | |
| 138 | http://ipxe.org/cfg |
| 139 | |
| 140 | iPXE by default will put the CPU to rest when waiting for input. U-Boot does |
| 141 | not wake it up due to missing interrupt support. To avoid this behavior create |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 142 | file src/config/local/nap.h: |
| 143 | |
| 144 | .. code-block:: c |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 145 | |
| 146 | /* nap.h */ |
| 147 | #undef NAP_EFIX86 |
| 148 | #undef NAP_EFIARM |
| 149 | #define NAP_NULL |
| 150 | |
| 151 | The supported commands in iPXE are controlled by an include, too. Putting the |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 152 | following into src/config/local/general.h is sufficient for most use cases: |
| 153 | |
| 154 | .. code-block:: c |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 155 | |
| 156 | /* general.h */ |
| 157 | #define NSLOOKUP_CMD /* Name resolution command */ |
| 158 | #define PING_CMD /* Ping command */ |
| 159 | #define NTP_CMD /* NTP commands */ |
| 160 | #define VLAN_CMD /* VLAN commands */ |
| 161 | #define IMAGE_EFI /* EFI image support */ |
| 162 | #define DOWNLOAD_PROTO_HTTPS /* Secure Hypertext Transfer Protocol */ |
| 163 | #define DOWNLOAD_PROTO_FTP /* File Transfer Protocol */ |
| 164 | #define DOWNLOAD_PROTO_NFS /* Network File System Protocol */ |
| 165 | #define DOWNLOAD_PROTO_FILE /* Local file system access */ |
| 166 | |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 167 | Open-iSCSI |
| 168 | ~~~~~~~~~~ |
Heinrich Schuchardt | b989648 | 2018-12-01 10:07:10 +0100 | [diff] [blame] | 169 | |
| 170 | When the root file system is on an iSCSI drive you should disable pings and set |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 171 | the replacement timer to a high value in the configuration file [3]:: |
Heinrich Schuchardt | b989648 | 2018-12-01 10:07:10 +0100 | [diff] [blame] | 172 | |
| 173 | node.conn[0].timeo.noop_out_interval = 0 |
| 174 | node.conn[0].timeo.noop_out_timeout = 0 |
| 175 | node.session.timeo.replacement_timeout = 86400 |
| 176 | |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 177 | Links |
| 178 | ----- |
Heinrich Schuchardt | 29a8a28 | 2018-01-28 15:26:02 +0100 | [diff] [blame] | 179 | |
Heinrich Schuchardt | 73d95c2 | 2019-07-26 06:46:08 +0200 | [diff] [blame] | 180 | * [1] https://ipxe.org - iPXE open source boot firmware |
| 181 | * [2] https://www.gnu.org/software/grub/ - |
| 182 | GNU GRUB (Grand Unified Bootloader) |
| 183 | * [3] https://github.com/open-iscsi/open-iscsi/blob/master/README - |
| 184 | Open-iSCSI README |