at 24.11-pre 3.0 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.frp; 7 settingsFormat = pkgs.formats.toml { }; 8 configFile = settingsFormat.generate "frp.toml" cfg.settings; 9 isClient = (cfg.role == "client"); 10 isServer = (cfg.role == "server"); 11in 12{ 13 options = { 14 services.frp = { 15 enable = mkEnableOption "frp"; 16 17 package = mkPackageOption pkgs "frp" { }; 18 19 role = mkOption { 20 type = types.enum [ "server" "client" ]; 21 description = '' 22 The frp consists of `client` and `server`. The server is usually 23 deployed on the machine with a public IP address, and 24 the client is usually deployed on the machine 25 where the Intranet service to be penetrated resides. 26 ''; 27 }; 28 29 settings = mkOption { 30 type = settingsFormat.type; 31 default = { }; 32 description = '' 33 Frp configuration, for configuration options 34 see the example of [client](https://github.com/fatedier/frp/blob/dev/conf/frpc_full_example.toml) 35 or [server](https://github.com/fatedier/frp/blob/dev/conf/frps_full_example.toml) on github. 36 ''; 37 example = { 38 serverAddr = "x.x.x.x"; 39 serverPort = 7000; 40 }; 41 }; 42 }; 43 }; 44 45 config = 46 let 47 serviceCapability = optionals isServer [ "CAP_NET_BIND_SERVICE" ]; 48 executableFile = if isClient then "frpc" else "frps"; 49 in 50 mkIf cfg.enable { 51 systemd.services = { 52 frp = { 53 wants = optionals isClient [ "network-online.target" ]; 54 after = if isClient then [ "network-online.target" ] else [ "network.target" ]; 55 wantedBy = [ "multi-user.target" ]; 56 description = "A fast reverse proxy frp ${cfg.role}"; 57 serviceConfig = { 58 Type = "simple"; 59 Restart = "on-failure"; 60 RestartSec = 15; 61 ExecStart = "${cfg.package}/bin/${executableFile} --strict_config -c ${configFile}"; 62 StateDirectoryMode = optionalString isServer "0700"; 63 DynamicUser = true; 64 # Hardening 65 UMask = optionalString isServer "0007"; 66 CapabilityBoundingSet = serviceCapability; 67 AmbientCapabilities = serviceCapability; 68 PrivateDevices = true; 69 ProtectHostname = true; 70 ProtectClock = true; 71 ProtectKernelTunables = true; 72 ProtectKernelModules = true; 73 ProtectKernelLogs = true; 74 ProtectControlGroups = true; 75 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ] ++ optionals isClient [ "AF_UNIX" ]; 76 LockPersonality = true; 77 MemoryDenyWriteExecute = true; 78 RestrictRealtime = true; 79 RestrictSUIDSGID = true; 80 PrivateMounts = true; 81 SystemCallArchitectures = "native"; 82 SystemCallFilter = [ "@system-service" ]; 83 }; 84 }; 85 }; 86 }; 87 88 meta.maintainers = with maintainers; [ zaldnoay ]; 89}