at 23.11-pre 3.8 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.xinetd; 8 9 configFile = pkgs.writeText "xinetd.conf" 10 '' 11 defaults 12 { 13 log_type = SYSLOG daemon info 14 log_on_failure = HOST 15 log_on_success = PID HOST DURATION EXIT 16 ${cfg.extraDefaults} 17 } 18 19 ${concatMapStrings makeService cfg.services} 20 ''; 21 22 makeService = srv: 23 '' 24 service ${srv.name} 25 { 26 protocol = ${srv.protocol} 27 ${optionalString srv.unlisted "type = UNLISTED"} 28 ${optionalString (srv.flags != "") "flags = ${srv.flags}"} 29 socket_type = ${if srv.protocol == "udp" then "dgram" else "stream"} 30 ${optionalString (srv.port != 0) "port = ${toString srv.port}"} 31 wait = ${if srv.protocol == "udp" then "yes" else "no"} 32 user = ${srv.user} 33 server = ${srv.server} 34 ${optionalString (srv.serverArgs != "") "server_args = ${srv.serverArgs}"} 35 ${srv.extraConfig} 36 } 37 ''; 38 39in 40 41{ 42 43 ###### interface 44 45 options = { 46 47 services.xinetd.enable = mkEnableOption (lib.mdDoc "the xinetd super-server daemon"); 48 49 services.xinetd.extraDefaults = mkOption { 50 default = ""; 51 type = types.lines; 52 description = lib.mdDoc '' 53 Additional configuration lines added to the default section of xinetd's configuration. 54 ''; 55 }; 56 57 services.xinetd.services = mkOption { 58 default = []; 59 description = lib.mdDoc '' 60 A list of services provided by xinetd. 61 ''; 62 63 type = with types; listOf (submodule ({ 64 65 options = { 66 67 name = mkOption { 68 type = types.str; 69 example = "login"; 70 description = lib.mdDoc "Name of the service."; 71 }; 72 73 protocol = mkOption { 74 type = types.str; 75 default = "tcp"; 76 description = 77 lib.mdDoc "Protocol of the service. Usually `tcp` or `udp`."; 78 }; 79 80 port = mkOption { 81 type = types.port; 82 default = 0; 83 example = 123; 84 description = lib.mdDoc "Port number of the service."; 85 }; 86 87 user = mkOption { 88 type = types.str; 89 default = "nobody"; 90 description = lib.mdDoc "User account for the service"; 91 }; 92 93 server = mkOption { 94 type = types.str; 95 example = "/foo/bin/ftpd"; 96 description = lib.mdDoc "Path of the program that implements the service."; 97 }; 98 99 serverArgs = mkOption { 100 type = types.separatedString " "; 101 default = ""; 102 description = lib.mdDoc "Command-line arguments for the server program."; 103 }; 104 105 flags = mkOption { 106 type = types.str; 107 default = ""; 108 description = lib.mdDoc ""; 109 }; 110 111 unlisted = mkOption { 112 type = types.bool; 113 default = false; 114 description = lib.mdDoc '' 115 Whether this server is listed in 116 {file}`/etc/services`. If so, the port 117 number can be omitted. 118 ''; 119 }; 120 121 extraConfig = mkOption { 122 type = types.lines; 123 default = ""; 124 description = lib.mdDoc "Extra configuration-lines added to the section of the service."; 125 }; 126 127 }; 128 129 })); 130 131 }; 132 133 }; 134 135 136 ###### implementation 137 138 config = mkIf cfg.enable { 139 systemd.services.xinetd = { 140 description = "xinetd server"; 141 after = [ "network.target" ]; 142 wantedBy = [ "multi-user.target" ]; 143 path = [ pkgs.xinetd ]; 144 script = "exec xinetd -syslog daemon -dontfork -stayalive -f ${configFile}"; 145 }; 146 }; 147}