123 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
		
		
			
		
	
	
			123 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			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";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 |