Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Modules

Below you find a short summary of functionality of the different modules comprising noxa.

Nodes

The core framework consists of the Nodes module, providing definitions of hosts.

SSH

The SSH module allows automatic configuration of SSH authorized keys between different hosts. You might for example want that some user (bob@source) can log in to a specific host (alice@destination) to forward the port 5555. This can be achieved by the following configuration, automatically creating required SSH keys, setting up authorized keys with connection restrictions, and configuration of the SSH config files.

nodes.source.configuration.ssh.grants = {

 # name of the grant, can be anything
 portForwarding = {
      
   # connection settings
   from = "bob";
   to.node = "target";
   to.user = "alice";

   # configure client side options
   to.extraOptions = {

     # extra option to the home manager SSH module
     localForward = [
       bind.port = 5555;
       host.address = "127.0.0.1";
       host.port = 5555;
     ];

     extraOptions = {
       # dont open a shell, only port forwarding
       SessionType = "none";
     };

   };

   # configure server side options
   options.open = ["127.0.0.1:5555"];
   
   commands = {pkgs}: [ # only allow port forwarding, no shell or other commands
     "${pkgs.coreutils}/bin/false"
   ];
 };
};

Now run agenix generate, then agenix rekey and voila.

Secrets

This module allows configuring of host specific and shared secrets.

For example when setting up a wireguard network, connection keys are neither owned by any of both peers. noxa will manage these shared secrets and make them available to the respective hosts. Under the hood, noxa uses agenix and agenix-rekey to manage these secrets, but adds required functionality for above mentioned use cases.

nodes.example.configuration = {
  noxa.secrets.def = [
    
    { # shared secret between "source" and "target"
      ident = "connection-psk-example";
      module = "noxa.wireguard";
      hosts = [ "source" "target" ];
      generator.script = "wireguard-psk";
    }
    
    { # host specific secret
      ident = "interface-key-example";
      module = "noxa.wireguard";
      generator.script = "wireguard-key";
    }

    { # instance wide secret, not assigned to any host
      ident = "instance-wide-secret";
      module = "something";
      global = true;
    }

  ];
};

Wireguard

This module allows the declaration of wireguard overlay networks to connect several hosts together. It uses the secrets module to automatically exchange secrets between the hosts, configures gateways and routing in case of hosts being behind NAT/without public IPs, while also allowing direct peer to peer connections for hosts reachable by each other.

wireguard.overlay-lan = {
  networkAddress = "10.0.0.0/24";

  members = {
    # define a host "someHost" as a member of this wireguard network 
    someHost.deviceAddresses = "10.0.0.1/32";
    someHost.backend = "wg-quick";
    someHost.advertise.server.listenPort = 51823;
    someHost.advertise.server.firewallAllow = true;

    # define another host "otherHost" as a member of this wireguard network
    otherHost.deviceAddresses = "10.0.0.2/32";
    otherHost.keepAlive = 30;
  };
};

Now run agenix generate, then agenix rekey and voila.