@decentnetwork/lan 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +31 -0
  2. package/README.md +296 -0
  3. package/bin/tun-helper-darwin-amd64 +0 -0
  4. package/bin/tun-helper-darwin-arm64 +0 -0
  5. package/bin/tun-helper-linux-amd64 +0 -0
  6. package/bin/tun-helper-linux-arm64 +0 -0
  7. package/dist/acl/acl-engine.d.ts +43 -0
  8. package/dist/acl/acl-engine.js +189 -0
  9. package/dist/acl/audit.d.ts +70 -0
  10. package/dist/acl/audit.js +144 -0
  11. package/dist/acl/index.d.ts +4 -0
  12. package/dist/acl/index.js +3 -0
  13. package/dist/acl/policy.d.ts +31 -0
  14. package/dist/acl/policy.js +102 -0
  15. package/dist/acl/types.d.ts +18 -0
  16. package/dist/acl/types.js +4 -0
  17. package/dist/carrier/frame.d.ts +18 -0
  18. package/dist/carrier/frame.js +66 -0
  19. package/dist/carrier/index.d.ts +5 -0
  20. package/dist/carrier/index.js +4 -0
  21. package/dist/carrier/packet-session.d.ts +32 -0
  22. package/dist/carrier/packet-session.js +151 -0
  23. package/dist/carrier/peer-manager.d.ts +113 -0
  24. package/dist/carrier/peer-manager.js +392 -0
  25. package/dist/carrier/types.d.ts +10 -0
  26. package/dist/carrier/types.js +11 -0
  27. package/dist/cli/commands.d.ts +223 -0
  28. package/dist/cli/commands.js +932 -0
  29. package/dist/cli/index.d.ts +7 -0
  30. package/dist/cli/index.js +196 -0
  31. package/dist/config/loader.d.ts +10 -0
  32. package/dist/config/loader.js +152 -0
  33. package/dist/daemon/index.d.ts +1 -0
  34. package/dist/daemon/index.js +1 -0
  35. package/dist/daemon/ipc.d.ts +60 -0
  36. package/dist/daemon/ipc.js +144 -0
  37. package/dist/daemon/server.d.ts +63 -0
  38. package/dist/daemon/server.js +510 -0
  39. package/dist/dns/index.d.ts +1 -0
  40. package/dist/dns/index.js +1 -0
  41. package/dist/dns/resolver.d.ts +44 -0
  42. package/dist/dns/resolver.js +82 -0
  43. package/dist/dns/server.d.ts +70 -0
  44. package/dist/dns/server.js +393 -0
  45. package/dist/dora/dora-integration.d.ts +90 -0
  46. package/dist/dora/dora-integration.js +325 -0
  47. package/dist/index.d.ts +13 -0
  48. package/dist/index.js +15 -0
  49. package/dist/ipam/index.d.ts +1 -0
  50. package/dist/ipam/index.js +1 -0
  51. package/dist/ipam/ipam.d.ts +99 -0
  52. package/dist/ipam/ipam.js +254 -0
  53. package/dist/proxy/connect-proxy.d.ts +78 -0
  54. package/dist/proxy/connect-proxy.js +204 -0
  55. package/dist/router/index.d.ts +5 -0
  56. package/dist/router/index.js +4 -0
  57. package/dist/router/ip-parser.d.ts +36 -0
  58. package/dist/router/ip-parser.js +127 -0
  59. package/dist/router/packet-router.d.ts +49 -0
  60. package/dist/router/packet-router.js +251 -0
  61. package/dist/router/session-manager.d.ts +50 -0
  62. package/dist/router/session-manager.js +138 -0
  63. package/dist/router/types.d.ts +21 -0
  64. package/dist/router/types.js +6 -0
  65. package/dist/tun/index.d.ts +3 -0
  66. package/dist/tun/index.js +2 -0
  67. package/dist/tun/route-manager.d.ts +59 -0
  68. package/dist/tun/route-manager.js +353 -0
  69. package/dist/tun/tun-device.d.ts +45 -0
  70. package/dist/tun/tun-device.js +265 -0
  71. package/dist/tun/types.d.ts +28 -0
  72. package/dist/tun/types.js +4 -0
  73. package/dist/types.d.ts +176 -0
  74. package/dist/types.js +4 -0
  75. package/dist/utils/logger.d.ts +20 -0
  76. package/dist/utils/logger.js +43 -0
  77. package/docs/CONFIGURATION.md +197 -0
  78. package/docs/INSTALL.md +145 -0
  79. package/package.json +93 -0
@@ -0,0 +1,197 @@
1
+ # Configuring `@decentnetwork/lan`
2
+
3
+ Everything decentlan needs is in **two YAML files** under
4
+ `~/.agentnet/` (or whatever you pass to `--config-dir`):
5
+
6
+ | file | what |
7
+ |---|---|
8
+ | `config.yaml` | Daemon-wide settings: this node's name, dora server(s), DNS domain/port, TUN interface, ACL files. |
9
+ | `policy.yaml` | Optional per-peer ACL rules (allow / deny by port). Empty by default = trust the Carrier friend boundary. |
10
+
11
+ See [`INSTALL.md`](INSTALL.md) for first-time setup.
12
+
13
+ ## `config.yaml` reference
14
+
15
+ A full default config (what `agentnet init` writes):
16
+
17
+ ```yaml
18
+ node:
19
+ name: my-laptop
20
+ namespace: agentnet-main
21
+
22
+ carrier:
23
+ dataDir: /home/you/.agentnet/carrier
24
+ bootstrapNodes:
25
+ - { host: 47.100.103.201, port: 33445, pk: CX1XH419p4xJ5SV4KvDxBeKYSRdMJW9QpdWJY8owUxHd }
26
+ - { host: 154.64.235.176, port: 33445, pk: GdNtV2N74fZnLjhH7NhQ18nGdxb1k8jRM9dQaK7WnxmL }
27
+ # ... more
28
+ expressNodes:
29
+ - { host: lens.beagle.chat, port: 443, pk: ECbs4GxwGzxGerNkmqDJFibEmevu8jAXqAZtikccvD95 }
30
+
31
+ network:
32
+ interface: agentnet0
33
+ ip: 10.86.1.10 # fallback if dora isn't reachable
34
+ subnet: 10.86.0.0/16
35
+ dnsDomain: decent
36
+ dnsPort: 5354
37
+
38
+ paths:
39
+ ipamFile: /home/you/.agentnet/ipam.yaml
40
+ policyFile: /home/you/.agentnet/policy.yaml
41
+ auditLog: /home/you/.agentnet/audit.log
42
+
43
+ proxy:
44
+ enabled: false # `agentnet proxy enable` flips this
45
+ port: 8888
46
+
47
+ friends:
48
+ autoAccept: true # accept incoming friend-requests automatically
49
+
50
+ dora:
51
+ enabled: false # `agentnet dora enable --userid ...` flips this
52
+ userids: [] # tried in order; first responder wins
53
+ refreshIntervalMs: 60000
54
+ ```
55
+
56
+ ### `node`
57
+
58
+ - **`name`** — your hostname inside the agentnet. Appears as
59
+ `<name>.<dnsDomain>` and in dora's roster. Must be unique per
60
+ dora.
61
+ - **`namespace`** — informational. Same-namespace peers are
62
+ expected to share the same dora; not enforced.
63
+
64
+ ### `carrier`
65
+
66
+ - **`dataDir`** — where the Carrier identity (`keypair.json`),
67
+ friend store, and Carrier-level metadata live. Treat this like
68
+ an SSH private key directory.
69
+ - **`bootstrapNodes`** — fixed list of public Carrier DHT entry
70
+ points. The defaults shipped in the package work today; replace
71
+ if you're running a private bootstrap fleet.
72
+ - **`expressNodes`** — HTTPS offline-message relays. Without one,
73
+ a friend-request sent while a peer is offline is lost.
74
+
75
+ ### `network`
76
+
77
+ - **`interface`** — TUN device name on Linux. macOS uses kernel-
78
+ assigned `utun*` regardless of this field.
79
+ - **`ip`** — fallback IP if dora can't be reached. **When dora is
80
+ enabled and reachable, dora's allocation overrides this.**
81
+ - **`subnet`** — `/16` is the only tested size today. Don't change
82
+ unless you're running an isolated agentnet that won't talk to
83
+ any peers using the default.
84
+ - **`dnsDomain`** — the suffix used by the in-process DNS server.
85
+ Default `decent`; legacy installs may have `agentnet`. Pick one
86
+ network-wide.
87
+ - **`dnsPort`** — UDP port the DNS server tries first. Defaults to
88
+ 5354 (5353 is held by `mDNSResponder` / Bonjour / `openclaw-
89
+ gateway` on most boxes). On EADDRINUSE the daemon falls back
90
+ upward (5354 → 5355 → ...). `agentnet dns install` reads the
91
+ actually-bound port via IPC and writes it into the OS resolver
92
+ config.
93
+
94
+ ### `proxy`
95
+
96
+ Built-in HTTP-CONNECT proxy that listens on `<network.ip>:port`
97
+ when `enabled: true`. Peers use it to proxy HTTPS through *this*
98
+ node (e.g. accessing a SaaS API that geofences by source IP).
99
+ ACL-gated; see `agentnet proxy --help`.
100
+
101
+ ### `friends`
102
+
103
+ - **`autoAccept`** — accept incoming friend-requests automatically.
104
+ Carrier IS the trust boundary; if you don't want a peer, don't
105
+ share your address. Set to `false` for stricter networks; you'll
106
+ then need to run `agentnet friend-accept` manually for each one.
107
+
108
+ ### `dora`
109
+
110
+ - **`enabled`** — turn on dora integration. When off, this node
111
+ uses `network.ip` directly and `paths.ipamFile` for peer lookups.
112
+ - **`userids`** — list of dora servers to try, in order. First
113
+ responder wins.
114
+ - **`refreshIntervalMs`** — how often to re-pull the roster from
115
+ dora (default 60s). Drives auto-friend discovery of new peers.
116
+
117
+ ## `policy.yaml` reference
118
+
119
+ Empty by default — meaning every Carrier friend has full
120
+ TCP / UDP access to this node's virtual IP. To tighten:
121
+
122
+ ```yaml
123
+ defaultAction: deny
124
+ rules:
125
+ - peer: wei.decent # match by name OR carrier id
126
+ direction: inbound # inbound | outbound | both
127
+ allow:
128
+ - { proto: tcp, port: 22, purpose: "ssh" }
129
+ - { proto: tcp, port: 18789, purpose: "openclaw" }
130
+ deny: []
131
+ expiresAt: 2026-05-09T23:59:00Z
132
+ audit: true
133
+ - peer: scratch.decent
134
+ direction: both
135
+ allow:
136
+ - { proto: any, port: 80 }
137
+ - { proto: any, port: 443 }
138
+ ```
139
+
140
+ - `defaultAction` applies when no rule matches.
141
+ - `direction` controls which side of the connection is checked:
142
+ `inbound` = packets from peer → us, `outbound` = us → peer,
143
+ `both` = both sides.
144
+ - `expiresAt` is ISO 8601; expired rules are skipped at eval time
145
+ but kept in the file for audit.
146
+ - `audit: true` logs every match (allowed or denied) to
147
+ `paths.auditLog`.
148
+
149
+ ACL only applies to TCP/UDP packets (those have ports). ICMP is
150
+ always allowed once IPAM lookup succeeds.
151
+
152
+ CLI shortcuts:
153
+
154
+ ```bash
155
+ agentnet grant --peer wei.decent --tcp 22 --tcp 18789 --expires 24h
156
+ agentnet revoke --peer wei.decent
157
+ agentnet audit log --tail 100
158
+ ```
159
+
160
+ ## Environment variables
161
+
162
+ | var | effect |
163
+ |---|---|
164
+ | `AGENTNET_LOG_LEVEL` | `debug` / `info` / `warn` / `error`. Default `info`. |
165
+ | `AGENTNET_HANDSHAKE_TIMEOUT_MS` | Packet-session handshake timeout. Default 30000. |
166
+ | `DECENT_DEBUG=1` | Verbose Carrier SDK logs (very noisy; useful for connection debugging). |
167
+ | `DECENT_EXPRESS_PULL_INTERVAL_MS` | Carrier express-relay poll interval. Default 4000. |
168
+
169
+ ## Operational commands
170
+
171
+ ```bash
172
+ agentnet up [--real-tun] [--config-dir DIR] # start daemon (foreground)
173
+ agentnet down # stop a backgrounded daemon
174
+ agentnet status # human-readable status
175
+ agentnet diag # JSON dump (over IPC)
176
+ agentnet identity show # this node's address + userid
177
+ agentnet peers list # peers from IPAM
178
+ agentnet resolve <name> # name → IP
179
+ agentnet ipam assign --peer <id> --ip <ip> --name <name>
180
+ agentnet friend-request --address <ADDRESS> # (when daemon is up: routed via IPC)
181
+ agentnet friends list
182
+ agentnet grant / revoke # ACL shortcuts
183
+ agentnet audit log [--tail N]
184
+ agentnet dora enable --userid <ID>
185
+ agentnet dora disable
186
+ agentnet dora status
187
+ agentnet dns install [--uninstall]
188
+ agentnet dns hosts # /etc/hosts-format dump
189
+ agentnet proxy { enable | disable | status | allow-host <H> | revoke-host <H> | list-hosts | use --peer <P> }
190
+ ```
191
+
192
+ ## See also
193
+
194
+ - [`INSTALL.md`](INSTALL.md) — bootstrap, first-time setup
195
+ - [`@decentnetwork/dora`](https://www.npmjs.com/package/@decentnetwork/dora) docs
196
+ - [`@decentnetwork/peer`](https://www.npmjs.com/package/@decentnetwork/peer) docs
197
+ - https://github.com/0xli/decentlan
@@ -0,0 +1,145 @@
1
+ # Installing `@decentnetwork/lan`
2
+
3
+ `@decentnetwork/lan` is the client / daemon that joins a Decent
4
+ AgentNet virtual LAN. It brings up a TUN interface, registers
5
+ with a [dora](https://www.npmjs.com/package/@decentnetwork/dora) name
6
+ server for an IP, and tunnels all `10.86.0.0/16` traffic to other
7
+ peers over the [Carrier](https://www.npmjs.com/package/@decentnetwork/peer)
8
+ peer-to-peer network. SSH, HTTP, and most TCP/UDP work
9
+ transparently between any two daemons that are Carrier friends.
10
+
11
+ ## Requirements
12
+
13
+ | | minimum |
14
+ |---|---|
15
+ | Node.js | **20+** |
16
+ | OS | Linux (`x86_64`, `aarch64`) or macOS (`aarch64`, `x86_64`) |
17
+ | Root / sudo | Yes — needed to create the TUN device. The daemon drops back to user-mode for everything else. |
18
+ | Outbound network | TCP and UDP to public Carrier bootstrap nodes (ports 33445 + 443). No inbound port needed; no public IP needed. |
19
+
20
+ Windows isn't supported yet; WSL2 with Linux mode works (UDP through
21
+ WSL's NAT is unreliable, so the SDK falls back to TCP relay — works,
22
+ just slower).
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ npm install -g @decentnetwork/lan
28
+ ```
29
+
30
+ This installs the `agentnet` CLI on `$PATH` along with platform-
31
+ specific TUN helper binaries (we ship `linux-amd64`, `linux-arm64`,
32
+ `darwin-amd64`, and `darwin-arm64`). Confirm:
33
+
34
+ ```bash
35
+ agentnet --help
36
+ ```
37
+
38
+ ## First-time setup
39
+
40
+ ```bash
41
+ # 1. Generate this machine's Carrier identity + default config
42
+ agentnet init --name my-laptop
43
+
44
+ # 2. (Once per network) friend the dora name server.
45
+ # Get the address from whoever runs dora.
46
+ agentnet friend-request --address Jt7w1pKkyLT5GVue9h6ZPkjg1EeuuTbD6JVSLycXLsdm6nvBGSUd
47
+
48
+ # 3. Tell decentlan to use that dora server
49
+ agentnet dora enable --userid 98rsHv17h8G6AP9RagyrBiT1kmw4cn8MFPEembS6ZVjv
50
+
51
+ # 4. Start the daemon (needs sudo for the TUN device)
52
+ sudo $(which agentnet) up --real-tun
53
+ ```
54
+
55
+ The daemon will:
56
+
57
+ 1. Open a Carrier connection
58
+ 2. Register with dora and get a virtual IP (e.g. `10.86.1.12`)
59
+ 3. Pull the network roster and auto-friend every other peer in it
60
+ 4. Bring up `agentnet0` on Linux (or `utun*` on macOS) at that IP
61
+ 5. Start a local DNS server for `*.decent` (default) so you can
62
+ `ping my-laptop.decent`, `ssh peer-name.decent`, etc.
63
+
64
+ ## OS DNS resolver (optional but recommended)
65
+
66
+ Out-of-the-box you can resolve peers via `agentnet resolve <name>`
67
+ or by IP. To make `ping <peer>.decent` work app-wide:
68
+
69
+ ```bash
70
+ sudo $(which agentnet) dns install
71
+ ```
72
+
73
+ - **macOS** — writes `/etc/resolver/<domain>` so the system
74
+ resolver routes `*.decent` queries to the daemon. Takes effect
75
+ immediately.
76
+ - **Linux** — uses `resolvectl` to configure systemd-resolved
77
+ (when feasible). If your daemon is on a non-53 port (default
78
+ is 5354), the install command prints a `dnsmasq` snippet you can
79
+ paste; alternatively `agentnet dns hosts | sudo tee -a /etc/hosts`
80
+ gives you static name resolution without DNS at all.
81
+
82
+ Reverse:
83
+
84
+ ```bash
85
+ sudo $(which agentnet) dns install --uninstall
86
+ ```
87
+
88
+ ## Verify
89
+
90
+ While the daemon is up (in another terminal — the daemon runs in
91
+ foreground unless you background it yourself with `nohup`, systemd,
92
+ etc.):
93
+
94
+ ```bash
95
+ agentnet diag # JSON dump of state, friends, IPAM
96
+ agentnet resolve <peer-name> # IP from the live roster
97
+ ping <peer-name>.decent # if you ran 'dns install'
98
+ ```
99
+
100
+ ## Running the daemon as a service
101
+
102
+ There's no built-in init script. Pattern is the same as any
103
+ foreground binary; rough sketches:
104
+
105
+ ### systemd (Linux)
106
+
107
+ ```ini
108
+ # /etc/systemd/system/agentnet.service
109
+ [Unit]
110
+ Description=Decent AgentNet daemon
111
+ After=network-online.target
112
+ Wants=network-online.target
113
+
114
+ [Service]
115
+ ExecStart=/usr/bin/agentnet up --real-tun --config-dir /home/<you>/.agentnet
116
+ User=root
117
+ Restart=on-failure
118
+ RestartSec=5
119
+
120
+ [Install]
121
+ WantedBy=multi-user.target
122
+ ```
123
+
124
+ ### launchd (macOS)
125
+
126
+ `/Library/LaunchDaemons/com.decent.agentnet.plist` — see
127
+ `man launchd.plist`. Important: `Sudo` env isn't a thing in
128
+ launchd, so put the daemon under `<key>UserName</key><string>root</string>`.
129
+
130
+ ## Uninstall
131
+
132
+ ```bash
133
+ sudo $(which agentnet) up # stop with Ctrl-C
134
+ sudo $(which agentnet) dns install --uninstall
135
+ npm uninstall -g @decentnetwork/lan
136
+ rm -rf ~/.agentnet # delete identity + config (data loss)
137
+ ```
138
+
139
+ ## See also
140
+
141
+ - [`CONFIGURATION.md`](CONFIGURATION.md) — full config.yaml reference,
142
+ ACL rules, proxy mode, debug logging.
143
+ - [`@decentnetwork/dora`](https://www.npmjs.com/package/@decentnetwork/dora) —
144
+ the name server every daemon needs to talk to.
145
+ - Project page: https://github.com/0xli/decentlan
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@decentnetwork/lan",
3
+ "version": "0.1.0",
4
+ "description": "Private virtual LAN for self-hosted services and AI agents, built on Elastos Carrier. NAT-traversal, name service, ACL, all over a peer-to-peer mesh — no public IP required.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "bin": {
15
+ "agentnet": "dist/cli/index.js",
16
+ "decentlan": "dist/cli/index.js"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "bin",
21
+ "README.md",
22
+ "LICENSE",
23
+ "docs/INSTALL.md",
24
+ "docs/CONFIGURATION.md"
25
+ ],
26
+ "sideEffects": false,
27
+ "engines": {
28
+ "node": ">=20.0.0"
29
+ },
30
+ "keywords": [
31
+ "decent",
32
+ "decentnet",
33
+ "agentnet",
34
+ "vpn",
35
+ "p2p",
36
+ "carrier",
37
+ "nat-traversal",
38
+ "tun",
39
+ "virtual-lan",
40
+ "private-network",
41
+ "dora",
42
+ "ai-agents"
43
+ ],
44
+ "license": "GPL-3.0-or-later",
45
+ "author": "Decent Network contributors",
46
+ "homepage": "https://github.com/0xli/decentlan#readme",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/0xli/decentlan.git"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/0xli/decentlan/issues"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "scripts": {
58
+ "build": "tsc -p tsconfig.json",
59
+ "build:helper": "cd helper/tun-helper && go build -o ../../bin/tun-helper-$(go env GOOS)-$(go env GOARCH) .",
60
+ "build:helper:linux-amd64": "cd helper/tun-helper && GOOS=linux GOARCH=amd64 go build -o ../../bin/tun-helper-linux-amd64 .",
61
+ "build:helper:linux-arm64": "cd helper/tun-helper && GOOS=linux GOARCH=arm64 go build -o ../../bin/tun-helper-linux-arm64 .",
62
+ "build:helper:darwin-arm64": "cd helper/tun-helper && GOOS=darwin GOARCH=arm64 go build -o ../../bin/tun-helper-darwin-arm64 .",
63
+ "build:helper:darwin-amd64": "cd helper/tun-helper && GOOS=darwin GOARCH=amd64 go build -o ../../bin/tun-helper-darwin-amd64 .",
64
+ "build:helpers:all": "npm run build:helper:linux-amd64 && npm run build:helper:linux-arm64 && npm run build:helper:darwin-arm64 && npm run build:helper:darwin-amd64",
65
+ "build:all": "npm run build && npm run build:helper",
66
+ "clean": "rm -rf dist bin",
67
+ "dev": "node --loader ts-node/esm src/index.ts",
68
+ "test": "vitest",
69
+ "test:watch": "vitest --watch",
70
+ "test:coverage": "vitest --coverage",
71
+ "typecheck": "tsc --noEmit",
72
+ "lint": "eslint src --ext .ts",
73
+ "prepublishOnly": "rm -rf dist && npm run build && npm run typecheck && npm run build:helpers:all"
74
+ },
75
+ "dependencies": {
76
+ "@decentnetwork/dora": "^0.1.0",
77
+ "@decentnetwork/peer": "^0.1.0",
78
+ "js-yaml": "^4.1.0",
79
+ "yargs": "^17.7.2"
80
+ },
81
+ "devDependencies": {
82
+ "@types/js-yaml": "^4.0.9",
83
+ "@types/node": "^20.12.12",
84
+ "@types/yargs": "^17.0.35",
85
+ "@typescript-eslint/eslint-plugin": "^7.10.0",
86
+ "@typescript-eslint/parser": "^7.10.0",
87
+ "@vitest/coverage-v8": "^1.6.0",
88
+ "eslint": "^8.57.0",
89
+ "ts-node": "^10.9.2",
90
+ "typescript": "^5.4.5",
91
+ "vitest": "^1.6.0"
92
+ }
93
+ }