February 14, 2021

Iain R. Learmonth


Mobile Operating System Consent + F-Droid

The LineageOS installation on my Fairphone 2 was getting really old and the updater wasn’t functioning, so I decided to switch back to the Fairphone operating system. I’m really starting to develop some significant aversions to applications collecting consent for things. The “consent overload” on the web triggered by GDPR has certainly affected me. I can entirely see the appeal of a coping strategy of ignoring the text of those boxes and choosing the fastest way to dismiss them but that would slowly eat away at me in the longer term.

February 14, 2021 03:00 PM

January 07, 2021

Iain R. Learmonth


Password Manager + TOTP

I’d like to have a backup method for TOTP. For this, I’m looking at using the pass-otp extension which is available both in OpenBSD packages and Debian. There appears to be some way of scanning QR codes with your webcam in order to extract the URIs, but I can skip this because I have a Honeywell Voyager 1450g handheld 2D barcode scanner (it is very fancy). Basic operation looks like:

January 07, 2021 12:00 PM

January 06, 2021

Iain R. Learmonth


Gopher Card Catalogue

I’ve recently started organising my “library”. This includes physical books, electronic books, posters, QSL cards, challenge coins and other interesting artifacts. The process of documentation has helped to remove some of the feeling of clutter, and turned it into something more valuable. In particular, manuals and leaflets that came with appliances and electronics that would usually be thrown in a box and forgotten about can now be found easily by simply searching a list to see if I have it.

January 06, 2021 12:00 PM

January 05, 2021

Iain R. Learmonth


Toy Finger Daemon

The finger protocol is defined in RFC742. It’s a pretty simple protocol. I’d like to have a more useful output at some point, perhaps including status updates from Mastodon or APRS, but for now I’ve got the hang of reading the request and sending some output with some simple C program. It uses inetd just like the Gopher server. #include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h> static __dead void handle_query(char *input, int len) { if (len == 0) { printf("Summary:\n\n"); printf("-USER-\n"); printf("irl\n"); } else if (len == 3 && memcmp(input, "irl", 3) == 0) { printf("+-----+\n"); printf("| irl |\n"); printf("+-----+\n"); printf("\n"); printf(" gopher://irl.

January 05, 2021 12:00 PM

January 04, 2021

Iain R. Learmonth


Installing Gophernicus on OpenBSD

Installing Gophernicus on OpenBSD was actually rather simple. It is packaged so a simple: doas pkg_add gophernicus will install the necessary files. According to the pkg-readme the preferred way to run it is through inetd so that’s what I set up. The exact line I added to /etc/inetd.conf was: gopher stream tcp nowait _gophernicus /usr/local/libexec/in.gophernicus in.gophernicus -h In the example, the hostname is in double quotes but the quotes ended up appearing in gophermap outputs so I removed them and testing with lynx everything is working now.

January 04, 2021 12:00 PM

October 06, 2020

Iain R. Learmonth


OpenBSD Worrying RAID

I wanted to move a couple of USB hard drives from one OpenBSD machine to another. They are configured with softraid(4) as RAID 1 (mirrored). When I plugged the drives into the new machine though, nothing happened with softraid. This was pretty worrying. Both the drives showed in dmesg output so the issue was specifically to do with softraid. The man page for bioctl(8) talks about -c creating a “new” RAID device which sounded a little too destructive.

October 06, 2020 11:50 AM

October 03, 2020



Radio Power in the Field - Follow on

Previously, I wrote about building a battery for my portable radio operations. This project has been a long and agonising one. Batteries are really difficult, and I spent a good chunk of June, July and August thinking about them. The Winning Design As I discussed in that last blog post, the architecture I settled upon was: I’ve learned quite a lot, made a large number of wrong assumptions and joined a lot of dots in my head as this has gone on.

October 03, 2020 05:00 PM

Tom Jones


Presentations with mdp

It feels like work is just a constant stream of preparing, travelling for and giving presentations. Brief words and pictures is an excellent for conveying information between small groups of humans. All of these presentations I write in keynote, keynote manages to be light weight, powerful and not horrific to use. As a bonus, my boss feels at home in keynote and is happy to make edits there.

The keynote workflow does not match well to how I think. When dreaming up a presentation I want to shit of a stream of conciousness and have it magically become slides in the right shape.

I might write a series of headings like:

# intro
# who
# meat 
# details
# questions?

I will iterate on these to add bodies, details and more slides.

For quite a while I have wanted a system where I could write plain text and have it become slides. I [wrote][3] about the [sent][4] tool from suckless, but in the end I found it wanting. I have also considered just showing screens of text, but a nightmare DEFCON wireess village talk by Hak5 scared me away. They attempted to just present using just a plain text file and less, but the window size got out of whack and it all fell apart.

Enter mdp

mdp is a terminal presentation program, it takes slides it approximately markdown and takes over the entire terminal as its presentation surface.

Intrigued I used an opportunity to speak at a [local tech event][5] to try out mdp. [The slides][6] from that presentation can be found on [my talks page][7] and overall I thought mdp worked quite well.

I was able to draft in the stream of conciousness style I want, getting the bulk of the slides written very quickly. Adding diagrams required resorting to ASCII art which isn't so bad, I like [ascii][10] [art][11]. mdp worked great in practice, I had to find readable dimensions for the text by trial and error, but overall it went well.

Plain text as a format does have some major downsides, mdp has a way to encode builds for text (see below), but I couldn't use it with my tools. ASCII art diagrams also meant that the builds I did use were eggregious to maintain, any modification required manual propigation through the build chain.

mdp does not support a portable output format. You may say the source markdown is an excellent format for portability, but I find it lacks the crispness of having a single slide in view at once.

I wanted to be able to point at a viewable copy of my slides and so I hacked together some tools to export the mdp presentation to html, but for this I had to sacrifice the built in build mechanism of mdp

Finally there was no way to include images in the mdp presentation let alone the sacride gif format required to correctly convey nyan cat. I played with some terminal graphics viewers, but none of them worked well and after a while I started to think 'what is the point of reinventing everything'.

Drafting the presentation in markdown fit very well with my work flow, but the difficulties in getting a complete presentation with mdp meant that I didn't want to use it for future presentations.

Exporting to html

Getting html of the mdp presentation hinged on a complete hack. There is a tool I had seen in the past that can output a html dump of a tmux session unsurprisingly called [tmux2html][12]. With some playing around I was able to automate a tmux session to work through the slides and use tmux2html to grab each slide as a frame.

Finding the number of slides in the deck required splitting on the slide seperator from the markdown, this ruled out using the built in build mechanism as I would end up with the wrong number of slides.

The output script runs through the markdown to find the number of slides then uses tmux send-keys to control moving through the deck.


set -e 

command -v tmux >/dev/null 2>&1 || { echo >&2 "I require tmux but it's not installed.  Aborting."; exit 1; }
command -v tmux2html >/dev/null 2>&1 || { echo >&2 "I require tmux2html but it's not installed.  Aborting."; exit 1; }
command -v mdp >/dev/null 2>&1 || { echo >&2 "I require mdp but it's not installed.  Aborting."; exit 1; }

if [ -z "$1" ]
    echo "tohtml [outfile.html]"


if [ ! -z "$2" ]

javascript="<script>function page(){var e=!1,n=document.getElementsByClassName('tmux-html'),l=0; document.onkeydown=function(t){if(t=t||window.event,key=t.keyCode,e)if(13==key){e=!1,l=0;for(var i=0;i<n.length;i++)n[i].style.display='inline'}else{37==key&&--l<0&&(l=0),39==key&&++l>=n.length&&(l=n.length-1);for(i=0;i<n.length;i++)n[i].style.display='none';n[l].style.display='inline'}else if(13==key){e=!0,n[0].style.display='inline',l=0;for(i=1;i<n.length;i++)n[i].style.display='none'}}}window.onload=function(){page()};</script>"


slides=`grep -e "^---" $file | wc -l`

tmux new-session -s $tmux -d -x 96 -y 25

tmux send-keys -t $tmux "mdp $file"
tmux send-keys -t $tmux "Enter"

tmux send-keys -t $tmux 'g'
tmux2html -o $tmpfile $tmux 1>/dev/null

# insert javascript
lines=`cat $tmpfile | wc -l`
styleend=`cat -n $tmpfile | grep -e "</style>" | awk '{print \$1}'`
head -n $styleend $tmpfile > $outfile
echo $javascript >> $outfile
tail -n $((lines-styleend)) $tmpfile >> $outfile
mv $outfile $tmpfile

# remove closing tag
lines=`cat $tmpfile | wc -l `
end=`tail -n 1 $tmpfile`
head -n $((lines-1)) $tmpfile > $outfile

echo turning $file into $((slides+1)) slides 

while [ $i -lt $((slides+1)) ]
    printf "\rSlide $i"
    tmux send-keys -t $tmux 'j'

    tmux2html -o $tmpfile $tmux 1>/dev/null 
    grep -e "^<div" $tmpfile >> $outfile
    (( i++ ))

echo $end >> $outfile
tmux kill-session -t $tmux 
rm $tmpfile
printf "\rwritten to $outfile \n"

[If you view the presentation page][6] you will see the entire slide deck, this was the first output I got from this script. All the slides in a nice order. After a little pondering I wrote up some javascript to give controls, if you hit enter it will go from all slides to single slide. Arrow keys in single slide mode will allow you to move through the slide deck. The unminified javascript for this is below.

function page() 
    var presenting = false
    var elements = document.getElementsByClassName('tmux-html');
    var current = 0;

    document.onkeydown = function(evt) {
        evt = evt || window.event;
        key = evt.keyCode 

        if (presenting) {
            if (key == 13) {
                presenting = false;
                current = 0;
                for (var i = 0; i < elements.length;i++)
            } else {
                if (key == 37) {    //left
                    if (current < 0)
                        current = 0;
                if (key == 39) {    //right
                    if (current >= elements.length)
                        current = elements.length-1;
                for (var i = 0; i < elements.length;i++)
        } else {
            if (key == 13) {
                presenting = true;

                current = 0;
                for (var i = 1; i < elements.length;i++)

window.onload = function () {

[3]: sent blog post [4]: sent link [5]: techmeetup aberdeen [6]: mdp slides [7]: talks page

[10]: ietf ascii art guidelines [11]: draft cco [12]: tmux to html

October 03, 2020 12:00 AM

September 27, 2020

Iain R. Learmonth


Multicast IPTV

For almost a decade, I’ve been very slowly making progress on a multicast IPTV system. Recently I’ve made a significant leap forward in this project, and I wanted to write a little on the topic so I’ll have something to look at when I pick this up next. I was aspiring to have a useable system by the end of today, but for a couple of reasons, it wasn’t possible.

September 27, 2020 09:35 PM

September 24, 2020

Ana Custura

Firefox modding with containers and SOCKS proxies

Here’s a guide to my lazy setup for running multiple Firefox tabs in the same session over different networks using the magic of SOCKS.

The use-case is that I sometimes want to access a web app or page which is only accessible via a specific network (i.e., my work network or Tor), but I most definitely don’t want the rest of my browsing traffic going through there.

The general idea is to use long-running SSH tunnels to provide one or more SOCKS5 proxies that can be used by Firefox (or your browser of choice). SOCKS is a protocol that allows applications to request connections through a proxy server. Applications, such as Firefox, must be configured to use it.

Generally, to do this manually, you’d first SSH with dynamic forwarding into a host on the desired network:

ssh -D1080 user@host

…and now a SOCKS proxy on localhost port 1080 is ready to forward connections to the remote host. Tor also provides a SOCKS proxy that can be used in much the same way by default on port 9050. This does not conflict with Tor Browser, which runs its own Tor daemon listening on port 9051, separate from the system Tor.

So, to use the proxy in a browser, the browser’s network settings should be changed to resemble something like this:

Firefox settings

Firefox also has a checkbox for proxying DNS requests through the same connection.

It’s a good idea to proxy your DNS requests because 1) the remote DNS resolver might know names of resources you can’t access locally and 2) due to the prevalence of CDNs in the Internet, the IP addresses obtained this way will often correspond to servers physically closer to the tunnel endpoint, speeding up connections.

These settings could be saved under a separate Firefox profile that can be fired up whenever the SSH connection is active. Any browser requests will be forwarded to the network of the host you’re SSHed into.

Now, this is an easy substitute for a VPN, but still requires launching a new SSH connection and browser instance every time you want to browse via the remote network. Plus, multiple networks mean multiple profiles or multiple SSH connections which is a pain to manage.

Enter Firefox containers and autossh. The first is an extension that allows you to keep website data, cookies, and cache separate between tabs and websites by assigning them to different containers.

The second is a way to maintain an SSH tunnel indefinitely. The way to glue them together is Container Proxy, another Firefox extension that allows per-container proxy settings.

Here’s how it works:

Autossh and Tor

This is a wrapper around ssh to keep tunnels open indefinitely in the background. It can use any SSH option or config. For simplicity, I have the following config specified for my proxy host in ~/.ssh/config:

Host pxhost
    ServerAliveInterval 30
    ServerAliveCountMax 3
    DynamicForward 1080

This command will run autossh in the background, forever keeping the connection alive.

autossh -M 0 -f -N pxhost 

To persist this on reboot, I use a systemd service file for Linux and a @reboot cronjob for macOS.

I also have Tor configured to run at startup, allowing me to use it alongside other connections. Tor can run as a service on distros using systemd. On macOS, I modified the .torrc file in my home directory to include RunAsDaemon 1, and just running tor with no options on the command line starts the SOCKS proxy.

Firefox Multi-Account Containers

The extension can be found in the official Firefox store. I have three containers: a Direct container for day-to-day browsing without a proxy, a Work container for accessing some infrastructure at work via an SSH connection into my work computer, and a Tor container for looking at .onion addresses or other web pages over Tor:

Firefox Containers

Tabs opened in each container are colour coded, and easy to keep track of.

An important note about the Tor container: using Tor as a proxy and not using Tor Browser does not provide anonymity, because any other browsers will leak client information allowing 3rd parties to identify users. I do this mostly for convenience and sometimes to avoid eavesdropping from my ISP. However, if you want anonymity, USE TOR BROWSER!

Container Proxy

Proxies for containers are not supported natively in the official Firefox extension. At the moment, another extension is required to make the containers use the tunnels. While not checked by Mozilla, this is open source and the code is auditable at

It lets you configure and test the proxies with DuckDuckGo, and assign them to containers:

Container proxy setup

If the tunnels are set up to persist on reboot, and your Firefox profile is not entirely erased with the latest update, this is how it looks/works:

Example container

That’s it. Containers are cool. Use more containers, before Mozilla dies off.

September 24, 2020 12:00 AM

September 21, 2020

Iain R. Learmonth


Matrix Synapse Certificates

I’ve had a need to set up and run a Matrix homeserver and I wanted to try to set it up for general use as well as just for this project. The one thing I wanted to do that is a little non-standard is to use the “plain” domain for my user ID while hosting the homeserver on a subdomain. In this case I wanted to use “” as the user ID domain, and “syn.

September 21, 2020 09:32 AM

August 31, 2020

Iain R. Learmonth


Portable Radio Setup

I’ve been wanting to document my portable radio setup for a while, so finally here is that blog post. This is a QRP setup, intended primarily for digimodes on HF. HF antenna set up on Elrick Hill, Aberdeen First I want to talk about the antenna setup. Pictured above is the antenna set up on Elrick Hill in Aberdeen. I walked straight up the hill last weekend with the kit and had the antenna up in under 10 minutes.

August 31, 2020 04:15 PM

August 29, 2020

Ana Custura

For sale

VX-8E VHF Amateur Handheld Transciever for sale

  • TX on 70cm, 2M and 6M.
  • Built-in packet modem 1200/9600bd with APRS support
  • Comes with mounted GPS antenna, charger, 3100mAh battery, extra clip and original battery pack
  • 5W power output
  • Modes: TX FM, RX FM/AM/WFM
  • Full specs:

Asking price for radio, accessories and postage is £180. Contact

August 29, 2020 12:00 AM


Impact of Acknowledgements using IETF QUIC on Satellite Performance. Ana Custura, Tom Jones, Gorry Fairhurst. ASMS/SPSC 2020: 1-8

Rethinking ACKs at the Transport Layer. Ana Custura, Tom Jones, Gorry Fairhurst. FIT 2020: 731-736

Measuring mobile performance in the Tor network with OnionPerf. Ana Custura, Iain Learmonth, Gorry Fairhurst. MNM 2019: 233-238

Exploring Usable Path MTU in the Internet. Ana Custura, Gorry Fairhurst, Iain Learmonth. Traffic Measurement Analysis 2018: 1-8

Experience: Implications of Roaming in Europe. Anna Maria Mandalari, Andra Lutu, Ana Custura, Ali Safari Khatouni, Özgü Alay, Marcelo Bagnulo, Vaibhav Bajpai, Anna Brunström, Jörg Ott, Marco Mellia, Gorry Fairhurst. MobiCom 2018: 179-189

Exploring DSCP modification pathologies in the Internet. Ana Custura, Raffaello Secchi, Gorry Fairhurst. Comput. Commun. 127: 86-94 (2018)

Exploring DSCP modification pathologies in mobile edge networks. Ana Custura, Andre Venne, Gorry Fairhurst. MNM 2017: 1-6

August 29, 2020 12:00 AM

August 04, 2020



SOTA Trip Reports: July 12, August 01, 02 2020

Here’re my first sota trip reports. I made some mistakes and have lots to learn still, but they were great days out and I’m dead keen to do more. Most importantly, I’ve got better at radio in general - I’m much more comfortable on a microphone, I understand the flow and format of an HF contact far better. It’s very different from the datamodes I’ve been doing for years! One thing that I’ve noticed, and it probably deserves mentioning, is that the SOTA web infrastructure is some of the best I’ve seen in ham radio.

August 04, 2020 07:50 PM

July 10, 2020

Iain R. Learmonth


Light OpenStreetMapping with GPS

Now that lockdown is lifting a bit in Scotland, I’ve been going a bit further for exercise. One location I’ve been to a few times is Tyrebagger Woods. In theory, I can walk here from my house via Brimmond Hill although I’m not yet fit enough to do that in one go. Instead of following the main path, I took a detour along some route that looked like it wanted to be a path but it hadn’t been maintained for a while.

July 10, 2020 02:00 PM

July 06, 2020



Splat for UHF radio station coverage modelling

I’ve been talking to Iain, MM0ROR a bit on the radio. After I persuaded him to build a 70cm version of the 1/4 wave vertical antenna I built earlier this year, I helped him test it on the radio tonight from my new /m setup. Initially I drove to the picturesque Aberdeen Beach, then the less pretty 57North Hacklab, and finally I took the long road to the very lovely Balmedie Beach, and for the bulk of the drive nattered away to Iain about nonsense and radios.

July 06, 2020 10:59 PM

July 02, 2020

Tom Jones


Blog more in 2020

In June I tried to write 4 blog posts and I elicited help from some of my friends to do this. I managed to write 5 posts beyond the announcement I would blog:

Of course it wasn't just me, I asked other people to blog to help me stay on track. The idea here was that seeing other peoples blog posts would inspire and force me to keep going. This worked reasonably well. The pressure to write the blog posts was there, but publishing was harder. This ended up with me pushing several posts in the final few days of June.

The pressure didn't really show up either, I know that the others wrote blog posts, but they didn't tell me!

They were great sports to get involved and help me with this, you should look up their blogs and drop them into your rss reader.

Because this wort of worked I think we should aim to keep doing this. Now 4 posts a month is a lot (maybe even too much) and so I thought that 8 more this year would be good. That is about 1.3333333... a month and seems entirely achievable.

I am going to try and blow this number out the water, but even if I fail completely and only manage one or two more post that will still be great.

July 02, 2020 12:00 AM

July 01, 2020

Tom Jones


Simple ipfw NAT for bhyve virtual machines and vnet jails

Most of the time, I want to do some throw away networking temporally to play with something or to try something out. I really don't like changing all the config on a machine just to try something. The FreeBSD documentation leans the other way first showing you what to edit in rc.conf before maybe mentioning that actual commands to run.

The ipfw documentation has a different problem. The example in the handbook and online are both very verbose and very complicated. Because ipfw is normally configured with a shell script the authors go absolutely wild with all the features they can.

I had a hard time figuring out ipfw in-kernel NAT from these guides. Instead here I present the simplest set of commands I could find to set up a NAT and a little explanation to help you debug when it doesn't work.

This is based on a great email from Allan Jude on the freebsd-virtualization list from 2014 that laid out the basics of this setup.

Set up Overview

For testing I want to run virtual machines and vnet jails on my laptop and give them have access to the internet. I want a throw away NAT setup that is ready to go quickly.

My laptop connects to my home network (and eventually the internet) over wifi. The wifi network offers me an address in the subnet. On my laptop I want to have multiple guests. To do this we are going to use ipfw NAT and a bridge interface. It will look something like this:

         TO INTERNET
          +-------+  192.168.1.x
+-------------| wlan0 |---------------+
|             +-------+               |
|                 ^                   |
|                 |                   |
|              ipfw nat               |
|                 |                   |
|                 V                   |
|            +---------+              |
|   | bridge0 |              |
|            +----+----+              |
|                 ^                   |
|                 |       |
|      ___________+_______________    |
|      |       |        |        |    |
|      v       v        v        v    |
|  +---+--+ +--+---+ +--+---+ +--+---+|
|  | jail | |  vm  | | jail | | ...  ||
|  +------+ +------+ +------+ +------+|
+-------------- laptop ---------------+

The interfaces in the jails (the b half of the epair) and the virtual machines (the vtnet in the V) won't be visible to ipfw, but will exist in their own world. To work around this we will use a bridge with the epairs and tap interfaces.

Setting up ipfw NAT

We need to load the kernel modules for ipfw and the ipfw in kernel NAT. ipfw has the frustrating default (and annoyingly different to ipf and pf) of to dening all traffic. This default has the great property of locking you out of a machine you are setting up remotely.

This is control by a sysctl that cannot be changed at run time, but we can change the default behaviour with kenv before we load the module:

# kenv net.inet.ip.fw.default_to_accept=1

Now we can safely load ipfw and the in-kernel NAT.

# kldload ipfw ipfw_nat

ipfw should load enabled, if you are having trouble later on double check that the firewall is actually enabled.

# sysctl net.inet.ip.fw.enable
net.inet.ip.fw.enable: 1

When we do NAT we are acting as a gateway between the traffic on the NATd interface and the real interface. For any packets to be passed we need to enable forwarding.

# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1

ipfw rule set

We need to create an IPFW NAT instance configured with the interface we want to NAT (wlan0 in this case) and configure rules to pass all traffic from the bridge through the NAT.

# ipfw nat 1 config if wlan0
# ipfw add 101 nat 1 ip from to any out via wlan0
# ipfw add 103 nat 1 ip from any to any in via wlan0

I like to leave a gap between rules like this so I can insert an ipfw log command for the eventual case that nothing makes sense and everything is broken.

set up interfaces

A bridge is the center of our guest network, we will give it the default root address that all of our guests will speak to.

# ifconfig bridge create
# ifconfig bridge0 inet up

Our jail will use an epair interface to speak to the outside world. They come as an a and a b part, ifconfig only tells us about the a part when it clones the interface. When we give a vnet jail an interface it is no longer visible to the host system. An epair gives us two interfaces that act like a virtual ethernet cable, we stick one end into the jail and the other is connected to the bridge.

# ifconfig epair create

Our virtual machine will use a tap interface to access the world. The tap interface needs to be brought up. There is a helpful sysctl that is off by default which will trigger the interface to be brought up when it is first opened. I like to set this to one, otherwise I find myself debugging networking inside the VM alot with little success.

# ifconfig tap create
# sysctl

With all the interfaces set up we need to add them to our bridge.

# ifconfig bridge0 addm epair0a addm tap0

Create jail

Never spoken about is the bsdinstall jail command. It takes a directory and installs a jail into it. This command will ask you some questions, it would be cool if it didn't, that would make automating jail creation in scripts much easier for me.

# mkdir testjail
# bsdinstall jail testjail

We make our jail persist so it will stick around as we experiment. The following command creates the jail on the host:

# jail -c name=testjail persist vnet path=testjail vnet.interface=epair0b 

Now we can jexec into the jail and configure the epair. When you bring one end of an epair up, the other end comes up, when it goes down the other end goes down. We just need to configure an address and a default route in our jail.

# jexec testjail sh
[testjail] # ifconfig epair0b inet up
[testjail] # route add default
[testjail] # ping -c 1
[testjail] # ping -c 1
[testjail] # ping -c 1

With this setup the jail can speak to our bridge, the local network and the wider Internet.

Create and config a VM

The FreeBSD offers prebuilt virtual machine images, The latest current one is available from a url like this:

# fetch

It would be cool if there was a latest symlink that gave you a new head VM from one static place. The image comes xz compressed, we need to unpack it and I like to move it to a consistent place:

# xz -d FreeBSD-13.0-CURRENT-amd64.raw.xz
# mv FreeBSD-13.0-CURRENT-amd64.raw /vms/freebsd-current

bhyve requires we load the vmm kernel module, with that we can use the excellent script to launch our vm.

# kldload vmm
# sh /usr/share/examples/bhyve/ -c 4 -m 1024 -t tap0 -d /vms/freebsd-current freebsd-current

Once that comes up you can log in and do some manual config.

[vm] # ifconfig vtnet0 inet up
[vm] # route add default
[vm] # ping

For DNS in both the jail and the virtual machines I have to manually set up the name server local from my network.


search lan

This won't be valid as I move to other networks, but I am sure I will remember after only a little confusion and debugging.


That is all it takes. The NAT configuration is 3 firewall rules and enabling forwarding. None of this is persistent and that isn't great practice for a production environment, but it you just want to experiment with ipfw and NAT, or spin up a VM for today knowing how to do this in a non-persistent way is really helpful.

July 01, 2020 12:00 AM


Last updated:
February 25, 2021 07:06 AM
All times are UTC.

Powered by: