There's no place like home

- Dorothy Gale, The Wizard of Oz, 1939

Home. It's a nice thing to have. I think it's obvious to anyone that it's also something worth protecting. You don't want people trespassing or messing with your home. But the home I'm talking about here is going to be a different kind of home. I'm talking about HOME.

This is where your documents, pictures, videos, music, code, etc. are put and stored. Anything that belongs to you and not really belonging to the system you're running are kept here.

Just like home, you don't want others messing with your HOME. I think it's a reasonable analogy. I would argue that in the same way that you don't want random strangers messing around with your home, you don't want random strangers messing with your HOME. This may sound far fetched, but if you think about it, I can almost guarantee you that someone that you don't know has messed with your HOME. Do a ls -lah $HOME and look at it. How many dotfiles do you have right now, placed by lazy developers who just dump their application configuration, cache, and data into ~/.mylazyapp?

Now you may not care, which is understandable. To be fair I don't care either if it's a remote server or a shared computer. But I DO care when it's my own personal machine I use everyday. And I'm sure that I'm not the only one that doesn't like their HOME being messed with:

Second, and much worse, the idea of a “hidden” or “dot” file was created.

As a consequence, more lazy programmers started dropping files into everyone's home directory. I don't have all that much stuff installed on the machine I'm using to type this, but my home directory has about a hundred dot files and I don't even know what most of them are or whether they're still needed. Every file name evaluation that goes through my home directory is slowed down by this accumulated sludge.

I'm pretty sure the concept of a hidden file was an unintended consequence. It was certainly a mistake.

How many bugs and wasted CPU cycles and instances of human frustration (not to mention bad design) have resulted from that one small shortcut about 40 years ago?

Keep that in mind next time you want to cut a corner in your code.

- Robe Pike on the Origin of Dot File Names

Unix like systems have traditionally lacked a standard way to store application or user data on a per-user basis. Consequently these data are often stored in an ad-hoc, inconsistent, and problematic way in "dot files" of the user's home directory.

This is a problem because:

  • It breaks when sharing a home directory between different machines, or sessions (eg. using NFS)
  • Not cleanly separating cache, runtime (eg. sockets), or app data from user settings make it very difficult to manage
  • It makes it extremely challenging to perform smart or selective migration of settings between different OS versions
  • It is hard to reset settings without breaking things
  • It is hard to determine how to clear cache data to make room when the disk is filling up
  • It is hard to write a robust and efficient backup solution
  • It doesn't allow an admin flexibility to change where data and settings are stored
  • It dramatically increases the complexity and incoherence of the system for administrators
  • Aggregated across the entire OS it is an embarrassing mess

- GNOME Goal: XDG Base Directory Specification Usage

It's my HOME! Please don't mess with it!

This is my 3-step guide to HOME protection.

1. Spec up.

A trusty Springfield XDG for HOME defense.

This idea of not letting others mess with your HOME is not a new idea. In fact, there has been a Freedesktop.org specification for the Linux desktop since 2000. It's essentially the standard followed by DEs (especially Gnome and KDE) to Not Fuck Your Shit Up™.

It's called the XDG Base Directory Specification. You may have heard of it. Unfortunately, there are still many that haven't, which is why we're here.

For the average HOME owner, all you have to do is set some environment variables:

Bash/Zsh

export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_RUNTIME_HOME="/run/user/1000/"
export XDG_DATA_DIRS="/usr/local/share:/usr/share"
export XDG_CONFIG_DIRS="/etc/xdg"

Fish

set -x XDG_CONFIG_HOME "$HOME/.config"
set -x XDG_CACHE_HOME "$HOME/.cache"
set -x XDG_DATA_HOME "$HOME/.local/share"
set -x XDG_RUNTIME_HOME "/run/user/1000/"
set -x XDG_DATA_DIRS "/usr/local/share:/usr/share"
set -x XDG_CONFIG_DIRS "/etc/xdg"

Ironically, if you use bash/zsh, you have to place these exports inside a non-compliant location. For fish however, it goes into "$XDG_CONFIG_HOME"/fish/config.fish, which is nice.

But generally, you don't even need to do this in most cases, as any sane1 software will fallback to ~/.config, ~/.cache, ~/.local/share, etc. without such env vars in place.

2. Lock down your  HOME.

Put this sign on floor level windows to deter potential break-ins.

Do this:

chmod 555 $HOME

This may seem extreme. But think about it. Do you know anyone that keeps their home unlocked? I've heard of some people living in some rural towns with tight-knit communities do so, but I'd wager that most of us leave our door locked.

So why not keep your HOME locked too?

Think about it.

If you want to keep people from accessing your HOME, the best way to guarantee that is to make it impossible to access in the first place.

"But that's going to break things!"

Not necessarily. Everyone is different with different ways of using their computer, so I guess I can't really guarantee it, but I can say from experience that it is easy to avoid.

And if you really need to for some reason, it's not a big deal. Just because you locked the front door doesn't mean you'll never be able to use it. Just unlock it:

chmod 755 $HOME

Just make sure to remember to lock it after you're done.

This has been successful at proactively preventing programs from messing with my HOME, allowing me to detect such programs and mitigate their lack of compliance. If I want to try out some new fangled program from github and it crashes complaining about HOME permissions, I usually uninstall it.

For example, I noticed that anytime I wanted to install a package from the AUR that relied on building from a git repo, if that package was written in Go or Rust, my install would fail. I would get error messages complaining about how the installation process couldn't molest my HOME. So I added this alias in my fish config that I use to install everything on my Arch Linux system:

function pac
    chmod 755 $HOME
    set TIME0 (date +%s)

    set -x pacman_program 'sudo -u d /usr/bin/yay --pacman powerpill'
    sudo --preserve-env=pacman_program /usr/bin/pacmatic $argv

    set HOME_PATHS $HOME/{,.}*

    for F in $HOME_PATHS
        if test (stat -c %W $F) -gt $TIME0
            # THE NEXT LINE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE NEXT LINE OR THE USE OR OTHER DEALINGS IN THE NEXT LINE.
            sudo rm -rfv $F
        end
    end

    chmod 555 $HOME
end

It defines a pac command that essentially wraps pacmatic, powerpill, and yay all into one. I also just copied yay's fish completion files and so I get really nice completion too.

The important part though is that the very first thing it does is unlock HOME, get the current timestamp, install stuff, then remove anything that entered after that initial timestamp.

This allows me to install programs that need to built with noncompliant languages, such as Rust or Golang.

Rust will happily litter your HOME with ~/.rustup, while Golang will not even bother to hide its sins and create ~/go. At least it's honest I guess?

What the fuck.

These days though it's mainly .yarn/ that I have to deal with.

3. Report any incidents.

Do your neighborly duty.

The Arch Wiki has a great page about this topic (as usual). When you notice software that's messing with your HOME and it's not accounted for, please add it to the wiki. There's a lot of software out there, some of which I'll probably never use, which may have varying degrees of compliance. It's really helpful to be able to check ahead of time with that page with a Ctrl + F (or / in my case, laughs in qutebrowser2) and see if the software is sane, or if there are workarounds that must be done.

On the other hand, if you know of a compliant program not on the page, it's also nice to have that documented as well.

Here's a list of programs I've personally added so far:

  • Spacemacs (naughty)
  • Elixir (nice)
  • sdcv (naughty)
  • Calcurse (extra naughty)3
  • Ghidra (naughty)
  • Nteract (nice)
  • Monero (naughty)
  • A bunch of plain text accounting tools (all naughty)4
    • ledger
    • hledger
    • buchhaltung

1

Compliant with the spec

2

Shout-outs to The-Compiler and his God-like browser

3

The public list of bug reports on the calcurse website is curated by the dev, who so far has not replied to my own email on the mailing list asking about XDG compliance. The pseudo-censorship just rubs me the wrong way.

4

If you know of a plain-text accounting program that follows the spec please let me know, so far it's been 0/7.