},
"nixpkgs": {
"locked": {
- "lastModified": 1598251641,
- "narHash": "sha256-5XRLDKBbFEyVdwbI+pXAkLFgM03wAEZCvH1sr4uSFKI=",
+ "lastModified": 1599246614,
+ "narHash": "sha256-l2QyMGtf8H4jbgbAPefbevMeYOufTzbDAdj35gaaCoY=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "a332da8588aeea4feb9359d23f58d95520899e3c",
+ "rev": "e3e39aa84e9d8c381d9f420f08a57eccb6e0a285",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "a332da8588aeea4feb9359d23f58d95520899e3c",
+ "rev": "e3e39aa84e9d8c381d9f420f08a57eccb6e0a285",
"type": "github"
}
},
{
-inputs.nixpkgs.url = "github:NixOS/nixpkgs/a332da8588aeea4feb9359d23f58d95520899e3c";
+inputs.nixpkgs.url = "github:NixOS/nixpkgs/e3e39aa84e9d8c381d9f420f08a57eccb6e0a285";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.shell = { type = "path"; path = "./shell"; flake = false; };
inputs.secrets = { type = "path"; path = "./sec"; flake = false; };
}
{ meta.description = "apparmor: fix and improve the service";
url = "https://github.com/NixOS/nixpkgs/pull/93457.diff";
- sha256 = "8QNOKDWNJiZujAvmDtZPZI5VRc+oh40IqjTYn/RCUi4=";
+ sha256 = "sha256-GxTZvaQrUxxV8vd7DT42k0xEXMQt2mAgEdiY3fsA8Gs=";
}
{ meta.description = "nixos/security.gnupg: provisioning GnuPG-protected secrets through the Nix store";
url = "https://github.com/NixOS/nixpkgs/pull/93659.diff";
}
{ meta.description = "nixos/croc: init";
url = "https://github.com/NixOS/nixpkgs/pull/93629.diff";
- sha256 = "0fv3lpj244hvxyixxv4akrr70jv5wwbhb3kmbmd2yskx59a71rch";
- }
- { meta.description = "nixos/biboumi: init";
- url = "https://github.com/NixOS/nixpkgs/pull/94917.diff";
- sha256 = "sha256-kUYk6Lr31rXUkbGnnIfpls6v1Jw/EVF4giByoH4MfEk=";
+ sha256 = "sha256-hzs5Z9cYCo6aNFfylB37W+1neejV4/kVyM1QmqVhVww=";
}
{ meta.description = "dovecot_fts_xapian: 1.3.1 -> 1.3.3";
url = "https://github.com/NixOS/nixpkgs/pull/94938.diff";
}
{ meta.description = "nixos-install: add support for flakes";
url = "https://github.com/NixOS/nixpkgs/pull/95194.diff";
- sha256 = "sha256-Y0KE9i+NFa3xLDdXXcVEAbpm//W7tCeOtKArgf2Dw2M=";
+ sha256 = "sha256-7EsqWguUWC4CQCMV0ZKQmjlsuLnQuR2/gI7Z/8sM8ww=";
}
{ meta.description = "transmission: use freeformType on settings";
url = "https://github.com/NixOS/nixpkgs/pull/96655.diff";
}
];
localNixpkgsPatches = [
- #nixpkgs/patches/security.apparmor.diff
#nixpkgs/patches/fix-ld-nix.diff
#nixpkgs/patches/fix-ld-nix-apparmor.diff
- #nixpkgs/patches/nixos-install.diff
];
originPkgs = inputs.nixpkgs.legacyPackages."x86_64-linux";
nixpkgs = originPkgs.applyPatches {
losurdo/hardware.nix
losurdo/networking.nix
losurdo/nginx.nix
- losurdo/postgresql.nix
+ #losurdo/postgresql.nix
losurdo/prosody.nix
(inputs.secrets + "/machines/losurdo/prosody.nix")
losurdo/sanoid.nix
{ pkgs, lib, config, machines, ... }:
{
services.openssh.logLevel = "VERBOSE";
-services.postgresql.extraConfig = "log_line_prefix = '%h '";
+services.postgresql.settings.log_line_prefix = "%h ";
/*
systemd.services.nftables.postStart = '' systemctl reload fail2ban '';
*/
{ pkgs, lib, config, machineName, machines, wireguard, ... }:
with builtins;
let
+ inherit (config) networking;
#lanIPv4 = "192.168.1.215";
lanNet = "192.168.1.0/24";
#lanIPv4Gateway = "192.168.1.1";
networking/nftables.nix
networking/ssh.nix
networking/wireguard.nix
+ networking/tor.nix
];
boot.initrd.network = {
networking = {
hostName = machineName;
domain = "sourcephile.fr";
-
+
useDHCP = false;
+ enableIPv6 = true;
/*
defaultGateway = {
address = lanIPv4Gateway;
let
inherit (builtins) hasAttr readFile;
inherit (pkgs.lib) unlinesAttrs;
+ inherit (config) networking;
inherit (config.users) users groups;
in
{
table inet filter {
set lograte4 { type ipv4_addr; size 65535; flags dynamic; }
set lograte6 { type ipv6_addr; size 65535; flags dynamic; }
+ chain block {
+ add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "block: "
+ add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "block: "
+ counter drop
+ }
chain ping-flood {
add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "ping-flood: "
add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "ping-flood: "
counter drop
}
- chain check-ping {
- ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood
- ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood
- }
chain smurf {
add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "smurf: "
add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "smurf: "
counter drop
}
- chain check-broadcast {
- ip saddr 0.0.0.0/32 counter accept comment "DHCP broadcast"
- fib saddr type broadcast counter goto smurf
- ip saddr 224.0.0.0/4 counter goto smurf
- }
chain bogus-tcp {
add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "bogus-tcp: "
add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "bogus-tcp: "
#jump non-internet
#ct state new add @connlimit { ip saddr ct count over 20 } counter tcp reject with tcp reset
-
+
# Some .nix append rules here with: add rule inet filter net2fw ...
}
chain fw2net {
- ip daddr 224.0.0.0/4 udp dport 1900 counter accept comment "UPnP"
tcp dport { 80, 443 } counter accept comment "HTTP"
udp dport 123 skuid ${users.systemd-timesync.name} counter accept comment "NTP"
tcp dport 9418 counter accept comment "Git"
-
+
# Some .nix append rules here with: add rule inet filter fw2net ...
}
chain intra2fw {
chain fwd-intra {
# Some .nix append rules here with: add rule inet filter fwd-intra ...
}
+ chain icmpv6 {
+ # Traffic That Must Not Be Dropped
+ # https://tools.ietf.org/html/rfc4890#section-4.4.1
+ ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept
+
+ # Address Configuration and Router Selection messages
+ # (must be received with hop limit = 255)
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-router-solicit ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter accept
+ # redirect messages provide a significant security risk,
+ # and administrators should take a case-by-case approach
+ # to whether firewalls, routers in general,
+ # and other nodes should accept these messages
+ #ip6 nexthdr ipv6-icmp icmpv6 type redirect ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-solicit ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-advert ip6 hoplimit 255 counter accept
+
+ # Link-local multicast receiver notification messages
+ # (must have link-local source address)
+ ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-query ip6 saddr fe80::/10 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-report ip6 saddr fe80::/10 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-done ip6 saddr fe80::/10 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type mld2-listener-report ip6 saddr fe80::/10 counter accept
+
+ # SEND Certificate Path notification messages
+ # (must be received with hop limit = 255)
+ ip6 nexthdr ipv6-icmp icmpv6 type 148 ip6 hoplimit 255 counter accept comment "certificate-path-solicitation"
+ ip6 nexthdr ipv6-icmp icmpv6 type 149 ip6 hoplimit 255 counter accept comment "certificate-path-advertisement"
+
+ # Multicast Router Discovery messages
+ # (must have link-local source address and hop limit = 1)
+ ip6 nexthdr ipv6-icmp icmpv6 type 151 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-advertisement"
+ ip6 nexthdr ipv6-icmp icmpv6 type 152 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-solicitation"
+ ip6 nexthdr ipv6-icmp icmpv6 type 153 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-termination"
+ }
chain input {
type filter hook input priority 0
policy drop
-
+
iifname lo accept
-
+
jump check-tcp
- jump check-ping
- jump check-broadcast
-
+
ct state { established, related } accept
+
+ # (multicast) ping
+ ip protocol icmp icmp type echo-reply counter accept
+
+ ${lib.optionalString networking.enableIPv6 ''
+ # drop packets with rh0 headers
+ rt type 0 jump block
+ rt type 0 jump block
+ rt type 0 jump block
+
+ # (multicast) ping
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
+ ''}
+
ct state invalid counter drop
-
+
+ ip protocol icmp icmp type destination-unreachable counter accept
+ ip protocol icmp icmp type time-exceeded counter accept
+ ip protocol icmp icmp type parameter-problem counter accept
+ ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood
+ ip protocol icmp icmp type echo-request counter accept
+ # echo-reply is handled before invalid packets to allow multicast ping
+ # which do not have an associated connection.
+
+ #ip daddr 224.0.0.251 udp dport 5353 counter accept comment "mDNS"
+ #ip daddr 239.255.255.250 udp dport 1900 counter accept comment "UPnP"
+ #ip saddr 0.0.0.0/32 counter accept comment "DHCP"
+ #ip udp sport 67 udp dport 68 counter accept comment "DHCP"
+
+ ${lib.optionalString networking.enableIPv6 ''
+ # Traffic That Must Not Be Dropped
+ # https://tools.ietf.org/html/rfc4890#section-4.4.1
+ ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept
+
+ # Connectivity checking messages
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
+ # echo-reply is handled before invalid packets to allow multicast ping
+ # which do not have an associated connection.
+
+ # Address Configuration and Router Selection messages
+ # (must be received with hop limit = 255)
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-router-solicit ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter accept
+ # redirect messages provide a significant security risk,
+ # and administrators should take a case-by-case approach
+ # to whether firewalls, routers in general,
+ # and other nodes should accept these messages
+ #ip6 nexthdr ipv6-icmp icmpv6 type redirect ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-solicit ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-advert ip6 hoplimit 255 counter accept
+
+ # Link-local multicast receiver notification messages
+ # (must have link-local source address)
+ ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-query ip6 saddr fe80::/10 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-report ip6 saddr fe80::/10 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-done ip6 saddr fe80::/10 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type mld2-listener-report ip6 saddr fe80::/10 counter accept
+
+ # SEND Certificate Path notification messages
+ # (must be received with hop limit = 255)
+ ip6 nexthdr ipv6-icmp icmpv6 type 148 ip6 hoplimit 255 counter accept comment "certificate-path-solicitation"
+ ip6 nexthdr ipv6-icmp icmpv6 type 149 ip6 hoplimit 255 counter accept comment "certificate-path-advertisement"
+
+ # Multicast Router Discovery messages
+ # (must have link-local source address and hop limit = 1)
+ ip6 nexthdr ipv6-icmp icmpv6 type 151 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-advertisement"
+ ip6 nexthdr ipv6-icmp icmpv6 type 152 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-solicitation"
+ ip6 nexthdr ipv6-icmp icmpv6 type 153 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-termination"
+
+ ip6 daddr ff02::fb udp dport 5353 counter accept comment "mDNS"
+ ip6 daddr ff02::f udp dport 1900 counter accept comment "UPnP"
+ ''}
+
+ ip saddr 224.0.0.0/4 counter goto smurf
+ fib saddr type broadcast counter goto smurf
+
# admin services
tcp dport 22 counter accept comment "SSH"
udp dport 60000-61000 counter accept comment "Mosh"
-
- # ICMP
- ip protocol icmp icmp type echo-request counter accept
+
+ # Some .nix append gotos here with: add rule inet filter input iffname ... goto ...
+ }
+ chain forward {
+ type filter hook forward priority 0
+ policy drop
+
ip protocol icmp icmp type destination-unreachable counter accept
- ip protocol icmp icmp type router-solicitation counter accept
- ip protocol icmp icmp type router-advertisement counter accept
ip protocol icmp icmp type time-exceeded counter accept
ip protocol icmp icmp type parameter-problem counter accept
- ip protocol icmp log level warn prefix "net2fw: icmpv: " counter accept
- #ip protocol icmp icmp type { echo-request, destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } counter accept
-
- ip6 nexthdr icmpv6 icmpv6 type echo-request counter accept
- ip6 nexthdr icmpv6 icmpv6 type nd-neighbor-solicit counter accept
- ip6 nexthdr icmpv6 icmpv6 type nd-neighbor-advert counter accept
- ip6 nexthdr icmpv6 icmpv6 type nd-router-solicit counter accept
- ip6 nexthdr icmpv6 icmpv6 type nd-router-advert counter accept
- ip6 nexthdr icmpv6 icmpv6 type mld-listener-query counter accept
- ip6 nexthdr icmpv6 icmpv6 type mld-listener-report counter accept
- ip6 nexthdr icmpv6 icmpv6 type mld-listener-reduction counter accept
- ip6 nexthdr icmpv6 icmpv6 type destination-unreachable counter accept
- ip6 nexthdr icmpv6 icmpv6 type packet-too-big counter accept
- ip6 nexthdr icmpv6 icmpv6 type time-exceeded counter accept
- ip6 nexthdr icmpv6 icmpv6 type parameter-problem counter accept
- ip6 nexthdr icmpv6 icmpv6 type ind-neighbor-solicit counter accept
- ip6 nexthdr icmpv6 icmpv6 type ind-neighbor-advert counter accept
- ip6 nexthdr icmpv6 icmpv6 type mld2-listener-report counter accept
- ip6 nexthdr icmpv6 log level warn prefix "net2fw: icmpv6: " counter accept
- #ip6 nexthdr icmpv6 icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert, mld-listener-query, mld-listener-report, mld-listener-reduction, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } counter accept
+ ip protocol icmp icmp type echo-request counter accept
- # Some .nix append gotos here with: add rule inet filter input iffname ... goto ...
+ ${lib.optionalString networking.enableIPv6 ''
+ # Traffic That Must Not Be Dropped
+ # https://tools.ietf.org/html/rfc4890#section-4.3.1
+ ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept
+
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
+
+ # Traffic That Normally Should Not Be Dropped
+ # https://tools.ietf.org/html/rfc4890#section-4.3.2
+ ip6 nexthdr ipv6-icmp icmpv6 type 144 counter accept comment "home-agent-address-discovery-request"
+ ip6 nexthdr ipv6-icmp icmpv6 type 145 counter accept comment "home-agent-address-discovery-reply"
+ ip6 nexthdr ipv6-icmp icmpv6 type 146 counter accept comment "mobile-prefix-solicitation"
+ ip6 nexthdr ipv6-icmp icmpv6 type 147 counter accept comment "mobile-prefix-advertisement"
+ ''}
}
chain output {
type filter hook output priority 0
ct state { related, established } accept
ct state invalid counter drop
- # ICMP
ip protocol icmp counter accept
- ip6 nexthdr icmpv6 counter accept
+ ip daddr 224.0.0.0/4 udp dport 1900 counter accept comment "UPnP"
+
+ ${lib.optionalString networking.enableIPv6 ''
+ # Connectivity checking messages
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
+ jump icmpv6
+
+
+ ip6 nexthdr udp ip6 saddr fe80::/10 udp sport 547 ip6 daddr fe80::/10 udp dport 546 counter accept comment "DHCPv6"
+ ''}
tcp dport 22 counter accept comment "SSH"
# Some .nix append gotos here with: add rule inet filter output oifname ... goto ...
}
- chain forward {
- type filter hook forward priority 0
- policy drop
- }
}
'';
};
--- /dev/null
+{ pkgs, lib, config, ... }:
+let inherit (config) networking; in
+{
+environment.systemPackages = [
+ pkgs.tor
+];
+
+systemd.services.tor.serviceConfig.StateDirectory = [
+ "tor"
+ "tor/onion"
+ "tor/onion/${networking.domain}"
+];
+systemd.services.tor.serviceConfig.StateDirectoryMode = "0700";
+services.tor = {
+ enable = true;
+ enableGeoIP = false;
+ hiddenServices = {
+ "${networking.domain}/${networking.hostName}".map = [
+ { port = 22; }
+ ];
+ };
+ extraConfig = ''
+ ClientUseIPv4 1
+ ClientUseIPv6 1
+ ClientPreferIPv6ORPort 0
+ '';
+};
+/*
+# copy your onion folder
+boot.initrd.secrets = {
+ "/etc/tor/onion/bootup" = /home/tony/tor/onion; # maybe find a better spot to store this.
+};
+
+# copy tor to you initrd
+boot.initrd.extraUtilsCommands = ''
+ copy_bin_and_libs ${pkgs.tor}/bin/tor
+'';
+
+# start tor during boot process
+boot.initrd.network.postCommands = let
+ torRc = (pkgs.writeText "tor.rc" ''
+ DataDirectory /etc/tor
+ SOCKSPort 127.0.0.1:9050 IsolateDestAddr
+ SOCKSPort 127.0.0.1:9063
+ HiddenServiceDir /etc/tor/onion/bootup
+ HiddenServicePort 22 127.0.0.1:22
+ '');
+in ''
+ echo "tor: preparing onion folder"
+ # have to do this otherwise tor does not want to start
+ chmod -R 700 /etc/tor
+
+ echo "make sure localhost is up"
+ ip a a 127.0.0.1/8 dev lo
+ ip link set lo up
+
+ echo "tor: starting tor"
+ tor -f ${torRc} --verify-config
+ tor -f ${torRc} &
+'';
+*/
+}
srv = "losurdo";
in
{
+services.tor.hiddenServices."${domain}/${srv}".map = [
+ { port = 443; toPort = 8443; }
+];
services.nginx = {
virtualHosts."${srv}" = {
serverName = "${srv}.${domain}";
enable = true;
package = pkgs.postgresql_9_6;
enableTCPIP = true;
- extraConfig = ''
+ settings = {
# ZFS is Copy on Write (CoW). As a result, it’s not possible
# to have a torn page because a page can’t be partially written
# without reverting to the previous copy.
- full_page_writes = off
- log_connections = true
- log_disconnections = true
- log_hostname = false
- max_connections = 25
- max_locks_per_transaction = 1024
- password_encryption = on # FIXME: replace md5 by scram-sha-256, which requires postfix >= 11
- ssl = on
- ssl_cert_file = '/var/lib/acme/${networking.domain}/fullchain.pem'
- ssl_key_file = '/var/lib/acme/${networking.domain}/key.pem'
- unix_socket_permissions = 0770
- '';
+ full_page_writes = false;
+ log_connections = true;
+ log_disconnections = true;
+ log_hostname = false;
+ max_connections = 25;
+ max_locks_per_transaction = 1024;
+ password_encryption = "on"; # FIXME: replace md5 by scram-sha-256, which requires postfix >= 11
+ ssl = true;
+ ssl_cert_file = '/var/lib/acme/${networking.domain}/fullchain.pem';
+ ssl_key_file = '/var/lib/acme/${networking.domain}/key.pem';
+ unix_socket_permissions = "0770";
+ };
authentication = lib.mkForce ''
# CONNECTION DATABASE USER AUTH OPTIONS
local all postgres peer map=admin
REVOKE ALL ON pg_catalog.pg_database FROM public;
REVOKE ALL ON pg_catalog.pg_tablespace FROM public;
EOF
-
+
pg_createdb () {
local db=$1
local owner=''${owner:-$db}
add rule inet filter net2fw tcp dport {${lib.concatMapStringsSep "," toString prosody.httpsPorts}} counter accept comment "XMPP HTTPS"
add rule inet filter fw2net meta skuid ${prosody.user} counter accept comment "Prosody"
'';
+services.tor.hiddenServices."${networking.domain}/xmpp".map = [
+ { port = 5222; }
+ { port = 5269; }
+ { port = 5000; }
+] ++ map (port: {inherit port;}) prosody.httpsPorts;
users.groups.acme.members = [ prosody.user ];
security.acme.certs."${networking.domain}" = {
postRun = "systemctl reload prosody";
turncredentials_host = "turn.${networking.domain}"
turncredentials_port = 3478
-
+
--http_files_dir = "/var/lib/prosody/files"
--http_external_url = "https://tmp.${networking.domain}:5281"
--https_certificate = "/var/lib/acme/${networking.domain}/fullchain.pem"
Component "proxy65.${networking.domain}" "proxy65"
proxy65_address = "proxy65.${networking.domain}"
proxy65_acl = { "${networking.domain}" }
-
+
Component "biboumi.${networking.domain}"
component_secret = "useless-secret-on-loopback"
'';
''tcp dport 5222 counter accept comment "XMPP"''
''tcp dport 11371 counter accept comment "HKP"''
''tcp dport {9009,9010,9011,9012,9013} counter accept comment "croc"''
+ #''ip protocol tcp counter accept comment "all"''
];
users = {
}
chain check-ping {
ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood
- #ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood
+ #ip6 nexthdr ipv6-icmp icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood
}
chain smurf {
add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "smurf: "
ip protocol icmp log level warn prefix "net2fw: icmpv: " counter accept
#ip protocol icmp icmp type { echo-request, destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } counter accept
- #ip6 nexthdr icmpv6 icmpv6 type echo-request counter accept
- #ip6 nexthdr icmpv6 icmpv6 type nd-neighbor-solicit counter accept
- #ip6 nexthdr icmpv6 icmpv6 type nd-neighbor-advert counter accept
- #ip6 nexthdr icmpv6 icmpv6 type nd-router-solicit counter accept
- #ip6 nexthdr icmpv6 icmpv6 type nd-router-advert counter accept
- #ip6 nexthdr icmpv6 icmpv6 type mld-listener-query counter accept
- #ip6 nexthdr icmpv6 icmpv6 type mld-listener-report counter accept
- #ip6 nexthdr icmpv6 icmpv6 type mld-listener-reduction counter accept
- #ip6 nexthdr icmpv6 icmpv6 type destination-unreachable counter accept
- #ip6 nexthdr icmpv6 icmpv6 type packet-too-big counter accept
- #ip6 nexthdr icmpv6 icmpv6 type time-exceeded counter accept
- #ip6 nexthdr icmpv6 icmpv6 type parameter-problem counter accept
- #ip6 nexthdr icmpv6 icmpv6 type ind-neighbor-solicit counter accept
- #ip6 nexthdr icmpv6 icmpv6 type ind-neighbor-advert counter accept
- #ip6 nexthdr icmpv6 icmpv6 type mld2-listener-report counter accept
- #ip6 nexthdr icmpv6 log level warn prefix "net2fw: icmpv6: " counter accept
- #ip6 nexthdr icmpv6 icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert, mld-listener-query, mld-listener-report, mld-listener-reduction, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-solicit counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-advert counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type nd-router-solicit counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-query counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-report counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-reduction counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-solicit counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-advert counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type mld2-listener-report counter accept
+ #ip6 nexthdr ipv6-icmp log level warn prefix "net2fw: icmpv6: " counter accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert, mld-listener-query, mld-listener-report, mld-listener-reduction, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } counter accept
# ICMP
ip protocol icmp icmp type echo-request accept
- #ip6 nexthdr icmpv6 icmpv6 type echo-request accept
+ #ip6 nexthdr ipv6-icmp icmpv6 type echo-request accept
# Some .nix append gotos here with: add rule inet filter input iffname ... goto ...
}
imports = [
modules/services/databases/openldap.nix
modules/services/mail/public-inbox.nix
+ modules/services/security/tor.nix
#modules/services/torrent/transmission.nix
#modules/security/gnupg.nix
#modules/services/networking/biboumi.nix
+ #modules/services/networking/croc.nix
#/home/julm/src/nix/nixpkgs/.git-worktree/transmission/nixos/modules/services/torrent/transmission.nix
#/home/julm/src/nix/nixpkgs/nixos/modules/services/torrent/transmission.nix
#modules/services/mail/mlmmj.nix
disabledModules = [
"services/mail/mlmmj.nix"
"services/mail/public-inbox.nix"
+ "services/security/tor.nix"
#"security/gnupg.nix"
#"services/networking/biboumi.nix"
+ #"services/networking/croc.nix"
#"services/torrent/transmission.nix"
];
}
--- /dev/null
+{ config, lib, pkgs, ... }:
+
+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"
+ ]);
+ default = [];
+ example = [
+ "IsolateClientAddr"
+ "IsolateSOCKSAuth"
+ "IsolateClientProtocol"
+ "IsolateDestPort"
+ "IsolateDestAddr"
+ ];
+ description = "Tor isolation options";
+ };
+
+
+ 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}/onion/${v.name}
+ ${optionalString (v.version != null) "HiddenServiceVersion ${toString v.version}"}
+ ${flip concatMapStrings v.map (p: ''
+ HiddenServicePort ${toString p.port} ${p.destination}
+ '')}
+ ${optionalString (v.authorizeClient != null) ''
+ HiddenServiceAuthorizeClient ${v.authorizeClient.authType} ${concatStringsSep "," v.authorizeClient.clientNames}
+ ''}
+ ''))
+ + cfg.extraConfig;
+
+ torRcFile = pkgs.writeText "torrc" torRc;
+
+in
+{
+ imports = [
+ (mkRenamedOptionModule [ "services" "tor" "relay" "portSpec" ] [ "services" "tor" "relay" "port" ])
+ (mkRemovedOptionModule [ "services" "tor" "relay" "isBridge" ] "Use services.tor.relay.role instead.")
+ (mkRemovedOptionModule [ "services" "tor" "relay" "isExit" ] "Use services.tor.relay.role instead.")
+ ];
+
+ options = {
+ services.tor = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable the Tor daemon. By default, the daemon is run without
+ relay, exit, bridge or client connectivity.
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.tor;
+ defaultText = "pkgs.tor";
+ example = literalExample "pkgs.tor";
+ description = ''
+ Tor package to use
+ '';
+ };
+
+ enableGeoIP = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whenever to configure Tor daemon to use GeoIP databases.
+
+ Disabling this will disable by-country statistics for
+ bridges and relays and some client and third-party software
+ functionality.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Extra configuration. Contents will be added verbatim to the
+ configuration file at the end.
+ '';
+ };
+
+ controlPort = mkOption {
+ type = types.nullOr (types.either types.int types.str);
+ default = null;
+ example = 9051;
+ description = ''
+ If set, Tor will accept connections on the specified port
+ and allow them to control the tor process.
+ '';
+ };
+
+ controlSocket = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable Tor control socket. Control socket is created
+ in <literal>${torRunDirectory}/control</literal>
+ '';
+ };
+ };
+
+ client = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable Tor daemon to route application
+ connections. You might want to disable this if you plan
+ running a dedicated Tor relay.
+ '';
+ };
+
+ socksListenAddress = mkOption {
+ type = types.str;
+ default = "127.0.0.1:9050";
+ example = "192.168.0.1:9100";
+ description = ''
+ Bind to this address to listen for connections from
+ Socks-speaking applications. Provides strong circuit
+ isolation, separate circuit per IP address.
+ '';
+ };
+
+ socksListenAddressFaster = mkOption {
+ type = types.str;
+ default = "127.0.0.1:9063";
+ example = "192.168.0.1:9101";
+ description = ''
+ Bind to this address to listen for connections from
+ Socks-speaking applications. Same as
+ <option>socksListenAddress</option> but uses weaker
+ circuit isolation to provide performance suitable for a
+ web browser.
+ '';
+ };
+
+ socksPolicy = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "accept 192.168.0.0/16, reject *";
+ description = ''
+ Entry policies to allow/deny SOCKS requests based on IP
+ address. First entry that matches wins. If no SocksPolicy
+ is set, we accept all (and only) requests from
+ <option>socksListenAddress</option>.
+ '';
+ };
+
+ socksIsolationOptions = mkOption (isolationOptions // {
+ default = ["IsolateDestAddr"];
+ });
+
+ transparentProxy = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable tor transparent proxy";
+ };
+
+ listenAddress = mkOption {
+ type = types.str;
+ default = "127.0.0.1:9040";
+ example = "192.168.0.1:9040";
+ description = ''
+ Bind transparent proxy to this address.
+ '';
+ };
+
+ isolationOptions = mkOption isolationOptions;
+ };
+
+ dns = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable tor dns resolver";
+ };
+
+ listenAddress = mkOption {
+ type = types.str;
+ default = "127.0.0.1:9053";
+ example = "192.168.0.1:9053";
+ description = ''
+ Bind tor dns to this address.
+ '';
+ };
+
+ isolationOptions = mkOption isolationOptions;
+
+ automapHostsSuffixes = mkOption {
+ type = types.listOf types.str;
+ default = [".onion" ".exit"];
+ example = [".onion"];
+ description = "List of suffixes to use with automapHostsOnResolve";
+ };
+ };
+
+ privoxy.enable = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to enable and configure the system Privoxy to use Tor's
+ faster port, suitable for HTTP.
+
+ To have anonymity, protocols need to be scrubbed of identifying
+ information, and this can be accomplished for HTTP by Privoxy.
+
+ Privoxy can also be useful for KDE torification. A good setup would be:
+ setting SOCKS proxy to the default Tor port, providing maximum
+ circuit isolation where possible; and setting HTTP proxy to Privoxy
+ to route HTTP traffic over faster, but less isolated port.
+ '';
+ };
+ };
+
+ relay = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable relaying TOR traffic for others.
+
+ See <link xlink:href="https://www.torproject.org/docs/tor-doc-relay" />
+ for details.
+
+ Setting this to true requires setting
+ <option>services.tor.relay.role</option>
+ and
+ <option>services.tor.relay.port</option>
+ options.
+ '';
+ };
+
+ role = mkOption {
+ type = types.enum [ "exit" "relay" "bridge" "private-bridge" ];
+ description = ''
+ Your role in Tor network. There're several options:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>exit</literal></term>
+ <listitem>
+ <para>
+ An exit relay. This allows Tor users to access regular
+ Internet services through your public IP.
+ </para>
+
+ <important><para>
+ Running an exit relay may expose you to abuse
+ complaints. See
+ <link xlink:href="https://www.torproject.org/faq.html.en#ExitPolicies" />
+ for more info.
+ </para></important>
+
+ <para>
+ You can specify which services Tor users may access via
+ your exit relay using <option>exitPolicy</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>relay</literal></term>
+ <listitem>
+ <para>
+ Regular relay. This allows Tor users to relay onion
+ traffic to other Tor nodes, but not to public
+ Internet.
+ </para>
+
+ <important><para>
+ Note that some misconfigured and/or disrespectful
+ towards privacy sites will block you even if your
+ relay is not an exit relay. That is, just being listed
+ in a public relay directory can have unwanted
+ consequences.
+
+ Which means you might not want to use
+ this role if you browse public Internet from the same
+ network as your relay, unless you want to write
+ e-mails to those sites (you should!).
+ </para></important>
+
+ <para>
+ See
+ <link xlink:href="https://www.torproject.org/docs/tor-doc-relay.html.en" />
+ for more info.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bridge</literal></term>
+ <listitem>
+ <para>
+ Regular bridge. Works like a regular relay, but
+ doesn't list you in the public relay directory and
+ hides your Tor node behind obfs4proxy.
+ </para>
+
+ <para>
+ Using this option will make Tor advertise your bridge
+ to users through various mechanisms like
+ <link xlink:href="https://bridges.torproject.org/" />, though.
+ </para>
+
+ <important>
+ <para>
+ WARNING: THE FOLLOWING PARAGRAPH IS NOT LEGAL ADVICE.
+ Consult with your lawer when in doubt.
+ </para>
+
+ <para>
+ This role should be safe to use in most situations
+ (unless the act of forwarding traffic for others is
+ a punishable offence under your local laws, which
+ would be pretty insane as it would make ISP
+ illegal).
+ </para>
+ </important>
+
+ <para>
+ See <link xlink:href="https://www.torproject.org/docs/bridges.html.en" />
+ for more info.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>private-bridge</literal></term>
+ <listitem>
+ <para>
+ Private bridge. Works like regular bridge, but does
+ not advertise your node in any way.
+ </para>
+
+ <para>
+ Using this role means that you won't contribute to Tor
+ network in any way unless you advertise your node
+ yourself in some way.
+ </para>
+
+ <para>
+ Use this if you want to run a private bridge, for
+ example because you'll give out your bridge address
+ manually to your friends.
+ </para>
+
+ <para>
+ Switching to this role after measurable time in
+ "bridge" role is pretty useless as some Tor users
+ would have learned about your node already. In the
+ latter case you can still change
+ <option>port</option> option.
+ </para>
+
+ <para>
+ See <link xlink:href="https://www.torproject.org/docs/bridges.html.en" />
+ for more info.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ '';
+ };
+
+ bridgeTransports = mkOption {
+ type = types.listOf types.str;
+ default = ["obfs4"];
+ example = ["obfs2" "obfs3" "obfs4" "scramblesuit"];
+ description = "List of pluggable transports";
+ };
+
+ nickname = mkOption {
+ type = types.str;
+ default = "anonymous";
+ description = ''
+ A unique handle for your TOR relay.
+ '';
+ };
+
+ contactInfo = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "admin@relay.com";
+ description = ''
+ Contact information for the relay owner (e.g. a mail
+ address and GPG key ID).
+ '';
+ };
+
+ accountingMax = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "450 GBytes";
+ description = ''
+ Specify maximum bandwidth allowed during an accounting period. This
+ allows you to limit overall tor bandwidth over some time period.
+ See the <literal>AccountingMax</literal> option by looking at the
+ tor manual <citerefentry><refentrytitle>tor</refentrytitle>
+ <manvolnum>1</manvolnum></citerefentry> for more.
+
+ Note this limit applies individually to upload and
+ download; if you specify <literal>"500 GBytes"</literal>
+ here, then you may transfer up to 1 TBytes of overall
+ bandwidth (500 GB upload, 500 GB download).
+ '';
+ };
+
+ accountingStart = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "month 1 1:00";
+ description = ''
+ Specify length of an accounting period. This allows you to limit
+ overall tor bandwidth over some time period. See the
+ <literal>AccountingStart</literal> option by looking at the tor
+ manual <citerefentry><refentrytitle>tor</refentrytitle>
+ <manvolnum>1</manvolnum></citerefentry> for more.
+ '';
+ };
+
+ bandwidthRate = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ example = 100;
+ description = ''
+ Specify this to limit the bandwidth usage of relayed (server)
+ traffic. Your own traffic is still unthrottled. Units: bytes/second.
+ '';
+ };
+
+ bandwidthBurst = mkOption {
+ type = types.nullOr types.int;
+ default = cfg.relay.bandwidthRate;
+ example = 200;
+ description = ''
+ Specify this to allow bursts of the bandwidth usage of relayed (server)
+ traffic. The average usage will still be as specified in relayBandwidthRate.
+ Your own traffic is still unthrottled. Units: bytes/second.
+ '';
+ };
+
+ address = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "noname.example.com";
+ description = ''
+ The IP address or full DNS name for advertised address of your relay.
+ Leave unset and Tor will guess.
+ '';
+ };
+
+ port = mkOption {
+ type = types.either types.int types.str;
+ example = 143;
+ description = ''
+ What port to advertise for Tor connections. This corresponds to the
+ <literal>ORPort</literal> section in the Tor manual; see
+ <citerefentry><refentrytitle>tor</refentrytitle>
+ <manvolnum>1</manvolnum></citerefentry> for more details.
+
+ At a minimum, you should just specify the port for the
+ relay to listen on; a common one like 143, 22, 80, or 443
+ to help Tor users who may have very restrictive port-based
+ firewalls.
+ '';
+ };
+
+ exitPolicy = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "accept *:6660-6667,reject *:*";
+ description = ''
+ A comma-separated list of exit policies. They're
+ considered first to last, and the first match wins. If you
+ want to _replace_ the default exit policy, end this with
+ either a reject *:* or an accept *:*. Otherwise, you're
+ _augmenting_ (prepending to) the default exit policy.
+ Leave commented to just use the default, which is
+ available in the man page or at
+ <link xlink:href="https://www.torproject.org/documentation.html" />.
+
+ Look at
+ <link xlink:href="https://www.torproject.org/faq-abuse.html#TypicalAbuses" />
+ for issues you might encounter if you use the default
+ exit policy.
+
+ If certain IPs and ports are blocked externally, e.g. by
+ your firewall, you should update your exit policy to
+ reflect this -- otherwise Tor users will be told that
+ those destinations are down.
+ '';
+ };
+ };
+
+ hiddenServices = mkOption {
+ description = ''
+ A set of static hidden services that terminate their Tor
+ circuits at this node.
+
+ Every element in this set declares a virtual onion host.
+
+ You can specify your onion address by putting corresponding
+ private key to an appropriate place in ${torDirectory}.
+
+ For services without private keys in ${torDirectory} Tor
+ daemon will generate random key pairs (which implies random
+ onion addresses) on restart. The latter could take a while,
+ please be patient.
+
+ <note><para>
+ Hidden services can be useful even if you don't intend to
+ actually <emphasis>hide</emphasis> them, since they can
+ also be seen as a kind of NAT traversal mechanism.
+
+ E.g. the example will make your sshd, whatever runs on
+ "8080" and your mail server available from anywhere where
+ the Tor network is available (which, with the help from
+ bridges, is pretty much everywhere), even if both client
+ and server machines are behind NAT you have no control
+ over.
+ </para></note>
+ '';
+ default = {};
+ example = literalExample ''
+ { "my-hidden-service-example".map = [
+ { port = 22; } # map ssh port to this machine's ssh
+ { port = 80; toPort = 8080; } # map http port to whatever runs on 8080
+ { port = "sip"; toHost = "mail.example.com"; toPort = "imap"; } # because we can
+ ];
+ }
+ '';
+ type = types.loaOf (types.submodule ({name, ...}: {
+ options = {
+
+ name = mkOption {
+ type = types.str;
+ description = ''
+ Name of this tor hidden service.
+
+ This is purely descriptive.
+
+ After restarting Tor daemon you should be able to
+ find your .onion address in
+ <literal>${torDirectory}/onion/$name/hostname</literal>.
+ '';
+ };
+
+ map = mkOption {
+ default = [];
+ description = "Port mapping for this hidden service.";
+ type = types.listOf (types.submodule ({config, ...}: {
+ options = {
+
+ port = mkOption {
+ type = types.either types.int types.str;
+ example = 80;
+ description = ''
+ Hidden service port to "bind to".
+ '';
+ };
+
+ destination = mkOption {
+ internal = true;
+ type = types.str;
+ description = "Forward these connections where?";
+ };
+
+ toHost = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = "Mapping destination host.";
+ };
+
+ toPort = mkOption {
+ type = types.either types.int types.str;
+ example = 8080;
+ description = "Mapping destination port.";
+ };
+
+ };
+
+ config = {
+ toPort = mkDefault config.port;
+ destination = mkDefault "${config.toHost}:${toString config.toPort}";
+ };
+ }));
+ };
+
+ authorizeClient = mkOption {
+ default = null;
+ description = "If configured, the hidden service is accessible for authorized clients only.";
+ type = types.nullOr (types.submodule ({...}: {
+
+ options = {
+
+ authType = mkOption {
+ type = types.enum [ "basic" "stealth" ];
+ description = ''
+ Either <literal>"basic"</literal> for a general-purpose authorization protocol
+ or <literal>"stealth"</literal> for a less scalable protocol
+ that also hides service activity from unauthorized clients.
+ '';
+ };
+
+ clientNames = mkOption {
+ type = types.nonEmptyListOf (types.strMatching "[A-Za-z0-9+-_]+");
+ description = ''
+ Only clients that are listed here are authorized to access the hidden service.
+ Generated authorization data can be found in <filename>${torDirectory}/onion/$name/hostname</filename>.
+ Clients need to put this authorization data in their configuration file using <literal>HidServAuth</literal>.
+ '';
+ };
+ };
+ }));
+ };
+
+ version = mkOption {
+ default = null;
+ description = "Rendezvous service descriptor version to publish for the hidden service. Currently, versions 2 and 3 are supported. (Default: 2)";
+ type = types.nullOr (types.enum [ 2 3 ]);
+ };
+ };
+
+ config = {
+ name = mkDefault name;
+ };
+ }));
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ # Not sure if `cfg.relay.role == "private-bridge"` helps as tor
+ # sends a lot of stats
+ warnings = optional (cfg.relay.enable && cfg.hiddenServices != {})
+ ''
+ Running Tor hidden services on a public relay makes the
+ presence of hidden services visible through simple statistical
+ analysis of publicly available data.
+
+ You can safely ignore this warning if you don't intend to
+ actually hide your hidden services. In either case, you can
+ always create a container/VM with a separate Tor daemon instance.
+ '';
+
+ users.groups.tor.gid = config.ids.gids.tor;
+ users.users.tor =
+ { description = "Tor Daemon User";
+ createHome = true;
+ home = torDirectory;
+ group = "tor";
+ uid = config.ids.uids.tor;
+ };
+
+ # We have to do this instead of using RuntimeDirectory option in
+ # the service below because systemd has no way to set owners of
+ # RuntimeDirectory and putting this into the service below
+ # requires that service to relax it's sandbox since this needs
+ # writable /run
+ systemd.services.tor-init =
+ { description = "Tor Daemon Init";
+ wantedBy = [ "tor.service" ];
+ script = ''
+ install -m 0700 -o tor -g tor -d ${torDirectory} ${torDirectory}/onion
+ install -m 0750 -o tor -g tor -d ${torRunDirectory}
+ '';
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ };
+ };
+
+ systemd.services.tor =
+ { description = "Tor Daemon";
+ path = [ pkgs.tor ];
+
+ wantedBy = [ "multi-user.target" ];
+ after = [ "tor-init.service" "network.target" ];
+ restartTriggers = [ torRcFile ];
+
+ serviceConfig =
+ { Type = "simple";
+ # Translated from the upstream contrib/dist/tor.service.in
+ ExecStartPre = "${cfg.package}/bin/tor -f ${torRcFile} --verify-config";
+ ExecStart = "${cfg.package}/bin/tor -f ${torRcFile}";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ KillSignal = "SIGINT";
+ TimeoutSec = 30;
+ Restart = "on-failure";
+ LimitNOFILE = 32768;
+
+ # Hardening
+ # this seems to unshare /run despite what systemd.exec(5) says
+ PrivateTmp = mkIf (!cfg.controlSocket.enable) "yes";
+ PrivateDevices = "yes";
+ ProtectHome = "yes";
+ ProtectSystem = "strict";
+ InaccessiblePaths = "/home";
+ ReadOnlyPaths = "/";
+ ReadWritePaths = [ torDirectory torRunDirectory ];
+ NoNewPrivileges = "yes";
+
+ # tor.service.in has this in, but this line it fails to spawn a namespace when using hidden services
+ #CapabilityBoundingSet = "CAP_SETUID CAP_SETGID CAP_NET_BIND_SERVICE";
+ };
+ };
+
+ environment.systemPackages = [ cfg.package ];
+
+ services.privoxy = mkIf (cfg.client.enable && cfg.client.privoxy.enable) {
+ enable = true;
+ extraConfig = ''
+ forward-socks4a / ${cfg.client.socksListenAddressFaster} .
+ toggle 1
+ enable-remote-toggle 0
+ enable-edit-actions 0
+ enable-remote-http-toggle 0
+ '';
+ };
+ };
+}
};
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
+# https://insanity.industries/post/sata-power-consumption/
+services.udev.extraRules = ''
+ SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="med_power_with_dipm"
+'';
+
boot.loader = {
grub = {
enable = true;
environment.systemPackages = with pkgs; [
pciutils
- #flashrom
nvme-cli
];
}
+++ /dev/null
-diff --git a/nixos/modules/config/malloc.nix b/nixos/modules/config/malloc.nix
-index 5c5752ef515..54ba3048fdb 100644
---- a/nixos/modules/config/malloc.nix
-+++ b/nixos/modules/config/malloc.nix
-@@ -90,7 +90,7 @@ in
- security.apparmor.includes = {
- "abstractions/base" = ''
- r /etc/ld-nix.so.preload,
-- r ${config.environment.etc."ld-nix.so.preload".source},
-+ r ${config.environment.etc."ld-nix.${pkgs.glibc.src.outputHash}.so.preload".source},
- mr ${providerLibPath},
- '';
- };
+++ /dev/null
-diff --git a/nixos/modules/config/malloc.nix b/nixos/modules/config/malloc.nix
-index 31a659ee83f..93089c220a2 100644
---- a/nixos/modules/config/malloc.nix
-+++ b/nixos/modules/config/malloc.nix
-@@ -84,7 +84,9 @@ in
- };
-
- config = mkIf (cfg.provider != "libc") {
-- environment.etc."ld-nix.so.preload".text = ''
-+ # See comment in pkgs/development/libraries/glibc/common.nix
-+ # for an explanation about the name of this file.
-+ environment.etc."ld-nix.${pkgs.glibc.src.outputHash}.so.preload".text = ''
- ${providerLibPath}
- '';
- };
-diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix
-index 0b2f34c7b76..e1349c0076b 100644
---- a/pkgs/development/libraries/glibc/common.nix
-+++ b/pkgs/development/libraries/glibc/common.nix
-@@ -68,9 +68,6 @@ stdenv.mkDerivation ({
- /* Don't use /etc/ld.so.cache, for non-NixOS systems. */
- ./dont-use-system-ld-so-cache.patch
-
-- /* Don't use /etc/ld.so.preload, but /etc/ld-nix.so.preload. */
-- ./dont-use-system-ld-so-preload.patch
--
- /* The command "getconf CS_PATH" returns the default search path
- "/bin:/usr/bin", which is inappropriate on NixOS machines. This
- patch extends the search path by "/run/current-system/sw/bin". */
-@@ -128,6 +125,18 @@ stdenv.mkDerivation ({
- # nscd needs libgcc, and we don't want it dynamically linked
- # because we don't want it to depend on bootstrap-tools libs.
- echo "LDFLAGS-nscd += -static-libgcc" >> nscd/Makefile
-+
-+ # Don't use /etc/ld.so.preload, but /etc/ld-nix.${sha256}.so.preload.
-+ # ${sha256} is included in the name
-+ # in order to only share a same .so.preload between the programs
-+ # built with that version of glibc,
-+ # otherwise it could break programs
-+ # requiring symbols from a more recent glibc
-+ # than the one loaded by shared libraries in that file.
-+ # This file may later be generated by a NixOS module,
-+ # using pkgs.glibc.src.outputHash instead of sha256
-+ substituteInPlace elf/rtld.c \
-+ --replace /etc/ld.so.preload /etc/ld-nix.${sha256}.so.preload
- ''
- # FIXME: find a solution for infinite recursion in cross builds.
- # For now it's hopefully acceptable that IDN from libc doesn't reliably work.
-diff --git a/pkgs/development/libraries/glibc/dont-use-system-ld-so-preload.patch b/pkgs/development/libraries/glibc/dont-use-system-ld-so-preload.patch
-deleted file mode 100644
-index 894e2a11cf8..00000000000
---- a/pkgs/development/libraries/glibc/dont-use-system-ld-so-preload.patch
-+++ /dev/null
-@@ -1,12 +0,0 @@
--diff -ru glibc-2.20-orig/elf/rtld.c glibc-2.20/elf/rtld.c
----- glibc-2.20-orig/elf/rtld.c 2014-09-07 10:09:09.000000000 +0200
--+++ glibc-2.20/elf/rtld.c 2014-10-27 11:32:25.203043157 +0100
--@@ -1513,7 +1513,7 @@
-- open(). So we do this first. If it succeeds we do almost twice
-- the work but this does not matter, since it is not for production
-- use. */
--- static const char preload_file[] = "/etc/ld.so.preload";
--+ static const char preload_file[] = "/etc/ld-nix.so.preload";
-- if (__glibc_unlikely (__access (preload_file, R_OK) == 0))
-- {
-- /* Read the contents of the file. */