223
Sarah’s Security Brief: I have spent the last three years building isolated penetration testing labs for clients who needed to simulate real network conditions without exposing production infrastructure. Privacy is not a single tool you install. It is a stack of decisions across three layers: your browser, your DNS, and your network. This guide walks you through hardening all three on Ubuntu 26.04, with every command captured from a live VM so you can see exactly what each step produces.
Threat Model Assessment: What Are You Actually Protecting? (2026)
Before I install a single tool, I need to know what I am protecting against. Privacy is not binary. A journalist protecting sources has a different threat model than a developer who simply does not want targeted ads. I learned this the hard way when a client asked me to set up Tor for their entire office, only to discover their real problem was DNS leaks from their ISP, not traffic interception.
Here is how I break down the three privacy layers that matter on a Linux desktop:
Layer 1: Browser fingerprinting and tracking. This is what most people think of when they hear privacy. Cookies, canvas fingerprinting, WebRTC leaks, and cross-site tracking. Firefox with the right configuration handles this layer well.
Layer 2: DNS resolution. Every domain you visit goes through a DNS resolver. If that resolver is your ISP, they know every site you visit even if the connection itself is encrypted. Encrypted DNS (DoH or DoT) closes this gap.
Layer 3: Network-level traffic analysis. Even with encrypted DNS and a hardened browser, your ISP can see which IP addresses you connect to and when. Tor or a VPN with a kill switch addresses this layer.
Most guides throw Tor at you and call it a day. That is like buying a deadbolt for your front door while leaving every window open. You need all three layers working together.
How to Set Up Tor Browser on Ubuntu 26.04 (2026)
Tor routes your traffic through three encrypted relays around the world, making it extremely difficult for anyone to trace your activity back to your real IP address. It is the strongest privacy tool available to regular users, but it comes with a speed tradeoff that you need to understand before relying on it.
I install Tor Browser from the official Ubuntu repository using torbrowser-launcher, which handles the download, verification, and desktop integration automatically.
fosslinux@ubuntu:~$ sudo apt update -qq && sudo apt install -y torbrowser-launcher tor
...
fosslinux@ubuntu:~$ tor --version
Tor version 0.4.9.6.
This build of Tor is covered by the GNU General Public License
fosslinux@ubuntu:~$ sudo systemctl status tor --no-pager | head -3
[OK] tor.service - Anonymizing overlay network for TCP
Loaded: loaded (/usr/lib/systemd/system/tor.service; enabled)
Active: active (exited) since Thu 2026-06-25 15:04:08 EDT
The torbrowser-launcher package does three things: it downloads the official Tor Browser bundle from the Tor Project, verifies the GPG signature to ensure authenticity, and creates a desktop shortcut for easy access. The tor package installs the Tor daemon itself, which handles the relay connections. The version shown above (0.4.9.6) was current at capture time. Check tor --version after installation to confirm you have the latest stable release.
Launch Tor Browser from your application menu. The first launch takes 30 to 60 seconds as it bootstraps the Tor circuit. You will see a progress bar labeled “Connecting to the Tor network.” Once connected, the browser opens with the default security level set to “Standard.”
Why It Matters: Tor is not a VPN replacement. A VPN encrypts traffic between you and the VPN server. Tor encrypts traffic across three independent relays, so no single point knows both who you are and what you are accessing. The tradeoff is speed: expect 2 to 5 times slower connections compared to your direct link.
I recommend setting the security level to “Safest” under the shield icon for maximum protection. This disables JavaScript on non-HTTPS sites and blocks many browser features that can leak your identity. The downside is that some websites will break or render incorrectly.
DNS over HTTPS and DNS over TLS: Encrypted DNS on Linux (2026)
DNS is the phonebook of the internet. When you type fosslinux.com, your system asks a DNS resolver for the IP address. On most Linux systems, that resolver is whatever your DHCP server hands out, which is usually your ISP. That means your ISP logs every domain you visit, even if the connection itself is HTTPS encrypted.
systemd-resolved, which ships with Ubuntu 26.04, supports DNS over TLS natively. Here is what the default state looks like before any configuration:
fosslinux@ubuntu:~$ resolvectl status | head -8
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Link 2 (ens33)
Current Scopes: DNS
Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
DNS Servers: YOUR_GATEWAY_IP
The -DNSOverTLS flag confirms that encrypted DNS is disabled. To enable it, I create a drop-in configuration file that specifies privacy-respecting resolvers:
fosslinux@ubuntu:~$ sudo tee /etc/systemd/resolved.conf.d/dot.conf [Resolve] DNS=9.9.9.9#dns.quad9.net 1.1.1.1#cloudflare-dns.com DNSOverTLS=yes DNSSEC=allow-downgrade FallbackDNS=8.8.8.8#dns.google fosslinux@ubuntu:~$ sudo systemctl restart systemd-resolved
After restarting systemd-resolved, the status changes to confirm encrypted DNS is active:
fosslinux@ubuntu:~$ resolvectl status | head -8
Global
Protocols: -LLMNR -mDNS +DNSOverTLS
DNSSEC=allow-downgrade/unsupported
resolv.conf mode: stub
DNS Servers: 9.9.9.9#dns.quad9.net 1.1.1.1#cloudflare-dns.com
Fallback DNS Servers: 8.8.8.8#dns.google
Link 2 (ens33)
Current Scopes: DNS
Protocols: +DefaultRoute -LLMNR -mDNS +DNSOverTLS
The +DNSOverTLS flag confirms the change. I verify that resolution works correctly:
fosslinux@ubuntu:~$ resolvectl query fosslinux.com
fosslinux.com: 172.67.175.245 -- link: ens33
104.21.72.63 -- link: ens33
2606:4700:3035::6815:483f -- link: ens33
2606:4700:3034::ac43:aff5 -- link: ens33
For Firefox users, you can also enable DoH directly in the browser. Open about:config, search for network.trr.mode, and set it to 2 (DoH with fallback to DoT). This means Firefox handles its own DNS resolution independently of the system resolver, which is useful if you want DoH in Firefox but DoT for other applications.
Pi-hole vs AdGuard Home: Network-Level Privacy Blocking (2026)
Pi-hole and AdGuard Home are DNS-based ad and tracker blockers. They sit between your devices and the internet, intercepting DNS queries and blocking domains known to serve ads, trackers, and malware. I have deployed both for clients and have strong opinions on when to use each.
Pi-hole is the mature choice. It has been around since 2014, has a massive community, and integrates with virtually every platform. AdGuard Home is newer, faster, and has a cleaner interface out of the box. Here is my typical Pi-hole Docker deployment:
fosslinux@ubuntu:~$ sudo docker pull pihole/pihole:latest 25b68e72aa6d: Pull complete b921dec6d192: Pull complete Digest: sha256:8ea95136e7c8c15b42d88eadf1a3875421aa1be30ad39e50f661188cc986fb27 Status: Downloaded newer image for pihole/pihole:latest fosslinux@ubuntu:~$ sudo docker run -d --name pihole \ -p 53:53/tcp -p 53:53/udp -p 80:80/tcp \ -e TZ=America/New_York -e WEBPASSWORD=fosslinux \ -e SERVERIP=YOUR_SERVER_IP --restart=unless-stopped \ pihole/pihole:latest d420c267a48e54dfba1939e46347adce1eb9a5e430c1d92b10a873da672e7e35
Replace YOUR_SERVER_IP with the actual IP address of the machine running Pi-hole. Find it with ip addr show or hostname -I.
Insight: Pi-hole binds to port 53, which conflicts with systemd-resolved on Ubuntu. Before starting the Pi-hole container, stop the resolved service with sudo systemctl stop systemd-resolved. If you skip this step, the container will fail silently and you will spend thirty minutes debugging a port conflict that the error messages do not clearly identify.
AdGuard Home takes a different installation approach. Instead of Docker, I download the binary directly:
fosslinux@ubuntu:~$ wget -O /tmp/AdGuardHome_linux_amd64.tar.gz \ fosslinux@ubuntu:~$ tar -xzf /tmp/AdGuardHome_linux_amd64.tar.gz -C /tmp/ fosslinux@ubuntu:~$ /tmp/AdGuardHome/AdGuardHome --version AdGuard Home, version v0.107.77
AdGuard Home includes a web-based setup wizard on first launch. Run sudo /tmp/AdGuardHome/AdGuardHome -s install to install it as a systemd service, then access the configuration at http://your-ip:3000. The wizard walks you through DNS configuration, upstream resolver selection, and filter list activation.
Pro Tip: For a fully self-hosted DNS stack, combine Pi-hole or AdGuard Home with Unbound. Unbound acts as a recursive resolver that queries root servers directly, eliminating any dependency on upstream resolvers like Google or Cloudflare. I cover this setup in the next section.
Firefox Hardening: about:config Tweaks and Extensions for Privacy (2026)
Firefox 152.0.1 ships with solid defaults, but several about:config tweaks significantly improve your privacy posture. I test every change on a fresh Firefox profile before recommending it, because some tweaks break legitimate websites.
fosslinux@ubuntu:~$ snap list | grep firefox firefox 152.0.1-1 8521 latest/stable/... mozilla -
Open Firefox and type about:config in the address bar. Accept the risk warning, then search for and modify these settings:
privacy.resistFingerprinting: Set to true. This enables a wide range of anti-fingerprinting measures including spoofed timezone, screen dimensions, and font enumeration. It is the single most impactful privacy tweak in Firefox.
privacy.firstparty.isolate: Set to true. This isolates cookies to the first-party domain, preventing cross-site tracking. The tradeoff is that some single sign-on flows may break.
network.http.referer.XOriginPolicy: Set to 2. This limits referrer headers to same-origin requests only, preventing sites from seeing where you came from.
media.peerconnection.enabled: Set to false. This disables WebRTC, which can leak your real IP address even when using a VPN or Tor. This is critical for VPN users.
geo.enabled: Set to false. Disables the Geolocation API entirely.
Worth Knowing: If a tweak breaks a website you need, you can create a per-site exception. Type about:config, search for the preference, and use the plus button to add a site-specific override. This lets you keep strict defaults while allowing exceptions for trusted sites.
For extensions, I recommend exactly two:
uBlock Origin: Not optional. It blocks ads, trackers, and malware domains at the network level. Install it first, before anything else. As of 2026, it holds the Firefox Recommended badge with over 10 million users and monthly updates.
Firefox Built-in HTTPS-Only Mode: Open about:preferences#privacy and enable “HTTPS-Only Mode” under Enhanced Tracking Protection. This replaces the deprecated HTTPS Everywhere extension and upgrades all HTTP connections to HTTPS automatically. Firefox 152 includes this as a native feature.
For cookie management, Firefox 152’s Enhanced Tracking Protection (set to “Strict” under about:preferences#privacy) handles cross-site tracking cookies automatically. Combined with privacy.firstparty.isolate, this gives you strong session isolation without needing a separate cookie extension.
VPN Kill Switch Setup on Linux (2026)
A VPN kill switch is a firewall rule that blocks all internet traffic if your VPN connection drops. Without it, a momentary disconnection exposes your real IP address to whatever site you are visiting. I have seen this happen in production environments where a VPN tunnel flapped for thirty seconds and leaked DNS queries to the ISP.
Here is a nftables-based kill switch that I use with WireGuard. It drops all outbound traffic by default, then makes exceptions for the WireGuard tunnel, SSH, and local network access:
fosslinux@ubuntu:~$ sudo apt install -y wireguard nftables
fosslinux@ubuntu:~$ sudo tee /etc/nftables-wireguard-killswitch.nft
table ip killswitch {
chain output {
type filter hook output priority 0; policy drop;
oifname "lo" accept
meta mark == 0x162 accept
ip daddr YOUR_LAN_CIDR accept
icmp type echo-request accept
udp dport 51820 accept
tcp dport 22 accept
}
}
fosslinux@ubuntu:~$ sudo nft -f /etc/nftables-wireguard-killswitch.nft
Let me explain each rule. The policy drop means all traffic is blocked by default. oifname "lo" allows loopback traffic so local services still work. meta mark == 0x162 allows traffic marked by WireGuard’s PostUp hook. ip daddr YOUR_LAN_CIDR allows local network access. Replace YOUR_LAN_CIDR with your actual subnet, such as 192.168.1.0/24 or 10.0.0.0/8. udp dport 51820 allows WireGuard’s default port. tcp dport 22 allows SSH so you do not lock yourself out.
fosslinux@ubuntu:~$ sudo nft list tables table ip mangle table ip6 mangle table ip nat table ip6 nat table ip6 filter table ip raw table ip filter table ip killswitch
To test the kill switch, bring up the WireGuard interface and then disconnect it. All internet traffic should stop immediately. If you can still reach external sites after disconnecting WireGuard, the kill switch is not working and you need to review your nftables rules.
Unbound: Making Your DNS Fully Self-Hosted (2026)
Unbound is a validating, recursive DNS resolver. Instead of forwarding your queries to Google or Cloudflare, it resolves domains by querying the root servers and TLD servers directly. This gives you complete DNS privacy with no third-party dependency. The version shown (1.24.2) was current at capture time. Check unbound --version after installation and consult the Unbound releases page for the latest security patches.
fosslinux@ubuntu:~$ sudo apt install -y unbound
Setting up unbound (1.24.2-1ubuntu2.1)...
fosslinux@ubuntu:~$ sudo tee /etc/unbound/unbound.conf.d/privacy.conf
server:
interface: 127.0.0.1
interface: ::1
access-control: 127.0.0.0/8 allow
access-control: ::1 allow
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
use-caps-for-id: yes
edns-buffer-size: 1232
prefetch: yes
num-threads: 1
message-cache-size: 64m
rrset-cache-size: 128m
fosslinux@ubuntu:~$ sudo systemctl restart unbound
fosslinux@ubuntu:~$ sudo systemctl is-active unbound
active
fosslinux@ubuntu:~$ dig @127.0.0.1 fosslinux.com A +short
172.67.175.245
104.21.72.63
The key settings here are hide-identity and hide-version, which prevent Unbound from leaking its version and configuration details in response to queries. harden-dnssec-stripped ensures DNSSEC validation is enforced. use-caps-for-id adds case randomization to DNS queries, which prevents DNS rebinding attacks.
With Unbound running on localhost, configure Pi-hole or AdGuard Home to use 127.0.0.1 as the upstream resolver instead of external servers. This creates a fully self-hosted DNS pipeline: your device queries Pi-hole, Pi-hole blocks ads and trackers, and Unbound resolves legitimate queries by talking directly to the root servers.
Privacy vs Convenience: The Tradeoffs You Need to Accept (2026)
Every privacy improvement comes with a convenience cost. I have tested this tradeoff extensively across my own machines and client deployments, and here is the honest breakdown.
Tor: Maximum privacy, minimum speed. Expect 2 to 5 times slower page loads. Some sites block Tor exit nodes entirely. I use Tor for research and sensitive browsing, not for daily driving.
Encrypted DNS: Minimal impact. DoT adds 5 to 15 milliseconds per query, which is imperceptible. The only noticeable issue is that some corporate networks block non-standard DNS ports, which can break DoT entirely. In those cases, fall back to DoH in Firefox.
Pi-hole or AdGuard Home: Significant quality-of-life improvement with occasional breakage. Some apps and sites break when their tracking domains are blocked. You will need to whitelist domains occasionally, which teaches you exactly how much tracking modern software does.
Firefox hardening: Moderate impact. privacy.resistFingerprinting breaks some sites that rely on accurate timezone or screen data. WebRTC disabling breaks video calling in the browser. I keep WebRTC enabled in my daily profile and disable it only in my high-privacy profile.
VPN kill switch: Low impact when configured correctly. The main risk is accidentally locking yourself out of SSH if you forget to allow port 22 in the rules. Always test the kill switch while physically at the machine, not remotely.
The right approach is layered. Start with encrypted DNS, which costs almost nothing. Add Firefox hardening for the tweaks that do not break your workflow. Set up Pi-hole or AdGuard Home for network-wide blocking. Use Tor for sensitive tasks. Add a VPN kill switch if you use a VPN. Not every layer is necessary for every person, but understanding what each layer protects against lets you make informed decisions.
Start Hardening Your Linux Privacy Today (2026)
Privacy on Linux in 2026 is not about installing one magic tool. It is about building a stack that covers your browser, your DNS, and your network traffic. I walked you through Tor Browser setup, systemd-resolved DoT configuration, Pi-hole and AdGuard Home deployment, Firefox hardening, WireGuard kill switch rules, and Unbound recursive DNS. Every command was captured from a live Ubuntu 26.04 VM running kernel 7.0.0.
Start with the layer that addresses your most pressing concern. If your ISP is logging your DNS queries, encrypted DNS is the fastest win. If you need anonymous browsing, Tor Browser is the standard. If you want to block trackers network-wide, Pi-hole or AdGuard Home covers every device on your network without installing anything on them individually.
The tools are free, the configuration takes an afternoon, and the privacy gains are real. The only thing standing between you and a more private Linux desktop is the decision to start.
