{ config, pkgs, lib, ... }: with lib; let cfgPrivoxy = config.services.privoxy; cfg = cfgPrivoxy.tls-wrapper; src = ./.; action = pkgs.writeText "privoxy-tls.action" '' { +client-header-tagger{privoxy-tls-tagger} } / { +forward-override{forward localhost:${toString cfg.rearPort}} } TAG:.*?privoxy-tls ''; filter = pkgs.writeText "privoxy-tls.filter" '' CLIENT-HEADER-TAGGER: privoxy-tls-tagger s@Tagged: privoxy-tls front@$0@i ''; dataDir = "/var/lib/privoxy"; configFile = pkgs.writeText "config.ini" '' [General] ProxAddr = http://${cfgPrivoxy.listenAddress} FrontPort = ${toString cfg.frontPort} RearPort = ${toString cfg.rearPort} CACert = ${dataDir}/ca.crt Certdir = /tmp LogLevel = ${cfg.logLevel} [TLS NoVerify] ${concatStringsSep "\n" cfg.noVerify} [TLS Passthru] ${concatStringsSep "\n" cfg.passthru} ${cfg.extraConfig} ''; python = pkgs.python3.withPackages (p: [ p.urllib3 ]); in { ###### interface options = { services.privoxy.tls-wrapper = { enable = mkEnableOption '' TLS proxy wrapper to allow privoxy to inspect and modify HTTPS traffic. ''; caCert = mkOption { type = types.path; description = '' The CA certificate, in PEM format, that will be used to reencrypt the traffic. This will be installed in the local trust store. ''; }; caKey = mkOption { type = types.path; description = '' The CA key, in PEM format, associated to the certificate. This will be copied to the privoxy-owned state directory but not in the nix-store. ''; }; frontPort = mkOption { type = types.port; default = 8117; description = '' The port the privoxy-tls front proxy will bind to. This will replace the standard privoxy HTTP proxy in your settings. ''; }; rearPort = mkOption { type = types.port; default = 8119; description = '' The port the privoxy-tls rear proxy will bind to. This will be the proxy privoxy will forward TLS-stripped HTTP traffic for reencryption. ''; }; passthru = mkOption { type = types.listOf types.str; default = []; example = [ "*.local" ]; description = '' List of URLs configured for passthrough, meaning the proxy will directly connect skipping privoxy. ''; }; noVerify = mkOption { type = types.listOf types.str; default = []; example = [ "localhost" ]; description = '' List of URLs configured that the TLS verification will ignore. For example use it for self-signed certs. ''; }; logLevel = mkOption { type = types.enum [ "DEBUG" "INFO" "WARNING" "ERROR" "CRITICAL" ]; default = "WARNING"; example = "The level of logging of privoxy-tls"; }; extraConfig = mkOption { type = types.lines; default = ""; example = '' [Bypass URL] example.com ''; description = '' Additional options that will be appended to the configuration file. ''; }; }; }; ###### implementation config = mkIf cfg.enable { # install custom CA security.pki.certificateFiles = [ cfg.caCert ]; # tag traffic for the rear proxy server services.privoxy.actionsFiles = [ (toString action) ]; services.privoxy.filterFiles = [ (toString filter) ]; users.users.privoxy-tls = { group = "privoxy"; home = dataDir; }; systemd.services.privoxy-tls = { description = "Privoxy TLS proxy wrapper."; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { User = "privoxy-tls"; PrivateTmp = true; PermissionsStartOnly = true; ExecStart = "${python}/bin/python ${src}/main.py -c ${configFile}"; }; preStart = '' if ! test -f ${dataDir}/ca.crt; then cat ${toString cfg.caCert} ${toString cfg.caKey} > ${dataDir}/ca.crt fi ''; }; }; }