Allow including CA signing key with JoiningBootstrap, and update docs
This commit is contained in:
parent
d2710db8f1
commit
67d17efde0
@ -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 <name> \
|
||||
--ip <ip> \
|
||||
--admin-path <path to admin.json> \
|
||||
> 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 <path to admin.json.gpg> | isle hosts create \
|
||||
--hostname <name> \
|
||||
--ip <ip> \
|
||||
--admin-path - \
|
||||
> bootstrap.json
|
||||
```
|
||||
|
||||
Note that the value of `--admin-path` is `-`, indicating that `admin.json`
|
||||
should be read from stdin.
|
||||
|
@ -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 <name> \
|
||||
--ip-net <subnet> \
|
||||
--domain <domain> \
|
||||
--hostname <hostname> \
|
||||
| gpg -e -r <my gpg email> \
|
||||
> admin.json.gpg
|
||||
--hostname <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.
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
if joiningBootstrap.Secrets, err = secrets.Export(
|
||||
ctx, d.secretsStore, []secrets.ID{
|
||||
secretsIDs := []secrets.ID{
|
||||
garageRPCSecretSecretID,
|
||||
garageS3APIGlobalBucketCredentialsSecretID,
|
||||
},
|
||||
}
|
||||
|
||||
if opts.CanCreateHosts {
|
||||
secretsIDs = append(secretsIDs, nebulaCASigningPrivateKeySecretID)
|
||||
}
|
||||
|
||||
if joiningBootstrap.Secrets, err = secrets.Export(
|
||||
ctx, d.secretsStore, secretsIDs,
|
||||
); err != nil {
|
||||
return JoiningBootstrap{}, fmt.Errorf("exporting secrets: %w", err)
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user