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;
backend_config = {
PORT = cfg.backendPort;
HTTP_WORKERS = 2;
PORT = cfg.internalBackendPort;
HTTP_WORKERS = cfg.httpWorkers;
PROXY_PART = "https://${cfg.proxyDomain}";
API_URL = "https://${cfg.backendDomain}";
FRONTEND_URL = "https://${cfg.frontendDomain}";
@ -48,7 +48,7 @@ let
in {
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 = {
wantedBy = [ "multi-user.target" ];
@ -66,6 +66,20 @@ in {
""}
''}";
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;
enableACME = true;
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";
};
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 {
type = types.number;
default = 30;
@ -151,13 +163,22 @@ in {
description = "Matrix access token file";
};
backendPort = mkOption {
internalBackendPort = mkOption {
type = types.number;
default = 3001;
};
internalProxyPort = mkOption {
type = types.number;
default = 3002;
};
};
config = (lib.mkIf cfg.enable) {
environment.systemPackages = with pkgs; [ piped-proxy ];
config = lib.mkIf (cfg.enable && (!cfg.disableBackend || !cfg.disableProxy)) {
users.users."piped" = {
isSystemUser = true;
group = "piped";
};
users.groups.piped = { };
};
}

View file

@ -24,18 +24,27 @@ let
'';
in {
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 = {
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 = {
User = "nginx";
WorkingDirectory = "/run/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;
enableACME = true;
locations."/" = {
proxyPass = "http://unix:/run/piped-proxy/socket/actix.sock";
proxyPass = "http://localhost:${toString cfg.internalProxyPort}";
extraConfig = proxy_nginx_extras + ''
add_header Cache-Control "public, max-age=604800";
'';
};
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 + ''
add_header Cache-Control private always;
'';

View file

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

View file

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