Safer netboot: Difference between revisions
m (→ROM flashen) |
m (→ROM flashen) |
||
Line 107: | Line 107: | ||
==== ROM flashen ==== |
==== ROM flashen ==== |
||
Um das Image auf physische Hardware zu bringen, muss der ROM-Speicher der Netzwerkkarte geflasht werden. Das kann mit den openSource Werkzeug flashrom getan werden. Es bietet sich an, dies unter einem Livesystem (wir haben [https://grml.org/ Grml] verwendet) zu tun. Dabei stellte sich heraus, dass Root-Rechte (wie zu erwarten) aber zusätzlich auch beim Booten der Kernelparameter <code> iomem=relaxed </code> erforderlich sind. |
Um das Image auf physische Hardware zu bringen, muss der ROM-Speicher der Netzwerkkarte geflasht werden. Das kann mit den openSource Werkzeug flashrom getan werden. Es bietet sich an, dies unter einem Livesystem (wir haben [https://grml.org/ Grml] verwendet) zu tun. Dabei stellte sich heraus, dass Root-Rechte (wie zu erwarten) aber zusätzlich auch beim Booten der Kernelparameter <code> iomem=relaxed </code> erforderlich sind. |
||
Wenn mit |
|||
<source lang=bash highlight=" |
<source lang=bash highlight="1"> |
||
lspci -nn | grep Ethernet |
lspci -nn | grep Ethernet |
||
05:04.0 Ethernet controller [0200]: Intel Corporation 82541PI Gigabit Ethernet Controller [8086:107c] (rev 05) |
05:04.0 Ethernet controller [0200]: Intel Corporation 82541PI Gigabit Ethernet Controller [8086:107c] (rev 05) |
||
</source> |
</source> |
||
herrausgefunden wurde, an welcher pci-Adresse (hier <code>05:04.0</code>) die Netzwerkkarte zu finden ist und welcher Programmer (in unserem Beispiel <code> nicintel_spi</code>)verwendet werden muss (letzteres verrät das flashrom Wiki im Abschnitt [https://www.flashrom.org/Supported_hardware "supported hardware"] beim Suchen nach <code>8086:107c</code>), kann man damit loslegen, die "Flasbarkeit" zu testen: |
herrausgefunden wurde, an welcher pci-Adresse (hier <code>05:04.0</code>) die Netzwerkkarte zu finden ist und welcher Programmer (in unserem Beispiel <code> nicintel_spi</code>)verwendet werden muss (letzteres verrät das flashrom Wiki im Abschnitt [https://www.flashrom.org/Supported_hardware "supported hardware"] beim Suchen nach <code>8086:107c</code>), kann man damit loslegen, die "Flasbarkeit" zu testen: |
||
<source lang=bash highlight=" |
<source lang=bash highlight="1"> |
||
flashrom -p nicintel_spi:pci=05:04.0 |
flashrom -p nicintel_spi:pci=05:04.0 |
||
flashrom v0.9.9-r1954 on Linux 4.19.0-1-grml-amd64 (x86_64) |
flashrom v0.9.9-r1954 on Linux 4.19.0-1-grml-amd64 (x86_64) |
||
Line 124: | Line 125: | ||
Please specify which chip definition to use with the -c <chipname> option. |
Please specify which chip definition to use with the -c <chipname> option. |
||
</source> |
</source> |
||
Auf der verwendeten Netzwerkkarte stehen offenbar zwei Chips zum flashen zur Auswahl, da unser iPXE-Image größer als 64kB ist, entscheiden wir uns für den weiten Chip und erstellen sicherheitshalber ein Backup (was natürlich anschließend extern des Live-Syystems GRML persistent gespeichert werden sollte): |
|||
Mit der folgenden Zeile wir ein Backup des aktuellen Flash gemacht: |
|||
<source lang=bash highlight="1"> |
|||
flashrom -p nicintel_spi:pci=05:04.0 -c "AT25F1024(A)" -r backup"AT25F1024(A)".rom |
|||
flashrom v0.9.9-r1954 on Linux 4.19.0-1-grml-amd64 (x86_64) |
|||
flashrom is free software, get the source code at https://flashrom.org |
|||
Calibrating delay loop... OK. |
|||
Found Atmel flash chip "AT25F1024(A)" (128 kB, SPI) on nicintel_spi. |
|||
Reading flash... done. |
|||
flashrom -p nicintel_spi:pci=05:04.0 -c "AT25F1024(A)" -r 7,28s user 0,00s system 99% cpu 7,285 total |
|||
</source> |
|||
Die Option <code>-c</code> gibt an, welcher Chip verwendet werden soll, wenn die Netzwerkkarte bzw. flashrom beim Probing mehrere Chips entdeckt. |
Die Option <code>-c</code> gibt an, welcher Chip verwendet werden soll, wenn die Netzwerkkarte bzw. flashrom beim Probing mehrere Chips entdeckt. |
||
Bevor das Image geflasht werden kann, muss das Image auf die Größe des Chips (hier 128kB) gepaddet werden. Das kann mit dem folgenden Kommando erledigt werden: |
Bevor das Image geflasht werden kann, muss das Image auf die Größe des Chips (hier 128kB) gepaddet werden. Das kann mit dem folgenden Kommando erledigt werden: |
||
<source lang=bash highlight="1"> |
|||
(cat bin/8086107c.rom; tr '\0' '\377' < /dev/zero) | dd bs=1 count=128k of=netBootCA/8086107c.rom_padded_128k |
|||
</source> |
|||
Dann kann das gepaddete Image geflasht werden: |
Dann kann das gepaddete Image geflasht werden: |
||
<source lang=bash highlight="1"> |
|||
flashrom -p nicintel_spi:pci=05:04.0 -c "AT25F1024(A)" -w 8086107c.rom_padded_128k |
|||
flashrom v0.9.9-r1954 on Linux 4.19.0-1-grml-amd64 (x86_64) |
|||
flashrom is free software, get the source code at https://flashrom.org |
|||
Calibrating delay loop... OK. |
|||
Found Atmel flash chip "AT25F1024(A)" (128 kB, SPI) on nicintel_spi. |
|||
Reading old flash chip contents... done. |
|||
Erasing and writing flash chip... Erase/write done. |
|||
Verifying flash... VERIFIED. |
|||
flashrom -p nicintel_spi:pci=05:04.0 -c "AT25F1024(A)" -w 25,76s user 0,00s system 99% cpu 25,765 total |
|||
</source> |
|||
Damit kann man nun über HTTPS mit Clientauthetisierung booten. |
Damit kann man nun über HTTPS mit Clientauthetisierung booten. |
Revision as of 12:52, 5 November 2019
Wenn eine Vielzahl von Clientrechnern vorhanden sind, die es zum Beipiel neu zu installieren gilt, dann bietet sich die Installation über Netboot - vorrangig über PXE - an. In der einfachen Umsetzung besteht die Infrastruktur, die nötig für den Netboot ist, aus einem DHCP-Server, der die nötige IP-Konfiguration bereitstellt, und den TFTP-Server, der die Files für den nächsten Bootstage bereit stellt. Wenn ein Client nun über sein PXE-Boot-ROM, welches auf der Netzwerkkarte oder direkt im BIOS, bei internen Netzwerkarten, gespeichert ist, bootet, sucht er nach einer gültigen Konfiguration für das Netzwerk. Daraufhin lädt er vom vom DHCP-Server angekündigten TFTP-Server nötige Komponenten für den nächsten Boot-Stage. Dies sind zum Beispiel Kernel und initrd. Das Problem an dieser Stelle ist das folgende: Die Kommunikation zwichen den Servern und dem Client, insbesondere zwischen TFTP-Server und Client sind unverschlüsselt. Das schreit praktisch schon nach einem Man-in-the-Middle-Angriff. Außerdem gibt es keine Restriktionen in Bezug darauf, welche Clients berechtigt sind, Daten von dem TFTP-Server herrunter zu laden. Das ist dann kritisch, wenn zum Beispiel in der initrd Schlüssel gespeichert werden, um geschützte Netzlaufwerke zu mounten, die es zu schützen gilt. Im Weiteren wird ein Konzept betrachtet, mit dem diesem Problem begegnet werden soll.
Netboot neu überdacht
Um beide Probleme zu beseitigen, ist eine mögliche Antwort HTTPS. In HTTPS sind bereits passende Lösungen eingebaut: Mit der asymmetrischen Krytographie wird das Verschüsselungsproblem gelöst, woduch keine Man-in-the-Middle-Angriffe mehr möglich sind; gleichzeitg werden in HTTPS auch clientseitig Authentifizierung unterstützt. Das heißt alleinig dadurch, dass das "Transportprotokoll", mit dem die Daten zum Client übertragen werden, geändert wird, werden beide Probeleme gelöst. Aber diese Änderung hat auch Änderung in der Infrastrutur zur Folge. Diese Änderungen werden nachfolgend beschrieben.
"neues PXE"
Da das gewöhnliche PXE-ROM standartmäßig kein HTTP unterstützt, wird hier eine Alternative gebraucht. Hier bietet sich iPXE an. Auf der Projektwebseite sagen die Autoren selbst: ”iPXE is the leading open source network boot firmware." iPXE unterstützt eine Vielzahl an Protokollen wie HTTP(S), iSCSI, FCoE, AoE, wireless und mehr. Weiter ist der Bootvorgang scriptable. Das heißt, man kann iPXE schon vorher sagen, welche Files von wo geladen werden sollen. Das entbindet von der Notwendigkeit, diese Addressen über DHCP zu verteilen. Von großem Vorteil ist, dass iPXE-ROMs auch für physische Hardware gebaut werden können, die auch auf die Chips dieser Hardware geflasht werden kann. Es bietet auch die Möglichkeit des Chainloadings und eines Bootpromps, um den Netboot manuell vor der Maschine zu bedienen.
"neue Public Key Infrastruktur"
Zertifikate
HTTP soll über TLS abgesichert werden. Dafür sind Zertifikate für die Serverseiter (Verschlüsselung) und die Clientseite (Authentifizierung) nötig. Im Folgendem sind die Befehle aufgeführt, die in der Testumgebung zur Erstellung ausgeführt wurden:
RootCA:
openssl req -x509 -newkey rsa:2048 -out ca.crt -keyout ca.key -days 1000
Server:
openssl req -newkey rsa -keyout server.key -out server.req
openssl ca -config ca.cnf -in server.req -out server.crt
Client:
openssl req -newkey rsa -keyout client.key -out client.req
openssl ca -config ca.cnf -in client.req -out client.crt
Die ca.cnf
trägt diesen Inhalt:
[ ca ]
default_ca = ca_default
[ ca_default ]
certificate = ca.crt
private_key = ca.key
serial = ca.srl
database = ca.idx
new_certs_dir = signed
default_md = default
policy = policy_anything
preserve = yes
default_days = 90
unique_subject = no
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = optional
emailAddress = optional
[ cross ]
basicConstraints = critical,CA:true
keyUsage = critical,cRLSign,keyCertSign
[ codesigning ]
keyUsage = digitalSignature
extendedKeyUsage = codeSigning
Webserver
Da der Webserver HTTPS-Anfragen entgegen nehmen soll, bedarf dieser ein kleines an Konfiguration:
<VirtualHost *:443>
SSLEngine on # SSL an
SSLCertificateFile /etc/apache2/server.crt # Serverzertifikat
SSLCertificateKeyFile /etc/apache2/server.key # Serverprivatekey
SSLVerifyClient require # verifiziere Clientzertifikate
SSLVerifyDepth 4 # lass Client mit Zertifikaten bis Tiefe 4 unterhalb ....
SSLCACertificateFile /etc/apache2/ca.crt # dieser CA zu
</VirtualHost>
Weiter müssen die Files für den nächsten Bootstage des Clients bereit liegen.
iPXE-Image
Die Images werden aus den Quellen direkt kompiliert. Anpassungen werden über die Kommandozeile beim Kompilieren mitgeteilt. Für HTTPS ist auch eine Anpassung in bin/general.h
nötig. Die Optionen, die benötigt werden sind, diese:
* script (”EMBED=”)
* Zertifikate (”CERT=”)
* Vertrauen (”TRUST=”)
* privaten SChlüssel (”PRIV=”)
Das beigefügt Script beihnhaltet:
#!ipxe # Shebang
dhcp # Netzwerkkonfiguration über DHCP bekommen
kernel https://192.168.122.2/linux # lade Kernel über HTTPS von URL
initrd https://192.168.122.2/initrd # lade initrd über HTTPS von URL
boot # Bootvorgang
Dann kann das ROM-Image gebaut werden. Mit folgender Zeile wird ein Boot-ROM-Image für eine Intelnetzwerkkarte des Typs 107c gebaut:
make bin/8086107c.rom EMBED=boot.ipxe TRUST=ca.crt CERT=ca.crt,client.crt PRIVKEY=client.key
Der Typ der Karte (VendorID und ProduktID) kann mittels lspci -nn ermittelt werden.
ROM flashen
Um das Image auf physische Hardware zu bringen, muss der ROM-Speicher der Netzwerkkarte geflasht werden. Das kann mit den openSource Werkzeug flashrom getan werden. Es bietet sich an, dies unter einem Livesystem (wir haben Grml verwendet) zu tun. Dabei stellte sich heraus, dass Root-Rechte (wie zu erwarten) aber zusätzlich auch beim Booten der Kernelparameter iomem=relaxed
erforderlich sind.
Wenn mit
lspci -nn | grep Ethernet
05:04.0 Ethernet controller [0200]: Intel Corporation 82541PI Gigabit Ethernet Controller [8086:107c] (rev 05)
herrausgefunden wurde, an welcher pci-Adresse (hier 05:04.0
) die Netzwerkkarte zu finden ist und welcher Programmer (in unserem Beispiel nicintel_spi
)verwendet werden muss (letzteres verrät das flashrom Wiki im Abschnitt "supported hardware" beim Suchen nach 8086:107c
), kann man damit loslegen, die "Flasbarkeit" zu testen:
flashrom -p nicintel_spi:pci=05:04.0
flashrom v0.9.9-r1954 on Linux 4.19.0-1-grml-amd64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Atmel flash chip "AT25F512" (64 kB, SPI) on nicintel_spi.
Found Atmel flash chip "AT25F1024(A)" (128 kB, SPI) on nicintel_spi.
Multiple flash chip definitions match the detected chip(s): "AT25F512", "AT25F1024(A)"
Please specify which chip definition to use with the -c <chipname> option.
Auf der verwendeten Netzwerkkarte stehen offenbar zwei Chips zum flashen zur Auswahl, da unser iPXE-Image größer als 64kB ist, entscheiden wir uns für den weiten Chip und erstellen sicherheitshalber ein Backup (was natürlich anschließend extern des Live-Syystems GRML persistent gespeichert werden sollte):
flashrom -p nicintel_spi:pci=05:04.0 -c "AT25F1024(A)" -r backup"AT25F1024(A)".rom
flashrom v0.9.9-r1954 on Linux 4.19.0-1-grml-amd64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Atmel flash chip "AT25F1024(A)" (128 kB, SPI) on nicintel_spi.
Reading flash... done.
flashrom -p nicintel_spi:pci=05:04.0 -c "AT25F1024(A)" -r 7,28s user 0,00s system 99% cpu 7,285 total
Die Option -c
gibt an, welcher Chip verwendet werden soll, wenn die Netzwerkkarte bzw. flashrom beim Probing mehrere Chips entdeckt.
Bevor das Image geflasht werden kann, muss das Image auf die Größe des Chips (hier 128kB) gepaddet werden. Das kann mit dem folgenden Kommando erledigt werden:
(cat bin/8086107c.rom; tr '\0' '\377' < /dev/zero) | dd bs=1 count=128k of=netBootCA/8086107c.rom_padded_128k
Dann kann das gepaddete Image geflasht werden:
flashrom -p nicintel_spi:pci=05:04.0 -c "AT25F1024(A)" -w 8086107c.rom_padded_128k
flashrom v0.9.9-r1954 on Linux 4.19.0-1-grml-amd64 (x86_64)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... OK.
Found Atmel flash chip "AT25F1024(A)" (128 kB, SPI) on nicintel_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
flashrom -p nicintel_spi:pci=05:04.0 -c "AT25F1024(A)" -w 25,76s user 0,00s system 99% cpu 25,765 total
Damit kann man nun über HTTPS mit Clientauthetisierung booten.