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