at 23.11-pre 3.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.envoy; 7 format = pkgs.formats.json { }; 8 conf = format.generate "envoy.json" cfg.settings; 9 validateConfig = required: file: 10 pkgs.runCommand "validate-envoy-conf" { } '' 11 ${cfg.package}/bin/envoy --log-level error --mode validate -c "${file}" ${lib.optionalString (!required) "|| true"} 12 cp "${file}" "$out" 13 ''; 14in 15 16{ 17 options.services.envoy = { 18 enable = mkEnableOption (lib.mdDoc "Envoy reverse proxy"); 19 20 package = mkPackageOptionMD pkgs "envoy" { }; 21 22 requireValidConfig = mkOption { 23 type = types.bool; 24 default = true; 25 description = lib.mdDoc '' 26 Whether a failure during config validation at build time is fatal. 27 When the config can't be checked during build time, for example when it includes 28 other files, disable this option. 29 ''; 30 }; 31 32 settings = mkOption { 33 type = format.type; 34 default = { }; 35 example = literalExpression '' 36 { 37 admin = { 38 access_log_path = "/dev/null"; 39 address = { 40 socket_address = { 41 protocol = "TCP"; 42 address = "127.0.0.1"; 43 port_value = 9901; 44 }; 45 }; 46 }; 47 static_resources = { 48 listeners = []; 49 clusters = []; 50 }; 51 } 52 ''; 53 description = lib.mdDoc '' 54 Specify the configuration for Envoy in Nix. 55 ''; 56 }; 57 }; 58 59 config = mkIf cfg.enable { 60 environment.systemPackages = [ cfg.package ]; 61 systemd.services.envoy = { 62 description = "Envoy reverse proxy"; 63 after = [ "network-online.target" ]; 64 requires = [ "network-online.target" ]; 65 wantedBy = [ "multi-user.target" ]; 66 serviceConfig = { 67 ExecStart = "${cfg.package}/bin/envoy -c ${validateConfig cfg.requireValidConfig conf}"; 68 CacheDirectory = [ "envoy" ]; 69 LogsDirectory = [ "envoy" ]; 70 Restart = "no"; 71 # Hardening 72 AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; 73 CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; 74 DeviceAllow = [ "" ]; 75 DevicePolicy = "closed"; 76 DynamicUser = true; 77 LockPersonality = true; 78 MemoryDenyWriteExecute = false; # at least wasmr needs WX permission 79 PrivateDevices = true; 80 PrivateUsers = false; # breaks CAP_NET_BIND_SERVICE 81 ProcSubset = "pid"; 82 ProtectClock = true; 83 ProtectControlGroups = true; 84 ProtectHome = true; 85 ProtectHostname = true; 86 ProtectKernelLogs = true; 87 ProtectKernelModules = true; 88 ProtectKernelTunables = true; 89 ProtectProc = "ptraceable"; 90 ProtectSystem = "strict"; 91 RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" "AF_XDP" ]; 92 RestrictNamespaces = true; 93 RestrictRealtime = true; 94 SystemCallArchitectures = "native"; 95 SystemCallErrorNumber = "EPERM"; 96 SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ]; 97 UMask = "0066"; 98 }; 99 }; 100 }; 101}