This page looks best with JavaScript enabled

CBSD OpenBSD Installation via TTY

 ·  🎃 kr0m

Installing OpenBSD on CBSD is somewhat complicated due to a bug that incorrectly detects keyboard input, making it impossible to install the operating system. In this article, we will enable output through the COM port to perform the installation from there. A similar article was previously written for Linux.

We must bear in mind that in modern versions of CBSD there seems to be no problem at all. We can see in this video an installation of OpenBSD, but if we use the version of FreeBSD RELEASE Production , it will install version cbsd-12.1.13 from binary packages, which is affected by the bug.

If we install software from ports in the same version of FreeBSD, we will obtain a more recent version: cbsd-12.1.16.

Another option could be to compile CBSD from the Git repository sources and install it manually.

The bug in question can be seen in the following screenshot when trying to type the letter “I” to start the installation:

According to the Bhyve documentation, it allows us to configure two COM serial ports:

man bhyve

-l [help|lpcdev[,conf]]  
                 Allow devices behind the LPC PCI-ISA bridge to be configured.  
                 The only supported devices are the TTY-class devices com1 and  
                 com2 and the boot ROM device bootrom.

We can view the ports with the following command:

bhyve -l help

bootrom  
COM1  
COM2

NOTE: Bhyve always uses COM1 for stdio output, so we can only configure COM2.

By using a nullmodem ( 1 , 2 ), we can access the VM console and perform the installation from there.

We add flags to the Bhyve process startup using the CBSD configuration wizard:

cbsd bconstruct-tui

We assign additional flags:

bhyve_flags: -l com2,/dev/nmdm0A

If we have multiple VMs for null modem access, we must choose a device name that is not being used in a previous VM. We check the existing ones by grepping the VMs configuration:

grep -r bhyve_flags /usr/jails/jails-system/*/bhyve.conf

/usr/jails/jails-system/openbsd1/bhyve.conf:bhyve_flags='-l com2,/dev/nmdm0A'

In this case, we see that nmdm0 is already being used by the openbsd1 VM.

We start the VM:

cbsd bstart openbsd1

We check the parameters with which the Bhyve process was started:

ps wwaux|grep openbsd

root       25961   0.0  0.2  1092620  26404      9  IN+  20:00      0:00.01 /usr/sbin/bhyve -l com2,/dev/nmdm0A -c 1 -m 1073741824 -H -A -w -U 0f1bcf08-02fb-11eb-9d5a-3497f636bf45 -s 0,amd_hostbridge -s 4,virtio-blk,/usr/jails/vm/openbsd1/dsk1.vhd,sectorsize=512/4096 -s 3,ahci-hd,/usr/jails/src/iso/cbsd-iso-install67.fs,ro -s 5,virtio-net,tap4,mac=00:a0:98:84:f2:ec -s 6,fbuf,tcp=127.0.0.1:5902,w=1024,h=768,vga=off,wait -s 30,xhci,tablet -s 31,lpc -l com1,stdio -l bootrom,/usr/local/cbsd/upgrade/patch/efi.fd openbsd1

We can see how the VM has both COM ports configured:

-l com2,/dev/nmdm0A  
-l com1,stdio

We leave a Screen listening on our null modem:

screen /dev/nmdm0B

We access the VM through VNC to enable installation via TTY:

cbsd blogin openbsd1
boot> set tty com1

In the console where we have the Screen started, we will get the installation wizard, and we start the installation using the boot command:

Welcome to the OpenBSD/amd64 6.7 installation program.
(I)nstall, (U)pgrade, (A)utoinstall or (S)hell? I

Terminal type? [vt220] 
System hostname? (short form, e.g. 'foo') openbsd1

Available network interfaces are: vio0 vlan0.
Which network interface do you wish to configure? (or 'done') [vio0] 
IPv4 address for vio0? (or 'dhcp' or 'none') [dhcp] 
vio0: 192.168.69.206 lease accepted from 192.168.69.200 (d4:63:fe:b0:3e:10)
IPv6 address for vio0? (or 'autoconf' or 'none') [none] 
Available network interfaces are: vio0 vlan0.
Which network interface do you wish to configure? (or 'done') [done] 
DNS domain name? (e.g. 'example.com') [my.domain] alfaexploit.com
Using DNS nameservers at 192.168.69.200

stty: tcsetattr: Invalid argument
Password for root account? (will not echo) XXXXXX
stty: tcsetattr: Invalid argument

stty: tcsetattr: Invalid argument
Password for root account? (again) XXXXXX
stty: tcsetattr: Invalid argument

Start sshd(8) by default? [yes] 
Do you want the X Window System to be started by xenodm(1)? [no] 
Change the default console to com0? [yes]
Available speeds are: 9600 19200 38400 57600 115200.
Which speed should com1 use? (or 'done') [-1] 9600
Setup a user? (enter a lower-case loginname, or 'no') [no] 
Since no user was setup, root logins via sshd(8) might be useful.
WARNING: root is targeted by password guessing attacks, pubkeys are safer.
Allow root ssh login? (yes, no, prohibit-password) [no] yes
What timezone are you in? ('?' for list) [Europe/Madrid] 

Available disks are: sd0 sd1.
Which disk is the root disk? ('?' for details) [sd0] ?
sd0: ATA, BHYVE SATA DISK, 001  (0.4G)
sd1: VirtIO, Block Device  (10.0G)
Available disks are: sd0 sd1.
Which disk is the root disk? ('?' for details) [sd0] sd1
No valid MBR or GPT.
Use (W)hole disk MBR, whole disk (G)PT or (E)dit? [gpt] G
Setting OpenBSD GPT partition to whole sd1...done.
The auto-allocated layout for sd1 is:
#                size           offset  fstype [fsize bsize   cpg]
  a:       1218736.0K             1024  4.2BSD   2048 16384     1 # /
  b:        262144.0K          2438496    swap                    
  c:      10485888.0K                0  unused                    
  d:       3145728.0K          2962784  4.2BSD   2048 16384     1 # /usr
  e:       2097152.0K          9254240  4.2BSD   2048 16384     1 # /home
  i:           480.0K               64   MSDOS                    
Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout? [a] A
/dev/rsd1a: 1190.2MB in 2437472 sectors of 512 bytes
6 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd1e: 2048.0MB in 4194304 sectors of 512 bytes
11 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd1d: 3072.0MB in 6291456 sectors of 512 bytes
16 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
Available disks are: sd0.
Which disk do you wish to initialize? (or 'done') [done] 
/dev/sd1a (476db13b9099d424.a) on /mnt type ffs (rw, asynchronous, local)
/dev/sd1e (476db13b9099d424.e) on /mnt/home type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd1d (476db13b9099d424.d) on /mnt/usr type ffs (rw, asynchronous, local, nodev)

Let's install the sets!
Location of sets? (disk http nfs or 'done') [http] 
HTTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]
HTTP Server? (hostname, list#, 'done' or '?') ftp.fr.openbsd.org
Server directory? [pub/OpenBSD/6.7/amd64] 

Select sets by entering a set name, a file name pattern or 'all'. De-select
sets by prepending a '-', e.g.: '-game*'. Selected sets are labelled '[X]'.
    [X] bsd           [X] comp67.tgz    [X] xbase67.tgz   [X] xserv67.tgz
    [X] bsd.rd        [X] man67.tgz     [X] xshare67.tgz
    [X] base67.tgz    [X] game67.tgz    [X] xfont67.tgz
Set name(s)? (or 'abort' or 'done') [done]
Get/Verify SHA256.sig   100% |**************************|  2141       00:00
Signature Verified
Get/Verify bsd          100% |**************************| 18117 KB    00:06    
Get/Verify bsd.rd       100% |**************************| 10109 KB    00:01    
Get/Verify base67.tgz   100% |**************************|   238 MB    00:36    
Get/Verify comp67.tgz   100% |**************************| 74451 KB    00:11    
Get/Verify man67.tgz    100% |**************************|  7464 KB    00:01    
Get/Verify game67.tgz   100% |**************************|  2745 KB    00:01    
Get/Verify xbase67.tgz  100% |**************************| 22912 KB    00:03    
Get/Verify xshare67.tgz 100% |**************************|  4499 KB    00:01    
Get/Verify xfont67.tgz  100% |**************************| 39342 KB    00:03    
Get/Verify xserv67.tgz  100% |**************************| 16767 KB    00:02    
Installing bsd          100% |**************************| 18117 KB    00:00    
Installing bsd.rd       100% |**************************| 10109 KB    00:00    
Installing base67.tgz   100% |**************************|   238 MB    00:09    
Extracting etc.tgz      100% |**************************|   261 KB    00:00    
Installing comp67.tgz   100% |**************************| 74451 KB    00:03    
Installing man67.tgz    100% |**************************|  7464 KB    00:00    
Installing game67.tgz   100% |**************************|  2745 KB    00:00    
Installing xbase67.tgz  100% |**************************| 22912 KB    00:01    
Extracting xetc.tgz     100% |**************************|  7023       00:00    
Installing xshare67.tgz 100% |**************************|  4499 KB    00:02    
Installing xfont67.tgz  100% |**************************| 39342 KB    00:18    
Installing xserv67.tgz  100% |**************************| 16767 KB    00:00    
Location of sets? (disk http nfs or 'done') [done] 
Time appears wrong.  Set to 'Tue Sep 29 20:43:12 CEST 2020'? [yes] 
Saving configuration files... done.
Making all device nodes... done.
Relinking to create unique kernel... done.

CONGRATULATIONS! Your OpenBSD install has been successfully completed!

When you login to your new system the first time, please read your mail
using the 'mail' command.

Exit to (S)hell, (H)alt or (R)eboot? [reboot] 

In the console, we will see the operating system boot process:

OpenBSD/amd64 (openbsd1.alfaexploit.com) (tty01)  
login: 

We can also access it via SSH:

ssh 192.168.69.206 -p22
root@192.168.69.206 ’s password:

OpenBSD 6.7 (GENERIC) #179: Thu May  7 21:02:37 MDT 2020  
  
Welcome to OpenBSD: The proactively secure Unix-like operating system.  
  
Please use the sendbug(1) utility to report bugs in the system.  
Before reporting a bug, please try to reproduce it with the latest  
version of the code.  With bug reports, please try to ensure that  
enough information to reproduce the problem is enclosed, and if a  
known fix for it exists, include that as well.  
  
openbsd1#

To make logging in easier, we will modify the login command for this VM:

vi /usr/jails/jails-system/openbsd1/etc/blogin.conf

login_cmd="screen /dev/nmdm0B"

We check that the login command launches the Screen session through the configured null modem:

cbsd blogin openbsd1
root
Password:

Last login: Wed Sep 30 21:03:28 on tty01  
OpenBSD 6.7 (GENERIC) #179: Thu May  7 21:05:37 MDT 2020  
  
Welcome to OpenBSD: The proactively secure Unix-like operating system.  
  
Please use the sendbug(1) utility to report bugs in the system.  
Before reporting a bug, please try to reproduce it with the latest  
version of the code.  With bug reports, please try to ensure that  
enough information to reproduce the problem is enclosed, and if a  
known fix for it exists, include that as well.  
  
You have new mail.  
openbsd1#

                                                       
We must keep in mind that if we leave any Screen open, even with the VM turned off, the null modem remains active:

cbsd bls

JNAME     JID    VM_RAM  VM_CURMEM  VM_CPUS  PCPU  VM_OS_TYPE  IP4_ADDR  STATUS  VNC
openbsd1  0      1024    0          1        0     openbsd     DHCP      Off     127.0.0.1:5902
ls -la /dev/nmdm*
crw-------  1 root  wheel  0xf4 Sep 29 20:09 /dev/nmdm0A  
crw-------  1 root  wheel  0xf5 Sep 29 20:09 /dev/nmdm0B
fstat | grep nmdm
root     screen     96110 ctty /dev        243 crw-------  nmdm0B rw  
root     screen     96110    6 /dev        243 crw-------  nmdm0B rw

We kill all Screen sessions or the one we are interested in:

killall screen

This method has some drawbacks. First, we have lost access via VNC. If we are going to run graphical applications, it can be a problem, although we will always have the possibility of enabling SSH XForwarding or installing a VNC server within the VM itself. Second, the null modem device must be manually configured in the configuration of each VM without overlapping previous existing configurations, and third, I have not found the correct way to exit the Screen session so that no sessions remain open.

If it were necessary to change any other parameter of the Bhyve process, we could do so by modifying the startup script, but we would be changing it for all VMs (not recommended). The line that determines how the process is launched is as follows:

vi /usr/local/cbsd/share/bhyverun.sh
        bhyve_cmd_run="env LIB9P_LOGGING=${jailsysdir}/${jname}/cbsd_lib9p.log /usr/bin/nice -n ${nice} ${bhyve_cmd} ${bhyve_flags} -c ${vm_cpus} -m ${vm_ram} ${add_bhyve_opts} ${hostbridge_args} ${virtio_9p_args} ${uefi_boot_args} ${dsk_args} ${dsk_controller_args} ${cd_args} ${nic_args} ${nvme_args} ${virtiornd_args} ${pci_passthru_args} ${vnc_args} ${xhci_args} ${soundhw_args} ${lpc_args} ${console_args} ${efi_args} ${checkpoint_args} ${live_migration_args} ${jname}"

In future versions, it will be possible to change the Bhyve wrapper script for a more granular one per VM:
https://www.youtube.com/watch?v=4SbrjKOWJU0&feature=youtu.be

If you liked the article, you can treat me to a RedBull here