Skip to content

Latest commit

Β 

History

28 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PrivacyOS

⚠️ Do not run this on a system you're already using. privacyos.sh reconfigures package sources, purges packages, rewrites /etc/hosts, and overwrites browser profiles β€” it's built for a fresh Debian 13 (Trixie) install with nothing on it you care about yet, not your daily driver. The script itself asks you to type yes to confirm this before it changes anything, but you should know that going in, not find out at that prompt.

🚧 Work in progress β€” actively in testing. The core install has completed successfully, repeatedly, end-to-end β€” packages, DNS, hosts blocklist, browser hardening, default browser and search engine, all confirmed working on a real install. A couple of pieces (automatic security updates, the firewall) were just added and haven't been through that same testing yet, and it's only been run on one setup so far, not a range of real hardware. You're welcome to try it and report anything that breaks β€” that's genuinely useful right now.

A single script that turns a fresh Debian 13 (Trixie) install into a hardened, privacy-first desktop β€” get networking working, run the script, done.

Everything it installs comes through apt: Debian's own repositories, or a vendor repository added the same way LibreWolf's/Waterfox's/Mozilla's/ VSCodium's are. Nothing here is a one-off .deb download, a tarball, an AppImage, or a Flatpak β€” one update mechanism (apt update && apt upgrade) covers everything, and nothing sits around unmanaged outside the package manager's tracking.

Read the script before you run it. That's the point β€” there's nothing here you can't see for yourself.

Why Debian, not Ubuntu or Linux Mint

Both are themselves built on Debian β€” Ubuntu is a Debian derivative, and Mint is built on top of Ubuntu, so it's two layers removed from Debian itself. This project builds directly on Debian instead, deliberately, for reasons that matter specifically for a hardening project rather than being a knock on either:

  • Fewer layers between an upstream security fix and your machine β€” packages come from Debian's own archive or a vendor's own repo, not a derivative's repackaging of one.
  • Debian doesn't carry Ubuntu's Snap-by-default packaging or its history of bundling things like commercial search integration β€” starting from the plainer, more scrutinized base means less to audit and undo before any hardening even starts.
  • It matches this project's own APT-only rule: everything stays one hop from upstream, not two.

Requirements

  • A fresh install of Debian 13 (Trixie) with the Cinnamon desktop already installed. This is a real requirement, not a suggestion β€” the Nemo file-manager integration and the bloat-purge list are both written specifically for what a Cinnamon install includes. Other desktops aren't supported.
  • Easiest way to get there: Debian publishes an official live image with Cinnamon already on it, installed via Calamares (the same graphical installer Linux Mint itself uses) β€” boot it, connect to Wi-Fi through its normal desktop applet if you need to, install to disk from there. No separate desktop-selection step, no apt install afterward.
  • This project is currently verified against Debian 13.6.0, released 2026-07-11.
    • Cinnamon live image: debian-live-13.6.0-amd64-cinnamon.iso (~3.8 GB) β€” links straight to the file itself, not the folder, so there's no risk of grabbing the GNOME/KDE/XFCE/etc. image by mistake. Debian also publishes a .torrent for it β€” often faster than downloading straight from Debian's own server, since you're pulling pieces from everyone else currently sharing the file at the same time instead of one single source. Any torrent client (Deluge, qBittorrent, Transmission, etc.) opens it directly.
    • Prefer a minimal/manual install instead? The plain debian-13.6.0-amd64-netinst.iso (~755 MB, .torrent) works too β€” just make sure to select Cinnamon in the installer's software selection screen (or run sudo apt install task-cinnamon-desktop afterward if you didn't). Unlike the Cinnamon live link above, both of these are on Debian's "current" path, so they'll silently serve whatever point release is newest by the time you click them, not necessarily 13.6.0.
    • Checksums: SHA256SUMS/SHA512SUMS (+ .sign files) sit in the same directory as whichever image you pick β€” verify before you install.
    • Newer Debian point releases should work fine β€” this project is pinned to the trixie codename, not a specific point release, and it runs apt update && apt upgrade as its first real step regardless of which point release you installed from.

Encrypt the disk

Do this during Debian's own installer, before privacyos.sh ever enters the picture β€” it's the one piece of real protection that has to happen at install time, not something the script can add afterward.

Full-disk encryption protects everything β€” not just your personal files, but the operating system itself: browser caches, swap, temp files, system logs, all of it. Without it, someone with physical access to a powered-off machine (lost, stolen, seized, whatever) can just pull the drive and read everything on it directly. With it, none of that is readable without the passphrase, full stop.

  • Using the Cinnamon live image (the recommended path above, installed via Calamares): when you get to partitioning, choose Erase disk, then enable the Encrypt system option before continuing. LVM gets set up underneath automatically as part of that same flow β€” nothing else to configure.
  • Using the netinst image (the classic Debian installer): on the Partition disks screen, choose Guided – use entire disk and set up encrypted LVM.

Either way, you'll be asked to set an encryption passphrase during this step. Write it down somewhere safe before you forget it β€” this isn't a login password, it's what makes the entire disk readable at all, asked for on every single boot before the system even starts. There is no recovery option and no "forgot password" flow. Lose the passphrase and everything on the disk is gone, permanently, by design β€” that's the same property that makes it real protection in the first place.

Root password (optional, but worth deciding on purpose)

Debian's installer separately asks whether to set a root password. This one's optional either way β€” privacyos.sh handles it automatically no matter what you choose β€” but knowing the tradeoff now saves a step later:

  • Leave it blank and Debian adds your regular user to the sudo group automatically (this is Ubuntu's default behavior, for comparison). Your user already has sudo by the time privacyos.sh runs, so it skips straight past the sudo-fix step entirely β€” one less reboot.
  • Set a root password (the traditional Debian way) and your user isn't added to sudo automatically. Nothing's broken β€” privacyos.sh detects this, walks you through fixing it, and reboots once to make it take effect β€” just an extra step compared to leaving it blank.

Neither choice is wrong. If you don't have a specific reason to want a separate root account, leaving the password blank gets you through the install with one fewer reboot.

Quick start

One file, fetched with curl (present by default where git and wget usually aren't), run from one terminal:

curl -fsSLO https://raw.githubusercontent.com/rjc3rd/PrivacyOS/main/privacyos.sh
chmod +x privacyos.sh
./privacyos.sh

That's genuinely it β€” privacyos.sh is fully self-contained, no sibling files it depends on, nothing else to download first. It checks whether your user actually has sudo yet and walks you through fixing it if not (a fresh Debian install doesn't always grant that automatically β€” depends on a choice made in Debian's own installer), installs a small set of basic tools it needs (wget, gnupg, git, curl), then goes straight into the actual PrivacyOS install this README describes below.

If your user wasn't a sudoer yet, fixing that needs a real reboot β€” tested directly, logging out and back in isn't reliably enough, so the script doesn't leave that to chance; it'll ask before rebooting, not just do it. Once it's back up, run ./privacyos.sh again β€” apt/package steps are idempotent, so it picks back up quickly rather than needing to resume from some exact point.

Prefer to do each step yourself instead of running a script you haven't read line by line first? Totally reasonable, and the point of this project is that you can β€” read it, then either run it as-is or do its steps by hand. git clone https://github.com/rjc3rd/PrivacyOS.git works fine too if you'd rather have the whole repo locally (e.g. you're planning to contribute back).

Run it as your normal user, not root β€” it calls sudo itself wherever it needs to.

Before it changes anything, privacyos.sh asks you to type yes to confirm this is actually a fresh install β€” same pattern installers like ISPConfig's use, on purpose: this reconfigures package sources, installed software, /etc/hosts, and browser profiles, and it's built for a machine with nothing on it you care about yet, not one you're already using.

Every optional choice is a command-line flag, so you can pre-decide exactly what you want (and script/document it, or eventually generate the command from a checkbox picker on privacyos.dev) instead of answering prompts. Anything you don't pass a flag for gets asked interactively β€” as a graphical dialog if available, a plain terminal prompt otherwise. E.g. ./privacyos.sh --theme --dns=quad9.

--dns=PROVIDER      quad9 (default) | nextdns | opendns | none
--theme / --no-theme          desktop theming extras (asks if omitted)
--apps  / --no-apps            creative/media/dev app bundle (asks if omitted)
--no-librewolf                 skip LibreWolf     (included by default)
--no-firefox                   skip Firefox        (included by default)
--no-tor                       skip Tor Browser    (included by default)
--no-waterfox                  skip Waterfox       (included by default)
--no-chromium                   skip Chromium (the no-extensions fallback browser)
--yes                           non-interactive: accept defaults for anything
                                 not given an explicit flag (theme=no, apps=no)
-h, --help                      show help and exit

Once every prompt is answered and it actually starts making changes, expect it to take 15-20 minutes, depending on your connection and hardware β€” it's genuinely doing a lot (packages, repos, DNS, the hosts file, browser hardening), not stuck. Long quiet stretches while apt or a download works in the background are normal.

What the core install does

  • Points /etc/apt/sources.list at Debian 13/Trixie explicitly (not the generic stable alias, so this keeps targeting Trixie even after the next Debian release ships).
  • Removes a set of default desktop apps this project doesn't need.
  • Installs core privacy/security tooling: secure-delete, wipe, bleachbit, riseup-vpn, tor, keepassxc, wireshark (plus a right-click "Secure Delete" action in the Nemo file manager). tor is the standalone background proxy daemon (distinct from Tor Browser, installed separately below) β€” it just runs, quietly, always available on 127.0.0.1:9050 for anything that wants to use it.
  • Installs a privacy-focused browser set β€” LibreWolf (primary), Firefox (fallback), Tor Browser, Waterfox β€” plus a deliberately bare, no-extensions Chromium kept entirely separate. Chromium isn't just a compatibility fallback for sites a hardened browser breaks; it's deliberate browser isolation β€” for sites you have to use but don't trust (job sites, Microsoft properties, etc.), using a completely separate, unlinked browser means whatever they collect there can't be correlated with anything in your real, hardened browsing identity. Each browser is individually skippable via flag.
  • Installs Thunderbird for mail.
  • Configures an encrypted DNS resolver (Quad9 by default) via systemd-resolved.
  • Installs and enables unattended-upgrades for automatic security updates specifically β€” Debian's own shipped default config already restricts to security-only, nothing else gets silently auto-installed. This doesn't replace upgrade (below) β€” it handles routine background security patching, upgrade is still how you refresh the hosts list and browser hardening, and do a full package upgrade whenever you want one.
  • Installs and enables ufw with the simplest correct desktop posture: deny all incoming, allow all outgoing. Nothing on this machine is meant to be reachable from the network, and everything an actual user does β€” browsing, email, messaging β€” is a connection this machine starts outward, so nothing here needs to be specially allowed.
  • Builds /etc/hosts from the StevenBlack list plus your own custom.hosts (see below).
  • Builds hardened browser preferences from Arkenfox + Betterfox plus this project's own small overrides-user.js, applied to Firefox/Waterfox. LibreWolf gets just the overrides file, since it already hardens its own defaults β€” layering the full Arkenfox/Betterfox set on top would fight settings it made on purpose.
  • Force-installs a standard extension set into Firefox, Waterfox, and LibreWolf via policies.json (Mozilla's own enterprise mechanism for this) β€” each extension with its own out-of-the-box defaults, no custom rules or filters layered in: uBlock Origin (Firefox and LibreWolf only β€” see notes below), ClearURLs, Don't track me Google, KeePassXC-Browser, LocalCDN, Onion Browser Button (see note below), Port Authority, SponsorBlock for YouTube.
  • Sets LibreWolf as the system default browser, and adds ProxySearch.org as an available and default search engine in Firefox, Waterfox, and LibreWolf β€” see Default browser and search engine below.
  • Sets the hostname to privacyos.
  • Finishes with apt update && apt upgrade and a reboot.

Optional extras

Neither of these is "hardening" β€” they're kept separate so installing them isn't forced on anyone who just wants the core setup.

  • --theme: Cinnamon config, Mint-Y-Dark theme, icons, wallpapers. Not yet built β€” tracked for a future update.
  • --apps: GIMP, Inkscape, darktable, RawTherapee, Scribus, Flowblade, Audacity, Audacious, mpv, Celluloid, Deluge, FileZilla, SimpleScreenRecorder, VSCodium, Terminator, mintstick, dconf-editor, gnome-clocks, plus a small, deliberately curated set of basic games β€” Mahjongg, Mines, Moonlander, Reversi, Solitaire, Sudoku, Yahtzee β€” chosen specifically instead of reintroducing the old bundled gnome-games package this project already purges from core.

Ad/tracker blocking

/etc/hosts is built from exactly one list β€” StevenBlack/hosts β€” plus custom.hosts, a plain local file in this repo for your own additions. This project used to stack several different lists from several maintainers; real, repeated experience was that it caused more site breakage (an overzealous or stale entry in one of them blackholing a domain some site actually needed) than it was worth. StevenBlack alone is well-maintained and strikes a better balance β€” one source is also just one thing that can go stale or move.

custom.hosts is merged in before StevenBlack's list, which matters if you ever want to override an entry: for a given hostname, the first matching line in /etc/hosts wins, so anything you put in custom.hosts takes priority over the downloaded list β€” useful both for adding your own blocks and for un-blocking something StevenBlack catches that you actually need.

Extension notes

  • uBlock Origin is excluded from Waterfox on purpose. Waterfox has its own native ad-blocking engine built in (Brave's open-source adblock engine, using uBlock Origin's own filter lists β€” EasyList, EasyPrivacy, and more), running in the browser process rather than as an extension. Installing the actual extension on top would just be redundant with what's already running.
  • LibreWolf gets a merge, not a fresh file. Firefox-family browsers use exactly one policies.json β€” picked by priority, never merged with any other β€” and LibreWolf ships its own, which does a lot more than extensions (disables telemetry/studies, forces HTTPS-Only, blocks local- network tracking, strips sponsored content, and more). Overwriting it blindly would have silently undone all of that. Instead, LibreWolf's real current defaults (pulled from their own settings repo) are reproduced here with this project's extensions added into the existing list β€” nothing else touched. If LibreWolf changes their own defaults later this copy won't automatically follow, so it's worth re-diffing against their repo occasionally rather than trusting it as a one-time copy. LibreWolf already installs uBlock Origin itself (removable, not locked) β€” left exactly as-is, not force-installed or duplicated.
  • Privacy Possum was considered and deliberately left out β€” its last release was 2019. Not something to include in a privacy-hardening tool without active maintenance behind it.
  • Onion Browser Button is not affiliated with the Tor Project β€” it's an independently-developed convenience extension, unrelated to Tor Browser itself (which this project already installs separately, properly isolated). Its actual purpose here: this project also installs the tor package itself, which runs a local Tor SOCKS proxy in the background all the time β€” this extension is a one-click way to route regular browser traffic through that already-running local proxy for something quick, without launching the full, heavier, more isolated Tor Browser every time. Checked its actual source rather than just trusting the listing (it's open source: github.com/jeremy-jr-benthum/onion-browser-button): permissions are minimal (proxy, storage, notifications β€” nothing broader), toggling it on points Firefox's proxy settings at 127.0.0.1:9050 (the standard local Tor SOCKS port β€” not some third party's server) and verifies the connection against Tor Project's own official check.torproject.org, exactly matching what it claims to do. The one thing worth knowing: on install/update it opens a changelog tab on the developer's own site with the version number in the URL (visible, low-sensitivity β€” you'd see the tab open, it's not hidden) β€” and that tab doesn't open when it detects an automated testing environment. Common, usually-benign pattern for not spamming testers with tabs, but also the kind of "behaves differently under review" detail worth knowing about rather than glossing over. Nothing else in the code goes beyond its stated purpose β€” this was independently verified for this project by reading the extension's actual shipped source, not just its store listing, so it's included here on that basis, not blind trust. If you'd still rather not run a third-party extension for this at all, the extension isn't doing anything you can't do yourself by hand: in any Firefox-based browser, Settings β†’ Network Settings β†’ Manual proxy configuration β†’ SOCKS Host 127.0.0.1, Port 9050, SOCKS v5 β€” that's the entire mechanism, one click or typed in by hand.

Default browser and search engine

  • LibreWolf is set as the system default browser (xdg-settings set default-web-browser librewolf.desktop) β€” it's the browser this project hardens the most conservatively (its own upstream defaults, not layered Arkenfox/Betterfox), so it's the one meant for everyday use. Skipped automatically if you installed with --no-librewolf.
  • ProxySearch.org β€” a privacy-respecting meta search engine β€” is added as an available search engine and set as the default in Firefox, Waterfox, and LibreWolf, via each browser's policies.json. None of the built-in engines (Google, DuckDuckGo, etc.) are removed β€” ProxySearch is just what a fresh search starts with; switch back to any of them in Settings β†’ Search any time.
  • The "make this your default browser" startup nag is suppressed on Firefox and Waterfox (browser.shell.checkDefaultBrowser set to false in overrides-user.js) β€” there's no need for either to keep asking when LibreWolf is already set as the actual default. LibreWolf never showed this prompt in the first place (DontCheckDefaultBrowser is already part of its own upstream policies.json, reproduced as-is here).

DNS resolver options

  • Quad9 (default) β€” free, unlimited, no account, run by the nonprofit Quad9 Foundation. Configured via DNS-over-TLS.
  • OpenDNS β€” configured as plain DNS only; its DNS-over-TLS support isn't well established enough to enable encryption automatically here.
  • NextDNS β€” uses a personal per-account config ID rather than a shared address, so it can't be wired in generically. The script prints a pointer to my.nextdns.io instead of guessing.
  • none β€” leaves DNS at whatever the network provides.

(Mullvad's public DNS service was considered but is being shut down by Mullvad itself, with users migrated to Quad9 β€” not included here for that reason.)

Staying up to date

Installing drops an upgrade command into ~/.local/bin/ (already on your PATH) β€” run it whenever you'd otherwise run apt update && apt upgrade by hand. It asks for your sudo password once, then: upgrades all packages, removes old kernels that pile up along the way, cleans up, rebuilds /etc/hosts from a fresh StevenBlack list plus your custom.hosts, and rebuilds Firefox/Waterfox/LibreWolf's hardened preferences from a fresh Arkenfox + Betterfox. One command, meant to become part of your normal routine rather than something you reach for occasionally.

Your own additions β€” custom.hosts and overrides-user.js β€” live in ~/.config/privacyos/ once installed, not in the cloned repo folder, so upgrade still works even if you delete that folder afterward. Edit them there; upgrade only ever reads them, never overwrites them.

Roadmap

  1. This script. βœ… (first draft β€” needs real-hardware testing; see below)
  2. A Debian preseed file that fully automates the official Debian installer and runs this script automatically as its last step, so installing PrivacyOS is closer to one step instead of two. Planned next, not yet built.
  3. A small companion site at privacyos.dev pointing here.

A full custom pre-built ISO was considered and set aside for now β€” a frozen image goes stale in a way this script doesn't (it always installs current packages at run time), and the preseed approach above gets most of the same benefit without that trade-off.

Status

Core install (packages, DNS, hosts blocklist, browser hardening/extensions, default browser, default search engine) has been tested end-to-end multiple times and completes successfully, including a full reboot into a working system. Automatic security updates and the firewall are newly added and haven't been through that same real-install testing yet. --theme is wired into the flag/prompt system but has no implementation behind it yet. All of this has only run on one testing setup so far β€” not yet tried across a range of real hardware or network configurations, so still expect the occasional rough edge outside what's been directly exercised, particularly around the DNS/NetworkManager interaction on hardware this hasn't been tried on.

License

MIT β€” see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages