Add Docker and Nix packaging for the node
server/docker/: multi-stage image (rust:1-slim build, trixie runtime) with all four binaries plus the pinned yggdrasil 0.5.14 .deb (sha256-verified, fetched from the official release), a compose example per household (host network, NET_ADMIN, /dev/net/tun, init: true), a German-commented node.toml.example (safe default: leech mode) and a README covering privileges, two-household wiring, leech mode and the kill switch. Image build and smoke tests verified locally with docker 29.8.1. flake.nix: builds the workspace as one spidernet package via rustPlatform.buildRustPackage (cargoLock against the committed Cargo.lock) plus an experimental NixOS module; written without a local Nix and marked accordingly.
This commit is contained in:
@@ -0,0 +1,193 @@
|
|||||||
|
# SpiderNet Nix flake — builds the Rust workspace in server/ and exposes
|
||||||
|
# one `spidernet` package containing all four binaries (sn-node, sn-exit,
|
||||||
|
# sn-fetch, sn-fair) in $out/bin, plus an experimental NixOS module.
|
||||||
|
#
|
||||||
|
# NO WARRANTY — SpiderNet is provided "as is" without warranty of any kind
|
||||||
|
# (AGPL-3.0, sections 15/16). Use is entirely at the operator's own
|
||||||
|
# responsibility.
|
||||||
|
#
|
||||||
|
# !!! NOT VERIFIED ON THIS MACHINE !!!
|
||||||
|
# Nix is not installed in the environment where this flake was written.
|
||||||
|
# `nix flake check` and `nix build` have NOT been run — treat everything
|
||||||
|
# below as best-effort and report build failures as issues.
|
||||||
|
#
|
||||||
|
# Usage (once Nix >= 2.19 is installed):
|
||||||
|
# nix build . # -> result/bin/{sn-node,sn-exit,...}
|
||||||
|
# nix shell .# -c sn-fair --capacity 100 --participant 1=contributing
|
||||||
|
#
|
||||||
|
# The nixpkgs input is pinned to the current stable NixOS release branch
|
||||||
|
# (nixos-26.05, released 2026-05-30; nixos-25.11 is already deprecated).
|
||||||
|
|
||||||
|
{
|
||||||
|
description =
|
||||||
|
"SpiderNet: pooled-bandwidth neighborhood network node software";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ self, nixpkgs }:
|
||||||
|
let
|
||||||
|
systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
"x86_64-darwin"
|
||||||
|
"aarch64-darwin"
|
||||||
|
];
|
||||||
|
forAllSystems = nixpkgs.lib.genAttrs systems;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
packages = forAllSystems (
|
||||||
|
system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
inherit (pkgs) lib;
|
||||||
|
|
||||||
|
# Only the files cargo needs; keeps target/, docs and any other
|
||||||
|
# clutter out of the Nix store hash.
|
||||||
|
src = lib.cleanSourceWith {
|
||||||
|
src = lib.cleanSource ./server;
|
||||||
|
filter =
|
||||||
|
path: type:
|
||||||
|
# Prune cargo build dirs entirely.
|
||||||
|
!(type == "directory" && lib.hasSuffix "/target" path)
|
||||||
|
&& (
|
||||||
|
type == "directory"
|
||||||
|
|| lib.hasSuffix ".rs" path
|
||||||
|
|| lib.hasSuffix ".toml" path
|
||||||
|
|| lib.hasSuffix ".lock" path
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
spidernet = pkgs.rustPlatform.buildRustPackage {
|
||||||
|
pname = "spidernet";
|
||||||
|
version = "0.1.0";
|
||||||
|
|
||||||
|
inherit src;
|
||||||
|
cargoLock.lockFile = ./server/Cargo.lock;
|
||||||
|
|
||||||
|
# Integration tests talk to real servers; skip them when
|
||||||
|
# packaging. Run `cargo test` inside server/ for development.
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description =
|
||||||
|
"SpiderNet node software (sn-node, sn-exit, sn-fetch, sn-fair)";
|
||||||
|
longDescription = ''
|
||||||
|
SpiderNet pools the bandwidth of household internet
|
||||||
|
connections over a neighborhood mesh (Yggdrasil overlay).
|
||||||
|
NO WARRANTY — AGPL-3.0, sections 15/16.
|
||||||
|
'';
|
||||||
|
license = lib.licenses.agpl3Only;
|
||||||
|
mainProgram = "sn-node";
|
||||||
|
platforms = lib.platforms.unix;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit spidernet;
|
||||||
|
default = spidernet;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# EXPERIMENTAL NixOS module — never built or activated anywhere.
|
||||||
|
# Runs `sn-node daemon` (which manages the yggdrasil sidecar) as a
|
||||||
|
# hardened systemd service.
|
||||||
|
#
|
||||||
|
# Usage example (in a NixOS configuration that imports this flake):
|
||||||
|
#
|
||||||
|
# imports = [ spidernet.nixosModules.default ];
|
||||||
|
#
|
||||||
|
# services.spidernet = {
|
||||||
|
# enable = true;
|
||||||
|
# configFile = "/etc/spidernet/node.toml";
|
||||||
|
# # stateDir defaults to "spidernet" -> /var/lib/spidernet,
|
||||||
|
# # which the example config uses as state_dir.
|
||||||
|
# };
|
||||||
|
#
|
||||||
|
# The config file must set state_dir = "/var/lib/spidernet" (or
|
||||||
|
# leave the default and rely on WorkingDirectory below).
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
nixosModules.default =
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.services.spidernet;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.spidernet = {
|
||||||
|
enable = lib.mkEnableOption "SpiderNet node daemon (sn-node)";
|
||||||
|
|
||||||
|
package = lib.mkOption {
|
||||||
|
type = lib.types.package;
|
||||||
|
# The flake package of the evaluating system; can be
|
||||||
|
# overridden with any build of spidernet.
|
||||||
|
default = self.packages.${pkgs.system}.default;
|
||||||
|
defaultText = lib.literalExpression "spidernet.packages.\${pkgs.system}.default";
|
||||||
|
description = "SpiderNet package to run (contains sn-node etc.).";
|
||||||
|
};
|
||||||
|
|
||||||
|
configFile = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = ''
|
||||||
|
Path to the node.toml config file read by
|
||||||
|
`sn-node daemon --config`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
stateDir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "spidernet";
|
||||||
|
description = ''
|
||||||
|
State directory (systemd StateDirectory), holding node.key
|
||||||
|
and the generated yggdrasil.conf. Created as
|
||||||
|
/var/lib/<stateDir>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
systemd.services.spidernet = {
|
||||||
|
description = "SpiderNet node (Yggdrasil overlay, optional exit)";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
|
||||||
|
# The daemon spawns yggdrasil (manage = true by default).
|
||||||
|
path = [ pkgs.yggdrasil ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart =
|
||||||
|
"${lib.getExe cfg.package} daemon --config ${cfg.configFile}";
|
||||||
|
StateDirectory = cfg.stateDir;
|
||||||
|
WorkingDirectory = "/var/lib/${cfg.stateDir}";
|
||||||
|
|
||||||
|
# TUN setup requires CAP_NET_ADMIN; nothing more.
|
||||||
|
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||||
|
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||||
|
DeviceAllow = [
|
||||||
|
"/dev/net/tun rw"
|
||||||
|
# Yggdrasil TUN devices are created at runtime.
|
||||||
|
"char-tun rwm"
|
||||||
|
];
|
||||||
|
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 5;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
# State dir must stay writable.
|
||||||
|
ReadWritePaths = [ "/var/lib/${cfg.stateDir}" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Keep the build context small; everything needed is Cargo.toml,
|
||||||
|
# Cargo.lock and crates/ (see server/docker/Dockerfile).
|
||||||
|
target/
|
||||||
|
.git/
|
||||||
|
docker/node.toml.example
|
||||||
|
docker/node.toml
|
||||||
|
docker/README.md
|
||||||
|
docker/docker-compose.yml
|
||||||
|
spidernet-state/
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
#
|
||||||
|
# SpiderNet node container image (multi-stage).
|
||||||
|
#
|
||||||
|
# NO WARRANTY — SpiderNet is provided "as is", without warranty of any kind
|
||||||
|
# (AGPL-3.0, sections 15/16). Running a node is entirely at the operator's
|
||||||
|
# own responsibility, including all traffic sent and received with it.
|
||||||
|
#
|
||||||
|
# Build context is the `server/` directory (see docker-compose.yml):
|
||||||
|
# docker build -t spidernet-node -f docker/Dockerfile ..
|
||||||
|
|
||||||
|
# --- Stage 1: build the Rust workspace --------------------------------------
|
||||||
|
|
||||||
|
FROM rust:1-slim AS build
|
||||||
|
|
||||||
|
WORKDIR /server
|
||||||
|
|
||||||
|
COPY Cargo.toml Cargo.lock ./
|
||||||
|
COPY crates ./crates
|
||||||
|
|
||||||
|
# --locked: the build must match the committed Cargo.lock exactly.
|
||||||
|
RUN cargo build --release --locked --workspace
|
||||||
|
|
||||||
|
# --- Stage 2: runtime --------------------------------------------------------
|
||||||
|
|
||||||
|
# trixie, not bookworm: rust:1-slim is trixie-based, and binaries built
|
||||||
|
# against its glibc (2.41) need a matching runtime (bookworm only has 2.36).
|
||||||
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
|
# Yggdrasil sidecar: current stable release of yggdrasil-go. Release v0.5.14
|
||||||
|
# ships official .deb packages (no raw tarballs). Binary inside: /usr/bin/yggdrasil.
|
||||||
|
# Digests from https://api.github.com/repos/yggdrasil-network/yggdrasil-go/releases/latest
|
||||||
|
ARG YGGDRASIL_VERSION=0.5.14
|
||||||
|
ARG TARGETARCH
|
||||||
|
|
||||||
|
# ca-certificates: TLS for sn-exit/sn-fetch (rustls) and tls:// peers.
|
||||||
|
# curl is only needed to fetch the yggdrasil .deb and is removed again.
|
||||||
|
# TARGETARCH is only set by BuildKit; fall back to the host arch otherwise
|
||||||
|
# (both use the same amd64/arm64 naming as the yggdrasil .deb assets).
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends ca-certificates curl \
|
||||||
|
&& ARCH="${TARGETARCH:-$(dpkg --print-architecture)}" \
|
||||||
|
&& case "$ARCH" in \
|
||||||
|
amd64) YGGDRASIL_SHA256=72745496b09baa1c3f5a6741e1257a704cfdb9d00cdf3ddbef025987b239699d ;; \
|
||||||
|
arm64) YGGDRASIL_SHA256=ac8c9a9a76c54b878fd251aef5a2bbd20375c6109b28b32435683441462360c9 ;; \
|
||||||
|
*) echo "unsupported architecture: $ARCH" >&2; exit 1 ;; \
|
||||||
|
esac \
|
||||||
|
&& curl -fsSL -o /tmp/yggdrasil.deb \
|
||||||
|
"https://github.com/yggdrasil-network/yggdrasil-go/releases/download/v${YGGDRASIL_VERSION}/yggdrasil-${YGGDRASIL_VERSION}-${ARCH}.deb" \
|
||||||
|
&& echo "${YGGDRASIL_SHA256} /tmp/yggdrasil.deb" | sha256sum -c - \
|
||||||
|
&& dpkg-deb -x /tmp/yggdrasil.deb /tmp/yggdrasil-root \
|
||||||
|
&& cp /tmp/yggdrasil-root/usr/bin/yggdrasil /usr/local/bin/yggdrasil \
|
||||||
|
&& rm -rf /tmp/yggdrasil.deb /tmp/yggdrasil-root \
|
||||||
|
&& apt-get purge -y curl \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY --from=build /server/target/release/sn-node /usr/local/bin/sn-node
|
||||||
|
COPY --from=build /server/target/release/sn-exit /usr/local/bin/sn-exit
|
||||||
|
COPY --from=build /server/target/release/sn-fetch /usr/local/bin/sn-fetch
|
||||||
|
COPY --from=build /server/target/release/sn-fair /usr/local/bin/sn-fair
|
||||||
|
|
||||||
|
# WORKDIR matches the state volume in docker-compose.yml; a config that
|
||||||
|
# leaves `state_dir` at its default then resolves to the volume as well.
|
||||||
|
WORKDIR /var/lib/spidernet
|
||||||
|
|
||||||
|
ENTRYPOINT ["sn-node", "daemon", "--config", "/etc/spidernet/node.toml"]
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
# SpiderNet-Node mit Docker
|
||||||
|
|
||||||
|
Dieser Ordner enthält alles, um den SpiderNet-Node eines Haushalts als
|
||||||
|
Container zu betreiben: Multi-Stage-Dockerfile, ein Compose-Beispiel für
|
||||||
|
einen Host und eine kommentierte Beispiel-Konfiguration.
|
||||||
|
|
||||||
|
## Haftungsausschluss
|
||||||
|
|
||||||
|
> **KEINE GARANTIE.** Diese Software wird "as is" ohne jegliche Garantie
|
||||||
|
> bereitgestellt (AGPL §§ 15/16). Die Betreiber und Contributor:innen dieses
|
||||||
|
> Projekts übernehmen **keinerlei Verantwortung oder Haftung** dafür, wozu
|
||||||
|
> Nutzer:innen die Software verwenden oder welche Inhalte über sie
|
||||||
|
> übertragen werden. Die Verantwortung für gesendete und empfangene Inhalte
|
||||||
|
> liegt vollständig bei den Nutzer:innen.
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# 1. Konfiguration anlegen und anpassen
|
||||||
|
cp node.toml.example node.toml
|
||||||
|
$EDITOR node.toml
|
||||||
|
|
||||||
|
# 2. Image bauen und starten (Build-Kontext ist server/, daher "context: ..")
|
||||||
|
docker compose up --build -d
|
||||||
|
|
||||||
|
# 3. Beobachten
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
|
# 4. Overlay-Status ansehen (Admin-Socket lauscht auf localhost:9001)
|
||||||
|
docker compose exec node sn-node status
|
||||||
|
|
||||||
|
# 5. Einen großen Download über die gepoolte Bandbreite laden
|
||||||
|
docker compose exec node sn-fetch "https://…/große-datei.iso" \
|
||||||
|
-o /tmp/out.iso -e "1=2,2=1@http://[<ygg-adresse-des-nachbarn>]:8080"
|
||||||
|
```
|
||||||
|
|
||||||
|
Image direkt bauen (ohne Compose), Build-Kontext `server/`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker build -t spidernet-node -f docker/Dockerfile ..
|
||||||
|
```
|
||||||
|
|
||||||
|
## Was die Container-Privilegien bedeuten
|
||||||
|
|
||||||
|
| Einstellung | Warum |
|
||||||
|
|---|---|
|
||||||
|
| `network_mode: host` | Yggdrasil muss auf dem realen LAN peeren und auf der Overlay-Seite erreichbar sein. Mit Bridge-NAT würden Peer-Verbindungen und der Exit-Port nicht stimmen. |
|
||||||
|
| `cap_add: [NET_ADMIN]` | Yggdrasil legt das TUN-Interface (`ifname`) an und konfiguriert es — das braucht `CAP_NET_ADMIN`. |
|
||||||
|
| `/dev/net/tun` | Das Kernel-TUN-Gerät, das Yggdrasil öffnet. |
|
||||||
|
| `init: true` | Sauberer PID 1: Reaping + SIGTERM erreicht den Daemon, damit `docker compose stop` als sauberer Kill-Switch funktioniert. |
|
||||||
|
|
||||||
|
Der Container läuft als `root` — für TUN im Container üblich. `NET_ADMIN`
|
||||||
|
ist bewusst nur als Capability gesetzt, ohne `privileged`.
|
||||||
|
|
||||||
|
## Zwei Haushalte verbinden
|
||||||
|
|
||||||
|
Beide Hosts laufen mit demselben Image; die Rolle (Exit oder Leech) steht
|
||||||
|
nur in der jeweiligen `node.toml`.
|
||||||
|
|
||||||
|
- **Die Mesh-Verbindung liegt außerhalb des Containers:** Glasfaser,
|
||||||
|
Switch oder WiFi zwischen den Haushalten. Der Container peeret über das
|
||||||
|
Host-Netzwerk.
|
||||||
|
- **Auto-Peering:** Im selben LAN (Multicast aktiv) finden sich
|
||||||
|
Yggdrasil-Nodes selbst — `peers = []` reicht.
|
||||||
|
- **Explizit:** Falls Multicast nicht geht (z. B. VLANs), trägt man in
|
||||||
|
`node.toml` bei `peers` URIs wie `tcp://<nachbar-lan-ip>:1337` ein.
|
||||||
|
- **ACL:** Die 64-Hex-Public-Keys der erlaubten Nachbarn gehören in
|
||||||
|
`allow_keys`, sonst kann jeder Node im Overlay peeren.
|
||||||
|
|
||||||
|
Die `node.toml` jedes Haushalts enthält persönliche Daten der Nachbarschaft
|
||||||
|
(Public Keys, Adressen) und später den Node-Private-Key im State-Verzeichnis:
|
||||||
|
**niemals committen**, außerhalb des Repos aufbewahren.
|
||||||
|
|
||||||
|
## Leech-Modus (Empfang ohne Exit)
|
||||||
|
|
||||||
|
Die Beispiel-Konfiguration startet sicher im **Leech-Modus** — ein
|
||||||
|
Haushalt, der nur empfangen will, muss nichts ändern:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[exit]
|
||||||
|
enabled = false
|
||||||
|
```
|
||||||
|
|
||||||
|
Das ist ausdrücklich legitim — Leeches werden bei Sättigung zuerst
|
||||||
|
gedrosselt, aber nie ausgeschlossen. Es gibt kein separates Leech-Image;
|
||||||
|
das Compose-Beispiel funktioniert unverändert.
|
||||||
|
|
||||||
|
Wer seinen Uplink als Exit anbieten will (opt-in), setzt:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[exit]
|
||||||
|
enabled = true
|
||||||
|
allow = ["<overlay-adresse-des-nachbarn>"]
|
||||||
|
```
|
||||||
|
|
||||||
|
`enabled = true` mit leerer `allow`-Liste ist ungültig — der Daemon
|
||||||
|
verweigert dann den Start (Ausnahme: Dev-Modus mit Loopback-bind).
|
||||||
|
|
||||||
|
## Kill-Switch
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose stop
|
||||||
|
```
|
||||||
|
|
||||||
|
Stoppen des Exits bzw. des Daemons ist der Kill-Switch: Sobald der Daemon
|
||||||
|
nicht läuft, stellt der Haushalt keinen Uplink mehr bereit. Der eigene Node
|
||||||
|
fällt auf den eigenen Internetanschluss zurück. Wichtig zum Verständnis:
|
||||||
|
SpiderNet v0 leitet **normalen Verkehr nicht um** — kein Routing, kein
|
||||||
|
NAT-Trick. Nur Downloads, die `sn-fetch` explizit über das Netz verteilt,
|
||||||
|
nutzen die gepoolte Bandbreite; alles andere geht wie gewohnt über den
|
||||||
|
eigenen Anschluss.
|
||||||
|
|
||||||
|
## Zustand
|
||||||
|
|
||||||
|
`node.key` und die generierte `yggdrasil.conf` liegen im State-Verzeichnis
|
||||||
|
(`/var/lib/spidernet`, Named Volume `spidernet-state` im Compose-Beispiel).
|
||||||
|
Der Node behält damit seine Identität über Container-Neustarts. Volume
|
||||||
|
löschen = neue Node-Identität.
|
||||||
|
|
||||||
|
## Noch offen / Hinweise
|
||||||
|
|
||||||
|
- Der `daemon`-Subcommand ist implementiert und die Beispiel-Konfiguration
|
||||||
|
wurde damit verifiziert (`sn-node daemon --check` → `config ok`).
|
||||||
|
- Images werden lokal gebaut, nicht in ein Registry gepusht (das Projekt
|
||||||
|
kennt keine zentrale Infrastruktur).
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# SpiderNet node — single-household example (one node per host).
|
||||||
|
#
|
||||||
|
# NO WARRANTY — SpiderNet is provided "as is" without warranty of any kind
|
||||||
|
# (AGPL-3.0, sections 15/16). Running a node is entirely at the operator's
|
||||||
|
# own responsibility.
|
||||||
|
#
|
||||||
|
# The same image serves both roles:
|
||||||
|
# - exit household: [exit] enabled = true in node.toml (plus neighbor
|
||||||
|
# addresses in [exit].allow — enabled with an empty allowlist is
|
||||||
|
# rejected by the daemon)
|
||||||
|
# - leech household: [exit] enabled = false in node.toml (the example
|
||||||
|
# config default — safe, receive-only)
|
||||||
|
# There is no separate leech image; only the config differs.
|
||||||
|
#
|
||||||
|
# Quickstart:
|
||||||
|
# cp node.toml.example node.toml # then edit node.toml
|
||||||
|
# docker compose up --build -d
|
||||||
|
|
||||||
|
services:
|
||||||
|
node:
|
||||||
|
build:
|
||||||
|
# Build context is server/, matching the Dockerfile paths.
|
||||||
|
context: ..
|
||||||
|
dockerfile: docker/Dockerfile
|
||||||
|
image: spidernet-node
|
||||||
|
container_name: spidernet-node
|
||||||
|
# Proper PID 1: reaps zombies and makes sure SIGTERM reaches sn-node
|
||||||
|
# so `docker compose stop` behaves as the documented kill switch.
|
||||||
|
init: true
|
||||||
|
# Yggdrasil must bind its TUN interface and peer on the real LAN;
|
||||||
|
# both require the host network stack (no NAT translation).
|
||||||
|
network_mode: host
|
||||||
|
cap_add:
|
||||||
|
# Needed by yggdrasil to create/configure the TUN interface.
|
||||||
|
- NET_ADMIN
|
||||||
|
devices:
|
||||||
|
# The kernel TUN device used for the overlay interface.
|
||||||
|
- /dev/net/tun:/dev/net/tun
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
# Config is read-only; state (node.key, yggdrasil.conf) goes to a
|
||||||
|
# named volume so the node identity survives container upgrades.
|
||||||
|
- ./node.toml:/etc/spidernet/node.toml:ro
|
||||||
|
- spidernet-state:/var/lib/spidernet
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# EXIT VARIANT (offering the household's uplink as exit):
|
||||||
|
#
|
||||||
|
# The example config defaults to leech mode ([exit] enabled = false). To
|
||||||
|
# become an exit household set enabled = true in node.toml and add the
|
||||||
|
# neighbor overlay addresses to [exit].allow. This compose file works
|
||||||
|
# unchanged for both roles (kill switch: `docker compose stop`).
|
||||||
|
#
|
||||||
|
# If you prefer two service definitions (e.g. to toggle via profiles), note
|
||||||
|
# that `network_mode: host` allows only ONE node per host — stop the other
|
||||||
|
# service first:
|
||||||
|
#
|
||||||
|
# node-leech:
|
||||||
|
# build:
|
||||||
|
# context: ..
|
||||||
|
# dockerfile: docker/Dockerfile
|
||||||
|
# image: spidernet-node
|
||||||
|
# container_name: spidernet-node-leech
|
||||||
|
# init: true
|
||||||
|
# network_mode: host
|
||||||
|
# cap_add: [NET_ADMIN]
|
||||||
|
# devices: ["/dev/net/tun:/dev/net/tun"]
|
||||||
|
# restart: unless-stopped
|
||||||
|
# volumes:
|
||||||
|
# - ./node-leech.toml:/etc/spidernet/node.toml:ro
|
||||||
|
# - spidernet-state-leech:/var/lib/spidernet
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
spidernet-state:
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
# Beispielkonfiguration für den SpiderNet-Node-Daemon (`sn-node daemon`).
|
||||||
|
#
|
||||||
|
# Vorlage: diese Datei nach `node.toml` kopieren und anpassen. Die
|
||||||
|
# Compose-Datei in diesem Ordner bindet `./node.toml` ein.
|
||||||
|
#
|
||||||
|
# KEINE GARANTIE — SpiderNet wird "as is" ohne jegliche Garantie
|
||||||
|
# bereitgestellt (AGPL §§ 15/16). Nutzung auf eigene Verantwortung;
|
||||||
|
# die Verantwortung für gesendete und empfangene Inhalte liegt bei den
|
||||||
|
# Nutzer:innen.
|
||||||
|
#
|
||||||
|
# WICHTIG: Die echte node.toml enthält persönliche Daten der Nachbarschaft
|
||||||
|
# (Public Keys, Adressen) und später den Node-Private-Key im state_dir.
|
||||||
|
# node.toml NIEMALS ins Repository committen.
|
||||||
|
|
||||||
|
[node]
|
||||||
|
# Admin-Socket des Yggdrasil-Knotens (tcp://host:port oder unix:///pfad).
|
||||||
|
# Wird auch als Yggdrasil-AdminListen verwendet, wenn der Daemon das
|
||||||
|
# Yggdrasil-Sidecar selbst verwaltet (siehe [yggdrasil].manage).
|
||||||
|
admin_endpoint = "tcp://localhost:9001"
|
||||||
|
|
||||||
|
# Verzeichnis für den Zustand des Nodes (node.key, generierte
|
||||||
|
# yggdrasil.conf). Optional, Standard "spidernet-state" — relativ zum
|
||||||
|
# Arbeitsverzeichnis des Daemons. Im Container besser absolut setzen,
|
||||||
|
# damit es auf das State-Volume fällt:
|
||||||
|
state_dir = "/var/lib/spidernet"
|
||||||
|
|
||||||
|
[yggdrasil]
|
||||||
|
# true = der Daemon startet und überwacht das Yggdrasil-Sidecar selbst.
|
||||||
|
# false = es wird ein bereits laufender Yggdrasil-Daemon verwendet.
|
||||||
|
manage = true
|
||||||
|
|
||||||
|
# Pfad/Name des Yggdrasil-Binary; nur relevant, wenn manage = true.
|
||||||
|
# Im Container ist yggdrasil unter /usr/local/bin/yggdrasil installiert.
|
||||||
|
binary = "yggdrasil"
|
||||||
|
|
||||||
|
# Peer-URIs (tcp://, tls://, quic://, socks://) für manuelles Peering.
|
||||||
|
# Über das Nachbarschafts-LAN peert Yggdrasil per Multicast automatisch;
|
||||||
|
# explizite Peers braucht man z. B. über WLAN-Brücken hinweg.
|
||||||
|
peers = []
|
||||||
|
|
||||||
|
# Listener-URIs für eingehende Peerings (tcp://, tls://, quic://).
|
||||||
|
listen = []
|
||||||
|
|
||||||
|
# Access-Control: 64-stellige Hex-Public-Keys der Nachbarn, die mit uns
|
||||||
|
# peeren dürfen (AllowedPublicKeys). Leere Liste = jeder darf peeren.
|
||||||
|
allow_keys = []
|
||||||
|
|
||||||
|
# true = Multicast-Auto-Peering im LAN deaktivieren.
|
||||||
|
no_multicast = false
|
||||||
|
|
||||||
|
# TUN-Interface: "auto" (Standard), "none" (headless, nur Router-Modus)
|
||||||
|
# oder ein fester Interface-Name.
|
||||||
|
ifname = "auto"
|
||||||
|
|
||||||
|
[exit]
|
||||||
|
# true = dieser Haushalt stellt seinen Uplink als Exit bereit (opt-in).
|
||||||
|
# false = Leech-Modus (Standard hier): der Node empfängt nur, bietet
|
||||||
|
# keinen Exit an — ausdrücklich legitim, niemand wird gedrosselt, nur
|
||||||
|
# fair priorisiert.
|
||||||
|
#
|
||||||
|
# Wer Exit anbieten will: enabled = true setzen UND in `allow` die
|
||||||
|
# Overlay-Adressen der Nachbarn eintragen — enabled = true mit leerer
|
||||||
|
# `allow`-Liste ist ungültig (der Daemon verweigert den Start; Ausnahme:
|
||||||
|
# Dev-Modus mit Loopback-bind).
|
||||||
|
enabled = false
|
||||||
|
|
||||||
|
# Explizite Bind-Adresse. Leer (Standard) = "[<Yggdrasil-Adresse>]:port",
|
||||||
|
# d. h. der Exit lauscht auf der eigenen Overlay-Adresse.
|
||||||
|
# UNGÜLTIG: allow = [] zusammen mit einem nicht-Loopback-bind — der Exit
|
||||||
|
# wäre sonst für beliebig viele Quellen offen (Schutz: ohne Allowlist nur
|
||||||
|
# Loopback, das ist der Dev-Modus).
|
||||||
|
bind = ""
|
||||||
|
|
||||||
|
# TCP-Port des Exit-Dienstes (u16, Standard 8080).
|
||||||
|
port = 8080
|
||||||
|
|
||||||
|
# Overlay-Adressen der Nachbarn, die diesen Exit nutzen dürfen.
|
||||||
|
# Leere Liste = nur Loopback (Dev-Modus); bei nicht-Loopback-bind Pflicht.
|
||||||
|
# Beispiel:
|
||||||
|
# allow = ["200:abcd:ef01::2", "200:abcd:ef01::3"]
|
||||||
|
allow = []
|
||||||
|
|
||||||
|
# Kontingent pro Nachbar: Bytes pro Zeitfenster (u64, Standard 1024 MiB).
|
||||||
|
# 0 = unbegrenzt (kein Kontingent).
|
||||||
|
quota_mib = 1024
|
||||||
|
|
||||||
|
# Länge des Kontingent-Zeitfensters in Stunden (fixed window).
|
||||||
|
window_hours = 24
|
||||||
|
|
||||||
|
# KILL-SWITCH: Wer nichts mehr teilen will, stoppt einfach den Exit bzw.
|
||||||
|
# den Daemon (Container: `docker compose stop`). Damit endet die
|
||||||
|
# Bereitstellung des eigenen Uplinks sofort — der eigene Node fällt auf
|
||||||
|
# den eigenen Internetanschluss zurück. SpiderNet v0 leitet normalen
|
||||||
|
# Verkehr nicht um: nur Downloads, die sn-fetch explizit über das Netz
|
||||||
|
# verteilt, nutzen die gepoolte Bandbreite.
|
||||||
Reference in New Issue
Block a user