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
|
## 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
|
To create a `bootstrap.json` file for the new host, the admin should perform the
|
||||||
following command from their own host:
|
following command from their own host:
|
||||||
|
|
||||||
@ -32,7 +30,6 @@ following command from their own host:
|
|||||||
isle hosts create \
|
isle hosts create \
|
||||||
--hostname <name> \
|
--hostname <name> \
|
||||||
--ip <ip> \
|
--ip <ip> \
|
||||||
--admin-path <path to admin.json> \
|
|
||||||
> bootstrap.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][getting-started] document.
|
||||||
|
|
||||||
[getting-started]: ../user/getting-started.md
|
[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
|
* IP: The IP of your host, which will be the first host in the network. This IP
|
||||||
must be within the chosen subnet range.
|
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
|
To create the network, run:
|
||||||
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:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo isle network create \
|
sudo isle network create \
|
||||||
--name <name> \
|
--name <name> \
|
||||||
--ip-net <subnet> \
|
--ip-net <subnet> \
|
||||||
--domain <domain> \
|
--domain <domain> \
|
||||||
--hostname <hostname> \
|
--hostname <hostname>
|
||||||
| gpg -e -r <my gpg email> \
|
|
||||||
> admin.json.gpg
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
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]
|
to the network you can reference the [Adding a Host to the Network][add-host]
|
||||||
document.
|
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
|
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.
|
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
|
### NATS
|
||||||
|
|
||||||
Garage is currently used to handle eventually-consistent persistent storage, but
|
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
|
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.
|
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
|
### FUSE Mount
|
||||||
|
|
||||||
KBFS style. Every user should be able to mount virtual directories to their host
|
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",
|
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 {
|
if err := flags.Parse(subCmdCtx.args); err != nil {
|
||||||
return fmt.Errorf("parsing flags: %w", err)
|
return fmt.Errorf("parsing flags: %w", err)
|
||||||
}
|
}
|
||||||
@ -49,6 +55,9 @@ var subCmdHostsCreate = subCmd{
|
|||||||
daemon.CreateHostRequest{
|
daemon.CreateHostRequest{
|
||||||
HostName: hostName,
|
HostName: hostName,
|
||||||
IP: ip,
|
IP: ip,
|
||||||
|
Opts: daemon.CreateHostOpts{
|
||||||
|
CanCreateHosts: *canCreateHosts,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -22,6 +22,13 @@ import (
|
|||||||
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
"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
|
// Daemon presents all functionality required for client frontends to interact
|
||||||
// with isle, typically via the unix socket.
|
// with isle, typically via the unix socket.
|
||||||
type Daemon interface {
|
type Daemon interface {
|
||||||
@ -65,6 +72,7 @@ type Daemon interface {
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
hostName nebula.HostName,
|
hostName nebula.HostName,
|
||||||
ip netip.Addr, // TODO automatically choose IP address
|
ip netip.Addr, // TODO automatically choose IP address
|
||||||
|
opts CreateHostOpts,
|
||||||
) (
|
) (
|
||||||
JoiningBootstrap, error,
|
JoiningBootstrap, error,
|
||||||
)
|
)
|
||||||
@ -670,6 +678,7 @@ func (d *daemon) CreateHost(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
hostName nebula.HostName,
|
hostName nebula.HostName,
|
||||||
ip netip.Addr,
|
ip netip.Addr,
|
||||||
|
opts CreateHostOpts,
|
||||||
) (
|
) (
|
||||||
JoiningBootstrap, error,
|
JoiningBootstrap, error,
|
||||||
) {
|
) {
|
||||||
@ -700,11 +709,17 @@ func (d *daemon) CreateHost(
|
|||||||
|
|
||||||
joiningBootstrap.Bootstrap.Hosts = currBootstrap.Hosts
|
joiningBootstrap.Bootstrap.Hosts = currBootstrap.Hosts
|
||||||
|
|
||||||
|
secretsIDs := []secrets.ID{
|
||||||
|
garageRPCSecretSecretID,
|
||||||
|
garageS3APIGlobalBucketCredentialsSecretID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CanCreateHosts {
|
||||||
|
secretsIDs = append(secretsIDs, nebulaCASigningPrivateKeySecretID)
|
||||||
|
}
|
||||||
|
|
||||||
if joiningBootstrap.Secrets, err = secrets.Export(
|
if joiningBootstrap.Secrets, err = secrets.Export(
|
||||||
ctx, d.secretsStore, []secrets.ID{
|
ctx, d.secretsStore, secretsIDs,
|
||||||
garageRPCSecretSecretID,
|
|
||||||
garageS3APIGlobalBucketCredentialsSecretID,
|
|
||||||
},
|
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return JoiningBootstrap{}, fmt.Errorf("exporting secrets: %w", err)
|
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 {
|
type CreateHostRequest struct {
|
||||||
HostName nebula.HostName
|
HostName nebula.HostName
|
||||||
IP netip.Addr
|
IP netip.Addr
|
||||||
|
Opts CreateHostOpts
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateHostResult wraps the results from the CreateHost RPC method.
|
// CreateHostResult wraps the results from the CreateHost RPC method.
|
||||||
@ -146,7 +147,7 @@ func (r *RPC) CreateHost(
|
|||||||
CreateHostResult, error,
|
CreateHostResult, error,
|
||||||
) {
|
) {
|
||||||
joiningBootstrap, err := r.daemon.CreateHost(
|
joiningBootstrap, err := r.daemon.CreateHost(
|
||||||
ctx, req.HostName, req.IP,
|
ctx, req.HostName, req.IP, req.Opts,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return CreateHostResult{}, err
|
return CreateHostResult{}, err
|
||||||
|
Loading…
Reference in New Issue
Block a user