+ + +
← BACK TO BLOG
2026-03-12 / 4 min read | PrivacySecurityNixOSLinux

My Privacy and Security Setup on NixOS

OpenSnitch blocking every outbound connection by default, Mullvad with SOCKS proxies, encrypted Firefox vaults, firejailed apps and a full pentesting toolkit. All declarative.

I take privacy and security pretty seriously. Not in a tinfoil hat way but in a "I want to know exactly what's leaving my machine and where it's going" way. And running NixOS makes this significantly easier than it would be on any other distro because I can declare my entire security posture in config files that I version control.

Let me walk through what my actual setup looks like.

OpenSnitch - application firewall

This is probably the most important piece. I run OpenSnitch as an application-level firewall with the default action set to deny. That means every single process that tries to make an outbound connection gets blocked unless I've explicitly allowed it. It uses eBPF for process monitoring and nftables for the actual filtering.

I've got rules for the stuff that obviously needs network access. Firefox, Claude Code, git, the nix daemon, Protonmail Bridge, Syncthing, Spotify. But here's the thing, curl is intentionally NOT whitelisted. It's the number one tool used by supply chain attacks to download payloads so every curl request that happens on my system prompts me through OpenSnitch so I can see exactly where it's going. If some random npm package tries to phone home I'll know about it.

I've also got a hard block rule on Discord domains. Not because I have anything against Discord but because I don't want anything on my system talking to their servers without me knowing.

Mullvad VPN

Mullvad is my VPN and I've got some specific hardening around it. When Mullvad is enabled on a machine my NixOS config automatically disables IPv6 system-wide. The reason is that Mullvad's tunnel has IPv6 turned off so any IPv6 traffic would bypass the tunnel and leak my real address. The config also forces Docker containers to use the host's systemd-resolved stub instead of falling back to Google DNS during Mullvad transitions.

I've built custom Go tools for managing Mullvad too. A TUI for quick relay switching and a relay selector. Both compiled as Go modules in my nix config. I also use SOCKS proxies through Mullvad for routing specific applications through different exit nodes which gives me more granular control over what traffic goes where.

I've also got Tailscale set up with Mullvad as my exit node. So all my devices including my phone are connected to my infrastructure through Tailscale but the traffic exits through Mullvad. That means I can access any of my servers from anywhere, even from my phone on mobile data, and I've still got the privacy of a VPN. It's the best of both worlds right. Private mesh networking for my fleet and encrypted tunnelling for everything going out to the internet.

Firejail sandboxing

Every application that doesn't need full system access runs in a firejail sandbox. I've got custom profiles for Spotify, Telegram and Steam. Each profile explicitly blacklists sensitive directories like .ssh, .gnupg, .mozilla and my nix-config. They whitelist only what the app actually needs and drop all capabilities, disable printers and USB, restrict namespaces and filter D-Bus access.

The Spotify profile for example can only see its own cache and config directories plus the nix store. It can't see my home directory, it can't see my SSH keys and it can't see any of my projects. If Spotify gets compromised the blast radius is basically zero.

Secrets management with agenix

All my secrets are managed through agenix. API keys, tokens, passwords, they're all encrypted with age and only decrypted at build time on the machines that need them. They never sit on disk in plaintext outside of the nix store.

I've even built a custom MCP secrets server that sits between Claude Code and my secrets. It runs as a dedicated system user, reads secrets from agenix and verifies callers by walking the process tree and matching against the exact Claude Code store path. A compromised process running as my user can't read the secrets because they're owned by a different user and it can't impersonate Claude because of the exact store path pinning. It's a proper defence-in-depth approach.

GnuPG

GPG is enabled with SSH support through the agent so I can use my GPG keys for both signing and SSH authentication. Kleopatra is installed for key management.

Why NixOS makes this work

The thing about all of this is that it's declarative. My entire security setup is in version-controlled nix files. If I set up a new machine it gets the same OpenSnitch rules, the same Mullvad hardening, the same firejail profiles, the same pentesting tools. I don't have to remember what I installed or configured. It's just there.

And because it's all code I can review changes, roll back if something breaks and know exactly what's running on every machine in my fleet. That's the kind of confidence you don't get from manually installing security tools and hoping you didn't forget anything.