wimotek-edge-agent 1.0.4 → 1.0.5
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.
- package/README.md +237 -171
- package/edge_agent/__init__.py +23 -0
- package/edge_agent/agent.py +361 -0
- package/edge_agent/audit.py +29 -0
- package/edge_agent/config.py +118 -0
- package/edge_agent/local_bypass.py +44 -0
- package/edge_agent/models.py +55 -0
- package/edge_agent/nat.py +28 -0
- package/edge_agent/policy.py +160 -0
- package/edge_agent/tokens.py +203 -0
- package/edge_agent/transport.py +111 -0
- package/edge_agent/trust_store.py +207 -0
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/agent.py +0 -330
- package/dist/wimotek_edge_agent-1.0.4-py3-none-any.whl +0 -0
- package/dist/wimotek_edge_agent-1.0.4.tar.gz +0 -0
- package/wimotek_edge_agent.egg-info/PKG-INFO +0 -228
- package/wimotek_edge_agent.egg-info/SOURCES.txt +0 -9
- package/wimotek_edge_agent.egg-info/dependency_links.txt +0 -1
- package/wimotek_edge_agent.egg-info/entry_points.txt +0 -3
- package/wimotek_edge_agent.egg-info/requires.txt +0 -2
- package/wimotek_edge_agent.egg-info/top_level.txt +0 -1
package/README.md
CHANGED
|
@@ -1,219 +1,285 @@
|
|
|
1
|
-
#
|
|
1
|
+
# edge_agent commercial module
|
|
2
|
+
|
|
3
|
+
Commercial-grade edge agent with explicit access policy, TOFU quarantine,
|
|
4
|
+
Edge Agent token verification, session fast re-auth, and NAT4 reverse tunnel.
|
|
5
|
+
|
|
6
|
+
## Table of contents
|
|
7
|
+
|
|
8
|
+
- [Design goals](#design-goals)
|
|
9
|
+
- [Architecture](#architecture)
|
|
10
|
+
- [Decision matrix](#decision-matrix)
|
|
11
|
+
- [Install](#install)
|
|
12
|
+
- [Environment variables](#environment-variables)
|
|
13
|
+
- [CLI usage](#cli-usage)
|
|
14
|
+
- [Programmatic usage](#programmatic-usage)
|
|
15
|
+
- [Reverse tunnel / NAT4](#reverse-tunnel--nat4)
|
|
16
|
+
- [Audit log](#audit-log)
|
|
17
|
+
- [Security model](#security-model)
|
|
18
|
+
- [Commercial deployment checklist](#commercial-deployment-checklist)
|
|
19
|
+
- [Publishing](#publishing)
|
|
20
|
+
- [License](#license)
|
|
21
|
+
|
|
22
|
+
## Design goals
|
|
23
|
+
|
|
24
|
+
1. **Local connections default allow**, gated by a `local_bypass_token`
|
|
25
|
+
written with mode `0600`, so other processes on the same host cannot
|
|
26
|
+
trivially reuse `127.0.0.1`.
|
|
27
|
+
2. **External connections default TOFU**. A node without a token is
|
|
28
|
+
placed in a quarantine that only exchanges heartbeats. No business
|
|
29
|
+
data is relayed until an administrator approves the node.
|
|
30
|
+
3. **External connections with token use Edge Agent mode**. The token is
|
|
31
|
+
verified for signature, TTL, audience, issuer, `node_uuid` binding,
|
|
32
|
+
optional source IP CIDR binding, and single-use replay protection.
|
|
33
|
+
4. **NAT4 / no public IP uses reverse tunnel**. Authentication strength
|
|
34
|
+
does not downgrade when the network profile is `nat4_reverse`.
|
|
35
|
+
5. **Trusted nodes re-auth with short-lived session tickets**. A trusted
|
|
36
|
+
node without token or session is denied, preventing downgrade to TOFU.
|
|
37
|
+
|
|
38
|
+
## Architecture
|
|
2
39
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
40
|
+
```text
|
|
41
|
+
+---------------------------+
|
|
42
|
+
loopback ---> | AccessPolicyEngine | ---> ALLOW_LOCAL
|
|
43
|
+
| (single decision point) |
|
|
44
|
+
external ---> | | ---> ALLOW_TOKEN
|
|
45
|
+
+ token | 1. local bypass token |
|
|
46
|
+
| 2. join token verify | ---> ALLOW_SESSION
|
|
47
|
+
external ---> | 3. session ticket |
|
|
48
|
+
no token | 4. TOFU pending | ---> PENDING_TOFU
|
|
49
|
+
| 5. revoked / mismatch |
|
|
50
|
+
nat4_rev ---> | | ---> DENY
|
|
51
|
+
+---------------------------+
|
|
52
|
+
|
|
|
53
|
+
v
|
|
54
|
+
+-------------------+
|
|
55
|
+
| TrustStore |
|
|
56
|
+
| pending/trusted/ |
|
|
57
|
+
| revoked + jti |
|
|
58
|
+
+-------------------+
|
|
59
|
+
|
|
|
60
|
+
v
|
|
61
|
+
+-------------------+
|
|
62
|
+
| AuditLogger |
|
|
63
|
+
| JSON Lines |
|
|
64
|
+
+-------------------+
|
|
65
|
+
```
|
|
7
66
|
|
|
8
|
-
|
|
67
|
+
## Decision matrix
|
|
9
68
|
|
|
10
|
-
|
|
69
|
+
| Source | Loopback | Join token | Session ticket | Existing trust | Decision |
|
|
70
|
+
|--------|----------|------------|----------------|----------------|----------|
|
|
71
|
+
| direct | yes | - | - | any | `ALLOW_LOCAL` if bypass token ok, else `DENY` |
|
|
72
|
+
| direct | no | valid | - | any | `ALLOW_TOKEN`, bind trust |
|
|
73
|
+
| direct | no | invalid | - | any | `DENY` |
|
|
74
|
+
| direct | no | - | valid | trusted | `ALLOW_SESSION` |
|
|
75
|
+
| direct | no | - | - | trusted | `DENY` (no downgrade) |
|
|
76
|
+
| direct | no | - | - | pending, same fp | `PENDING_TOFU` |
|
|
77
|
+
| direct | no | - | - | pending, diff fp | `DENY` |
|
|
78
|
+
| direct | no | - | - | none | `PENDING_TOFU` |
|
|
79
|
+
| direct | no | - | - | revoked | `DENY` |
|
|
80
|
+
| nat4_reverse | no | valid | - | any | `ALLOW_TOKEN` |
|
|
81
|
+
| nat4_reverse | no | - | - | none | `PENDING_TOFU` |
|
|
11
82
|
|
|
12
|
-
|
|
83
|
+
## Install
|
|
13
84
|
|
|
14
|
-
|
|
85
|
+
```bash
|
|
86
|
+
pip install edge-agent-commercial
|
|
87
|
+
```
|
|
15
88
|
|
|
16
|
-
|
|
17
|
-
- **🛡️ 生产级双模身份认证与防伪造(TOFU + Edge Agent)**:
|
|
18
|
-
- **默认 TOFU 模式(Trust On First Use)**:零配置启动,节点自动生成硬件指纹 UUID,管理端后台实时弹出审核认领,管理员「一键信任锁定」后完成公钥防篡改绑定。
|
|
19
|
-
- **Edge Agent 模式**:批量注入 `JOIN_TOKEN`,节点开机秒级自验证入网,支持 CI/CD 与大规模集群全自动挂靠。
|
|
20
|
-
- **🤖 智能命名与设备自协商**:自动探测出口公网 IP 或物理网卡 IP 智能拼接命名(如 `Node-123.45.67.89`),嗅探失败平滑降级为容器主机名。
|
|
21
|
-
- **🔌 通用本地服务透明桥接(Decoupled & Multi-Service)**:业务完全解耦,不仅支持 Chromium CDP(9222),亦可同时中继 VNC 桌面(6080)、Web 业务 API(8080)等任意本地端口。
|
|
22
|
-
- **🌐 跨语言分发与 CLI 驱动**:同时发布至 PyPI 与 npm,支持系统级全局命令 `edge-agent` 与 `npx wimotek-edge-agent`。
|
|
89
|
+
From source:
|
|
23
90
|
|
|
24
|
-
|
|
91
|
+
```bash
|
|
92
|
+
git clone https://github.com/yourorg/edge-agent.git
|
|
93
|
+
cd edge-agent
|
|
94
|
+
pip install -e ".[dev]"
|
|
95
|
+
```
|
|
25
96
|
|
|
26
|
-
##
|
|
97
|
+
## Environment variables
|
|
98
|
+
|
|
99
|
+
| Variable | Required | Default | Description |
|
|
100
|
+
|----------|----------|---------|-------------|
|
|
101
|
+
| `EDGE_AGENT_DATA_DIR` | no | `./edge_agent_data` | Data directory for trust DB, audit log, local bypass token |
|
|
102
|
+
| `EDGE_AGENT_TOKEN_SECRET` | yes | - | HMAC secret, >= 32 bytes |
|
|
103
|
+
| `EDGE_AGENT_TOKEN_AUDIENCE` | no | `edge-agent` | Token audience |
|
|
104
|
+
| `EDGE_AGENT_TOKEN_ISSUER` | no | `central` | Token issuer |
|
|
105
|
+
| `EDGE_AGENT_TOKEN_MAX_TTL_SECONDS` | no | `600` | Max token TTL |
|
|
106
|
+
| `EDGE_AGENT_SESSION_TICKET_TTL_SECONDS` | no | `300` | Session ticket TTL |
|
|
107
|
+
| `EDGE_AGENT_TOFU_HEARTBEAT_SECONDS` | no | `10` | TOFU quarantine heartbeat interval |
|
|
108
|
+
| `EDGE_AGENT_REQUIRE_LOCAL_BYPASS_TOKEN` | no | `true` | Require local bypass token for loopback |
|
|
109
|
+
| `EDGE_AGENT_REVERSE_TUNNEL` | no | auto | `true` / `false` / unset |
|
|
110
|
+
| `EDGE_AGENT_NAT_TYPE` | no | `unknown` | `nat4`, `symmetric`, etc. |
|
|
111
|
+
| `EDGE_AGENT_NODE_UUID` | reverse only | - | Agent node UUID |
|
|
112
|
+
| `EDGE_AGENT_PUBLIC_KEY_FINGERPRINT` | reverse only | - | Agent public key fingerprint |
|
|
113
|
+
| `EDGE_AGENT_JOIN_TOKEN` | reverse only | - | Join token for Edge Agent mode |
|
|
114
|
+
| `EDGE_AGENT_TLS_SERVER_NAME` | no | - | TLS SNI |
|
|
115
|
+
| `EDGE_AGENT_CERTIFICATE_PIN_SHA256` | no | - | TLS certificate pin |
|
|
116
|
+
|
|
117
|
+
Generate a secret:
|
|
27
118
|
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
│ 边缘内网节点 (家用宽带 / NAT4 / 容器无公网IP) │
|
|
31
|
-
│ │
|
|
32
|
-
│ - Chromium CDP (:9222) │
|
|
33
|
-
│ - noVNC 桌面 (:6080) │
|
|
34
|
-
│ - 自定义业务服务 (:8080) │
|
|
35
|
-
└──────────────────────────┬─────────────────────────────┘
|
|
36
|
-
▲ 本地 127.0.0.1 访问
|
|
37
|
-
▼
|
|
38
|
-
┌────────────────────────────────────────────────────────┐
|
|
39
|
-
│ wimotek-edge-agent 客户端 │
|
|
40
|
-
│ │
|
|
41
|
-
│ 职责: 硬件指纹生成 + TOFU/Token协商 + 本地服务透明中继 │
|
|
42
|
-
└──────────────────────────┬─────────────────────────────┘
|
|
43
|
-
│
|
|
44
|
-
│ 主动发起出站反向长连接 (Outbound TLS/WSS)
|
|
45
|
-
│ 仅需中心管理端暴露 8443 端口,无视客户端网络环境
|
|
46
|
-
▼
|
|
47
|
-
┌────────────────────────────────────────────────────────┐
|
|
48
|
-
│ 中心控制端 (Central Hub) │
|
|
49
|
-
│ │
|
|
50
|
-
│ - 管理员在线认领锁定 (TOFU) / Token 自动化放行 │
|
|
51
|
-
│ - 借由反向长连接随时下发指令、Cookie同步、采集探针 │
|
|
52
|
-
└────────────────────────────────────────────────────────┘
|
|
119
|
+
```bash
|
|
120
|
+
python -c "import secrets; print(secrets.token_urlsafe(48))"
|
|
53
121
|
```
|
|
54
122
|
|
|
55
|
-
|
|
123
|
+
## CLI usage
|
|
56
124
|
|
|
57
|
-
|
|
125
|
+
Start a direct TLS JSON-line server:
|
|
58
126
|
|
|
59
|
-
### 1. Python / PyPI 安装(推荐)
|
|
60
127
|
```bash
|
|
61
|
-
|
|
128
|
+
edge-agent listen --host 0.0.0.0 --port 8443 \
|
|
129
|
+
--cert /path/server.crt --key /path/server.key
|
|
62
130
|
```
|
|
63
|
-
安装后直接获得系统全局命令 **`edge-agent`**。
|
|
64
131
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
npx wimotek-edge-agent --hub-url https://hub.yourdomain.com:8443
|
|
68
|
-
```
|
|
69
|
-
或全局安装:
|
|
132
|
+
Approve a pending TOFU node (admin, out-of-band):
|
|
133
|
+
|
|
70
134
|
```bash
|
|
71
|
-
|
|
135
|
+
edge-agent approve --node-uuid node-xxx --fingerprint sha256:...
|
|
72
136
|
```
|
|
73
137
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
## 🚀 快速上手
|
|
138
|
+
Revoke a trusted node:
|
|
77
139
|
|
|
78
|
-
### 1. 命令行直接启动 (CLI)
|
|
79
140
|
```bash
|
|
80
|
-
|
|
81
|
-
|
|
141
|
+
edge-agent revoke --node-uuid node-xxx
|
|
142
|
+
```
|
|
82
143
|
|
|
83
|
-
|
|
84
|
-
edge-agent --hub-url https://hub.yourdomain.com:8443 --reverse
|
|
144
|
+
Show a node record:
|
|
85
145
|
|
|
86
|
-
|
|
87
|
-
edge-agent
|
|
146
|
+
```bash
|
|
147
|
+
edge-agent show-node --node-uuid node-xxx
|
|
88
148
|
```
|
|
89
149
|
|
|
90
|
-
|
|
91
|
-
|
|
150
|
+
Issue a single-use Edge Agent join token:
|
|
151
|
+
|
|
92
152
|
```bash
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
153
|
+
edge-agent issue-token \
|
|
154
|
+
--node-group group-a \
|
|
155
|
+
--ttl 300 \
|
|
156
|
+
--node-uuid node-xxx \
|
|
157
|
+
--allowed-ip-cidr 203.0.113.0/24
|
|
97
158
|
```
|
|
98
159
|
|
|
99
|
-
|
|
100
|
-
```python
|
|
101
|
-
from wimotek_edge_agent import EdgeAgent
|
|
102
|
-
|
|
103
|
-
agent = EdgeAgent(
|
|
104
|
-
hub_url="https://hub.yourdomain.com:8443",
|
|
105
|
-
join_token="hub_join_xxxxxx", # 可选
|
|
106
|
-
node_name="Seoul-Worker-01", # 可选,留空自动按 IP 拼接
|
|
107
|
-
node_group="爬虫矩阵组", # 默认: 默认分组
|
|
108
|
-
cdp_port=9222, # 默认: 9222
|
|
109
|
-
reverse_tunnel=True # 开启 NAT4 反向长连接
|
|
110
|
-
)
|
|
160
|
+
## Programmatic usage
|
|
111
161
|
|
|
112
|
-
|
|
113
|
-
|
|
162
|
+
```python
|
|
163
|
+
import asyncio
|
|
164
|
+
from edge_agent import Config, EdgeAgent
|
|
165
|
+
|
|
166
|
+
async def main() -> None:
|
|
167
|
+
config = Config.from_env()
|
|
168
|
+
agent = EdgeAgent(config)
|
|
169
|
+
|
|
170
|
+
async def data_handler(transport, ctx):
|
|
171
|
+
while True:
|
|
172
|
+
msg = await transport.read_message()
|
|
173
|
+
if msg.get("type") == "ping":
|
|
174
|
+
await transport.write_message({"type": "pong"})
|
|
175
|
+
|
|
176
|
+
agent.data_handler = data_handler
|
|
177
|
+
|
|
178
|
+
server = await asyncio.start_server(
|
|
179
|
+
lambda r, w: agent.handle_connection(
|
|
180
|
+
__import__("edge_agent.transport", fromlist=["JsonLineTransport"]).JsonLineTransport(r, w),
|
|
181
|
+
w.get_extra_info("peername")[0],
|
|
182
|
+
),
|
|
183
|
+
host="0.0.0.0",
|
|
184
|
+
port=8443,
|
|
185
|
+
)
|
|
186
|
+
async with server:
|
|
187
|
+
await server.serve_forever()
|
|
188
|
+
|
|
189
|
+
asyncio.run(main())
|
|
114
190
|
```
|
|
115
191
|
|
|
116
|
-
|
|
192
|
+
## Reverse tunnel / NAT4
|
|
117
193
|
|
|
118
|
-
|
|
194
|
+
`transport.TunnelDialer` is a protocol. Implement it with your existing
|
|
195
|
+
WebSocket stack, then call:
|
|
119
196
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
| `LOCAL_CDP_HOST`| `--cdp-host` | `127.0.0.1` | 节点本地被中继服务的绑定地址 |
|
|
129
|
-
| `SERVICES` | `--services` | *无* | 多服务端口定义,格式:`cdp:9222,vnc:6080,api:8080` |
|
|
130
|
-
| `UUID_FILE` | `--uuid-file` | `/data/node_machine.id` | 硬件指纹持久化文件路径,保障重启后身份不漂移 |
|
|
131
|
-
|
|
132
|
-
---
|
|
197
|
+
```python
|
|
198
|
+
await agent.run_reverse_tunnel(
|
|
199
|
+
url="wss://central.example.com/tunnel",
|
|
200
|
+
dialer=your_dialer,
|
|
201
|
+
ssl_context=ssl_context,
|
|
202
|
+
server_hostname="central.example.com",
|
|
203
|
+
)
|
|
204
|
+
```
|
|
133
205
|
|
|
134
|
-
|
|
206
|
+
The reverse tunnel:
|
|
135
207
|
|
|
136
|
-
|
|
137
|
-
|
|
208
|
+
- uses TLS and supports certificate pinning via
|
|
209
|
+
`EDGE_AGENT_CERTIFICATE_PIN_SHA256`;
|
|
210
|
+
- sends the same handshake fields as direct mode (`node_uuid`,
|
|
211
|
+
`public_key_fingerprint`, `join_token`, `nat_type`, `reverse_tunnel`);
|
|
212
|
+
- keeps waiting on `pending_tofu` until the central side sends
|
|
213
|
+
`approved` or `denied`;
|
|
214
|
+
- applies exponential backoff on reconnect.
|
|
138
215
|
|
|
139
|
-
|
|
140
|
-
|
|
216
|
+
Authentication is performed by the central side using the same
|
|
217
|
+
`AccessPolicyEngine`. The network profile is `nat4_reverse`; the auth
|
|
218
|
+
strength is identical to direct mode.
|
|
141
219
|
|
|
142
|
-
|
|
143
|
-
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
144
|
-
chromium xvfb x11vnc novnc websockify python3 python3-pip curl \
|
|
145
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
220
|
+
## Audit log
|
|
146
221
|
|
|
147
|
-
|
|
148
|
-
RUN pip3 install --no-cache-dir --break-system-packages wimotek-edge-agent
|
|
222
|
+
Every `AccessDecision` is written to `EDGE_AGENT_DATA_DIR/audit.jsonl`:
|
|
149
223
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
ENTRYPOINT ["/app/entrypoint.sh"]
|
|
224
|
+
```json
|
|
225
|
+
{"ts":"2026-11-06T12:00:00+00:00","event":"access_decision","node_uuid":"node-xxx","source_ip":"203.0.113.10","is_loopback":false,"decision":"allow_token","reason":"edge_agent_token_verified","network_profile":"direct","nat_type":"unknown","fingerprint":"sha256:...","node_status":"trusted"}
|
|
153
226
|
```
|
|
154
227
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
228
|
+
Ship this file to your central log platform (Loki, ELK, CloudWatch, etc.).
|
|
229
|
+
Do not store the raw join token in the audit log; only record the decision.
|
|
230
|
+
|
|
231
|
+
## Security model
|
|
232
|
+
|
|
233
|
+
- **Token secret**: >= 32 bytes. Rotate by restarting with a new secret;
|
|
234
|
+
old tokens become invalid immediately.
|
|
235
|
+
- **Token single use**: `jti` is stored in `used_tokens` until `exp`.
|
|
236
|
+
- **Token binding**: optional `node_uuid` and `allowed_ip_cidr`.
|
|
237
|
+
- **TOFU quarantine**: pending nodes exchange heartbeat only. No data
|
|
238
|
+
relay, no business messages.
|
|
239
|
+
- **Fingerprint mismatch**: pending node presenting a different
|
|
240
|
+
fingerprint is denied; trusted node presenting a different fingerprint
|
|
241
|
+
is denied.
|
|
242
|
+
- **No downgrade**: trusted node without token or session is denied.
|
|
243
|
+
- **Local bypass**: `local_bypass.token` is written with mode `0600`.
|
|
244
|
+
Set `EDGE_AGENT_REQUIRE_LOCAL_BYPASS_TOKEN=false` only if you fully
|
|
245
|
+
trust every process on the host.
|
|
246
|
+
- **TLS pinning**: optional SHA-256 pin of the peer certificate.
|
|
247
|
+
- **Audit**: every decision is logged. Revocation is immediate on the
|
|
248
|
+
next handshake.
|
|
249
|
+
|
|
250
|
+
## Commercial deployment checklist
|
|
251
|
+
|
|
252
|
+
- [ ] Rotate `EDGE_AGENT_TOKEN_SECRET` per environment.
|
|
253
|
+
- [ ] Store `EDGE_AGENT_DATA_DIR` on persistent, encrypted storage.
|
|
254
|
+
- [ ] Ship `audit.jsonl` to central logging with retention policy.
|
|
255
|
+
- [ ] Enable TLS with a valid certificate; set
|
|
256
|
+
`EDGE_AGENT_CERTIFICATE_PIN_SHA256` for reverse tunnel.
|
|
257
|
+
- [ ] Restrict `edge-agent approve` to an admin-only host or CI job.
|
|
258
|
+
- [ ] Monitor `tofu_pending_queue_size`, `token_replay_rejections`,
|
|
259
|
+
`reverse_tunnel_reconnect_count`.
|
|
260
|
+
- [ ] Run `edge-agent revoke` on node decommission.
|
|
261
|
+
- [ ] Back up `trust_store.sqlite3` before upgrades.
|
|
262
|
+
- [ ] Pin Python and Node versions in CI.
|
|
263
|
+
- [ ] Publish PyPI and npm from tagged releases only.
|
|
264
|
+
|
|
265
|
+
## Publishing
|
|
266
|
+
|
|
267
|
+
PyPI:
|
|
166
268
|
|
|
167
|
-
|
|
269
|
+
```bash
|
|
270
|
+
python -m build
|
|
271
|
+
python -m twine check dist/*
|
|
272
|
+
python -m twine upload dist/*
|
|
168
273
|
```
|
|
169
274
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
#### 无公网 IP / 家用宽带 / NAT4(开启反向长连接):
|
|
173
|
-
```yaml
|
|
174
|
-
version: '3.8'
|
|
175
|
-
|
|
176
|
-
services:
|
|
177
|
-
browser-node:
|
|
178
|
-
image: your-browser-image:latest
|
|
179
|
-
restart: unless-stopped
|
|
180
|
-
ports:
|
|
181
|
-
- "6080:6080" # 仅供内网访问桌面,公网无需暴露 9222
|
|
182
|
-
environment:
|
|
183
|
-
- HUB_URL=https://hub.yourdomain.com:8443
|
|
184
|
-
- JOIN_TOKEN=hub_join_abcdef1234567890 # 可选:留空在控制台一键点击认领
|
|
185
|
-
- REVERSE_TUNNEL=true # NAT4 穿透开关
|
|
186
|
-
- NODE_GROUP=北美爬虫矩阵组
|
|
187
|
-
volumes:
|
|
188
|
-
- ./data:/data
|
|
189
|
-
```
|
|
275
|
+
npm (CLI wrapper):
|
|
190
276
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
services:
|
|
196
|
-
browser-node:
|
|
197
|
-
image: your-browser-image:latest
|
|
198
|
-
restart: unless-stopped
|
|
199
|
-
ports:
|
|
200
|
-
- "9222:9222" # 防火墙已开放端口
|
|
201
|
-
environment:
|
|
202
|
-
- HUB_URL=https://hub.yourdomain.com:8443
|
|
203
|
-
- REVERSE_TUNNEL=false # 默认即为 false,仅发起轻量 HTTP 登记,零长连接开销
|
|
277
|
+
```bash
|
|
278
|
+
cd npm
|
|
279
|
+
npm pack --dry-run
|
|
280
|
+
npm publish --access public
|
|
204
281
|
```
|
|
205
282
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
## 🔒 安全性考量
|
|
209
|
-
|
|
210
|
-
1. **防恶意伪造(SSRF 防御)**:在直连上报模式下,管理端强制从底层 TCP 握手来源直接锁定节点的真实来源 IP,杜绝假冒内网私网地址。
|
|
211
|
-
2. **防公网扫描冒充**:未携带 `JOIN_TOKEN` 的未知连接一律进入隔离待审核队列(TOFU),未经管理端管理员后台显式认领的节点,绝不参与任何数据交互。
|
|
212
|
-
3. **安全通信**:长连接反向通道强制基于 TLS (WSS) 传输,天然防御中间人窃听与数据篡改。
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## 📄 License
|
|
283
|
+
## License
|
|
217
284
|
|
|
218
|
-
MIT
|
|
219
|
-
```
|
|
285
|
+
MIT. See `LICENSE`.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from .agent import EdgeAgent
|
|
2
|
+
from .config import Config
|
|
3
|
+
from .models import (
|
|
4
|
+
AccessDecision,
|
|
5
|
+
AccessDecisionResult,
|
|
6
|
+
ConnectionContext,
|
|
7
|
+
NodeRecord,
|
|
8
|
+
TrustStatus,
|
|
9
|
+
)
|
|
10
|
+
from .policy import AccessPolicyEngine
|
|
11
|
+
from .trust_store import TrustStore
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"EdgeAgent",
|
|
15
|
+
"Config",
|
|
16
|
+
"AccessDecision",
|
|
17
|
+
"AccessDecisionResult",
|
|
18
|
+
"ConnectionContext",
|
|
19
|
+
"NodeRecord",
|
|
20
|
+
"TrustStatus",
|
|
21
|
+
"AccessPolicyEngine",
|
|
22
|
+
"TrustStore",
|
|
23
|
+
]
|