shellinabox service: intial implementation

+123
+1
nixos/modules/module-list.nix
··· 383 383 ./services/web-servers/lighttpd/gitweb.nix 384 384 ./services/web-servers/nginx/default.nix 385 385 ./services/web-servers/phpfpm.nix 386 + ./services/web-servers/shellinabox.nix 386 387 ./services/web-servers/tomcat.nix 387 388 ./services/web-servers/uwsgi.nix 388 389 ./services/web-servers/varnish/default.nix
+122
nixos/modules/services/web-servers/shellinabox.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + let 6 + 7 + cfg = config.services.shellinabox; 8 + 9 + # If a certificate file is specified, shellinaboxd requires 10 + # a file descriptor to retrieve it 11 + fd = "3"; 12 + createFd = optionalString (cfg.certFile != null) "${fd}<${cfg.certFile}"; 13 + 14 + # Command line arguments for the shellinabox daemon 15 + args = [ "--background" ] 16 + ++ optional (! cfg.enableSSL) "--disable-ssl" 17 + ++ optional (cfg.certFile != null) "--cert-fd=${fd}" 18 + ++ optional (cfg.certDirectory != null) "--cert=${cfg.certDirectory}" 19 + ++ cfg.extraOptions; 20 + 21 + # Command to start shellinaboxd 22 + cmd = "${pkgs.shellinabox}/bin/shellinaboxd ${concatStringsSep " " args}"; 23 + 24 + # Command to start shellinaboxd if certFile is specified 25 + wrappedCmd = "${pkgs.bash}/bin/bash -c 'exec ${createFd} && ${cmd}'"; 26 + 27 + in 28 + 29 + { 30 + 31 + ###### interface 32 + 33 + options = { 34 + services.shellinabox = { 35 + enable = mkEnableOption "shellinabox daemon"; 36 + 37 + user = mkOption { 38 + type = types.str; 39 + default = "root"; 40 + description = '' 41 + User to run shellinaboxd as. If started as root, the server drops 42 + privileges by changing to nobody, unless overridden by the 43 + <literal>--user</literal> option. 44 + ''; 45 + }; 46 + 47 + enableSSL = mkOption { 48 + type = types.bool; 49 + default = false; 50 + description = '' 51 + Whether or not to enable SSL (https) support. 52 + ''; 53 + }; 54 + 55 + certDirectory = mkOption { 56 + type = types.nullOr types.path; 57 + default = null; 58 + example = "/var/certs"; 59 + description = '' 60 + The daemon will look in this directory far any certificates. 61 + If the browser negotiated a Server Name Identification the daemon 62 + will look for a matching certificate-SERVERNAME.pem file. If no SNI 63 + handshake takes place, it will fall back on using the certificate in the 64 + certificate.pem file. 65 + 66 + If no suitable certificate is installed, shellinaboxd will attempt to 67 + create a new self-signed certificate. This will only succeed if, after 68 + dropping privileges, shellinaboxd has write permissions for this 69 + directory. 70 + ''; 71 + }; 72 + 73 + certFile = mkOption { 74 + type = types.nullOr types.path; 75 + default = null; 76 + example = "/var/certificate.pem"; 77 + description = "Path to server SSL certificate."; 78 + }; 79 + 80 + extraOptions = mkOption { 81 + type = types.listOf types.str; 82 + default = [ ]; 83 + example = [ "--port=443" "--service /:LOGIN" ]; 84 + description = '' 85 + A list of strings to be appended to the command line arguments 86 + for shellinaboxd. Please see the manual page 87 + <link xlink:href="https://code.google.com/p/shellinabox/wiki/shellinaboxd_man"/> 88 + for a full list of available arguments. 89 + ''; 90 + }; 91 + 92 + }; 93 + }; 94 + 95 + ###### implementation 96 + 97 + config = mkIf cfg.enable { 98 + 99 + assertions = 100 + [ { assertion = cfg.enableSSL == true 101 + -> cfg.certDirectory != null || cfg.certFile != null; 102 + message = "SSL is enabled for shellinabox, but no certDirectory or certFile has been specefied."; } 103 + { assertion = ! (cfg.certDirectory != null && cfg.certFile != null); 104 + message = "Cannot set both certDirectory and certFile for shellinabox."; } 105 + ]; 106 + 107 + systemd.services.shellinaboxd = { 108 + description = "Shellinabox Web Server Daemon"; 109 + 110 + wantedBy = [ "multi-user.target" ]; 111 + requires = [ "sshd.service" ]; 112 + after = [ "sshd.service" ]; 113 + 114 + serviceConfig = { 115 + Type = "forking"; 116 + User = "${cfg.user}"; 117 + ExecStart = "${if cfg.certFile == null then "${cmd}" else "${wrappedCmd}"}"; 118 + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 119 + }; 120 + }; 121 + }; 122 + }