pfSense and locales

or: how to get tmux to run on pfSense

Posted by Hendrik 'T4cC0re' Meyer on June 04, 2020 · ˜3 mins read

I recently moved apartments, which came with a change in my ISP. After a long time of using my Ubiquiti USG, this meant change there as well.
Before I ran my USG, I ran pfSense for a long while (on a modified WatchGuard Firebox X700 like this one) and I kinda missed it’s versatility. And with my new gigabit downstream completely crushing my USG in IDS mode}, this was reason enough for me, to switch back.

More on the details of that following in another post. :)

Something that ground my gears for a while is that I could not get tmux to work on pfSense. Well… Technically, tmux would work, if we had the right locales. And this is what this blog post is about. How to teach the en_US.UTF-8 locale to pfSense.

Whenever you run tmux on a blank pfSense you will get something like this:

tmux: need UTF-8 locale (LC_CTYPE) but have US-ASCII

pfSense and (the lack of) locales

First things first. pfSense kinda messed up with locales…

locale -a displays all available locales and en_US.UTF-8 seems to be available.

# locale -a | grep en_US.UTF-8

But when we actually go ahead and look there:

# ls -lsa /usr/share/locale/en_US.UTF-8/
total 12
4 drwxr-xr-x    2 root  wheel   512 Mar 24 19:27 .
8 drwxr-xr-x  193 root  wheel  4608 Mar 24 19:27 ..

Nothing. That definitely explains, why tmux isn’t happy. Not even when we set our locale via setenv. We tell it to use the locale, but the files just don’t exist.

Okay, but we can fix that pretty easily. Just use the upstream locales from FreeBSD :)

The “fix”

First we need to know which version of FreeBSD our pfSense build runs on. This might not matter too much, but I figured it’s probably better to stick to that.

# uname -r

Cool, so we’re tracking the STABLE-branch of FreeBSD 11.3. So we need to fetch the base.txz for the 11.3 release from

# fetch

Next up we simply extract the locale we need.

# tar -C / -xvf base.txz ./usr/share/locale/en_US.UTF-8/
x ./usr/share/locale/en_US.UTF-8/
x ./usr/share/locale/en_US.UTF-8/LC_TIME
x ./usr/share/locale/en_US.UTF-8/LC_MESSAGES
x ./usr/share/locale/en_US.UTF-8/LC_NUMERIC
x ./usr/share/locale/en_US.UTF-8/LC_MONETARY
x ./usr/share/locale/en_US.UTF-8/LC_COLLATE
x ./usr/share/locale/en_US.UTF-8/LC_CTYPE

And we’re done. You don’t even need to setenv a locale. It will just automagically work :)
This can of course be repeated for any other locale as well.