Advanced Programming in the UNIX Environment

CS631 - APUE - NetBSD/VirtualBox Setup


This document will guide you through the setup of a NetBSD VM using VirtualBox to perform all your course work on. Please follow these steps as shown; if you run into problems or have questions, please send them to the class mailing list.

Installing your NetBSD VM

Creating a new VirtualBox Image

First, install VirtualBox from https://www.virtualbox.org/.

Next, download the latest ISO for NetBSD/amd64 from e.g. https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.3/images/NetBSD-9.3-amd64.iso and save it as /tmp/NetBSD.iso.

Start VirtualBox.

Screenshot: VirtualBox at first start

Select 'New' and fill in the following values:

Name "apue"
Type: BSD
Version: NetBSD (64-bit)

Screenshot: Creating a new VirtualBox image

Accept all defaults after this, clicking 'Continue' until the initial VM image is configured:

Screenshot: A new VirtualBox image

Configuring the new VM

Select the newly created image and go to 'Settings':

Go to 'System' and bump up 'Hard Disk' in the boot order to the top.

Screenshot: VirtualBox Bootorder Screen

We do this, so that we can initially boot off the CD, but then boot off the disk once the OS installed without having to eject the CD from the VM (although we will do that later, too).

Go to 'Storage':

Select the (empty) CD drive on the left-hand side, then select the disc icon on the right-hand side next to the 'Optical Drive: IDE Secondary Master' option.

Screenshot: VirtualBox Storage Screen

Select 'Choose Virtual Optical Disk File...'.

Find the ISO you had downloaded before, i.e. /tmp/NetBSD.iso.

Select 'Network':

Screenshot: VirtualBox Network Screen

Select the first adapter, keep it as 'NAT', select 'Advanced' and then 'Port Forwarding'.

Add a new rule (upper right), and fill in:

Name: ssh
Protocol: TCP
Host IP: 127.0.0.1
Host Port: 2222
Guest IP:
Guest Port: 22

Screenshot: VirtualBox Portforwarding Screen

If you want a dual-stack environment, and your network serves you an IPv6 address, you can enable another interface in bridge mode (NAT does not apply to IPv6):

To do that, select 'Adapter 2', 'Enable Network Adapter', and select 'Bridged Adapter'.

Finally, select 'Ok' to commit your configuration changes.

(You may also wish to adjust the display size for the virtual machine. To do that, select the "Display" option and slide the 'Scale Factor' slider to, say, 200%, then click 'Ok'.

Installing NetBSD

Start your newly created VM by selecting 'Start'.

The VM should start and get you to the NetBSD install screen, where we'll follow a very basic NetBSD installation:

NetBSD Installation Screenshot

Select 'Install messages in English', then leave the keyboard type 'unchanged', then select 'Install NetBSD to hard disk'. Then:

Shall we continue? yes
Available disks: wd0
Master Boot Record (MBR)
This is the correct geometry
Use the entire disk
Use default partition sizes
Partition sizes are ok
Shall we continue? 'yes'
Use the BIOS console
Select your distribution: 'Installation without X11'
Install from: 'CD-ROM'

NetBSD Installation Screenshot: Set Extraction

After extraction is complete, 'hit enter to continue', then configure the network:

Available interfaces: 'wm0'
Network media type: autoselect
Perform autoconfiguration? yes

This should get you a DHCP lease and an overall network configuration that we wish to commit to the system:

Are they ok? yes
Do you want it installed in /etc?
yes

(If you enabled a second interface above for IPv6 only, then leave wm1 unconfigured; we will configure that interface manually further below.)

Back on the configuration screen, 'Enable installation of binary packages' should be set to 'install'. While not immediately necessary, this will allow you to later on install additional software via the pkgin tool, so is a useful step to complete here. Go ahead and hit 'enter', then select "Install pkgin and update package summary" at the bottom, accepting all other defaults.

'Hit enter to continue'.

The option 'Fetch and unpack pkgsrc' can be disabled if you so choose -- we won't be using pkgsrc in this class, but if you're interested, installing it doesn't hurt.

Next, select:

'g: Enable sshd'
'h: Enable ntpd'
'o: Add a user'

Add your username, e.g., "jschauma".

Note: it is required for this class to create and run your code as a non-root user, so this step is not optional.

Add the user to 'wheel', so you can su(1).

Select a shell, e.g. /bin/sh and set a password.

(Note: we did not set a password for the root account. If you like, you can do that. You may also choose not to do that, but it's important to understand why that might be acceptable: root is not allowed to log in remotely (which is one of the reasons why you had to create an additional user account), but any user on the system could run su(1) to become the super user without requiring a password.)

NetBSD requires users to be in the 'wheel' group to run su(1), so only your newly created user should be able to do this.

This, together with the fact that the VM is intended for nothing of importance whatsoever may make it ok to not have any additional protections on the superuser account.)

Select 'x: Finished configuring', then 'Hit enter to continue'.

Now you're back at the main install menu, where we will perform a few minor configuration changes before we reboot, so select 'x: Exit install System. This drops you into a shell. Mount the virtual disk and edit the file /etc/rc.conf on it:

mount /dev/wd0a /mnt
vi /mnt/etc/rc.conf

If you want to enable the second network interface for IPv6 only connectivity, update dhcpcd_flags="-qM wm0" to become dhcpcd_flags="-qM wm0 wm1". Either way append the following lines, then write the file and quit (:wq):

no_swap=YES
hostname=apue

NetBSD /etc/rc.conf configuration

If you are connected to an IPv6 enabled network, and you previously created the second network interface in bridged mode, then you can now configure it for IPv6 only. To do that, run the following command to append the right lines to /mnt/etc/dhcpcd.conf:

( echo; echo "interface wm1"; echo "ipv6only"; ) >> /mnt/etc/dhcpcd.conf

You also want to change the SLAAC address used by NetBSD, if you use IPv6. To do that:

sed -i -e 's/^#slaac hwaddr/slaac hwaddr/' -e 's/^slaac private/#slaac private/' /mnt/etc/dhcpcd.conf

Finally, unmount the disk and reboot the system. It should now boot into your newly installed system with the ISO still in the CD drive:

umount /mnt
shutdown -r now

NetBSD boot selector

When the system comes up, it should display messages about DHCP etc. and ultimately present you with a prompt:

NetBSD login screen

You can now log in and verify network connectivity (for IPv6 only if your network is IPv6 enabled and you did configure the second interface as described above), then eject the CD:

NetBSD/amd64 (apue) (constty)

login: jschauma
Password:

NetBSD 9.3 (GENERIC) #0: Wed May 12 13:15:55 UTC 2021

Welcome to NetBSD!

apue$ ifconfig -a
wm0: flags=0x8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        capabilities=2bf80<TSO4,IP4CSUM_Rx,IP4CSUM_Tx,TCP4CSUM_Rx>
        capabilities=2bf80<TCP4CSUM_Tx,UDP4CSUM_Rx,UDP4CSUM_Tx,TCP6CSUM_Tx>
        capabilities=2bf80<UDP6CSUM_Tx>
        enabled=0
        ec_capabilities=7<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU>
        ec_enabled=0
        address: 08:00:27:db:b9:08
        media: Ethernet autoselect (1000baseT full-duplex)
        status: active
        inet 10.0.2.15/24 broadcast 10.0.2.255 flags 0x0
        inet6 fe80::a00:27ff:fedb:b908%wm0/64 flags 0x0 scopeid 0x1
wm1: flags=0x8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        capabilities=2bf80<TSO4,IP4CSUM_Rx,IP4CSUM_Tx,TCP4CSUM_Rx>
        capabilities=2bf80<TCP4CSUM_Tx,UDP4CSUM_Rx,UDP4CSUM_Tx,TCP6CSUM_Tx>
        capabilities=2bf80<UDP6CSUM_Tx>
        enabled=0
        ec_capabilities=7<VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU>
        ec_enabled=0
        address: 08:00:27:30:f5:5b
        media: Ethernet autoselect (1000baseT full-duplex)
        status: active
        inet6 fe80::5464:961e:7368:2449%wm1/64 flags 0x0 scopeid 0x2
        inet6 2001:470:1f07:1d1:32bb:2d83:face:e3/64 flags 0x0
lo0: flags=0x8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33624
        inet 127.0.0.1/8 flags 0x0
        inet6 ::1/128 flags 0x20<NODAD>
        inet6 fe80::1%lo0/64 flags 0x0 scopeid 0x3
apue$ ping -c 3 www.yahoo.com
PING atsv2-fp-shed.wg1.b.yahoo.com (74.6.142.32): 56 data bytes
64 bytes from 74.6.142.32: icmp_seq=0 ttl=254 time=23.906584 ms
64 bytes from 74.6.142.32: icmp_seq=1 ttl=254 time=27.090306 ms
64 bytes from 74.6.142.32: icmp_seq=2 ttl=254 time=24.113525 ms

----atsv2-fp-shed.wg1.b.yahoo.com PING Statistics----
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 23.906584/25.036805/27.090306/1.781392 ms
apue$ ping6 -c 3 www.yahoo.com
PING6(56=40+8+8 bytes) 2001:470:1f07:1d1:32bb:2d83:face:e3 --> 2001:4998:58:207::1000
16 bytes from 2001:4998:58:207::1000, icmp_seq=0 hlim=53 time=25.138 ms
16 bytes from 2001:4998:58:207::1000, icmp_seq=1 hlim=53 time=28.066 ms
16 bytes from 2001:4998:58:207::1000, icmp_seq=2 hlim=53 time=27.468 ms

--- atsv2-fp-shed.wg1.b.yahoo.com ping6 statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 25.138/26.891/28.066/1.547 ms
apue$ su root -c "eject cd0"
apue$ 

Finally, we also want to avoid having to use the VirtualBox application GUI every time we want to work with our VM. So instead of relying on the GUI to start our VM, we will use the command-line utility 'VBoxManage'. To verify that this works as intended, let's first shut down and power off our VM. For that, we need super-user privileges, which we gain via the su(1) command, and because we're notoriously lazy, we immediately create another alias to save ourselves some typing:

apue$ cat >> ~/.shrc <<EOF

alias poff='su root -c "/sbin/shutdown -p now"'
EOF
apue$ . ~/.shrc
apue$ poff
*** FINAL System shutdown message from jschauma@apue ***                     
System going down IMMEDIATELY                                                  

System shutdown time has arrived

About to run shutdown hooks...
Stopping cron.
Stopping inetd.
Saved entropy to /var/db/entropy-file.
Forcibly unmounting tmpfs filesystems
Removing block-type swap devices
Wed Aug 25 21:59:47 UTC 2021

Done running shutdown hooks.
Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.
$ 

And now to start the VM again, we create an alias in our parent OS, here assuming your login shell is bash(1):

parent$ cat >> ~/.bashrc <<EOF

alias start-apue='VBoxManage startvm "apue" --type headless'
EOF
parent$ . ~/.bashrc
parent$ start-apue
Waiting for VM "apue" to power on...
VM "apue" has been successfully started.
parent$ 

Set up your VM for this class

With the VM now ready for use, you can next follow the steps to set up everything for use in this class. That will include configuration of SSH, configuring your development environment, and fetching all source code and code examples.

These steps are more or less the same for use of VirtualBox and UTM, and you can find them in this document.


[Course Website]