I’ve been running FreeBSD on my laptop for under a year now. One of my biggest pain points so far has been completely around WiFi. It’s slow, janky to connect sometimes, and very manual (sometimes not a big deal on that last part). However, I still prefer to use it. Lately, I’ve left my house more to do some stuff on coffee shop WiFi. I used to come out more before I got married and got my Flair 58 espresso maker, however, sometimes it’s nice to get out or, in my more recent cases, my wife has been needing rides to meet people so I’m "stuck in town".

This is a bit of a reminder to self, and maybe this will help you out when you’re banging your head against the wall trying to figure out why you can’t connect to a captive portal.

If you have a better way to do what I’m doing here, hit me up on Twitter!

TL;DR

  1. Add the wifi network to wpa_supplicant

  2. Find the resolver IP in /var/unbound/forward.conf and set it on top in /etc/resolv.conf

  3. Remove "WPA" from your wlan interface in /etc/rc.conf

  4. service netif restart

  5. Connect to captive portal

  6. Test connection

  7. Connect to VPN

  8. Re-enable your own resolver in /etc/resolv.conf

Things to Note

I’ve noticed a few things when it comes to public WiFi:

  1. A lot of the time, it isn’t encrypted

  2. Captive portal won’t let you use a local resolver like unbound

  3. When switching your VPN on, you have to make even More changes

Now, I believe the last 2 parts can be completely left in the back of your mind if you are doing all your DNS with resolvconf editing your resolv.conf file. I however, run local unbound (for better or worse).

wpa_supplicant

You will need to add an entry to your /etc/wpa_supplicant.conf file. Should just be like this:

network={
	ssid="public wifi"
}

rc.conf

In the rc.conf file, you will have to make one edit. You’ll have to knock out the "WPA" part for your wireless interface (assuming the network you are connecting to does not do any sort of encryption). I like to have 2 lines in my rc.conf file: one with WPA and one without, otherwise identical, and I’ll comment out each line according to where I’m at.

resolv.conf

If you have local_unbound running, and you connect to the wireless network, you can find the network’s DNS resolver in the /var/unbound/forward.conf file. I put that at the top of my resolv.conf file.

Connecting

With these edits in place, you can try a service netif restart and check with ifconfig to see if you are connected to the right SSID. If so, open a browser and a search should bring up a captive portal.

From here, you may be able to uncomment their resolver from the resolv.conf file and use your own, but in my experience, you might be stuck using their resolver. This is where a VPN becomes handy.

VPN

On public WiFi, you should ALWAYS use a VPN. As I pointed out, all the traffic is unencrypted. Anyone could sit and sniff your internet traffic with ther right hardware. Another handy thing to a VPN is you can use any resolver you please.

Enabling the VPN

I found you have to use the local network’s resolver to connect to your VPN first, then you can switch to your own. So ensure you are still using their VPN first, then connect. I use my own WireGuard server so I just run service wireguard onestart to temporarily enable my VPN. From there, you can uncomment out the network resolver from your resolv.conf file. At that point for me, I use 127.0.0.1 to use unbound.

Conclusion

Connecting to public wifi on FreeBSD is still pretty janky. You definitely get a smoother experience with Windows/Mac/Linux. Maybe it’s better on OpenBSD even? Who knows. But this is my process, and I hope this helps somebody out. If not, I at least know where to find my own instructions :)