diff options
author | Jörg Thalheim <joerg@thalheim.io> | 2020-12-31 07:31:38 +0100 |
---|---|---|
committer | Jörg Thalheim <joerg@thalheim.io> | 2020-12-31 07:31:38 +0100 |
commit | f19b7b03a03b7f1d5beb44471eb9298de4b9e186 (patch) | |
tree | 2bb5fabe03cff0c2058f69921315ab3ff724f9d0 /nixos | |
parent | 572a864d024b0c91ac39133f35364362b2376c07 (diff) | |
parent | 7a580a12196e63eb665de6eb4db8bb3b6da142f5 (diff) |
Merge branch 'master' into staging-next
Diffstat (limited to 'nixos')
19 files changed, 1182 insertions, 654 deletions
diff --git a/nixos/doc/manual/man-nixos-rebuild.xml b/nixos/doc/manual/man-nixos-rebuild.xml index d0ff81c1dbb3..4510fdd44225 100644 --- a/nixos/doc/manual/man-nixos-rebuild.xml +++ b/nixos/doc/manual/man-nixos-rebuild.xml @@ -113,6 +113,18 @@ <replaceable>path</replaceable> </arg> <arg> + <option>-L</option> + </arg> + <arg> + <option>--refresh</option> + </arg> + <arg> + <option>--no-net</option> + </arg> + <arg> + <option>--impure</option> + </arg> + <arg> <group choice='req'> <arg choice='plain'><option>--verbose</option></arg> <arg choice='plain'><option>-v</option></arg> @@ -131,6 +143,18 @@ <replaceable>number</replaceable> </arg> <arg> + <option>--fallback</option> + </arg> + <arg> + <option>--repair</option> + </arg> + <arg> + <group choice='req'> + <arg choice='plain'><option>--no-build-output</option></arg> + <arg choice='plain'><option>-Q</option></arg> + </group> + </arg> + <arg> <group choice='req'> <arg choice='plain'><option>--keep-failed</option></arg> <arg choice='plain'><option>-K</option></arg> @@ -567,10 +591,19 @@ <para> In addition, <command>nixos-rebuild</command> accepts various Nix-related - flags, including <option>--max-jobs</option> / <option>-j</option>, + flags: <option>-I</option>, <option>--max-jobs</option> / <option>-j</option>, <option>--show-trace</option>, <option>--keep-failed</option>, - <option>--keep-going</option>, <option>--impure</option>, and <option>--verbose</option> / + <option>--keep-going</option>, <option>--impure</option>, and <option>--verbose</option> / + <option>--builders</option>, <option>--show-trace</option>, + <option>--fallback</option>, <option>--repair</option>, + <option>--no-build-output</option> / <option>-Q</option>, + <option>--keep-failed</option> / <option>-K</option>, + <option>--keep-going</option> / <option>-k</option> and <option>--verbose</option> / <option>-v</option>. See the Nix manual for details. + + The following Nix flags that are support by the upcoming nix 2.4 version: + <option>-L</option>, <option>--refresh</option>, <option>--no-net</option>, + <option>--no-net</option>, <option>--impure</option>. See <command>nix --help</command> or <command>nix build --help</command> for details. </para> </refsection> diff --git a/nixos/modules/programs/command-not-found/command-not-found.nix b/nixos/modules/programs/command-not-found/command-not-found.nix index 656c255fcb18..da09488d82c7 100644 --- a/nixos/modules/programs/command-not-found/command-not-found.nix +++ b/nixos/modules/programs/command-not-found/command-not-found.nix @@ -9,17 +9,9 @@ with lib; let cfg = config.programs.command-not-found; - commandNotFound = pkgs.substituteAll { - name = "command-not-found"; - dir = "bin"; - src = ./command-not-found.pl; - isExecutable = true; - inherit (pkgs) perl; + commandNotFound = pkgs.callPackage ./. { inherit (cfg) dbPath; - perlFlags = concatStrings (map (path: "-I ${path}/${pkgs.perl.libPrefix} ") - [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite pkgs.perlPackages.StringShellQuote ]); }; - in { @@ -91,5 +83,4 @@ in environment.systemPackages = [ commandNotFound ]; }; - } diff --git a/nixos/modules/programs/command-not-found/command-not-found.pl b/nixos/modules/programs/command-not-found/command-not-found.pl deleted file mode 100644 index ab7aa204653c..000000000000 --- a/nixos/modules/programs/command-not-found/command-not-found.pl +++ /dev/null @@ -1,51 +0,0 @@ -#! @perl@/bin/perl -w @perlFlags@ - -use strict; -use DBI; -use DBD::SQLite; -use String::ShellQuote; -use Config; - -my $program = $ARGV[0]; - -my $dbPath = "@dbPath@"; - -my $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "") - or die "cannot open database `$dbPath'"; -$dbh->{RaiseError} = 0; -$dbh->{PrintError} = 0; - -my $system = $ENV{"NIX_SYSTEM"} // $Config{myarchname}; - -my $res = $dbh->selectall_arrayref( - "select package from Programs where system = ? and name = ?", - { Slice => {} }, $system, $program); - -if (!defined $res || scalar @$res == 0) { - print STDERR "$program: command not found\n"; -} elsif (scalar @$res == 1) { - my $package = @$res[0]->{package}; - if ($ENV{"NIX_AUTO_INSTALL"} // "") { - print STDERR <<EOF; -The program ‘$program’ is currently not installed. It is provided by -the package ‘$package’, which I will now install for you. -EOF - ; - exit 126 if system("nix-env", "-iA", "nixos.$package") == 0; - } elsif ($ENV{"NIX_AUTO_RUN"} // "") { - exec("nix-shell", "-p", $package, "--run", shell_quote("exec", @ARGV)); - } else { - print STDERR <<EOF; -The program ‘$program’ is currently not installed. You can install it by typing: - nix-env -iA nixos.$package -EOF - } -} else { - print STDERR <<EOF; -The program ‘$program’ is currently not installed. It is provided by -several packages. You can install it by typing one of the following: -EOF - print STDERR " nix-env -iA nixos.$_->{package}\n" foreach @$res; -} - -exit 127; diff --git a/nixos/modules/programs/command-not-found/default.nix b/nixos/modules/programs/command-not-found/default.nix new file mode 100644 index 000000000000..bbe949fa86a3 --- /dev/null +++ b/nixos/modules/programs/command-not-found/default.nix @@ -0,0 +1,18 @@ +{ stdenv, rustPlatform, pkgconfig, sqlite +, dbPath ? "/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite" }: + +rustPlatform.buildRustPackage { + name = "command-not-found"; + src = ./rust; + + DB_PATH = dbPath; + NIX_SYSTEM = stdenv.system; + + postInstall = '' + strip $out/bin/command-not-found + ''; + + buildInputs = [ sqlite ]; + nativeBuildInputs = [ pkgconfig ]; + cargoSha256 = "13q61bb4b1q40g424pbssyp3ln79q1a33vmyz9s9wlqnac34cibd"; +} diff --git a/nixos/modules/programs/command-not-found/rust/Cargo.lock b/nixos/modules/programs/command-not-found/rust/Cargo.lock new file mode 100644 index 000000000000..ce3a9358c5c2 --- /dev/null +++ b/nixos/modules/programs/command-not-found/rust/Cargo.lock @@ -0,0 +1,131 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "command-not-found" +version = "0.1.0" +dependencies = [ + "rusqlite 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libsqlite3-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rusqlite" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fallible-streaming-iterator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libsqlite3-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "smallvec" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "vcpkg" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +"checksum fallible-streaming-iterator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +"checksum libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" +"checksum libsqlite3-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e704a02bcaecd4a08b93a23f6be59d0bd79cd161e0963e9499165a0a35df7bd" +"checksum linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" +"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" +"checksum rusqlite 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "45d0fd62e1df63d254714e6cb40d0a0e82e7a1623e7a27f679d851af092ae58b" +"checksum smallvec 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" +"checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/nixos/modules/programs/command-not-found/rust/Cargo.toml b/nixos/modules/programs/command-not-found/rust/Cargo.toml new file mode 100644 index 000000000000..f965c7df76a5 --- /dev/null +++ b/nixos/modules/programs/command-not-found/rust/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "command-not-found" +version = "0.1.0" +edition = "2018" + +[dependencies] +rusqlite = "0.*.*" + +[profile.release] +lto = true diff --git a/nixos/modules/programs/command-not-found/rust/src/main.rs b/nixos/modules/programs/command-not-found/rust/src/main.rs new file mode 100644 index 000000000000..b0af2871cc29 --- /dev/null +++ b/nixos/modules/programs/command-not-found/rust/src/main.rs @@ -0,0 +1,52 @@ +use rusqlite::{params, Connection, Result}; +use std::env; +use std::process::exit; + +const NIX_SYSTEM: &str = env!("NIX_SYSTEM"); +const DB_PATH: &str = env!("DB_PATH"); + +fn query_packages(system: &str, program: &str) -> Result<Vec<String>> { + Ok(Connection::open(DB_PATH)? + .prepare("select package from Programs where system = ? and name = ?;")? + .query_map(params![system, program], |row| row.get("package"))? + .collect::<Result<Vec<String>>>()?) +} + +fn run_app() -> i32 { + let args: Vec<_> = env::args().collect(); + if args.len() < 2 { + eprintln!("USAGE: {} PROGRAMNAME", args[0]); + return 1; + } + let program = &args[1]; + let system = env::var("NIX_SYSTEM").unwrap_or_else(|_| NIX_SYSTEM.to_string()); + let packages = match query_packages(&system, program) { + Ok(packages) => packages, + Err(err) => { + eprintln!("Failed to query package database: {}", err); + return 1; + } + }; + if packages.is_empty() { + eprintln!("{}: command not found", program); + } else { + let advice = if packages.len() > 1 { + "It is provided by several packages. You can install it by typing on of the of following commands:" + } else { + "You can install it by typing:" + }; + eprintln!( + "The program '{}' is currently not installed. {}", + program, advice + ); + for pkg in packages { + eprintln!(" nix-env -iA nixos.{}", pkg); + } + } + + 127 +} + +fn main() { + exit(run_app()); +} diff --git a/nixos/modules/services/databases/redis.nix b/nixos/modules/services/databases/redis.nix index 6b8853ae390b..9988f382a1b1 100644 --- a/nixos/modules/services/databases/redis.nix +++ b/nixos/modules/services/databases/redis.nix @@ -12,7 +12,7 @@ let ${condOption "bind" cfg.bind} ${condOption "unixsocket" cfg.unixSocket} daemonize no - supervised systemd + #supervised systemd loglevel ${cfg.logLevel} logfile ${cfg.logfile} syslog-enabled ${redisBool cfg.syslog} @@ -242,7 +242,9 @@ in ExecStart = "${cfg.package}/bin/redis-server /run/redis/redis.conf"; RuntimeDirectory = "redis"; StateDirectory = "redis"; - Type = "notify"; + TimeoutStartSec = "infinity"; + TimeoutStopSec = "infinity"; + Type = "simple"; User = "redis"; Group = "redis"; }; diff --git a/nixos/modules/services/misc/home-assistant.nix b/nixos/modules/services/misc/home-assistant.nix index 1f2e13f37325..16fff215e616 100644 --- a/nixos/modules/services/misc/home-assistant.nix +++ b/nixos/modules/services/misc/home-assistant.nix @@ -62,6 +62,17 @@ let lovelace.mode = "yaml"; }; + #pythonScripts = pkgs.runCommand "python_scripts" { + # nativeBuildInputs = [ pkgs.python3 ]; + # scripts = cfg.pythonScripts; + #} '' + # mkdir $out + # for s in $scripts; do + # echo "checking syntax of $s" + # python -m py_compile "$s" + # ln -s "$s" "$out/$(basename $s" + # done + #''; in { meta.maintainers = with maintainers; [ dotlambda ]; @@ -214,6 +225,17 @@ in { ''; }; + pythonScripts = mkOption { + #default = []; + #type = types.listOf types.path; + default = null; + type = types.nullOr types.path; + description = '' + List of python scripts to use in the <literal>python_scripts</literal> integration. + Also see in the <link xlink:href="https://www.home-assistant.io/integrations/python_script">Homeassistant documentation</link> + ''; + }; + openFirewall = mkOption { default = false; type = types.bool; @@ -224,6 +246,12 @@ in { config = mkIf cfg.enable { networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ]; + systemd.tmpfiles.rules = mkIf (cfg.pythonScripts != null) [ + "L+ ${cfg.configDir}/python_scripts - - - - ${cfg.pythonScripts}" + ]; + + services.home-assistant.config.python_script = mkIf (cfg.pythonScripts != null) {}; + systemd.services.home-assistant = { description = "Home Assistant"; after = [ "network.target" ]; diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix index 0eeff31d6c4d..b0763c8d0de4 100644 --- a/nixos/modules/services/misc/nix-daemon.nix +++ b/nixos/modules/services/misc/nix-daemon.nix @@ -11,6 +11,7 @@ let nixVersion = getVersion nix; isNix23 = versionAtLeast nixVersion "2.3pre"; + isNix24 = versionAtLeast nixVersion "2.4pre"; makeNixBuildUser = nr: { name = "nixbld${toString nr}"; @@ -40,7 +41,11 @@ let max-jobs = ${toString (cfg.maxJobs)} cores = ${toString (cfg.buildCores)} sandbox = ${if (builtins.isBool cfg.useSandbox) then boolToString cfg.useSandbox else cfg.useSandbox} - extra-sandbox-paths = ${toString cfg.sandboxPaths} + + ${optionalString (!isNix24) '' + extra-sandbox-paths = ${toString cfg.sandboxPaths} + ''} + substituters = ${toString cfg.binaryCaches} trusted-substituters = ${toString cfg.trustedBinaryCaches} trusted-public-keys = ${toString cfg.binaryCachePublicKeys} diff --git a/nixos/modules/services/networking/privoxy.nix b/nixos/modules/services/networking/privoxy.nix index e3b34cb0c616..7caae3282032 100644 --- a/nixos/modules/services/networking/privoxy.nix +++ b/nixos/modules/services/networking/privoxy.nix @@ -16,7 +16,7 @@ let ${concatMapStrings (f: "actionsfile ${f}\n") cfg.actionsFiles} ${concatMapStrings (f: "filterfile ${f}\n") cfg.filterFiles} '' + optionalString cfg.enableTor '' - forward-socks4a / ${config.services.tor.client.socksListenAddressFaster} . + forward-socks5t / 127.0.0.1:9063 . toggle 1 enable-remote-toggle 0 enable-edit-actions 0 @@ -123,6 +123,11 @@ in serviceConfig.ProtectSystem = "full"; }; + services.tor.settings.SOCKSPort = mkIf cfg.enableTor [ + # Route HTTP traffic over a faster port (without IsolateDestAddr). + { addr = "127.0.0.1"; port = 9063; IsolateDestAddr = false; } + ]; + }; meta.maintainers = with lib.maintainers; [ rnhmjoj ]; diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix index 1cceee065b1b..ececb633983c 100644 --- a/nixos/modules/services/security/tor.nix +++ b/nixos/modules/services/security/tor.nix @@ -1,297 +1,300 @@ { config, lib, pkgs, ... }: +with builtins; with lib; let cfg = config.services.tor; - torDirectory = "/var/lib/tor"; - torRunDirectory = "/run/tor"; - - opt = name: value: optionalString (value != null) "${name} ${value}"; - optint = name: value: optionalString (value != null && value != 0) "${name} ${toString value}"; - - isolationOptions = { - type = types.listOf (types.enum [ - "IsolateClientAddr" - "IsolateSOCKSAuth" - "IsolateClientProtocol" - "IsolateDestPort" - "IsolateDestAddr" + stateDir = "/var/lib/tor"; + runDir = "/run/tor"; + descriptionGeneric = option: '' + See <link xlink:href="https://2019.www.torproject.org/docs/tor-manual.html.en#${option}">torrc manual</link>. + ''; + bindsPrivilegedPort = + any (p0: + let p1 = if p0 ? "port" then p0.port else p0; in + if p1 == "auto" then false + else let p2 = if isInt p1 then p1 else toInt p1; in + p1 != null && 0 < p2 && p2 < 1024) + (flatten [ + cfg.settings.ORPort + cfg.settings.DirPort + cfg.settings.DNSPort + cfg.settings.ExtORPort + cfg.settings.HTTPTunnelPort + cfg.settings.NATDPort + cfg.settings.SOCKSPort + cfg.settings.TransPort ]); + optionBool = optionName: mkOption { + type = with types; nullOr bool; + default = null; + description = descriptionGeneric optionName; + }; + optionInt = optionName: mkOption { + type = with types; nullOr int; + default = null; + description = descriptionGeneric optionName; + }; + optionString = optionName: mkOption { + type = with types; nullOr str; + default = null; + description = descriptionGeneric optionName; + }; + optionStrings = optionName: mkOption { + type = with types; listOf str; default = []; - example = [ - "IsolateClientAddr" - "IsolateSOCKSAuth" - "IsolateClientProtocol" - "IsolateDestPort" - "IsolateDestAddr" + description = descriptionGeneric optionName; + }; + optionAddress = mkOption { + type = with types; nullOr str; + default = null; + example = "0.0.0.0"; + description = '' + IPv4 or IPv6 (if between brackets) address. + ''; + }; + optionUnix = mkOption { + type = with types; nullOr path; + default = null; + description = '' + Unix domain socket path to use. + ''; + }; + optionPort = mkOption { + type = with types; nullOr (oneOf [port (enum ["auto"])]); + default = null; + }; + optionPorts = optionName: mkOption { + type = with types; listOf port; + default = []; + description = descriptionGeneric optionName; + }; + optionIsolablePort = with types; oneOf [ + port (enum ["auto"]) + (submodule ({config, ...}: { + options = { + addr = optionAddress; + port = optionPort; + flags = optionFlags; + SessionGroup = mkOption { type = nullOr int; default = null; }; + } // genAttrs isolateFlags (name: mkOption { type = types.bool; default = false; }); + config = { + flags = filter (name: config.${name} == true) isolateFlags ++ + optional (config.SessionGroup != null) "SessionGroup=${toString config.SessionGroup}"; + }; + })) + ]; + optionIsolablePorts = optionName: mkOption { + default = []; + type = with types; either optionIsolablePort (listOf optionIsolablePort); + description = descriptionGeneric optionName; + }; + isolateFlags = [ + "IsolateClientAddr" + "IsolateClientProtocol" + "IsolateDestAddr" + "IsolateDestPort" + "IsolateSOCKSAuth" + "KeepAliveIsolateSOCKSAuth" + ]; + optionSOCKSPort = doConfig: let + flags = [ + "CacheDNS" "CacheIPv4DNS" "CacheIPv6DNS" "GroupWritable" "IPv6Traffic" + "NoDNSRequest" "NoIPv4Traffic" "NoOnionTraffic" "OnionTrafficOnly" + "PreferIPv6" "PreferIPv6Automap" "PreferSOCKSNoAuth" "UseDNSCache" + "UseIPv4Cache" "UseIPv6Cache" "WorldWritable" + ] ++ isolateFlags; + in with types; oneOf [ + port (submodule ({config, ...}: { + options = { + unix = optionUnix; + addr = optionAddress; + port = optionPort; + flags = optionFlags; + SessionGroup = mkOption { type = nullOr int; default = null; }; + } // genAttrs flags (name: mkOption { type = types.bool; default = false; }); + config = mkIf doConfig { # Only add flags in SOCKSPort to avoid duplicates + flags = filter (name: config.${name} == true) flags ++ + optional (config.SessionGroup != null) "SessionGroup=${toString config.SessionGroup}"; + }; + })) ]; - description = "Tor isolation options"; + optionFlags = mkOption { + type = with types; listOf str; + default = []; + }; + optionORPort = optionName: mkOption { + default = []; + example = 443; + type = with types; oneOf [port (enum ["auto"]) (listOf (oneOf [ + port + (enum ["auto"]) + (submodule ({config, ...}: + let flags = [ "IPv4Only" "IPv6Only" "NoAdvertise" "NoListen" ]; + in { + options = { + addr = optionAddress; + port = optionPort; + flags = optionFlags; + } // genAttrs flags (name: mkOption { type = types.bool; default = false; }); + config = { + flags = filter (name: config.${name} == true) flags; + }; + })) + ]))]; + description = descriptionGeneric optionName; + }; + optionBandwith = optionName: mkOption { + type = with types; nullOr (either int str); + default = null; + description = descriptionGeneric optionName; + }; + optionPath = optionName: mkOption { + type = with types; nullOr path; + default = null; + description = descriptionGeneric optionName; }; - - torRc = '' - User tor - DataDirectory ${torDirectory} - ${optionalString cfg.enableGeoIP '' - GeoIPFile ${cfg.package.geoip}/share/tor/geoip - GeoIPv6File ${cfg.package.geoip}/share/tor/geoip6 - ''} - - ${optint "ControlPort" cfg.controlPort} - ${optionalString cfg.controlSocket.enable "ControlPort unix:${torRunDirectory}/control GroupWritable RelaxDirModeCheck"} - '' - # Client connection config - + optionalString cfg.client.enable '' - SOCKSPort ${cfg.client.socksListenAddress} ${toString cfg.client.socksIsolationOptions} - SOCKSPort ${cfg.client.socksListenAddressFaster} - ${opt "SocksPolicy" cfg.client.socksPolicy} - - ${optionalString cfg.client.transparentProxy.enable '' - TransPort ${cfg.client.transparentProxy.listenAddress} ${toString cfg.client.transparentProxy.isolationOptions} - ''} - - ${optionalString cfg.client.dns.enable '' - DNSPort ${cfg.client.dns.listenAddress} ${toString cfg.client.dns.isolationOptions} - AutomapHostsOnResolve 1 - AutomapHostsSuffixes ${concatStringsSep "," cfg.client.dns.automapHostsSuffixes} - ''} - '' - # Explicitly disable the SOCKS server if the client is disabled. In - # particular, this makes non-anonymous hidden services possible. - + optionalString (! cfg.client.enable) '' - SOCKSPort 0 - '' - # Relay config - + optionalString cfg.relay.enable '' - ORPort ${toString cfg.relay.port} - ${opt "Address" cfg.relay.address} - ${opt "Nickname" cfg.relay.nickname} - ${opt "ContactInfo" cfg.relay.contactInfo} - - ${optint "RelayBandwidthRate" cfg.relay.bandwidthRate} - ${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst} - ${opt "AccountingMax" cfg.relay.accountingMax} - ${opt "AccountingStart" cfg.relay.accountingStart} - - ${if (cfg.relay.role == "exit") then - opt "ExitPolicy" cfg.relay.exitPolicy - else - "ExitPolicy reject *:*"} - - ${optionalString (elem cfg.relay.role ["bridge" "private-bridge"]) '' - BridgeRelay 1 - ServerTransportPlugin ${concatStringsSep "," cfg.relay.bridgeTransports} exec ${pkgs.obfs4}/bin/obfs4proxy managed - ExtORPort auto - ${optionalString (cfg.relay.role == "private-bridge") '' - ExtraInfoStatistics 0 - PublishServerDescriptor 0 - ''} - ''} - '' - # Hidden services - + concatStrings (flip mapAttrsToList cfg.hiddenServices (n: v: '' - HiddenServiceDir ${torDirectory |