Compare commits

...

3 Commits

Author SHA1 Message Date
3d207ab7bb coturn: allocate 256 ports instead of 16 2024-04-26 08:47:52 +00:00
95447eb765 goaccess: fix missing state dir 2024-04-26 08:47:09 +00:00
593268f620 coturn: run inside ovpns namespace 2024-04-26 08:01:34 +00:00
2 changed files with 61 additions and 49 deletions

View File

@ -24,50 +24,57 @@
# that is NOT the case when the STUN server and client A are on the same LAN # that is NOT the case when the STUN server and client A are on the same LAN
# even if client A contacts the STUN server via its WAN address with port reflection enabled. # even if client A contacts the STUN server via its WAN address with port reflection enabled.
# hence, there's no obvious way to put the STUN server on the same LAN as either client and expect the rest to work. # hence, there's no obvious way to put the STUN server on the same LAN as either client and expect the rest to work.
# - there an old version which *half worked*, which is:
# - run the turn server in the root namespace.
# - bind the turn server to the veth connecting it to the VPN namespace (so it sends outgoing traffic to the right place).
# - NAT the turn port range from VPN into root namespace (so it receives incomming traffic).
# - this approach would fail the prosody conversations.im check, but i didn't notice *obvious* call routing errors.
{ lib, ... }: { lib, ... }:
let let
# TODO: this range could be larger, but right now that's costly because each element is its own UPnP forward # TURN port range (inclusive).
# TURN port range (inclusive) # default coturn behavior is to use the upper quarter of all ports. i.e. 49152 - 65535.
turnPortLow = 49152; # i believe TURN allocations expire after either 5 or 10 minutes of inactivity.
turnPortHigh = 49167; turnPortLow = 49152; # 49152 = 0xc000
turnPortHigh = turnPortLow + 256;
turnPortRange = lib.range turnPortLow turnPortHigh; turnPortRange = lib.range turnPortLow turnPortHigh;
in in
{ {
sane.ports.ports = lib.mkMerge ([ # the port definitions are only needed if running in the root net namespace
{ # sane.ports.ports = lib.mkMerge ([
"3478" = { # {
# this is the "control" port. # "3478" = {
# i.e. no client data is forwarded through it, but it's where clients request tunnels. # # this is the "control" port.
protocol = [ "tcp" "udp" ]; # # i.e. no client data is forwarded through it, but it's where clients request tunnels.
# visibleTo.lan = true; # protocol = [ "tcp" "udp" ];
# visibleTo.wan = true; # # visibleTo.lan = true;
visibleTo.ovpn = true; # # visibleTo.wan = true;
description = "colin-stun-turn"; # visibleTo.ovpn = true; # forward traffic from the VPN to the root NS
}; # description = "colin-stun-turn";
"5349" = { # };
# the other port 3478 also supports TLS/DTLS, but presumably clients wanting TLS will default 5349 # "5349" = {
protocol = [ "tcp" ]; # # the other port 3478 also supports TLS/DTLS, but presumably clients wanting TLS will default 5349
# visibleTo.lan = true; # protocol = [ "tcp" ];
# visibleTo.wan = true; # # visibleTo.lan = true;
visibleTo.ovpn = true; # # visibleTo.wan = true;
description = "colin-stun-turn-over-tls"; # visibleTo.ovpn = true;
}; # description = "colin-stun-turn-over-tls";
} # };
] ++ (builtins.map # }
(port: { # ] ++ (builtins.map
"${builtins.toString port}" = let # (port: {
count = port - turnPortLow + 1; # "${builtins.toString port}" = let
numPorts = turnPortHigh - turnPortLow + 1; # count = port - turnPortLow + 1;
in { # numPorts = turnPortHigh - turnPortLow + 1;
protocol = [ "tcp" "udp" ]; # in {
# visibleTo.lan = true; # protocol = [ "tcp" "udp" ];
# visibleTo.wan = true; # # visibleTo.lan = true;
visibleTo.ovpn = true; # # visibleTo.wan = true;
description = "colin-turn-${builtins.toString count}-of-${builtins.toString numPorts}"; # visibleTo.ovpn = true;
}; # description = "colin-turn-${builtins.toString count}-of-${builtins.toString numPorts}";
}) # };
turnPortRange # })
)); # turnPortRange
# ));
services.nginx.virtualHosts."turn.uninsane.org" = { services.nginx.virtualHosts."turn.uninsane.org" = {
# allow ACME to procure a cert via nginx for this domain # allow ACME to procure a cert via nginx for this domain
@ -113,12 +120,15 @@ in
"verbose" "verbose"
# "Verbose" #< even MORE verbosity than "verbose" # "Verbose" #< even MORE verbosity than "verbose"
# "no-multicast-peers" # disables sending to IPv4 broadcast addresses (e.g. 224.0.0.0/3) # "no-multicast-peers" # disables sending to IPv4 broadcast addresses (e.g. 224.0.0.0/3)
"listening-ip=10.0.1.5" # "listening-ip=10.0.1.5" "external-ip=185.157.162.178" #< 2024/04/25: works, if running in root namespace
"listening-ip=185.157.162.178" "external-ip=185.157.162.178"
# old attempts:
# "external-ip=185.157.162.178/10.0.1.5" # "external-ip=185.157.162.178/10.0.1.5"
"external-ip=185.157.162.178"
# "listening-ip=10.78.79.51" # can be specified multiple times; omit for * # "listening-ip=10.78.79.51" # can be specified multiple times; omit for *
# "external-ip=97.113.128.229/10.78.79.51" # "external-ip=97.113.128.229/10.78.79.51"
# "external-ip=97.113.128.229" # "external-ip=97.113.128.229"
# "mobility" # "mobility with ICE (MICE) specs support" (?) # "mobility" # "mobility with ICE (MICE) specs support" (?)
]; ];
systemd.services.coturn.serviceConfig.NetworkNamespacePath = "/run/netns/ovpns";
} }

View File

@ -20,7 +20,7 @@
--ignore-panel=HOSTS \ --ignore-panel=HOSTS \
--ws-url=wss://sink.uninsane.org:443/ws \ --ws-url=wss://sink.uninsane.org:443/ws \
--port=7890 \ --port=7890 \
-o /var/lib/uninsane/sink/index.html -o /var/lib/goaccess/index.html
''; '';
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
Type = "simple"; Type = "simple";
@ -28,17 +28,19 @@
RestartSec = "10s"; RestartSec = "10s";
# hardening # hardening
WorkingDirectory = "/tmp"; # TODO: run as `goaccess` user and add `goaccess` user to group `nginx`.
NoNewPrivileges = true; NoNewPrivileges = true;
PrivateDevices = "yes";
PrivateTmp = true; PrivateTmp = true;
ProtectHome = "read-only"; ProtectHome = "read-only";
ProtectSystem = "strict";
SystemCallFilter = "~@clock @cpu-emulation @debug @keyring @memlock @module @mount @obsolete @privileged @reboot @resources @setuid @swap @raw-io";
ReadOnlyPaths = "/";
ReadWritePaths = [ "/proc/self" "/var/lib/uninsane/sink" ];
PrivateDevices = "yes";
ProtectKernelModules = "yes"; ProtectKernelModules = "yes";
ProtectKernelTunables = "yes"; ProtectKernelTunables = "yes";
ProtectSystem = "strict";
ReadOnlyPaths = [ "/var/log/nginx" ];
ReadWritePaths = [ "/proc/self" "/var/lib/goaccess" ];
StateDirectory = "goaccess";
SystemCallFilter = "~@clock @cpu-emulation @debug @keyring @memlock @module @mount @obsolete @privileged @reboot @resources @setuid @swap @raw-io";
WorkingDirectory = "/var/lib/goaccess";
}; };
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
@ -49,7 +51,7 @@
addSSL = true; addSSL = true;
enableACME = true; enableACME = true;
# inherit kTLS; # inherit kTLS;
root = "/var/lib/uninsane/sink"; root = "/var/lib/goaccess";
locations."/ws" = { locations."/ws" = {
proxyPass = "http://127.0.0.1:7890"; proxyPass = "http://127.0.0.1:7890";