restrict what syscalls piped can make

This commit is contained in:
Chaos 2022-12-03 15:30:16 +00:00
parent f1722f84a4
commit 650e145370
No known key found for this signature in database
5 changed files with 63 additions and 17 deletions

View file

@ -4,8 +4,8 @@ let
cfg = config.services.piped; cfg = config.services.piped;
backend_config = { backend_config = {
PORT = cfg.backendPort; PORT = cfg.internalBackendPort;
HTTP_WORKERS = 2; HTTP_WORKERS = cfg.httpWorkers;
PROXY_PART = "https://${cfg.proxyDomain}"; PROXY_PART = "https://${cfg.proxyDomain}";
API_URL = "https://${cfg.backendDomain}"; API_URL = "https://${cfg.backendDomain}";
FRONTEND_URL = "https://${cfg.frontendDomain}"; FRONTEND_URL = "https://${cfg.frontendDomain}";
@ -48,7 +48,7 @@ let
in { in {
config = lib.mkIf (cfg.enable && !cfg.disableBackend) { config = lib.mkIf (cfg.enable && !cfg.disableBackend) {
systemd.tmpfiles.rules = [ "d /run/piped-backend - root root" ]; systemd.tmpfiles.rules = [ "d /run/piped-backend - piped piped" ];
systemd.services.piped-backend = { systemd.services.piped-backend = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
@ -66,6 +66,20 @@ in {
""} ""}
''}"; ''}";
ExecStart = "${pkgs.piped-backend}/bin/piped-backend"; ExecStart = "${pkgs.piped-backend}/bin/piped-backend";
RestartSec = "5s";
User = "piped";
CapabilityBoundingSet = "";
PrivateDevices = true;
PrivateUsers = true;
ProtectHome = true;
ProtectKernelLogs = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
SystemCallArchitectures = "native";
SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
}; };
}; };
@ -93,7 +107,7 @@ in {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
locations."/" = { locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.backendPort}"; proxyPass = "http://127.0.0.1:${toString cfg.internalBackendPort}";
}; };
}; };
}; };

View file

@ -32,6 +32,18 @@ in {
description = "Don't host proxy"; description = "Don't host proxy";
}; };
proxyIPv4Only = mkOption {
type = types.bool;
default = false;
description = "Only use IPv4 querying youtube's servers for proxy";
};
httpWorkers = mkOption {
type = types.number;
default = 2;
description = "Number of workers for HTTP backend tasks";
};
feedRetentionDays = mkOption { feedRetentionDays = mkOption {
type = types.number; type = types.number;
default = 30; default = 30;
@ -151,13 +163,22 @@ in {
description = "Matrix access token file"; description = "Matrix access token file";
}; };
backendPort = mkOption { internalBackendPort = mkOption {
type = types.number; type = types.number;
default = 3001; default = 3001;
}; };
internalProxyPort = mkOption {
type = types.number;
default = 3002;
};
}; };
config = (lib.mkIf cfg.enable) { config = lib.mkIf (cfg.enable && (!cfg.disableBackend || !cfg.disableProxy)) {
environment.systemPackages = with pkgs; [ piped-proxy ]; users.users."piped" = {
isSystemUser = true;
group = "piped";
};
users.groups.piped = { };
}; };
} }

View file

@ -24,18 +24,27 @@ let
''; '';
in { in {
config = lib.mkIf (cfg.enable && !cfg.disableProxy) { config = lib.mkIf (cfg.enable && !cfg.disableProxy) {
systemd.tmpfiles.rules = [
"d /run/piped-proxy - nginx nginx"
"d /run/piped-proxy/socket - nginx nginx"
];
systemd.services.piped-proxy = { systemd.services.piped-proxy = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
environment.UDS = "1"; environment.BIND = "0.0.0.0:${toString cfg.internalProxyPort}";
environment.IPV4_ONLY = lib.mkIf cfg.proxyIPv4Only "1";
serviceConfig = { serviceConfig = {
User = "nginx";
WorkingDirectory = "/run/piped-proxy"; WorkingDirectory = "/run/piped-proxy";
ExecStart = "${pkgs.piped-proxy}/bin/piped-proxy"; ExecStart = "${pkgs.piped-proxy}/bin/piped-proxy";
RestartSec = "5s";
User = "piped";
CapabilityBoundingSet = "";
PrivateDevices = true;
PrivateUsers = true;
ProtectHome = true;
ProtectKernelLogs = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
SystemCallArchitectures = "native";
SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
}; };
}; };
@ -43,13 +52,13 @@ in {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
locations."/" = { locations."/" = {
proxyPass = "http://unix:/run/piped-proxy/socket/actix.sock"; proxyPass = "http://localhost:${toString cfg.internalProxyPort}";
extraConfig = proxy_nginx_extras + '' extraConfig = proxy_nginx_extras + ''
add_header Cache-Control "public, max-age=604800"; add_header Cache-Control "public, max-age=604800";
''; '';
}; };
locations."~ (/videoplayback|/api/v4/|/api/manifest/)" = { locations."~ (/videoplayback|/api/v4/|/api/manifest/)" = {
proxyPass = "http://unix:/run/piped-proxy/socket/actix.sock"; proxyPass = "http://localhost:${toString cfg.internalProxyPort}";
extraConfig = proxy_nginx_extras + '' extraConfig = proxy_nginx_extras + ''
add_header Cache-Control private always; add_header Cache-Control private always;
''; '';

View file

@ -11,6 +11,7 @@
invidious = 3000; invidious = 3000;
piped-backend = 3012; piped-backend = 3012;
piped-proxy = 3013;
smtp = 25; smtp = 25;
submission = 587; submission = 587;

View file

@ -6,6 +6,7 @@ in {
frontendDomain = "piped.owo.monster"; frontendDomain = "piped.owo.monster";
backendDomain = "backend.piped.owo.monster"; backendDomain = "backend.piped.owo.monster";
proxyDomain = "proxy.piped.owo.monster"; proxyDomain = "proxy.piped.owo.monster";
backendPort = ports.piped-backend; internalBackendPort = ports.piped-backend;
internalProxyPort = ports.piped-proxy;
}; };
} }