diff --git a/docs/admin/adding-a-host-to-the-network.md b/docs/admin/adding-a-host-to-the-network.md index cd32993..439c82a 100644 --- a/docs/admin/adding-a-host-to-the-network.md +++ b/docs/admin/adding-a-host-to-the-network.md @@ -23,8 +23,6 @@ was configured when creating the network. ## Step 3: Create a `bootstrap.json` File -Access to an `admin.json` file is required for this step. - To create a `bootstrap.json` file for the new host, the admin should perform the following command from their own host: @@ -32,7 +30,6 @@ following command from their own host: isle hosts create \ --hostname \ --ip \ - --admin-path \ > bootstrap.json ``` @@ -44,21 +41,3 @@ The user can now proceed with calling `isle network join`, as described in the [Getting Started][getting-started] document. [getting-started]: ../user/getting-started.md - -### Encrypted `admin.json` - -If `admin.json` is kept in an encrypted format on disk (it should be!) then the -decrypted form can be piped into `isle hosts create` over stdin. For example, if -GPG is being used to secure `admin.json` then the following could be used to -generate a `bootstrap.json`: - -``` -gpg -d | isle hosts create \ - --hostname \ - --ip \ - --admin-path - \ - > bootstrap.json -``` - -Note that the value of `--admin-path` is `-`, indicating that `admin.json` -should be read from stdin. diff --git a/docs/admin/creating-a-new-network.md b/docs/admin/creating-a-new-network.md index d0f7db0..f8c26af 100644 --- a/docs/admin/creating-a-new-network.md +++ b/docs/admin/creating-a-new-network.md @@ -82,44 +82,18 @@ be chosen with care. * IP: The IP of your host, which will be the first host in the network. This IP must be within the chosen subnet range. -## Step 3: Prepare to Encrypt `admin.json` +## Step 3: Create the Network -The `admin.json` file (which will be created in the next step) is the most -sensitive part of an isle network. If it falls into the wrong hands it can be -used to completely compromise your network, impersonate hosts on the network, -and will likely lead to someone stealing or deleting all of your data. - -Therefore it is important that the file remains encrypted when it is not being -used, and that it is never stored to disk in its decrypted form. - -This guide assumes that you have GPG already set up with your own secret key, -and that you are familiar with how it works. There is no requirement to use GPG, -if you care to use a different method. - -## Step 4: Create the `admin.json` File - -To create the network, and the `admin.json` file in the process, run: +To create the network, run: ``` sudo isle network create \ --name \ --ip-net \ --domain \ - --hostname \ - | gpg -e -r \ - > admin.json.gpg + --hostname ``` -A couple of notes here: - -* Only one gpg recipient is specified. If you intend on including other users as - network administrators you can add them to the recipients list at this step, - so they will be able to use the `admin.json` file as well. You can also - manually add them as recipients later. - -The `isle network create` command may take up to a minute to complete. Once -completed you should have an `admin.json.gpg` file in your current directory. - At this point your host, and your network, are ready to go! To add other hosts to the network you can reference the [Adding a Host to the Network][add-host] document. diff --git a/docs/roadmap.md b/docs/roadmap.md index 5524d42..8314b60 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -8,6 +8,14 @@ order they will be implemented. These items are listed more or less in the order they need to be completed, as they generally depend on the items previous to them. +### Windows Support + GUI + +Support for Windows is a must. This requirement also includes a simple GUI, +which would essentially act as a thin layer on top of `daemon.yml` to start +with. + +Depending on difficulty level, OSX support might be added at this stage as well. + ### NATS Garage is currently used to handle eventually-consistent persistent storage, but @@ -36,14 +44,6 @@ files. The bootstrap file would be stored, encrypted, in garage, with the invite code being able to both identify and decrypt it. To instantiate a host, the user only needs to input the network domain name and the invite code. -### Windows Support + GUI - -Support for Windows is a must. This requirement also includes a simple GUI, -which would essentially act as a thin layer on top of `daemon.yml` to start -with. - -Depending on difficulty level, OSX support might be added at this stage as well. - ### FUSE Mount KBFS style. Every user should be able to mount virtual directories to their host diff --git a/go/cmd/entrypoint/hosts.go b/go/cmd/entrypoint/hosts.go index 9b93c56..69b7375 100644 --- a/go/cmd/entrypoint/hosts.go +++ b/go/cmd/entrypoint/hosts.go @@ -33,6 +33,12 @@ var subCmdHostsCreate = subCmd{ textUnmarshalerFlag{&ip}, "ip", "i", "IP of the new host", ) + canCreateHosts := flags.Bool( + "can-create-hosts", + false, + "The new host should have the ability to create hosts too", + ) + if err := flags.Parse(subCmdCtx.args); err != nil { return fmt.Errorf("parsing flags: %w", err) } @@ -49,6 +55,9 @@ var subCmdHostsCreate = subCmd{ daemon.CreateHostRequest{ HostName: hostName, IP: ip, + Opts: daemon.CreateHostOpts{ + CanCreateHosts: *canCreateHosts, + }, }, ) if err != nil { diff --git a/go/daemon/daemon.go b/go/daemon/daemon.go index 7d9f850..dbd5cfd 100644 --- a/go/daemon/daemon.go +++ b/go/daemon/daemon.go @@ -22,6 +22,13 @@ import ( "dev.mediocregopher.com/mediocre-go-lib.git/mlog" ) +// CreateHostOpts are optional parameters to the CreateHost method. +type CreateHostOpts struct { + // CanCreateHosts indicates that the bootstrap produced by CreateHost should + // give the new host the ability to create new hosts as well. + CanCreateHosts bool +} + // Daemon presents all functionality required for client frontends to interact // with isle, typically via the unix socket. type Daemon interface { @@ -65,6 +72,7 @@ type Daemon interface { ctx context.Context, hostName nebula.HostName, ip netip.Addr, // TODO automatically choose IP address + opts CreateHostOpts, ) ( JoiningBootstrap, error, ) @@ -670,6 +678,7 @@ func (d *daemon) CreateHost( ctx context.Context, hostName nebula.HostName, ip netip.Addr, + opts CreateHostOpts, ) ( JoiningBootstrap, error, ) { @@ -700,11 +709,17 @@ func (d *daemon) CreateHost( joiningBootstrap.Bootstrap.Hosts = currBootstrap.Hosts + secretsIDs := []secrets.ID{ + garageRPCSecretSecretID, + garageS3APIGlobalBucketCredentialsSecretID, + } + + if opts.CanCreateHosts { + secretsIDs = append(secretsIDs, nebulaCASigningPrivateKeySecretID) + } + if joiningBootstrap.Secrets, err = secrets.Export( - ctx, d.secretsStore, []secrets.ID{ - garageRPCSecretSecretID, - garageS3APIGlobalBucketCredentialsSecretID, - }, + ctx, d.secretsStore, secretsIDs, ); err != nil { return JoiningBootstrap{}, fmt.Errorf("exporting secrets: %w", err) } diff --git a/go/daemon/rpc.go b/go/daemon/rpc.go index d77f661..5c24afa 100644 --- a/go/daemon/rpc.go +++ b/go/daemon/rpc.go @@ -131,6 +131,7 @@ func (r *RPC) RemoveHost(ctx context.Context, req RemoveHostRequest) (struct{}, type CreateHostRequest struct { HostName nebula.HostName IP netip.Addr + Opts CreateHostOpts } // CreateHostResult wraps the results from the CreateHost RPC method. @@ -146,7 +147,7 @@ func (r *RPC) CreateHost( CreateHostResult, error, ) { joiningBootstrap, err := r.daemon.CreateHost( - ctx, req.HostName, req.IP, + ctx, req.HostName, req.IP, req.Opts, ) if err != nil { return CreateHostResult{}, err