at 16.09-beta 3.8 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 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 27in 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}