Update roadmap, gateway doc is no longer necessary

This commit is contained in:
Brian Picciano 2023-09-06 22:24:30 +02:00
parent 5ee80b1b7d
commit 745f7786e8
3 changed files with 84 additions and 232 deletions

View File

@ -101,8 +101,6 @@ Documentation for devs:
created by `isle daemon` at runtime. created by `isle daemon` at runtime.
* [Rebuilding Documentation](docs/dev/rebuilding-documentation.md) * [Rebuilding Documentation](docs/dev/rebuilding-documentation.md)
* [Releases](docs/dev/releases.md) * [Releases](docs/dev/releases.md)
* [Gateway](docs/dev/gateway.md): Tentative spec for gateway functionality in
Isle.
## Misc ## Misc

View File

@ -1,200 +0,0 @@
# Gateway
This document acts as the spec for a general purpose gateway system built into
the isle daemon.
The high level goal of the gateway is to remove significant barriers to entry
for individuals hosting data and services at their own domain names:
* Maintaining a public IP or dDNS
* Keeping a server always online
If a network operator has configured their host as a lighthouse for their
network they will have already solved these problems. By providing gateway
functionality they can share that work with their community.
The gateway functions by serving requests for a user's DNS domain on their
behalf. Requests are served by publicly facing hosts of an isle network using
a backend configured by the user.
## Terminology
* "gateway process" refers to the the system process running on a single host
which serves requests for an isle network's gateway.
* "gateway" refers to the collection of all gateway processes which are
configured and running for an isle network. All gateway processes exhibit
the same behavior, and serve the same domain names, and so are conceived as
being a single unit.
* "gateway DNS name" refers to the single DNS domain or subdomain which contains
a A/AAAA record for each of the gateway processes of an isle network.
## Gateway DNS Setup
In order to support the gateway feature, the operators of a network will need to
agree on a single public DNS name (which could be any arbitrary domain or
sub-domain) which will be used by the gateway. The operators will need to agree
on who is able to edit this name, taking into consideration "bus factor"
concerns.
For an operator to enable their host's gateway process they need to:
* Enable the option within their `daemon.yml`, and include the appropriate
public IP or DNS name for their host.
* Make ports 80/443 publicly available on their host.
* Have that same public IP/DNS name added as an A/AAAA record on the gateway DNS
name.
## Backends
Within the context of the gateway, a backend is any method used by the gateway
to serve requests at a domain. Backends could include:
- Public git repositories (like how github pages works)
- S3 buckets on the private garage cluster
- IPFS files or IPNS names
- Services which are available privately over an isle network
A backend is uniquely described and identified by an object containing a `type`
field, and then further fields which depend on the type. The object for a git
repository backend would look like:
```json
{
"type":"git",
"origin":"URL",
"branch":"main"
}
```
All backends essentially act as a static filesystem, from which requests are
served by the gateway. For example, given a domain `example.com` which has been
configured with an isle network gateway to serve a git repo, if
`example.com/foo/bar` is requested then the file at `/foo/bar` within the
current tip of the git repo is served.
## User Experience
It should be noted up-front that a gateway user should not need to have any
hosts registered on an isle network, or have any other material connection to
the network, in order to use the gateway.
### Setup a Domain
The user navigates to a webpage hosted at the gateway DNS name, and selects the
option to "setup domain". This brings them to a new webpage.
This page presents the user with a dropdown input containing options for each
supported backend type. When the user selects a backend type, the page updates
to present further fields depending on the backend type. The presented fields
are all those required to construct a backend object of the selected type.
Once the user has input all necessary information, they click a button to
continue to the next step.
At the next step they are prompted for a secret passphrase that is only known by
the network operators. The user must get this passphrase from an operator, if
they haven't already. Once successfully input, they continue to the next step.
At the next step they are presented with a unique, opaque string, along with
instructions. The instructions prompt the user to:
* Add a CNAME record to their DNS domain, pointing to the gateway DNS name.
* Add a TXT record to their DNS domain containing `isle_gateway=<opaque
string>`.
The page provides the user with an input box to input their domain name into,
and a "Check" button to click once they have completed these instructions. If
they have not successfully completed the instructions then clicking "Check" will
display an appropriate error to them. If they have successfully completed the
instructions then clicking "Check" will result in a "Success" screen.
At this point navigating to their domain should result in their chosen backend
being served.
### Checking a Domain
The user navigates to a webpage hosted at the gateway DNS name, and selects the
option to "check existing domain". This brings them to a new webpage.
This page presents the user with a text box to input a domain name into, and a
"Check" button. When the button is clicked and a domain without a backend
already set up on it is given then an error is displayed. When the button is
clicked and a domain with a backend set up is given then the information for
that backend is displayed in a read-only mode.
### Updating a Domain
The user navigates to a webpage hosted at the gateway DNS name, and selects the
option to "update existing domain". This brings them to a new webpage.
This webpage works almost the same as the "Checking a Domain" page. The
difference comes at the final step, when the "Check" button is clicked and a
domain with a backend set up is given. At this point the existing backend
information for that domain is displayed in a _read-write_ mode, i.e. in a form
similar to that used in the "Setup a Domain" step for the same backend. From
here the user can edit any information they want, and the flow continues exactly
as if they were in the "Setup a Domain" flow.
## Implementation Notes
The following are general notes and ideas about how this can be implemented.
They are not meant to be set in stone.
* A backend object can be deterministically hashed to form a unique ID for that
backend. The "opaque string" which is added to a user's domain's TXT record is
this ID.
* The gateway processes use a shared garage S3 bucket for persistence of
domain/backend mappings.
* Each process periodically re-reads all mapping data from S3 and uses that as
its currently active set of mappings. A pubsub system like NATS can be added
later to ensure that re-syncing happens at the same time.
* Each file in the bucket corresponds to a domain name which has been
successfully setup. The value contains the backend which is set up for the
domain.
* When the "Check" button is clicked during the "Setup/Update a Domain" flows,
the gateway process which handles the call does the following:
* Checks that a TXT record with the expected value exists on the domain being
added.
* Checks that a CNAME record with the expected value exists on the domain
being added.
* Performs ACME challenge for SSL cert. It will do this via an
[HTTP-01][http01] challenge. The challenge token will be put in the shared
garage S3 bucket, so that all gateway processes can potentially serve it
when requested.
* Depending on the backend, it may be required to sync some data into the
shared garage S3 bucket. For example, if the git backend is being used, then
the tip of the repo+branch will be synced into the S3 bucket.
* Adds a file to the shared garage S3 bucket corresponding to the new
domain/backend mapping.
* Each gateway process is responsible for keeping its own SSL certificates up to
date via periodic ACME challenges.
* Backend data in the shared garage S3 bucket will need to be periodically kept
up to date. A mechanism needs to be devised to do this reasonably reliably,
but without _all_ gateway processes constantly doing it. A communication layer
like NATS might come in handy here.
[http01]: https://letsencrypt.org/docs/challenge-types/#http-01-challenge
## Future Work
It should be possible for someone accessing a private domain on the isle
network to access the gateway web panel and use it _without_ requiring a secret
passphrase. This way community members who have already been vetted (by being
added to the VPN) can have even less friction.

View File

@ -14,9 +14,59 @@ Currently the only supported OS/CPU is Linux/amd64. This can be expanded
_theoretically_ quite easily, using nix's cross compilation tools. First target _theoretically_ quite easily, using nix's cross compilation tools. First target
should be OSX/arm64, but windows would also be quite the get. should be OSX/arm64, but windows would also be quite the get.
### Testing ### NATS
Once bootstrap is generalized, we'll be able to write some automated tests. Garage is currently used to handle eventually-consistent persistent storage, but
there is no mechanism for inter-host realtime communication as of yet. NATS
would be a good candidate for this, as it uses a gossip protocol which does not
require a central coordinator (I don't think), and is well supported.
### Integration of [domani](https://code.betamike.com/micropelago/domani)
Integration of domani will require some changes on domani's end. We want domani
to be able to store cert information in S3 (garage), so that all isle lighthouse
nodes can potentially become gateways as well. Once done, it would be possible
for lighthouses to forward public traffic to inner nodes.
It should also be possible for users within the network to take advantage of
domani's hosting ability even without an always-on host of their own, without
requiring a passphrase.
Most likely this integration will require NATS as well, to coordinate cache
invalidation and cert refreshing.
### Web server + interface
Have every `isle daemon` run a webserver as one of its sub-processes. Status and
connectivity information for the local host could be provided via a simple web
interface, which the user can open in their browser. This saves us the effort of
needing to develop UIs for individual OSs. This could also make remotely
debugging hosts easier for admins.
### Invitation code bootstrapping
Once an HTTP gateway/load-balancer is set up it should be possible to do host
bootstrapping using invite codes rather than manually giving new users bootstrap
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.
### FUSE Mount
KBFS style. Every user should be able to mount virtual directories to their host
which correspond to various buckets in garage.
- "public": editable amongst all users on the host, shared publicly via HTTP
gateway.
- "protected": editable amongst all users on the host, but not accessible
outside the network.
- "private": only accessible to a particular user (client-side encrypted).
Whether it's necessary to support directories which are shared only between
specific users remains to be seen. The identification of a single "user" between
different hosts is also an unsolved problem.
## Side quests ## Side quests
@ -24,6 +74,31 @@ These items aren't necessarily required by the main quest, and aren't dependent
on any other items being completed. They are nice-to-haves that we do want to on any other items being completed. They are nice-to-haves that we do want to
eventually complete, but aren't the main focus. eventually complete, but aren't the main focus.
### Design System
It would be great to get some help from a designer or otherwise
artistically-minded person to create some kind of design framework which could
be used across publicly-facing frontends. Such a system would provide a simple
but cohesive vision for how things should look, include:
- Color schemes
- Fonts and text decoration in different situations
- Some simple, reusable layout templates (splash page, documentation, form)
- Basic components like tables, lists, media, etc..
### DHCP
Currently all hosts require a static IP to be reserved by the admin. Nebula may
support DHCP already, but if it doesn't we should look into how this could be
accomplished. Depending on how reliable DNS support is it may be possible to use
DHCP for all non-lighthouse hosts, which would be excellent.
### IPv6 network ranges
It should theoretically be possible for the internal network IP range to be on
IPv6 rather than IPv4. This may be a simple matter of just testing it to confirm
it works.
### DNS resolver settings ### DNS resolver settings
The daemon should update the resolver settings of the host, so that it The daemon should update the resolver settings of the host, so that it
@ -34,34 +109,12 @@ automatically serves DNS queries, unless set to not do so in `daemon.yml`.
It would be great to have a `isle install` sub-command which would It would be great to have a `isle install` sub-command which would
auto-detect the installed operating system and install the daemon automatically. auto-detect the installed operating system and install the daemon automatically.
### Web server + interface
One idea is to have every `isle daemon` run a webserver as one of its
sub-processes. This server could serve multiple functions:
- [Gateway service](./dev/gateway.md).
- Local interface for the `isle daemon` process. For example, status and
connectivity information for the local host could be provided via a simple web
interface, which the user can open in their browser. This saves us the effort
of needing to develop UIs for individual OSs. This could also make remotely
debugging hosts easier for admins.
### Mobile app ### Mobile app
To start with a simple mobile app which provided connectivity to the network To start with a simple mobile app which provided connectivity to the network
would be great. Such a mobile app could be based on the existing would be great. We are not able to use the existing nebula mobile app because it
[mobile_nebula](https://github.com/DefinedNet/mobile_nebula). The main changes is not actually open-source, but we can at least use it as a reference to see
needed would be: how this can be accomplished.
- Allow importing a `bootstrap.yml` file, rather than requiring manual setup by
users.
- Set device's DNS settings. There is an [open
PR](https://github.com/DefinedNet/mobile_nebula/pull/18) for android to do
this upstream.
- Rebranding and possibly submitting to Apple app store (bleh).
### Don't run as root ### Don't run as root
@ -72,9 +125,10 @@ root. This is due to:
- dnsmasq listening on port 53, generally a protected port. - dnsmasq listening on port 53, generally a protected port.
If we can't figure out how to get these things running from the start as On linux it should be fairly straightforward to grant the entrypoint the
non-privileged users, we at least need to get isle to drop privileges necessary ambient capabilities up-front, and then drop down to a specified user.
from root after initial startup. This is how the tests work. Doing this with other OS's will depend on how they
work.
### Plugins ### Plugins