nixos/rush: init module
This commit is contained in:
		
							parent
							
								
									20b2600fa7
								
							
						
					
					
						commit
						24ad63ef2a
					
				@ -203,6 +203,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- [Pareto Security](https://paretosecurity.com/) is an alternative to corporate compliance solutions for companies that care about security but know it doesn't have to be invasive. Available as [services.paretosecurity](#opt-services.paretosecurity.enable)
 | 
					- [Pareto Security](https://paretosecurity.com/) is an alternative to corporate compliance solutions for companies that care about security but know it doesn't have to be invasive. Available as [services.paretosecurity](#opt-services.paretosecurity.enable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- [GNU Rush](https://gnu.org/software/rush/) is a Restricted User Shell, designed for systems providing limited remote access to their resources. Available as [programs.rush](#opt-programs.rush.enable).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [ipfs-cluster](https://ipfscluster.io/), Pinset orchestration for IPFS. Available as [services.ipfs-cluster](#opt-services.ipfs-cluster.enable)
 | 
					- [ipfs-cluster](https://ipfscluster.io/), Pinset orchestration for IPFS. Available as [services.ipfs-cluster](#opt-services.ipfs-cluster.enable)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [bitbox-bridge](https://github.com/BitBoxSwiss/bitbox-bridge), a bridge software that connects BitBox hardware wallets to computers & web wallets like [Rabby](https://rabby.io/). Allows one to interact & transact with smart contracts, Web3 websites & financial services without storing private keys anywhere other than the hardware wallet. Available as [services.bitbox-bridge](#opt-services.bitbox-bridge.enable).
 | 
					- [bitbox-bridge](https://github.com/BitBoxSwiss/bitbox-bridge), a bridge software that connects BitBox hardware wallets to computers & web wallets like [Rabby](https://rabby.io/). Allows one to interact & transact with smart contracts, Web3 websites & financial services without storing private keys anywhere other than the hardware wallet. Available as [services.bitbox-bridge](#opt-services.bitbox-bridge.enable).
 | 
				
			||||||
 | 
				
			|||||||
@ -290,6 +290,7 @@
 | 
				
			|||||||
  ./programs/quark-goldleaf.nix
 | 
					  ./programs/quark-goldleaf.nix
 | 
				
			||||||
  ./programs/regreet.nix
 | 
					  ./programs/regreet.nix
 | 
				
			||||||
  ./programs/rog-control-center.nix
 | 
					  ./programs/rog-control-center.nix
 | 
				
			||||||
 | 
					  ./programs/rush.nix
 | 
				
			||||||
  ./programs/rust-motd.nix
 | 
					  ./programs/rust-motd.nix
 | 
				
			||||||
  ./programs/ryzen-monitor-ng.nix
 | 
					  ./programs/ryzen-monitor-ng.nix
 | 
				
			||||||
  ./programs/screen.nix
 | 
					  ./programs/screen.nix
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										109
									
								
								nixos/modules/programs/rush.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								nixos/modules/programs/rush.nix
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  config,
 | 
				
			||||||
 | 
					  lib,
 | 
				
			||||||
 | 
					  pkgs,
 | 
				
			||||||
 | 
					  ...
 | 
				
			||||||
 | 
					}:
 | 
				
			||||||
 | 
					let
 | 
				
			||||||
 | 
					  cfg = config.programs.rush;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  indent =
 | 
				
			||||||
 | 
					    lines:
 | 
				
			||||||
 | 
					    lib.pipe lines [
 | 
				
			||||||
 | 
					      (lib.splitString "\n")
 | 
				
			||||||
 | 
					      (builtins.filter (line: line != ""))
 | 
				
			||||||
 | 
					      (map (line: "  " + line))
 | 
				
			||||||
 | 
					      (builtins.concatStringsSep "\n")
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					in
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  meta.maintainers = pkgs.rush.meta.maintainers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  options.programs.rush = with lib.types; {
 | 
				
			||||||
 | 
					    enable = lib.mkEnableOption "Restricted User Shell.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    package = lib.mkPackageOption pkgs "rush" { } // {
 | 
				
			||||||
 | 
					      type = shellPackage;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    global = lib.mkOption {
 | 
				
			||||||
 | 
					      type = lines;
 | 
				
			||||||
 | 
					      description = "The `global` statement defines global settings.";
 | 
				
			||||||
 | 
					      default = "";
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rules = lib.mkOption {
 | 
				
			||||||
 | 
					      type = attrsOf lines;
 | 
				
			||||||
 | 
					      default = { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      description = ''
 | 
				
			||||||
 | 
					        The rule statement configures a GNU Rush rule. This is a block statement, which means that all
 | 
				
			||||||
 | 
					        statements located between it and the next rule statement (or end of file, whichever occurs first)
 | 
				
			||||||
 | 
					        modify the definition of that rule.
 | 
				
			||||||
 | 
					      '';
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    shell = lib.mkOption {
 | 
				
			||||||
 | 
					      readOnly = true;
 | 
				
			||||||
 | 
					      type = either shellPackage path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      description = ''
 | 
				
			||||||
 | 
					        The resolved shell path that users can inherit to set `rush` as their login shell.
 | 
				
			||||||
 | 
					        This is a convenience option for use in user definitions. Example:
 | 
				
			||||||
 | 
					          `users.users.alice = { inherit (config.programs.rush) shell; ... };`
 | 
				
			||||||
 | 
					      '';
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wrap = lib.mkOption {
 | 
				
			||||||
 | 
					      type = bool;
 | 
				
			||||||
 | 
					      default = config.security.enableWrappers;
 | 
				
			||||||
 | 
					      defaultText = lib.literalExpression "config.security.enableWrappers";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      description = ''
 | 
				
			||||||
 | 
					        Whether to wrap the `rush` binary with a SUID-enabled wrapper.
 | 
				
			||||||
 | 
					        This is required if {option}`security.enableWrappers` is enabled in your configuration.
 | 
				
			||||||
 | 
					      '';
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  config = lib.mkIf cfg.enable (
 | 
				
			||||||
 | 
					    lib.mkMerge [
 | 
				
			||||||
 | 
					      (lib.mkIf cfg.wrap {
 | 
				
			||||||
 | 
					        security.wrappers.rush = lib.mkDefault {
 | 
				
			||||||
 | 
					          group = "root";
 | 
				
			||||||
 | 
					          owner = "root";
 | 
				
			||||||
 | 
					          permissions = "u+rx,g+x,o+x";
 | 
				
			||||||
 | 
					          setgid = false;
 | 
				
			||||||
 | 
					          setuid = true;
 | 
				
			||||||
 | 
					          source = lib.getExe cfg.package;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        programs.rush.shell = if cfg.wrap then config.security.wrapperDir + "/rush" else cfg.package;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        environment = {
 | 
				
			||||||
 | 
					          shells = [ cfg.shell ];
 | 
				
			||||||
 | 
					          systemPackages = [ cfg.package ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          etc."rush.rc".text =
 | 
				
			||||||
 | 
					            lib.pipe
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                "# This file was created by the module `programs.rush`;"
 | 
				
			||||||
 | 
					                "rush 2.0"
 | 
				
			||||||
 | 
					                (lib.optionalString (cfg.global != "") "global\n${indent cfg.global}")
 | 
				
			||||||
 | 
					                (lib.optionals (cfg.rules != { }) (
 | 
				
			||||||
 | 
					                  lib.mapAttrsToList (name: content: "rule ${name}\n${indent content}") cfg.rules
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
 | 
					              [
 | 
				
			||||||
 | 
					                (lib.flatten)
 | 
				
			||||||
 | 
					                (builtins.filter (line: line != ""))
 | 
				
			||||||
 | 
					                (builtins.concatStringsSep "\n\n")
 | 
				
			||||||
 | 
					                (lib.mkDefault)
 | 
				
			||||||
 | 
					              ];
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1169,6 +1169,7 @@ in
 | 
				
			|||||||
  rsyslogd = handleTest ./rsyslogd.nix { };
 | 
					  rsyslogd = handleTest ./rsyslogd.nix { };
 | 
				
			||||||
  rtkit = runTest ./rtkit.nix;
 | 
					  rtkit = runTest ./rtkit.nix;
 | 
				
			||||||
  rtorrent = handleTest ./rtorrent.nix { };
 | 
					  rtorrent = handleTest ./rtorrent.nix { };
 | 
				
			||||||
 | 
					  rush = runTest ./rush.nix;
 | 
				
			||||||
  rustls-libssl = handleTest ./rustls-libssl.nix { };
 | 
					  rustls-libssl = handleTest ./rustls-libssl.nix { };
 | 
				
			||||||
  rxe = handleTest ./rxe.nix { };
 | 
					  rxe = handleTest ./rxe.nix { };
 | 
				
			||||||
  sabnzbd = handleTest ./sabnzbd.nix { };
 | 
					  sabnzbd = handleTest ./sabnzbd.nix { };
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										88
									
								
								nixos/tests/rush.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								nixos/tests/rush.nix
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					{ pkgs, ... }:
 | 
				
			||||||
 | 
					let
 | 
				
			||||||
 | 
					  inherit (import ./ssh-keys.nix pkgs) snakeOilEd25519PrivateKey snakeOilEd25519PublicKey;
 | 
				
			||||||
 | 
					  username = "nix-remote-builder";
 | 
				
			||||||
 | 
					in
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  name = "rush";
 | 
				
			||||||
 | 
					  meta = { inherit (pkgs.rush.meta) maintainers platforms; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  nodes = {
 | 
				
			||||||
 | 
					    client =
 | 
				
			||||||
 | 
					      { ... }:
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        nix.settings.extra-experimental-features = [ "nix-command" ];
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    server =
 | 
				
			||||||
 | 
					      { config, ... }:
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        nix.settings.trusted-users = [ "${username}" ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        programs.rush = {
 | 
				
			||||||
 | 
					          enable = true;
 | 
				
			||||||
 | 
					          global = "debug 1";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          rules = {
 | 
				
			||||||
 | 
					            daemon = ''
 | 
				
			||||||
 | 
					              match $# == 2
 | 
				
			||||||
 | 
					              match $0 == "nix-daemon"
 | 
				
			||||||
 | 
					              match $1 == "--stdio"
 | 
				
			||||||
 | 
					              match $user == "${username}"
 | 
				
			||||||
 | 
					              chdir "${config.nix.package}/bin"
 | 
				
			||||||
 | 
					            '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            whoami = ''
 | 
				
			||||||
 | 
					              match $# == 1
 | 
				
			||||||
 | 
					              match $0 == "whoami"
 | 
				
			||||||
 | 
					              match $user == "${username}"
 | 
				
			||||||
 | 
					              chdir "${dirOf config.environment.usrbinenv}"
 | 
				
			||||||
 | 
					            '';
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        services.openssh = {
 | 
				
			||||||
 | 
					          enable = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          extraConfig = ''
 | 
				
			||||||
 | 
					            Match User ${username}
 | 
				
			||||||
 | 
					              AllowAgentForwarding no
 | 
				
			||||||
 | 
					              AllowTcpForwarding no
 | 
				
			||||||
 | 
					              PermitTTY no
 | 
				
			||||||
 | 
					              PermitTunnel no
 | 
				
			||||||
 | 
					              X11Forwarding no
 | 
				
			||||||
 | 
					            Match All
 | 
				
			||||||
 | 
					          '';
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        users = {
 | 
				
			||||||
 | 
					          groups."${username}" = { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          users."${username}" = {
 | 
				
			||||||
 | 
					            inherit (config.programs.rush) shell;
 | 
				
			||||||
 | 
					            group = "${username}";
 | 
				
			||||||
 | 
					            isSystemUser = true;
 | 
				
			||||||
 | 
					            openssh.authorizedKeys.keys = [ snakeOilEd25519PublicKey ];
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  testScript = ''
 | 
				
			||||||
 | 
					    start_all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    client.succeed("mkdir -m 700 /root/.ssh")
 | 
				
			||||||
 | 
					    client.succeed("cat '${snakeOilEd25519PrivateKey}' | tee /root/.ssh/id_ed25519")
 | 
				
			||||||
 | 
					    client.succeed("chmod 600 /root/.ssh/id_ed25519")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    server.wait_for_unit("sshd")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    client.succeed("ssh-keyscan -H server | tee -a /root/.ssh/known_hosts")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    client.succeed("ssh ${username}@server -- whoami")
 | 
				
			||||||
 | 
					    client.succeed("nix store info --store 'ssh-ng://${username}@server'")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    client.fail("ssh ${username}@server -- date")
 | 
				
			||||||
 | 
					    client.fail("nix store info --store 'ssh://${username}@server'")
 | 
				
			||||||
 | 
					  '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -4,6 +4,7 @@
 | 
				
			|||||||
  stdenv,
 | 
					  stdenv,
 | 
				
			||||||
  bash,
 | 
					  bash,
 | 
				
			||||||
  perl,
 | 
					  perl,
 | 
				
			||||||
 | 
					  nixosTests,
 | 
				
			||||||
}:
 | 
					}:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stdenv.mkDerivation rec {
 | 
					stdenv.mkDerivation rec {
 | 
				
			||||||
@ -61,5 +62,6 @@ stdenv.mkDerivation rec {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  passthru = {
 | 
					  passthru = {
 | 
				
			||||||
    shellPath = "/bin/rush";
 | 
					    shellPath = "/bin/rush";
 | 
				
			||||||
 | 
					    tests = { inherit (nixosTests) rush; };
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user