Tor-Snowflake on NixOS

2 minute read Published: 2022-03-05

Snowflake is a tool that helps users circumvent censorship when Tor is blocked.

Running a snowflake proxy on NixOS is simple. It is already packaged and just needs to be setup as a service.

I decided to wrap it in a container as well - because I can and NixOS makes it incredibly simple.

Here's a section that you can just paste into your configuration.nix:

  containers.snowflake = {
    autoStart = true;
    ephemeral = true;
    config = {
      systemd.services.snowflake = {
        wantedBy = [ "multi-user.target" ];
        serviceConfig = {
          IPAccounting = "yes";
          ExecStart = "${pkgs.snowflake}/bin/proxy";
          DynamicUser = "yes";
          # Read-only filesystem
          ProtectSystem = "strict";
          PrivateDevices = "yes";
          ProtectKernelTunables = "yes";
          ProtectControlGroups = "yes";
          ProtectHome = "yes";
          # Deny access to as many things as possible
          NoNewPrivileges = "yes";
          PrivateUsers = "yes";
          LockPersonality = "yes";
          MemoryDenyWriteExecute = "yes";
          ProtectClock = "yes";
          ProtectHostname = "yes";
          ProtectKernelLogs = "yes";
          ProtectKernelModules = "yes";
          RestrictAddressFamilies = "AF_INET AF_INET6";
          RestrictNamespaces = "yes";
          RestrictRealtime = "yes";
          RestrictSUIDSGID = "yes";
          SystemCallArchitectures = "native";
          SystemCallFilter = "~@chown @clock @cpu-emulation @debug @module @mount @obsolete @raw-io @reboot @setuid @swap @privileged @resources";
          CapabilityBoundingSet = "";
          ProtectProc = "invisible";
          ProcSubset = "pid";
        };
      };
    };
  };

You can get the snowflake logs with this command: machinectl shell snowflake $(which journalctl) -fu snowflake

Keep in mind that running the snowflake proxy causes some traffic, so this may be unsuitable for some metered connections. I had it running for nearly a day and saw roughly 5 GB of data logged by systemd in systemctl status container@snowflake.service, but your mileage may vary.

If you don't want the container overhead, you can just drop the contents of containers.snowflake.config into your configuration.nix, but I prefer the extra layer of isolation.