diff --git a/roles/netbootxyz/defaults/main.yml b/roles/netbootxyz/defaults/main.yml index e717e353..ec4c0dbe 100644 --- a/roles/netbootxyz/defaults/main.yml +++ b/roles/netbootxyz/defaults/main.yml @@ -96,6 +96,38 @@ bootloaders: ipxe_bin: snp.efi.dsk output_bin: -snp.efi.dsk type: Floppy-snp + secureboot_x86_64: + - desc: Secure Boot x86_64 shim, loads iPXE with built-in NIC drivers + output_bin: ipxe-shim.efi + type: Secure Boot + - desc: Secure Boot x86_64 iPXE, built-in NIC drivers (loaded via shim) + output_bin: ipxe.efi + type: Secure Boot + - desc: Secure Boot x86_64 SNP only, boots from chained device (loaded via shim) + output_bin: snponly.efi + type: Secure Boot + - desc: Secure Boot x86_64 SNP shim, loads SNP-only iPXE + output_bin: snponly-shim.efi + type: Secure Boot + - desc: Secure Boot autoexec.ipxe boot script + output_bin: autoexec.ipxe + type: Script + secureboot_arm64: + - desc: Secure Boot ARM64 shim, loads iPXE with built-in NIC drivers + output_bin: ipxe-shim.efi + type: Secure Boot + - desc: Secure Boot ARM64 iPXE, built-in NIC drivers (loaded via shim) + output_bin: ipxe.efi + type: Secure Boot + - desc: Secure Boot ARM64 SNP only, boots from chained device (loaded via shim) + output_bin: snponly.efi + type: Secure Boot + - desc: Secure Boot ARM64 SNP shim, loads SNP-only iPXE + output_bin: snponly-shim.efi + type: Secure Boot + - desc: Secure Boot autoexec.ipxe boot script + output_bin: autoexec.ipxe + type: Script cert_dir: /etc/netbootxyz/certs cert_file_filename: ca-netboot-xyz.crt checksums_filename: '{{ site_name }}-sha256-checksums.txt' @@ -115,6 +147,7 @@ generate_disks_hybrid: false generate_disks_legacy: true generate_disks_linux: false generate_disks_rpi: false +generate_disks_secureboot: false generate_local_vars: true generate_menus: true generate_signatures: false @@ -122,6 +155,8 @@ generate_version_file: true ipxe_branch: master ipxe_ca_filename: ca-ipxe-org.crt ipxe_ca_url: http://ca.ipxe.org/ca.crt +ipxe_secureboot_version: v2.0.0 +ipxe_secureboot_archive_url: "https://github.com/ipxe/ipxe/releases/download/{{ ipxe_secureboot_version }}/ipxeboot.tar.gz" ipxe_debug_enabled: false ipxe_debug_options: httpcore,tls ipxe_repo: https://github.com/ipxe/ipxe diff --git a/roles/netbootxyz/tasks/generate_checksums.yml b/roles/netbootxyz/tasks/generate_checksums.yml index 2ad99c8c..d68fd058 100644 --- a/roles/netbootxyz/tasks/generate_checksums.yml +++ b/roles/netbootxyz/tasks/generate_checksums.yml @@ -1,6 +1,6 @@ --- - name: Register a listing of all created iPXE bootloaders - ansible.builtin.command: ls -I {{ checksums_filename }} {{ netbootxyz_root }}/ipxe/ + ansible.builtin.shell: ls -p -I {{ checksums_filename }} {{ netbootxyz_root }}/ipxe/ | grep -v / register: netboot_disks - name: Generate date @@ -15,6 +15,41 @@ chdir: "{{ netbootxyz_root }}/ipxe/" register: netboot_disks_stat +- name: Register Secure Boot x86_64 bootloaders + ansible.builtin.shell: ls {{ netbootxyz_root }}/ipxe/secureboot-x86_64/ 2>/dev/null || true + register: secureboot_x86_64_disks + when: generate_disks_secureboot | default(false) | bool + +- name: Gather Secure Boot x86_64 checksums + ansible.builtin.command: sha256sum -b {{ item }} + with_items: + - "{{ secureboot_x86_64_disks.stdout_lines | default([]) }}" + args: + chdir: "{{ netbootxyz_root }}/ipxe/secureboot-x86_64/" + register: secureboot_x86_64_disks_stat + when: + - generate_disks_secureboot | default(false) | bool + - secureboot_x86_64_disks.stdout_lines | default([]) | length > 0 + +- name: Register Secure Boot ARM64 bootloaders + ansible.builtin.shell: ls {{ netbootxyz_root }}/ipxe/secureboot-arm64/ 2>/dev/null || true + register: secureboot_arm64_disks + when: + - generate_disks_secureboot | default(false) | bool + - generate_disks_arm | default(false) | bool + +- name: Gather Secure Boot ARM64 checksums + ansible.builtin.command: sha256sum -b {{ item }} + with_items: + - "{{ secureboot_arm64_disks.stdout_lines | default([]) }}" + args: + chdir: "{{ netbootxyz_root }}/ipxe/secureboot-arm64/" + register: secureboot_arm64_disks_stat + when: + - generate_disks_secureboot | default(false) | bool + - generate_disks_arm | default(false) | bool + - secureboot_arm64_disks.stdout_lines | default([]) | length > 0 + - name: Generate ipxe disk checksums ansible.builtin.template: src: checksums.txt.j2 diff --git a/roles/netbootxyz/tasks/generate_disks.yml b/roles/netbootxyz/tasks/generate_disks.yml index f1e9825c..90e2a335 100644 --- a/roles/netbootxyz/tasks/generate_disks.yml +++ b/roles/netbootxyz/tasks/generate_disks.yml @@ -34,3 +34,9 @@ when: - generate_disks_hybrid | default(false) | bool - bootloader_filename == "netboot.xyz" + +- name: Generate Secure Boot iPXE bootloaders + ansible.builtin.include_tasks: generate_disks_secureboot.yml + when: + - generate_disks_secureboot | default(false) | bool + - bootloader_filename == "netboot.xyz" diff --git a/roles/netbootxyz/tasks/generate_disks_secureboot.yml b/roles/netbootxyz/tasks/generate_disks_secureboot.yml new file mode 100644 index 00000000..4e16f98e --- /dev/null +++ b/roles/netbootxyz/tasks/generate_disks_secureboot.yml @@ -0,0 +1,64 @@ +--- + +- name: Create Secure Boot output directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + with_items: + - "{{ netbootxyz_root }}/ipxe/secureboot-x86_64" + - "{{ netbootxyz_root }}/ipxe/secureboot-arm64" + +- name: Download iPXE Secure Boot archive + ansible.builtin.get_url: + url: "{{ ipxe_secureboot_archive_url }}" + dest: "/tmp/ipxeboot.tar.gz" + +- name: Extract iPXE Secure Boot archive + ansible.builtin.unarchive: + src: "/tmp/ipxeboot.tar.gz" + dest: "/tmp" + remote_src: true + +- name: Copy x86_64 Secure Boot binaries to output directory + ansible.builtin.copy: + src: "/tmp/ipxeboot/x86_64-sb/{{ item }}" + dest: "{{ netbootxyz_root }}/ipxe/secureboot-x86_64/{{ item }}" + remote_src: true + with_items: + - ipxe.efi + - ipxe-shim.efi + - shimx64.efi + - snponly.efi + - snponly-shim.efi + +- name: Copy ARM64 Secure Boot binaries to output directory + ansible.builtin.copy: + src: "/tmp/ipxeboot/arm64-sb/{{ item }}" + dest: "{{ netbootxyz_root }}/ipxe/secureboot-arm64/{{ item }}" + remote_src: true + with_items: + - ipxe.efi + - ipxe-shim.efi + - shimaa64.efi + - snponly.efi + - snponly-shim.efi + when: generate_disks_arm | default(false) | bool + +- name: Template autoexec.ipxe for x86_64 Secure Boot + ansible.builtin.template: + src: "disks/autoexec.ipxe.j2" + dest: "{{ netbootxyz_root }}/ipxe/secureboot-x86_64/autoexec.ipxe" + +- name: Template autoexec.ipxe for ARM64 Secure Boot + ansible.builtin.template: + src: "disks/autoexec.ipxe.j2" + dest: "{{ netbootxyz_root }}/ipxe/secureboot-arm64/autoexec.ipxe" + when: generate_disks_arm | default(false) | bool + +- name: Clean up Secure Boot archive + ansible.builtin.file: + path: "{{ item }}" + state: absent + with_items: + - "/tmp/ipxeboot.tar.gz" + - "/tmp/ipxeboot" diff --git a/roles/netbootxyz/templates/checksums.txt.j2 b/roles/netbootxyz/templates/checksums.txt.j2 index 4cbb0547..3cf1aa50 100644 --- a/roles/netbootxyz/templates/checksums.txt.j2 +++ b/roles/netbootxyz/templates/checksums.txt.j2 @@ -3,4 +3,22 @@ {% for item in netboot_disks_stat.results %} {{ item.stdout }} -{% endfor %} \ No newline at end of file +{% endfor %} +{% if secureboot_x86_64_disks_stat is defined and secureboot_x86_64_disks_stat.results is defined %} + +# Secure Boot x86_64 (iPXE {{ ipxe_secureboot_version }}) +{% for item in secureboot_x86_64_disks_stat.results %} +{% if item.stdout is defined %} +{{ item.stdout | replace('*', '*secureboot-x86_64/') }} +{% endif %} +{% endfor %} +{% endif %} +{% if secureboot_arm64_disks_stat is defined and secureboot_arm64_disks_stat.results is defined %} + +# Secure Boot ARM64 (iPXE {{ ipxe_secureboot_version }}) +{% for item in secureboot_arm64_disks_stat.results %} +{% if item.stdout is defined %} +{{ item.stdout | replace('*', '*secureboot-arm64/') }} +{% endif %} +{% endfor %} +{% endif %} \ No newline at end of file diff --git a/roles/netbootxyz/templates/disks/autoexec.ipxe.j2 b/roles/netbootxyz/templates/disks/autoexec.ipxe.j2 new file mode 100644 index 00000000..95e5e4a3 --- /dev/null +++ b/roles/netbootxyz/templates/disks/autoexec.ipxe.j2 @@ -0,0 +1,98 @@ +#!ipxe +# +# {{ site_name }} - Secure Boot autoexec.ipxe +# +# This script is loaded automatically by iPXE v2.0.0+ Secure Boot +# binaries from the same directory. It replaces the embedded script +# used in self-compiled netboot.xyz bootloaders. +# + +set esc:hex 1b +set bold ${esc:string}[1m +set boldoff ${esc:string}[22m +set fg_gre ${esc:string}[32m +set fg_cya ${esc:string}[36m +set fg_whi ${esc:string}[37m +set HTTPS_ERR HTTPS appears to have failed... attempting HTTP +set HTTP_ERR HTTP has failed, localbooting... +set site_name {{ site_name }} +set boot_domain {{ boot_domain }} +set ipxe_version ${version} +set version {{ boot_version }} +set conn_type https + +:start +echo ${bold}${fg_gre}${site_name} - ${fg_whi}v${version} (Secure Boot)${boldoff} +iseq ${site_name} netboot.xyz || echo ${bold}${fg_whi}Powered by ${fg_gre}netboot.xyz${fg_whi}${boldoff} +prompt --key m --timeout 4000 Hit the ${bold}m${boldoff} key to open failsafe menu... && goto failsafe || goto dhcp + +:dhcp +echo +dhcp || goto netconfig +goto menu + +:failsafe +menu ${boot_domain} Failsafe Menu +item localboot Boot to local drive +item netconfig Manual network configuration +item retry Retry boot +item debug iPXE Debug Shell +item reboot Reboot System +choose failsafe_choice || exit +goto ${failsafe_choice} + +:netconfig +echo Network Configuration: +echo Available interfaces... +ifstat +imgfree +echo -n Set network interface number [0 for net0, defaults to 0]: ${} && read net +isset ${net} || set net 0 +echo -n IP: && read net${net}/ip +echo -n Subnet mask: && read net${net}/netmask +echo -n Gateway: && read net${net}/gateway +echo -n DNS: && read dns +ifopen net${net} +echo Attempting chainload of ${boot_domain}... +goto menu || goto failsafe + +:menu +{% if bootloader_https_enabled | bool %} +:menu_https +set conn_type https +goto menu_start +{% endif %} + +{% if bootloader_http_enabled | bool %} +:menu_http +set conn_type http +goto menu_start +{% endif %} + +:menu_start +isset ${netX/dns6} && goto menu_v6 || goto menu_v4 +:menu_v6 +isset ${netX/dns6_bak} && set netX/dns6 ${netX/dns6_bak} || +set netX/dns6_bak ${netX/dns6} +echo Attempting ${conn_type} boot over IPv6... +chain --autofree ${conn_type}://${boot_domain}/menu.ipxe || echo ${conn_type} IPv6 failed... attempting IPv4... +clear netX/dns6 +:menu_v4 +echo Attempting ${conn_type} boot over IPv4... +chain --autofree ${conn_type}://${boot_domain}/menu.ipxe || echo ${conn_type} IPv4 failed... +iseq ${conn_type} https && goto menu_http || goto localboot + +:localboot +exit + +:retry +goto start + +:reboot +reboot +goto start + +:debug +echo Type "exit" to return to menu +shell +goto failsafe diff --git a/roles/netbootxyz/templates/index.html.j2 b/roles/netbootxyz/templates/index.html.j2 index acf27276..a9322b99 100644 --- a/roles/netbootxyz/templates/index.html.j2 +++ b/roles/netbootxyz/templates/index.html.j2 @@ -135,6 +135,48 @@ exit {% endif %} +{% if generate_disks_secureboot == true %} +
x86_64 UEFI Secure Boot iPXE Bootloaders (place all files from directory together)
+ +| Type | +Bootloader | +Description | +
|---|---|---|
| {{ item.type }} | +{{ item.output_bin }} | +{{ item.desc }} | +
ARM64 UEFI Secure Boot iPXE Bootloaders (place all files from directory together)
+ +| Type | +Bootloader | +Description | +
|---|---|---|
| {{ item.type }} | +{{ item.output_bin }} | +{{ item.desc }} | +
Raspberry Pi iPXE Bootloaders
diff --git a/roles/netbootxyz/templates/menu/debian.ipxe.j2 b/roles/netbootxyz/templates/menu/debian.ipxe.j2 index 2e89fd8a..f3bc025e 100644 --- a/roles/netbootxyz/templates/menu/debian.ipxe.j2 +++ b/roles/netbootxyz/templates/menu/debian.ipxe.j2 @@ -85,6 +85,8 @@ initrd ${debian_mirror}/${dir}/initrd.gz echo echo MD5sums: md5sum linux initrd.gz +iseq ${os_arch} amd64 && shim ${debian_mirror}/${dir}/bootnetx64.efi || +iseq ${os_arch} arm64 && shim ${debian_mirror}/${dir}/bootnetaa64.efi || boot :debian_exit diff --git a/script/netbootxyz-overrides.yml b/script/netbootxyz-overrides.yml index f2a4b70a..de38878a 100644 --- a/script/netbootxyz-overrides.yml +++ b/script/netbootxyz-overrides.yml @@ -5,6 +5,7 @@ generate_disks_arm: true generate_disks_hybrid: true generate_disks_linux: true generate_disks_rpi: false +generate_disks_secureboot: true generate_version_file: true generate_local_vars: false make_num_jobs: 4