Re: How to use serial console to enter GELI password to boot kernel on a GELI encrypted ZFS pool
- Reply: Guido van Rooij : "Re: How to use serial console to enter GELI password to boot kernel on a GELI encrypted ZFS pool"
- In reply to: Guido van Rooij : "Re: How to use serial console to enter GELI password to boot kernel on a GELI encrypted ZFS pool"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 19 Aug 2022 15:07:25 UTC
On Fri, Aug 19, 2022 at 2:20 AM Guido van Rooij <guido@gvr.org> wrote: > On Wed, Aug 17, 2022 at 09:19:42AM -0600, Warner Losh wrote: > > On Wed, Aug 17, 2022 at 7:35 AM Guido van Rooij <[1]guido@gvr.org> > > wrote: > > > > On 16 Aug 2022, at 19:09, Warner Losh <[2]imp@bsdimp.com> wrote: > > > >  > > On Tue, Aug 16, 2022 at 3:44 AM Guido van Rooij <[3]guido@gvr.org> > > wrote: > > > > On Mon, Aug 15, 2022 at 02:20:32PM -0600, Warner Losh wrote: > > >  On Mon, Aug 15, 2022 at 8:23 AM Guido van Rooij > > <[1][4]guido@gvr.org> > > >  wrote: > > > > > >   Currently I have a system with ZFS on GELI. I use the > > ability in > > >   the EFI loader to enter the GELI password. > > >   Is it possible somehow to use a serial console to enter > > the > > >   password? > > >   My system does have a COM1 port but it isn't recognised at > > the early > > >   bot stage. There I only see: > > >   Ã Ã Consoles: EFI console > > >   Ã Ã GELI Passphrase for disk0p4: > > >   (Note: this is early in the boot process so there is no > > access to > > >   boot.config (or any other file in the ZFS pool) as it > > still on > > >   encrypted storage at that time). > > > > > >  The boot loader.efi will read ESP:/efi/freebsd/loader.env for > > >  environment > > >  variables. You can use that to set the COM1 port since it > > appears your > > >  EFI system doesn't do console redirection. > > >  If you want it to only prompt COM1 for the password, but > > everything > > >  else is > > >  on the efi console, that's a lot harder. > > Hi Warner, > > Thanks, but somehow I still cannot get it to work properly. > > Content of /efi/freebsd/loader.env: > > boot_multicons="YES" > > console="efi comconsole" > > The boot prompt still only shows "Consoles: EFI console". > > > > Yes. That's printed before we process the ESP file and switch to the > > new console... > >  > > > > When I boot I get the GELI passphrase prompt at the EFI console > > only. But when the kernel starts > > to run I do get output to the serial console, staring with: > > ---<<BOOT>>--- > > Copyright (c) 1992-2021 The FreeBSD Project. > > So it seems the loader.env file is read correctly (it didn't output > > anything to the serial > > console before I created efi/freebsd/loader.env). But looking at the > > source I see in > > efi/loader/main.c:read_loader_env(): > >     if (fn) { > >         printf("  Reading loader env vars from > > %s\n", fn); > >         > > parse_loader_efi_config(boot_img->DeviceHandle, fn); > >     } > > I never saw the printf appearing. I do not understand this. > > > > It should have appeared on the video console of the EFI console > > (assuming no serial > > redirect is going on in that BIOS). > > > > It surely did not. > > > > I'd have to delve more deeply into the prompts for the GELI password > > than I have > > time to do this morning. What if you type the password blind into the > > serial port? > > > > Tried that but nothing happened. When I > > enter the passphrase after typing it in via > > the serial port, it worked immediately so > > we can conclude that no single keystroke > > got through. > > > > OK. I'll have to delve a little more deeply then... > > I Think I know why it does not work. The "Consoles:" line is printed in > cons_probe() > which is called in main(): > setenv("console", "efi", 1); > cons_probe(); > So that explains why we see Consoles: EFI console > Then we see in main(): > for (i = 0; devsw[i] != NULL; i++) > if (devsw[i]->dv_init != NULL) > (devsw[i]->dv_init)(); > The way I understand it, is this the place where the GELI passphrase > prompt originates > from. > Well, not quite. We prompt for the GELI password when we first open a device in devopen (at least that's where we call geli_probe_and_attach())[*]. This should be a bit later, though. I'll have to put some debug prints in to see when it's called... But it looks like we probe for geli, according to the debug, at this point, so something needs to be done to sort out this chicken and egg problem. > But only after that, we see the call to load /efi/freebsd/loader.env > > Shouldn't the dv_init() calls be moved to after the call to > boot_howto_to_env(howto)? > You have discovered a wonderful chicken and egg. If we don't call dv_init we can't do I/O to the devices, so we can't change the console. But, the boot_hwoto_to_env() call only sets env variables that will be used to either set boot args to the kernel or other env variables that are used to communicate the console. It doesn't actually change the console, so is the wrong thing to locate. The likely best way to approach this is to fix loader.efi to initialize enough of the devices so that we can read files off the ESP early enough to set a good console for further interaction. Warner [*] this leads to a bit of a layering violation that causes a circular dependency, but I digress...