vssh 3.7.4__tar.gz → 3.7.5__tar.gz

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.
vssh-3.7.5/PKG-INFO ADDED
@@ -0,0 +1,478 @@
1
+ Metadata-Version: 2.4
2
+ Name: vssh
3
+ Version: 3.7.5
4
+ Summary: Secure SSH/SCP tool with Tailscale failover, P2P transport, and MCP server
5
+ Author-email: MeshPOP <mpop@mpop.dev>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/meshpop/vssh
8
+ Project-URL: Repository, https://github.com/meshpop/vssh
9
+ Keywords: ssh,scp,tailscale,p2p,vpn,mcp,remote
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Topic :: System :: Networking
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Dynamic: license-file
23
+
24
+ # vssh
25
+
26
+ **Fast SSH alternative for server fleets — no key management, instant connections, AI-assisted.**
27
+
28
+ ```bash
29
+ pip install vssh
30
+ ```
31
+
32
+ No external dependencies. Pure Python standard library. Works on Linux and macOS.
33
+
34
+ ---
35
+
36
+ ## Why vssh?
37
+
38
+ ### The problem with SSH at scale
39
+
40
+ SSH is the industry standard for remote access — but it was designed for single-server use. Managing a fleet with SSH means:
41
+
42
+ **Key management sprawl:**
43
+ ```bash
44
+ # Adding a new admin to 20 servers
45
+ for server in web{1..10} db{1..5} worker{1..5}; do
46
+ ssh-copy-id -i ~/.ssh/newadmin.pub root@$server
47
+ done
48
+ # When they leave: remove the key from all 20 servers
49
+ # Key rotation: touch every server again
50
+ ```
51
+
52
+ **IP address bookkeeping:**
53
+ ```bash
54
+ # You have to remember or look up IPs constantly
55
+ ssh root@10.0.1.42 # which server is this again?
56
+ ssh -i ~/.ssh/id_rsa root@10.0.1.42 "df -h"
57
+ # Different key for different servers? Different user? Port?
58
+ ```
59
+
60
+ **Connection overhead:**
61
+ SSH does a full TLS-style handshake on every connection — key exchange, algorithm negotiation, authentication. For a fleet-wide operation this adds up to seconds of overhead per server.
62
+
63
+ **No unified view:**
64
+ There's no built-in way to see which servers are reachable right now, or to run commands across multiple servers with clean output.
65
+
66
+ ### Before vssh
67
+
68
+ ```bash
69
+ # Deploy nginx config to 10 servers and reload
70
+ for ip in 10.0.1.10 10.0.1.11 10.0.1.12 10.0.1.13 10.0.1.14 \
71
+ 10.0.1.15 10.0.1.16 10.0.1.17 10.0.1.18 10.0.1.19; do
72
+ scp -i ~/.ssh/id_rsa ./nginx.conf root@$ip:/etc/nginx/nginx.conf
73
+ ssh -i ~/.ssh/id_rsa root@$ip "nginx -t && systemctl reload nginx"
74
+ done
75
+ # ~200-400ms per server just for connection setup
76
+ # Must track IPs, keys, users manually
77
+ # No visibility into which succeeded or failed
78
+ ```
79
+
80
+ ### After vssh
81
+
82
+ ```bash
83
+ # Same operation with vssh
84
+ for node in web{1..10}; do
85
+ vssh put ./nginx.conf $node:/etc/nginx/nginx.conf
86
+ vssh $node "nginx -t && systemctl reload nginx"
87
+ done
88
+ # Names auto-discovered from wire mesh
89
+ # One shared secret — no per-server keys
90
+ # Persistent daemon — connections are instant
91
+ ```
92
+
93
+ ### Comparison
94
+
95
+ | | SSH | vssh |
96
+ |---|---|---|
97
+ | Authentication | Per-server public keys | One shared HMAC secret |
98
+ | Key management | Add/remove on every server | Change one secret, done |
99
+ | Connection setup | Full handshake every time (~200-400ms) | HMAC token check (~1ms) |
100
+ | Server discovery | IP addresses / /etc/hosts / DNS | Wire mesh auto-discovery |
101
+ | Fleet health view | None built-in | `vssh status` shows all nodes |
102
+ | File transfer | `scp` (new connection each time) | Persistent connection, resumable |
103
+ | AI management | ✗ | ✓ MCP integration |
104
+ | Dependencies | OpenSSH (system) | None (pure Python) |
105
+
106
+ ---
107
+
108
+ ## Architecture
109
+
110
+ vssh has two parts: a **daemon** (vsshd) running on each server, and a **client** (`vssh`) you run from your machine.
111
+
112
+ ```
113
+ ┌─────────────────────────────────────────────┐
114
+ │ Your Server Fleet │
115
+ │ │
116
+ │ ┌──────┐ ┌──────┐ ┌──────┐ │
117
+ │ │ web1 │ │ web2 │ │ db1 │ │
118
+ │ │vsshd │ │vsshd │ │vsshd │ ... │
119
+ │ │:48291│ │:48291│ │:48291│ │
120
+ │ └──┬───┘ └──┬───┘ └──┬───┘ │
121
+ │ └───────────┴───────────┘ │
122
+ │ WireGuard mesh (wire) │
123
+ └──────────────────┬──────────────────────────┘
124
+ │ TCP :48291
125
+ ┌──────┴──────┐
126
+ │ vssh client │ ← your machine
127
+ │ (Mac/Linux) │
128
+ └─────────────┘
129
+ ```
130
+
131
+ All communication happens on **TCP port 48291** using a simple line-delimited protocol with HMAC-SHA256 authentication.
132
+
133
+ vssh is **Layer 2** of the MeshPOP stack:
134
+
135
+ ```
136
+ Layer 3 mpop Fleet orchestration — monitor, manage, automate
137
+ Layer 2 vssh Authenticated transport — remote exec, file transfer ← this
138
+ Layer 1 wire Encrypted mesh VPN — connects all nodes
139
+ ```
140
+
141
+ Each layer is independently installable. vssh works without wire (use a static config file) and without mpop.
142
+
143
+ ---
144
+
145
+ ## Installation
146
+
147
+ ### Install vssh
148
+
149
+ ```bash
150
+ pip install vssh
151
+ ```
152
+
153
+ This installs:
154
+ - `vssh` — CLI client
155
+ - `vsshd` / `vssh server` — daemon
156
+ - `vssh-mcp` — MCP server for AI integration
157
+
158
+ Pure Python standard library — no external packages required.
159
+
160
+ ### Start the daemon on each server
161
+
162
+ Set the same shared secret on every server (environment variable or file):
163
+
164
+ ```bash
165
+ # Option 1: environment variable
166
+ export VSSH_SECRET=your-shared-secret-here
167
+ vssh server
168
+
169
+ # Option 2: secret file
170
+ echo "your-shared-secret-here" > ~/.vssh/secret
171
+ chmod 600 ~/.vssh/secret
172
+ vssh server
173
+ ```
174
+
175
+ The secret can be any string. Use a long random value:
176
+ ```bash
177
+ python3 -c "import secrets; print(secrets.token_hex(32))"
178
+ ```
179
+
180
+ ### Install as a system service (recommended)
181
+
182
+ ```bash
183
+ # Set the secret first, then:
184
+ vssh install # writes /etc/systemd/system/vssh.service and enables it
185
+ ```
186
+
187
+ The service starts automatically on boot.
188
+
189
+ ### Configure the client (your machine)
190
+
191
+ If you use **wire** mesh VPN, vssh discovers all nodes automatically — no config needed.
192
+
193
+ For standalone use without wire, create `~/.vssh/config`:
194
+
195
+ ```ini
196
+ # Server names and IPs
197
+ web1=192.168.1.10
198
+ web2=192.168.1.11
199
+ db1=192.168.1.20
200
+
201
+ # Shared secret (same as on servers)
202
+ SECRET=your-shared-secret-here
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Authentication
208
+
209
+ vssh uses **HMAC-SHA256** — a time-based token derived from the shared secret:
210
+
211
+ ```
212
+ token = hmac_{timestamp}_{sha256(secret + timestamp)[:32]}
213
+ ```
214
+
215
+ Every command includes this token. The server verifies it against its own secret. Tokens are valid for ±60 seconds (clock skew window).
216
+
217
+ **One secret to manage all servers.** To revoke access, change the secret on all servers. No key files to track, no per-user certificates.
218
+
219
+ Secret is read from (priority order):
220
+ 1. `VSSH_SECRET` environment variable
221
+ 2. `~/.vssh/secret` file
222
+ 3. `SECRET=` entry in `~/.vssh/config`
223
+
224
+ ---
225
+
226
+ ## CLI Reference
227
+
228
+ ### Fleet status
229
+
230
+ ```bash
231
+ vssh status # Connection status to all mesh nodes
232
+ vssh status --full # Status + disk / memory / load per node
233
+ ```
234
+
235
+ ```
236
+ vssh v3.7.4 - Cluster Status (full)
237
+ ======================================================================
238
+ web1 10.99.1.10 ● online (8ms)
239
+ disk: 45% used (120GB / 250GB) mem: 4.2GB / 16GB load: 0.42
240
+ web2 10.99.1.11 ● online (9ms)
241
+ disk: 31% used mem: 2.1GB / 8GB load: 0.15
242
+ db1 10.99.1.20 ✗ offline
243
+
244
+ Total: 2/3 online
245
+ ```
246
+
247
+ ---
248
+
249
+ ### Remote execution
250
+
251
+ ```bash
252
+ vssh <host> # Interactive terminal (PTY — like SSH)
253
+ vssh <host> "command" # Run a single command
254
+ vssh session <host> # Persistent PTY session
255
+ ```
256
+
257
+ ```bash
258
+ # Examples
259
+ vssh web1 # Open interactive shell on web1
260
+ vssh web1 "uptime" # Check uptime
261
+ vssh web1 "df -h && free -h" # Chain commands
262
+ vssh db1 "systemctl status postgresql"
263
+ ```
264
+
265
+ ---
266
+
267
+ ### File transfer
268
+
269
+ ```bash
270
+ # Upload
271
+ vssh put <local> <host>:<remote>
272
+ vssh put -z <local> <host>:<remote> # Force compression
273
+ vssh put --resume <local> <host>:<remote> # Resume interrupted upload
274
+
275
+ # Download
276
+ vssh get <host>:<remote> <local>
277
+ vssh get --retry=3 <host>:<remote> <local> # Retry on failure
278
+
279
+ # Directory sync
280
+ vssh sync <local_dir> <host>:<remote_dir> # 8 parallel streams
281
+
282
+ # Delta sync (only changed blocks — like rsync)
283
+ vssh rsync <local> <host>:<remote>
284
+
285
+ # Multiple files in one connection
286
+ vssh mput <host>:<base_path> file1 file2 file3
287
+ ```
288
+
289
+ ```bash
290
+ # Examples
291
+ vssh put ./app.tar.gz web1:/opt/app.tar.gz
292
+ vssh get web1:/var/log/app.log ./app.log
293
+ vssh sync ./config/ web1:/etc/app/
294
+ vssh rsync ./src/ web1:/opt/src/
295
+ ```
296
+
297
+ vssh auto-compresses text files (`.py`, `.js`, `.json`, `.log`, etc.) and skips upload if remote MD5 matches.
298
+
299
+ ---
300
+
301
+ ### Speed test
302
+
303
+ ```bash
304
+ vssh speed-test web1 # 10MB test
305
+ vssh speed-test web1 --size=50
306
+ ```
307
+
308
+ ---
309
+
310
+ ### Pipe operations
311
+
312
+ ```bash
313
+ # Upload stdin to remote file
314
+ cat data.csv | vssh pipe-up web1:/data/input.csv
315
+
316
+ # Download remote command output to stdout
317
+ vssh pipe-down web1:"journalctl -u nginx -n 100" | grep ERROR
318
+ ```
319
+
320
+ ---
321
+
322
+ ### Daemon management
323
+
324
+ ```bash
325
+ vssh server # Start daemon (foreground)
326
+ vssh install # Install as systemd (Linux) or launchd (macOS) service
327
+ vssh up # Start via systemd
328
+ vssh down # Stop daemon
329
+ vssh restart # Restart daemon
330
+ ```
331
+
332
+ ---
333
+
334
+ ### Node info
335
+
336
+ ```bash
337
+ vssh info <host> # OS, IPs, vsshd version, load
338
+ ```
339
+
340
+ ---
341
+
342
+ ### History and stats
343
+
344
+ ```bash
345
+ vssh history # Last 20 commands
346
+ vssh history 50 # Last 50
347
+ vssh history put # Filter by operation (SSH, PUT, GET, RPC, SYNC)
348
+ vssh stats # Transfer stats (last 7 days)
349
+ vssh stats 30 # Last 30 days
350
+ ```
351
+
352
+ ---
353
+
354
+ ## RPC — Structured Remote Calls
355
+
356
+ RPC is vssh's structured interface for getting typed JSON data from remote servers — no screen scraping, no parsing shell output.
357
+
358
+ ```bash
359
+ vssh rpc <host> <method> # No arguments
360
+ vssh rpc <host> <method> '{"key":"value"}' # With JSON payload
361
+ vssh rpc-list <host> # List available methods
362
+ ```
363
+
364
+ ### Available RPC methods
365
+
366
+ | Method | Description |
367
+ |---|---|
368
+ | `get_disk` | Disk usage (path optional) |
369
+ | `get_memory` | Memory usage in bytes |
370
+ | `get_load` | Load average (1m / 5m / 15m) |
371
+ | `get_processes` | Top processes by CPU or memory |
372
+ | `get_gpu` | GPU VRAM, utilization, temperature |
373
+ | `get_logs` | Read log file or journalctl output |
374
+ | `get_network_info` | Local and public IPs |
375
+ | `list_services` | Running systemd services |
376
+ | `service_status` | Check if a service is active |
377
+ | `restart_service` | Restart nginx / docker / ollama / postgresql / redis |
378
+ | `docker_containers` | List Docker containers and status |
379
+ | `file_read` | Read a file (with security restrictions) |
380
+ | `file_write` | Write a file (system paths blocked) |
381
+
382
+ ```bash
383
+ # Examples
384
+ vssh rpc web1 get_disk
385
+ vssh rpc web1 get_disk '{"path": "/data"}'
386
+ vssh rpc web1 get_memory
387
+ vssh rpc web1 get_processes '{"n": 5, "sort": "mem"}'
388
+ vssh rpc web1 get_gpu
389
+ vssh rpc web1 get_logs '{"service": "nginx", "lines": 50}'
390
+ vssh rpc web1 restart_service '{"service": "nginx"}'
391
+ ```
392
+
393
+ ---
394
+
395
+ ## Tailscale Failover
396
+
397
+ If a node's primary VPN IP (wire) is unreachable, vssh automatically retries via Tailscale:
398
+
399
+ 1. Try wire VPN IP (2s timeout)
400
+ 2. Retry once after 300ms (WireGuard handshake may be completing)
401
+ 3. Fall back to Tailscale IP, cache for 60s
402
+ 4. After 60s: retry wire — if recovered, clear failover cache
403
+
404
+ The failover map (`~/.vssh/tailscale_map`) is built automatically by cross-referencing `tailscale status` with the wire peer list. No manual configuration needed.
405
+
406
+ ---
407
+
408
+ ## AI Management via MCP
409
+
410
+ vssh ships with an MCP server that lets AI agents (Claude, etc.) manage your fleet through natural language — from installation through daily operations.
411
+
412
+ ### Setup
413
+
414
+ ```bash
415
+ pip install vssh # installs vssh-mcp automatically
416
+ ```
417
+
418
+ Add to Claude config (`~/.claude/settings.json`):
419
+
420
+ ```json
421
+ {
422
+ "mcpServers": {
423
+ "vssh": { "command": "vssh-mcp" }
424
+ }
425
+ }
426
+ ```
427
+
428
+ ### What the AI can do
429
+
430
+ Once connected, you can ask Claude in plain language:
431
+
432
+ > "Check which servers are online and show me their disk usage"
433
+ > "Deploy the new config to all web servers and reload nginx"
434
+ > "Show me the last 50 nginx error log lines from web1"
435
+ > "What's using the most memory on db1?"
436
+ > "Sync the /etc/app/ config directory from web1 to web2"
437
+ > "Run a speed test to web1"
438
+
439
+ The AI handles the vssh commands, interprets the results, and tells you what it found.
440
+
441
+ ### MCP Tools Reference
442
+
443
+ | Tool | Description |
444
+ |---|---|
445
+ | `vssh_status` | Fleet status — all nodes, online/offline, latency |
446
+ | `vssh_exec` | Run a shell command on a remote server |
447
+ | `vssh_put` | Upload a file to a remote server |
448
+ | `vssh_get` | Download a file from a remote server |
449
+ | `vssh_sync` | Sync a directory between two servers |
450
+ | `vssh_speed_test` | Measure upload/download speed to a server |
451
+ | `vssh_tunnel` | Create a port-forwarding tunnel |
452
+ | `vssh_keys` | Show configured secrets and available servers |
453
+
454
+ ### Example AI workflow — deploy update
455
+
456
+ ```
457
+ You: "Deploy app-v2.tar.gz to all web servers and restart the app service"
458
+
459
+ AI:
460
+ 1. vssh_status → check which web servers are online
461
+ 2. vssh_put(web1, /tmp/app-v2.tar.gz, /opt/app.tar.gz)
462
+ 3. vssh_exec(web1, "cd /opt && tar xf app.tar.gz && systemctl restart app")
463
+ 4. vssh_exec(web1, "systemctl is-active app")
464
+ 5. Repeats for web2, web3...
465
+ 6. Reports: "Deployed to 3/3 servers. All app services active."
466
+ ```
467
+
468
+ ---
469
+
470
+ ## Links
471
+
472
+ - Wire VPN: [github.com/meshpop/wire](https://github.com/meshpop/wire)
473
+ - Fleet orchestration: [github.com/meshpop/mpop](https://github.com/meshpop/mpop)
474
+ - PyPI: [pypi.org/project/vssh](https://pypi.org/project/vssh/)
475
+
476
+ ## License
477
+
478
+ MIT — [MeshPOP](https://github.com/meshpop)