If you wanna go fast, you go alone.
If you wanna go far, you go together.
Category Archives: Uncategorized
Bhyve OpenBSD on FreeNAS
Lately I’ve been playing with bhyve on FreeBSD and FreeNAS in the prospect of spinning up small VMs for a mini compile farm (and just as an excuse to play around). In this post I will share my experience in installing OpenBSD 6.4 as a bhyve UEFI VM on FreeNAS-11.2 through the new GUI.
This post is divided in three parts. First the creation of the VM through FreeNAS new GUI. Then the installation of OpenBSD from boot to finish. Lastly some bits of documentation and related posts that were helpful along the way.
Create the VM
The installation will go through serial instead of VNC. Also, instead of the CDROM ISO we use a disk image for the installation.
In the FreeNAS GUI, selects Virtual Machines > ADD, then proceed with the wizard. Some parameters of the wizard are pretty obvious, so there won’t be an explanation for each one of them. If need be, check the FreeNAS doc on creating VMs.
Guest Operating System, not exactly sure what this does. Guess it’s basically a template for the next steps of the wizard. Since this is a BSD system, select FreeBSD as this is the closest there is.
We don’t need VNC, so make sure that Enable VNC is unchecked. As for Boot Method, you can select UEFI, you don’t need UEFI-CSM.
For the hard disk in Select Disk Type and similarly for the network interface in Adapter Type, select a VirtIO type.
For the Installation Media, leave it blank. This is for an ISO image but OpenBSD’s installXX.iso didn’t work so we are going to use a raw disk image instead.
Go ahead and create the VM. But don’t start it yet. We have to add a raw disk device.
Fetch installXX.fs from OpenBSD download page, and put it somewhere on the FreeNAS host. For the following, I’ll assume this is install64.fs.
Then select Devices > ADD for the VM. Select Type: Raw File and Raw File: the location of install64.fs on the FreeNAS host. Also Mode: VirtIO; Device Order: 1003 (the device order is important, otherwise the OpenBSD install would incorrectly guess the target device); Raw filesize: 1 (which means 1GB).
Now you can start the VM and open the Serial console. You should be greeted by:
>> OpenBSD/amd64 BOOTX64 3.40 boot>
Time to install OpenBSD!
Install OpenBSD
You are on the serial console with the OpenBSD install bootloader waiting for you. On the console boot>, type set tty com0, then boot.
Do not directly start the installation, we first have to create the EFI partition, so select (S)hell instead. At the command prompt, create the EFI partition as described below, then start the install.
## Check that sd0 is the correct target device # disklabel -p M sd0 ... 16 partitions: # size offset fstype [fsize bsize cpg] c: 15625.0M 0 unused ## Initialise a GPT partition table with the special boot partition on sd0. # fdisk -iyg -b 960 sd0 Writing MBR at offset 0. Writing GPT. ## Start the installer # install
At the partitioning step, select (O)penBSD area. We will setup a single root partition layout. You should know that the OpenBSD bootloader likes its root partition on slice a of the first hard disk, so we create the layout that way.
# Check the current partition
> p M
OpenBSD area: 1024-31999937; size: 15624.5M; free: 15624.5M
# size offset fstype [fsize bsize cpg]
c: 15625.0M 0 unused
i: 0.5M 64 MSDOS
# Start with the root partition.
# Again, the bootloader likes it that way.
> a
...
size: {your-root-partition-size}M
FS type: 4.2BSD
mount point: /
# Now the swap partition
> a
...
FS type: swap
# Check again
> p M
OpenBSD area: 1024-31999937; size: 15624.5M; free: 0.0M
# size offset fstype [fsize bsize cpg]
a: 15493.9M 1024 4.2BSD 2048 16384 1 # /
b: 130.5M 31732576 swap
c: 15625.0M 0 unused
i: 0.5M 64 MSDOS
# Quit and save
> q
Write new label?: y
Proceed with the installation and the file sets and once you are done, reboot in your new system. Remove the Raw File device from the VM and on the VM itself, use syspatch to patch the base system. Finally reboot and you are done!
Relevant bits of documentation
Drop TCP connections
On FreeBSD you can drop existing TCP connection using the tcpdrop command. For instance you can drop all ESTABLISHED connections using tcpdrop -s ESTABLISHED. Or you can even list them all with:
$ tcpdrop -la tcpdrop ::1 59298 ::1 1180 tcpdrop 10.0.0.10 59299 163.172.87.245 80 tcpdrop 10.0.0.10 59300 163.172.87.245 22 tcpdrop 10.0.0.10 59301 96.47.72.84 443
Notice the fun thing here. Those are actual commands that you can use to drop the connections. In fact you can use this to filter which connection you want to drop. For example:
# Drop all but SSH connections tcpdrop -la | grep -vw 22 | sh # Drop all incoming HTTP connections tcpdrop -la | grep -v " 80 " | sh # Drop all connections to a specific IP tcpdrop -la | grep -vw 8.8.8.8 | sh
This can be useful for instance on a desktop when you just switched interface, or say just started a VPN daemon, and want all prior TCP connections not originating from your new addresses to be killed. Then you would just add those IP you would like to keep and filter them out:
# List of IPs you want to keep echo 192.168.1.122 > keep-ip.txt echo 10.0.0.10 >> keep-ip.txt tcpdrop -la | grep -Ev "(::1|127.0.0.1)" | grep -vwf keep-ip.txt | sh
MSP430-GCC on FreeBSD
I have explained in a previous post how the old version of msp430-gcc is getting depreciated everywhere. Now even the binaries are getting bit rot. So if msp430-gcc complains on FreeBSD that libmpfr.so.4 is missing, here is a quick dirty hack that you can use:
cd /usr/local/lib ln -s libmpfr.so.6 libmpfr.so.4
Automount not working with FreeBSD 12
FreeBSD 12 is out. This is great! However I had the surprise to find that the automount feature didn’t work in KDE, probably also Gnome, XFCE and any other desktop environment that provide such a feature.
The culprit was easy to find, the Hardware Abstraction Layer has not yet updated to the peculiarities of the latest FreeBSD release.
See, when HAL tries to mount a vfat filesystem on FreeBSD, it adds by default the large option which according to FreeBSD 11.2 mount_msdosfs’s manpage provide support for very large files (>128GB). This option, however, was removed in FreeBSD 12. Thus automount fails.
To temporarily fix this, edit /usr/local/share/hal/fdi/policy/10osvendor/20-storage-methods.fdi. Then remove the large option in the vfat match for FreeBSD. That is:
<match key="volume.fstype" string="vfat">
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="Linux">
...
</match>
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name" string="FreeBSD">
...
<!-- <append key="volume.mount.valid_options" type="strlist">large</append> -->
</match>
This was already reported in #221709.
Don’t forget the pipe subshell
This is a common error while using pipe over while loops. Consider this shell snippet:
#!/bin/sh cat file.txt | while read line do echo "inside loop" exit 1 done echo "outside loop" exit 0
You’d expect the script to exit on the first line in file.txt. However execute this script and you have:
inside loop outside loop
It is as if the exit 1 inside the loop is ignored. Another example:
#!/bin/sh a=0 cat file.txt | while read line do echo "inside loop" a=1 done echo "outside loop" echo "a=$a"
Here you’d expect the value of a to be 1 at the end of the script. Instead, if you execute this you have:
inside loop outside loop a=0
It’s as if the variable a isn’t even updated. In fact it is, though only inside the loop. So what is happening here?
The pipe (|) you use to feed the loop creates a subshell. In fact this is really just another process. So the exit 1 or a=1 only apply to these piped processes.
How can you fix that?
In the simple case presented above, you can simply use file redirection:
while read line do ... done < file.txt
But what if you really want to feed the loop with the output of another process. Like you would do with find for instance.
If you use bash you can use process substitution as described here. But you shouldn’t use bash for scripting anyway. For shell scripting you might be tempted to use a temporary file to store the process output:
# Use a temporary file. tmp=$(mktemp) find . > $tmp while read line do ... done < $tmp rm $tmp
However this consumes disk space, and the loop only starts after the find process exited. Another option would be to use a named fifo:
fifo=$(mktemp -u) mkfifo $fifo find . > $fifo & while read file do ... done < $fifo rm $fifo
This time you create a single file, yet no disk space is used (apart for the fifo inode itself). Also the find command is a child process, so the loop reads find output as it comes.
Although the version above already works as it should, you may want to use an anonymous fifo. This way you only need to create a fifo file, although you can delete it immediatly. You can achieve this with a little help from our beloved file descriptor 3.
fifo=$(mktemp -u) # Create fifo mkfifo $fifo # Create fd 3 and unlink fifo file. exec 3<> $fifo rm $fifo # Redirect find to fd 3. find . >&3 & # Feed fd 3 to while loop. while read line do ... done <&3 # Close fd 3. exec 3>&-
Epson 3490 Scanner
This is an information that tends to be forgotten on the Internet, so I’m publishing it here. How to get an Epson Perfection 3490 Photo scanner running under Linux, FreeBSD or whatever. Paths may change on your system, so you may need to adapt the instructions below.
1. Install xsane.
2. Download the Epson firmwares. For the Epson 3490, you need esfw52.bin. You may find this file on Internet, although it tends to disappear. But in any case you can also find this file here.
3. Uncompress the firmwares. That is, sudo tar -Jxvf epson-firmwares.tar.xz -C /usr/local/share/sane.
4. Modify /usr/local/etc/sane.d/snapscan.conf, change the firmware line to point to the esfw52.bin firmware. That is following the commands above, change the firmware line to firmware /usr/local/share/sane/epson-firmwares/esfw52.bin.
If you are running FreeBSD
You should still ensure that you can use the scanner as a normal user.
5.Let’s change the owner of the scanner so that it’s available to users in the saned group. Create /etc/devd/saned.conf and add:
notify 100 {
match "system" "USB";
match "subsystem" "INTERFACE";
match "type" "ATTACH";
match "cdev" "ugen[0-9].[0-9]";
match "vendor" "0x04b8";
match "product" "0x0122";
action "chown -L cups:saned /dev/$cdev && chmod -L 660 /dev/$cdev";
};
Notice the 0x4b8:0x0122, identifying the scanner USB device which you can get from the lsusb command while the scanner is plugged in.
6.Restart devd with service devd restart.
7.Add yourself to the saned group with sudo pw groupmod saned -m {{your-user}}
8.You may need to log in again so that new group changes are taken into account.
Fastd and truncated IP
You might have guessed from the last post that I’ve been playing a bit with Fastd the last few days.
However I had some surprises after successfully configuring my first tunnel. Light traffic such as ping would go through without problem. But larger traffic such as rsync transfers or downloading/uploading files would hang endlessly.
At the remote side of the tunnel, I looked with tcpdump at the traffic out of the tun interface. Packets were going through, although packets with a large payload were apparently truncated:
truncated-ip6 - 4 bytes missing truncated-ip - 4 bytes missing
Indeed large packets were 4 bytes shorter than intended both for IPv4 and IPv6 traffic. This sounded a lot like some kind of MTU mismatch in the tunnel itself. Still, both sides of the tunnel were configured with the same MTU. Also, Fastd ensures that both sides use the same MTU during the tunnel creation.
So what is it? I don’t know. I did not investigate further. But I’ve found a workaround.
Once the tunnel is created, I simply reduce the MTU on the entry/client side interface of the tunnel of 4B. That is in the establish script:
mtu=$(("$INTERFACE_MTU" - 4))
ifconfig "$INTERFACE" mtu "$mtu"
That’s still weird though. So I’d like to find some definitive answer as to why this is happening.
Fastd on FreeBSD
Fastd is nice and small secure tunneling daemon. A bit like OpenVPN, if you wish, but geared toward small devices, simpler in its design and in some ways more generic.
There was a FreeBSD port, but it has been marked as broken. The fix, however, is very simple, if you accept to get rid of AES128 and instead use the SALSA stream cipher:
cmake -DWITH_CIPHER_AES128_CTR=FALSE CMakeLists.txt make make install
Chromium on FreeBSD
Good news everyone! Chromium is now perfectly usable on FreeBSD.
The longstanding hanging tab bug has been resolved. See also PR 212812 and this this FreeBSD forum post.
This was fixed in r337328 but is not yet available in 11.2-RELEASE. Fortunately there are temporary fixes too that you can use while waiting for the patch to be included in the next release.
First add this line to /etc/sysctl.conf:
net.local.stream.recvspace=16384
Second use a memory backed filesystem for the chromium cache. A script to do so was included in the chromium package, but it has since been removed now that a proper fix is coming in.
But if you want to do this manually, first ensure that ~/.cache/chromium directory exists and is empty. Then in /etc/fstab add this line with $USER changed accordingly:
md /home/$USER/.cache/chromium mfs rw,late,noatime,noexec,nosuid,-w$USER:$USER,-s300m 2 0
This will mount the chromium cache path on an UFS partition over a memory backed virtual disk.
I’ve been testing this for several days now and it works like a charm. Don’t forget to remove this workaround when you are past r337328 though.
