Lain Uplink eXchange
Find a file
2024-12-29 08:55:13 +02:00
host refactor config format 2024-12-28 10:01:08 +02:00
.gitignore begin writing config parsing 2024-12-27 12:47:33 +02:00
go.mod begin writing config parsing 2024-12-27 12:47:33 +02:00
go.sum begin writing config parsing 2024-12-27 12:47:33 +02:00
LICENSE begin writing spec 2024-12-27 09:05:00 +02:00
main.go refactor config format 2024-12-28 10:01:08 +02:00
README.md update spec 2024-12-29 08:55:13 +02:00

lux

Lain Uplink eXchange

        ______________                   ______________
        |            |                   |            |
        |   Node A   |     Interior      |   Node B   |
        |            |  <------------>   |            |
        |   State    |      State        |   State    |
        ______________                   ______________

               ^                                ^
            E  |                                | I
            x  |                                | n
            t  |                                | t
            e  |                                | e
            r  |                                | r
            i  |                                | i
            o  |                                | o
            r  |                                | r
               |                                |
        ______________                   ______________
        |            |                   |            |
        |   Host 1   |                   |   Host 2   |
        |            |                   |            |
        |            |                   |            |
        ______________                   ______________

Node

Each node receives heartbeats from different hosts, registering their state, name, WAN IP and uptime over Exterior connections. Each host can request information about other host only over interior connection. The state must be kept same across all nodes, so fail-over can be configured.

Node can also provide DNS server front-end for ease integration into DNS resolvers such as unbound, dnsmasq or systemd-resolved.

Exterior and Interior

Exterior connections are made over low-trust medium, such as WAN internet, therefore encryption layer must protect from replay attacks and ensure unique packets.

Interior connections are made over high-trust medium, like VPN tunnels, such as OpenVPN or Tailscale. Only interior connection can be used to sync state between nodes.

Host

Each host "heartbeats" it's state - such as WAN IP, uptime, resource usage. Host can heartbeat over exterior and interior connections, but information request can only be made through interior, and state must be synced only over interior, since, at moment of request or sync, the exterior uplink information, such as WAN IP, may not be availble, thus, interior connection must be always available and low-cost.

State

Host's state consists of:

  • Hostname(+.lux)
  • WAN IP

Node's state is table of hosts' states + their last heartbeat time. Node state must also include generation ID, which must be guaranteed to be unique in scope of last 128 generations. A new generation should only happen when any of the hosts has new heartbeat.

Sync state broadcast

When consensus met state must be synchronized across all nodes. In order to that happen, neighbor nodes must be discovered.

The broadcast procedure is follow.

  1. List of neighbor list must be already established (through neighbor discovery)
  2. Sync packet formed including the list of nodes it's targeted to: all neighbor (excluding broadcasting node)
  3. Send sync packet over interior connections to all nodes
  4. In order for broadcast to not loop and be short, each node, on sync packet arrival, must
  • Merge it's neighbor list - that way neighbor discovery will also happen, update node neighbor list and/or add new nodes to broadcast
  • Remember generation ID of sync packet and ignore any other sync packets with same generation ID.

This procedure will cause tolerable amount of packet storm, but it will also serve good purpose of re-sending packet if previous was dropped on network path

Encryption

For host-to-node and node-to-node communication AES-256 symmetric cipher is used.

Each node has node key, and for each host node stores host key. The host must be configured with its host key, provided by node.

Node key is used only for node-to-node and must be kept private, unless another node is being deployed.

Identification

Each host and each node has its own unique UUID that is used in packet addressing.

Software architecture

  • Config are INI files.
  • Daemon, that constantly runs and serves protocol. Also provides UNIX socket for cli configuration
  • CLI to communicate with UNIX socket and issue commands