at 25.11-pre 3.5 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.echoip; 9in 10{ 11 meta.maintainers = with lib.maintainers; [ defelo ]; 12 13 options.services.echoip = { 14 enable = lib.mkEnableOption "echoip"; 15 16 package = lib.mkPackageOption pkgs "echoip" { }; 17 18 virtualHost = lib.mkOption { 19 type = lib.types.nullOr lib.types.str; 20 description = '' 21 Name of the nginx virtual host to use and setup. If null, do not setup anything. 22 ''; 23 default = null; 24 }; 25 26 extraArgs = lib.mkOption { 27 type = lib.types.listOf lib.types.str; 28 description = "Extra command line arguments to pass to echoip. See <https://github.com/mpolden/echoip> for details."; 29 default = [ ]; 30 }; 31 32 listenAddress = lib.mkOption { 33 type = lib.types.str; 34 description = "The address echoip should listen on"; 35 default = ":8080"; 36 example = "127.0.0.1:8000"; 37 }; 38 39 enablePortLookup = lib.mkEnableOption "port lookup"; 40 41 enableReverseHostnameLookups = lib.mkEnableOption "reverse hostname lookups"; 42 43 remoteIpHeader = lib.mkOption { 44 type = lib.types.nullOr lib.types.str; 45 description = "Header to trust for remote IP, if present"; 46 default = null; 47 example = "X-Real-IP"; 48 }; 49 }; 50 51 config = lib.mkIf cfg.enable { 52 systemd.services.echoip = { 53 wantedBy = [ "multi-user.target" ]; 54 55 wants = [ "network-online.target" ]; 56 after = [ "network-online.target" ]; 57 58 serviceConfig = { 59 User = "echoip"; 60 Group = "echoip"; 61 DynamicUser = true; 62 ExecStart = lib.escapeShellArgs ( 63 [ 64 (lib.getExe cfg.package) 65 "-l" 66 cfg.listenAddress 67 ] 68 ++ lib.optional cfg.enablePortLookup "-p" 69 ++ lib.optional cfg.enableReverseHostnameLookups "-r" 70 ++ lib.optionals (cfg.remoteIpHeader != null) [ 71 "-H" 72 cfg.remoteIpHeader 73 ] 74 ++ cfg.extraArgs 75 ); 76 77 # Hardening 78 AmbientCapabilities = ""; 79 CapabilityBoundingSet = [ "" ]; 80 DevicePolicy = "closed"; 81 LockPersonality = true; 82 MemoryDenyWriteExecute = true; 83 NoNewPrivileges = true; 84 PrivateDevices = true; 85 PrivateTmp = true; 86 PrivateUsers = true; 87 ProcSubset = "pid"; 88 ProtectClock = true; 89 ProtectControlGroups = true; 90 ProtectHome = true; 91 ProtectHostname = true; 92 ProtectKernelLogs = true; 93 ProtectKernelModules = true; 94 ProtectKernelTunables = true; 95 ProtectProc = "invisible"; 96 ProtectSystem = "strict"; 97 RemoveIPC = true; 98 RestrictAddressFamilies = [ "AF_INET AF_INET6 AF_UNIX" ]; 99 RestrictNamespaces = true; 100 RestrictRealtime = true; 101 RestrictSUIDSGID = true; 102 SystemCallArchitectures = "native"; 103 SystemCallFilter = [ 104 "@system-service" 105 "~@privileged" 106 "~@resources" 107 "setrlimit" 108 ]; 109 UMask = "0077"; 110 }; 111 }; 112 113 services.nginx = lib.mkIf (cfg.virtualHost != null) { 114 enable = true; 115 virtualHosts.${cfg.virtualHost} = { 116 locations."/" = { 117 proxyPass = "http://${cfg.listenAddress}"; 118 recommendedProxySettings = true; 119 }; 120 }; 121 }; 122 123 services.echoip = lib.mkIf (cfg.virtualHost != null) { 124 listenAddress = lib.mkDefault "127.0.0.1:8080"; 125 remoteIpHeader = "X-Real-IP"; 126 }; 127 }; 128}