175 lines
6.7 KiB
Nix
175 lines
6.7 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
...
|
|
}: {
|
|
# TODO: Explain why we use containers (tor is bad: cpu)
|
|
# > sudo machinectl shell tor-1 /usr/bin/env systemctl status tor
|
|
# > sudo machinectl shell tor-1 /usr/bin/env journalctl -eu tor.service
|
|
containers = let
|
|
mkTorContainer = {
|
|
stateDir,
|
|
orPort,
|
|
controlPort,
|
|
}: {
|
|
autoStart = true;
|
|
ephemeral = true; # impermanence
|
|
bindMounts = {
|
|
"/var/lib/tor/" = {
|
|
hostPath = stateDir;
|
|
isReadOnly = false;
|
|
};
|
|
};
|
|
config = {...}: {
|
|
services.tor = {
|
|
enable = true;
|
|
relay = {
|
|
enable = true;
|
|
role = "exit";
|
|
};
|
|
# https://manpages.debian.org/testing/tor/torrc.5.en.html
|
|
settings = {
|
|
Nickname = "DXV7520";
|
|
ContactInfo = "admin@caspervk.net";
|
|
ORPort = [
|
|
{
|
|
addr = "185.231.102.51";
|
|
port = orPort;
|
|
}
|
|
{
|
|
addr = "[2a0c:5700:3133:650:b0ea:eeff:fedb:1f7b]";
|
|
port = orPort;
|
|
}
|
|
];
|
|
ControlPort = controlPort; # for nyx, localhost only
|
|
ExitRelay = true;
|
|
IPv6Exit = true;
|
|
ExitPolicy = [
|
|
"reject *:22"
|
|
"reject *:25"
|
|
"accept *:*"
|
|
];
|
|
# https://support.torproject.org/relay-operators/multiple-relays/
|
|
# Note that bridges should not configure their own -- or be listed
|
|
# in other relay's -- MyFamily as per the torrc man page.
|
|
MyFamily = builtins.concatStringsSep "," [
|
|
"1B9D2C9E0EFE2C6BD23D62B2FCD145886AD242D1" # /var/lib/tor-1/fingerprint
|
|
"293CE00D11B1D8B99AE8811CBDFDA3F353353710" # /var/lib/tor-2/fingerprint
|
|
];
|
|
};
|
|
};
|
|
system.stateVersion = config.system.stateVersion;
|
|
};
|
|
};
|
|
in {
|
|
tor-1 = mkTorContainer {
|
|
stateDir = "/var/lib/tor-1/";
|
|
orPort = 443;
|
|
controlPort = 9051;
|
|
};
|
|
tor-2 = mkTorContainer {
|
|
stateDir = "/var/lib/tor-2/";
|
|
orPort = 444;
|
|
controlPort = 9052;
|
|
};
|
|
};
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
nyx # Command-line monitor for Tor
|
|
];
|
|
|
|
# Serve Exit Relay Notice HTML page
|
|
# https://community.torproject.org/relay/setup/exit/
|
|
services.caddy = {
|
|
enable = true;
|
|
virtualHosts = {
|
|
"http://" = {
|
|
extraConfig = ''
|
|
header Content-Type text/html
|
|
respond `${builtins.readFile ./tor-exit-notice.html}`
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
# https://support.torproject.org/relay-operators/#relay-operators_relay-bridge-overloaded
|
|
# https://lists.torproject.org/pipermail/tor-talk/2012-August/025296.html
|
|
# https://www.ibm.com/docs/en/linux-on-systems?topic=recommendations-network-performance-tuning
|
|
# https://github.com/Enkidu-6/tor-ddos
|
|
boot.kernel.sysctl = {
|
|
# Increase the maximum size of the network interface's receive queue, used
|
|
# to store received frames after removing them from the network adapter's
|
|
# ring buffer. High speed adapters should use a high value to prevent the
|
|
# queue from becoming full and dropping packets causing retransmits.
|
|
"net.core.netdev_max_backlog" = 262144;
|
|
# Increase TCP read/write buffers to enable scaling to a larger window
|
|
# size. Larger windows increase the amount of data to be transferred before
|
|
# an acknowledgement (ACK) is required. This reduces overall latencies and
|
|
# results in increased throughput.
|
|
"net.core.rmem_max" = 33554432;
|
|
"net.core.wmem_max" = 33554432;
|
|
"net.ipv4.tcp_rmem" = "4096 131072 33554432";
|
|
"net.ipv4.tcp_wmem" = "4096 65536 33554432";
|
|
# Reduce the length of time an orphaned connection will wait before it is
|
|
# aborted. For workloads or systems that generate or support high levels of
|
|
# network traffic, it can be advantageous to more aggressively reclaim dead
|
|
# or stale resources.
|
|
"net.ipv4.tcp_fin_timeout" = 10;
|
|
# Maximal number of TCP sockets not attached to any user file handle, held
|
|
# by system. If this number is exceeded orphaned connections are reset
|
|
# immediately and warning is printed. This limit exists only to prevent
|
|
# simple DoS attacks, you _must_ not rely on this or lower the limit
|
|
# artificially, but rather increase it (probably, after increasing
|
|
# installed memory), if network conditions require more than default value,
|
|
# and tune network services to linger and kill such states more
|
|
# aggressively. Let me to remind again: each orphan eats up to ~64K of
|
|
# unswappable memory.
|
|
"net.ipv4.tcp_max_orphans" = 262144;
|
|
# Maximal number of timewait sockets held by system simultaneously. If this
|
|
# number is exceeded time-wait socket is immediately destroyed and warning
|
|
# is printed. This limit exists only to prevent simple DoS attacks, you
|
|
# _must_ not lower the limit artificially, but rather increase it
|
|
# (probably, after increasing installed memory), if network conditions
|
|
# require more than default value.
|
|
"net.ipv4.tcp_max_tw_buckets" = 2097152;
|
|
# In high traffic environments, sockets are created and destroyed at very
|
|
# high rates. This parameter, when set, allows "no longer needed" and
|
|
# "about to be destroyed" sockets to be used for new connections. When
|
|
# enabled, this parameter can bypass the allocation and initialization
|
|
# overhead normally associated with socket creation saving CPU cycles,
|
|
# system load and time.
|
|
"net.ipv4.tcp_tw_reuse" = 1;
|
|
# Aggressivelly check for and close broken connections
|
|
"net.ipv4.tcp_keepalive_time" = 60;
|
|
"net.ipv4.tcp_keepalive_probes" = 3;
|
|
"net.ipv4.tcp_keepalive_intvl" = 10;
|
|
# Increase the length of the SYN queue and socket listen() backlog to
|
|
# accommodate more connections waiting to connect.
|
|
"net.ipv4.tcp_max_syn_backlog" = 262144;
|
|
"net.core.somaxconn" = 32768;
|
|
# Expand local port range used for outgoing connections
|
|
"net.ipv4.ip_local_port_range" = "1025 65530";
|
|
# Disable RFC1323 timestamps (TODO: why?)
|
|
"net.ipv4.tcp_timestamps" = 0;
|
|
};
|
|
|
|
# Mounting /var/lib/tor/ relies on the 'tor' user having the same static
|
|
# uid/gid inside and outside the container. This might break if NixOS
|
|
# switches to a DynamicUser for the tor service.
|
|
environment.persistence."/nix/persist" = {
|
|
directories = [
|
|
{
|
|
directory = "/var/lib/tor-1";
|
|
user = builtins.toString config.ids.uids.tor;
|
|
group = builtins.toString config.ids.gids.tor;
|
|
mode = "0700";
|
|
}
|
|
{
|
|
directory = "/var/lib/tor-2";
|
|
user = builtins.toString config.ids.uids.tor;
|
|
group = builtins.toString config.ids.gids.tor;
|
|
mode = "0700";
|
|
}
|
|
];
|
|
};
|
|
}
|