shellinabox service: intial implementation

Changed files
+123
nixos
modules
services
web-servers
+1
nixos/modules/module-list.nix
···
./services/web-servers/lighttpd/gitweb.nix
./services/web-servers/nginx/default.nix
./services/web-servers/phpfpm.nix
+
./services/web-servers/shellinabox.nix
./services/web-servers/tomcat.nix
./services/web-servers/uwsgi.nix
./services/web-servers/varnish/default.nix
+122
nixos/modules/services/web-servers/shellinabox.nix
···
+
{ config, lib, pkgs, ... }:
+
+
with lib;
+
+
let
+
+
cfg = config.services.shellinabox;
+
+
# If a certificate file is specified, shellinaboxd requires
+
# a file descriptor to retrieve it
+
fd = "3";
+
createFd = optionalString (cfg.certFile != null) "${fd}<${cfg.certFile}";
+
+
# Command line arguments for the shellinabox daemon
+
args = [ "--background" ]
+
++ optional (! cfg.enableSSL) "--disable-ssl"
+
++ optional (cfg.certFile != null) "--cert-fd=${fd}"
+
++ optional (cfg.certDirectory != null) "--cert=${cfg.certDirectory}"
+
++ cfg.extraOptions;
+
+
# Command to start shellinaboxd
+
cmd = "${pkgs.shellinabox}/bin/shellinaboxd ${concatStringsSep " " args}";
+
+
# Command to start shellinaboxd if certFile is specified
+
wrappedCmd = "${pkgs.bash}/bin/bash -c 'exec ${createFd} && ${cmd}'";
+
+
in
+
+
{
+
+
###### interface
+
+
options = {
+
services.shellinabox = {
+
enable = mkEnableOption "shellinabox daemon";
+
+
user = mkOption {
+
type = types.str;
+
default = "root";
+
description = ''
+
User to run shellinaboxd as. If started as root, the server drops
+
privileges by changing to nobody, unless overridden by the
+
<literal>--user</literal> option.
+
'';
+
};
+
+
enableSSL = mkOption {
+
type = types.bool;
+
default = false;
+
description = ''
+
Whether or not to enable SSL (https) support.
+
'';
+
};
+
+
certDirectory = mkOption {
+
type = types.nullOr types.path;
+
default = null;
+
example = "/var/certs";
+
description = ''
+
The daemon will look in this directory far any certificates.
+
If the browser negotiated a Server Name Identification the daemon
+
will look for a matching certificate-SERVERNAME.pem file. If no SNI
+
handshake takes place, it will fall back on using the certificate in the
+
certificate.pem file.
+
+
If no suitable certificate is installed, shellinaboxd will attempt to
+
create a new self-signed certificate. This will only succeed if, after
+
dropping privileges, shellinaboxd has write permissions for this
+
directory.
+
'';
+
};
+
+
certFile = mkOption {
+
type = types.nullOr types.path;
+
default = null;
+
example = "/var/certificate.pem";
+
description = "Path to server SSL certificate.";
+
};
+
+
extraOptions = mkOption {
+
type = types.listOf types.str;
+
default = [ ];
+
example = [ "--port=443" "--service /:LOGIN" ];
+
description = ''
+
A list of strings to be appended to the command line arguments
+
for shellinaboxd. Please see the manual page
+
<link xlink:href="https://code.google.com/p/shellinabox/wiki/shellinaboxd_man"/>
+
for a full list of available arguments.
+
'';
+
};
+
+
};
+
};
+
+
###### implementation
+
+
config = mkIf cfg.enable {
+
+
assertions =
+
[ { assertion = cfg.enableSSL == true
+
-> cfg.certDirectory != null || cfg.certFile != null;
+
message = "SSL is enabled for shellinabox, but no certDirectory or certFile has been specefied."; }
+
{ assertion = ! (cfg.certDirectory != null && cfg.certFile != null);
+
message = "Cannot set both certDirectory and certFile for shellinabox."; }
+
];
+
+
systemd.services.shellinaboxd = {
+
description = "Shellinabox Web Server Daemon";
+
+
wantedBy = [ "multi-user.target" ];
+
requires = [ "sshd.service" ];
+
after = [ "sshd.service" ];
+
+
serviceConfig = {
+
Type = "forking";
+
User = "${cfg.user}";
+
ExecStart = "${if cfg.certFile == null then "${cmd}" else "${wrappedCmd}"}";
+
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+
};
+
};
+
};
+
}