polaris-vpn 1.1.0 → 1.1.2
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/CHANGELOG.md +10 -0
- package/README.md +74 -97
- package/package.json +6 -1
- package/src/commands/check.js +3 -2
- package/src/commands/dashboard.js +10 -5
- package/src/commands/deploy.js +2 -1
- package/src/commands/monitor.js +1 -1
- package/src/commands/start.js +1 -2
- package/src/commands/status.js +22 -9
- package/src/commands/tui.js +14 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.1.2] - 2026-07-22
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Start Command**: Fixed `ReferenceError: config is not defined` crash when invoking `polaris start` without `--server` argument.
|
|
13
|
+
- **WireGuard & AmneziaWG Status**: Fixed `polaris status` and `polaris check` reporting false proxy failures for system-wide VPN interfaces.
|
|
14
|
+
- **AmneziaWG Bandwidth Monitoring**: Updated `polaris monitor`, `dashboard`, `status`, and TUI components to query `awg` interface statistics and accept `--mode amneziawg`.
|
|
15
|
+
- **Deploy Local Auto-Connect**: Updated `polaris deploy` to automatically trigger local connection passing correct server and mode arguments upon provisioning completion.
|
|
16
|
+
- **Status Table Formatting**: Replaced invalid SOCKS5 proxy port display (`socks5://127.0.0.1:0`) with clear `System-wide (All OS traffic)` label for WireGuard and AmneziaWG connections.
|
|
17
|
+
|
|
8
18
|
## [1.0.0] - 2026-07-15
|
|
9
19
|
|
|
10
20
|
### Added
|
package/README.md
CHANGED
|
@@ -1,132 +1,109 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Polaris VPN
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
<img src="./docs/demo.gif" alt="Polaris VPN Terminal Demo" width="800">
|
|
7
|
-
</div>
|
|
5
|
+
**Command your privacy.**
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
[](https://www.npmjs.com/package/polaris-vpn)
|
|
8
|
+
[](https://github.com/Divyo/polaris-vpn)
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+

|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
A production-grade, self-hosted VPN CLI with a beautiful Terminal User
|
|
13
|
+
Interface (TUI).
|
|
12
14
|
|
|
13
|
-
-
|
|
14
|
-
- SSH access to a remote Linux VPS (Ubuntu/Debian recommended)
|
|
15
|
-
- **Linux/macOS**: `sudo` privileges for configuring WireGuard and network routes locally.
|
|
16
|
-
- **Windows**: The official [WireGuard for Windows](https://www.wireguard.com/install/) client must be installed, and `polaris` must be run from an Administrator prompt.
|
|
15
|
+
Deploy an enterprise-grade WireGuard or Stealth VPN in under 60 seconds.
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
---
|
|
19
18
|
|
|
20
|
-
##
|
|
19
|
+
## ✨ Features
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
- **🚀 Automated Deployment**: Instantly provision a WireGuard or AmneziaWG VPN
|
|
22
|
+
on any fresh Linux VPS.
|
|
23
|
+
- **🎨 Beautiful TUI**: A master dashboard with real-time bandwidth
|
|
24
|
+
monitoring, ping latency, and server locations.
|
|
25
|
+
- **🛡️ Smart Kill-Switch**: Native OS firewall integration (`pf` for Mac,
|
|
26
|
+
`iptables` for Linux) that ensures 0 leaks.
|
|
27
|
+
- **👻 Stealth Mode**: DPI (Deep Packet Inspection) bypass using AmneziaWG to
|
|
28
|
+
defeat state-level censorship.
|
|
29
|
+
- **🔗 SSH Fallback**: Can't install WireGuard? Polaris seamlessly falls back
|
|
30
|
+
to an encrypted SOCKS5 SSH tunnel.
|
|
31
|
+
- **☁️ Own Your Infra**: We run no servers. You bring your own VPS (Oracle
|
|
32
|
+
Free Tier recommended).
|
|
25
33
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
Once you have your server's IP address and SSH credentials (e.g. `ubuntu@1.2.3.4`), just run:
|
|
34
|
+
## 📦 Installation
|
|
29
35
|
|
|
30
36
|
```bash
|
|
31
|
-
|
|
37
|
+
npm install -g polaris-vpn
|
|
32
38
|
```
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Verify it's working:
|
|
40
|
+
Requires Node.js 18+
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
polaris check
|
|
40
|
-
```
|
|
42
|
+
## ⚡ Quick Start
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
Got a fresh Linux VPS? Let Polaris set everything up for you.
|
|
43
45
|
|
|
44
46
|
```bash
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
## Command Reference
|
|
49
|
-
|
|
50
|
-
| Command | Description |
|
|
51
|
-
| --- | --- |
|
|
52
|
-
| `polaris deploy --server user@host --mode amneziawg` | Provision server with AmneziaWG (Stealth Mode) |
|
|
53
|
-
| `polaris start --server user@host [--port 1080] [--mode <type>]` | Start the encrypted tunnel. |
|
|
54
|
-
| `polaris stop` | Stop the active tunnel. |
|
|
55
|
-
| `polaris dashboard` | Opens a rich Terminal User Interface (TUI) with real-time stats. |
|
|
56
|
-
| `polaris status [--full]` | Show current tunnel status. `--full` shows GeoIP, ping latency, and WG stats. |
|
|
57
|
-
| `polaris monitor` | Live bandwidth monitor for WireGuard tunnels. |
|
|
58
|
-
| `polaris killswitch on/off` | Enable or disable the system-wide VPN kill switch. |
|
|
59
|
-
| `polaris peer add <name>` | Generate and add a new peer config for WireGuard/AmneziaWG. |
|
|
60
|
-
| `polaris peer list` | List all peers configured on the server. |
|
|
61
|
-
| `polaris peer remove <name>` | Revoke a peer from the server. |
|
|
62
|
-
| `polaris peer qr <name>` | Display the peer config as a QR code for mobile devices. |
|
|
63
|
-
| `polaris check` | Run a 3-point privacy check (IP, DNS leak, IPv6 leak). |
|
|
64
|
-
| `polaris add <alias> --server user@host` | Save a server profile for quick access. |
|
|
65
|
-
| `polaris list` | List all saved server profiles. |
|
|
66
|
-
| `polaris use <alias>` | Set a saved profile as the active default. |
|
|
67
|
-
| `polaris server start` | Start a local REST API on `127.0.0.1:7070`. |
|
|
68
|
-
| `polaris update` | Update `polaris-vpn` to the latest version via npm. |
|
|
47
|
+
# 1. Provision the server automatically
|
|
48
|
+
polaris deploy --server root@1.2.3.4 --mode amneziawg
|
|
69
49
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
#### `polaris status [--full]`
|
|
75
|
-
|
|
76
|
-
Displays the connection state, mode, current proxy IP, and active server. Use `--full` to query GeoIP and ping latency.
|
|
50
|
+
# 2. Connect to your new VPN
|
|
51
|
+
polaris start --server root@1.2.3.4
|
|
52
|
+
```
|
|
77
53
|
|
|
78
|
-
|
|
54
|
+
> **Pro Tip**: Run `polaris add my-server --server root@1.2.3.4`
|
|
55
|
+
> so you can just type `polaris start` next time!
|
|
79
56
|
|
|
80
|
-
|
|
57
|
+
## 🖥️ The Dashboard
|
|
81
58
|
|
|
82
|
-
|
|
59
|
+
Experience the modern terminal UI by running:
|
|
83
60
|
|
|
84
|
-
|
|
61
|
+
```bash
|
|
62
|
+
polaris
|
|
63
|
+
```
|
|
85
64
|
|
|
86
|
-
|
|
65
|
+
Use your **Arrow Keys** to navigate through:
|
|
87
66
|
|
|
88
|
-
|
|
67
|
+
- **Home**: Quick connect/disconnect and privacy check tools.
|
|
68
|
+
- **Live Monitor**: Watch your real-time Rx/Tx bandwidth graphs and server latency.
|
|
69
|
+
- **Peers**: Add or revoke VPN access for friends, or generate a QR code for
|
|
70
|
+
your phone.
|
|
71
|
+
- **Settings**: Manage your saved server profiles.
|
|
89
72
|
|
|
90
|
-
|
|
73
|
+
## 🛠️ CLI Command Reference
|
|
91
74
|
|
|
92
|
-
|
|
93
|
-
- 10 TB outbound bandwidth/month — more than enough for personal use.
|
|
94
|
-
- Best regions from South/Southeast Asia: India (Hyderabad) ~30ms, Singapore ~50ms, Japan (Tokyo) ~80ms.
|
|
95
|
-
- Sign up at [cloud.oracle.com](https://cloud.oracle.com) (requires a credit card for verification but charges nothing for Always Free resources).
|
|
96
|
-
- After VM creation, just grab the IP and SSH key, and run `polaris start --server ubuntu@<your-oracle-ip>`.
|
|
75
|
+
Prefer the raw CLI? Everything is accessible via commands:
|
|
97
76
|
|
|
98
|
-
|
|
77
|
+
| Command | Description |
|
|
78
|
+
| :--- | :--- |
|
|
79
|
+
| `polaris deploy` | Provision a server with WireGuard or AmneziaWG |
|
|
80
|
+
| `polaris start` | Connect to the VPN and engage the Kill-Switch |
|
|
81
|
+
| `polaris stop` | Disconnect and restore normal internet routing |
|
|
82
|
+
| `polaris dashboard` | Open the TUI Live Monitor directly |
|
|
83
|
+
| `polaris status --full` | Check connection state, GeoIP, and latency |
|
|
84
|
+
| `polaris peer add <name>` | Generate a new peer config for a friend/device |
|
|
85
|
+
| `polaris peer qr <name>` | Display the config as a QR code for mobile apps |
|
|
86
|
+
| `polaris check` | Run a 3-point privacy test (IP, DNS leak, IPv6 leak) |
|
|
99
87
|
|
|
100
|
-
|
|
88
|
+
*(All commands support the `--json` flag for machine-readable output or scripting)*
|
|
101
89
|
|
|
102
|
-
|
|
103
|
-
- YouTube/social (5 Mbps/user): 8–10 people simultaneously.
|
|
104
|
-
- One person owns the VM, others get SSH keys.
|
|
105
|
-
- Or each person creates their own free Oracle account for full isolation.
|
|
90
|
+
## ☁️ The Oracle Cloud Advantage
|
|
106
91
|
|
|
107
|
-
|
|
92
|
+
We highly recommend using the **Oracle Cloud Always Free Tier** to
|
|
93
|
+
host your Polaris server:
|
|
108
94
|
|
|
109
|
-
|
|
95
|
+
- **ARM VM (A1.Flex)**: Up to 4 OCPUs and 24 GB RAM — completely free forever.
|
|
96
|
+
- **10 TB Bandwidth**: More than enough for high-speed streaming and gaming.
|
|
97
|
+
- No third-party VPN company logging your data or selling your traffic.
|
|
98
|
+
You are in total command.
|
|
110
99
|
|
|
111
|
-
## Trust Model
|
|
100
|
+
## 🔒 Trust Model
|
|
112
101
|
|
|
113
|
-
- **You own the server**: No reliance on third-party VPN providers.
|
|
102
|
+
- **You own the server**: No reliance on third-party commercial VPN providers.
|
|
114
103
|
- **Zero telemetry**: No tracking, no crash reporting, no analytics.
|
|
115
|
-
- **
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
## Roadmap
|
|
119
|
-
|
|
120
|
-
- **v0.1**: MVP — SSH SOCKS5 tunnel
|
|
121
|
-
- **v0.5**: WireGuard full tunnel + server provisioning
|
|
122
|
-
- **v0.6**: Windows NT Service bindings + Blessed TUI Dashboard
|
|
123
|
-
- **v0.7**: AmneziaWG stealth mode (DPI bypass)
|
|
124
|
-
- **v1.0**: Multi-peer management + QR codes + Kill switch (Current)
|
|
125
|
-
|
|
126
|
-
## Contributing
|
|
127
|
-
|
|
128
|
-
Contributions, issues, and feature requests are welcome!
|
|
129
|
-
|
|
130
|
-
## License
|
|
104
|
+
- **Local Kill-Switch**: Traffic is strictly locked to the VPN interface to
|
|
105
|
+
prevent IP leaks.
|
|
106
|
+
- **Open Source**: Apache 2.0 licensed, fully auditable codebase.
|
|
131
107
|
|
|
132
|
-
|
|
108
|
+
---
|
|
109
|
+
*Built for developers who value privacy, speed, and beautiful terminal tools.*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polaris-vpn",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Your True North in Digital Privacy. A self-hosted VPN CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -74,5 +74,10 @@
|
|
|
74
74
|
"socks-proxy-agent": "^10.1.0",
|
|
75
75
|
"ssh2": "^1.17.0",
|
|
76
76
|
"update-notifier": "^7.3.1"
|
|
77
|
+
},
|
|
78
|
+
"overrides": {
|
|
79
|
+
"lodash": "^4.18.1",
|
|
80
|
+
"uuid": "^11.1.1",
|
|
81
|
+
"xml2js": "^0.6.2"
|
|
77
82
|
}
|
|
78
83
|
}
|
package/src/commands/check.js
CHANGED
|
@@ -22,12 +22,13 @@ export default async (options) => {
|
|
|
22
22
|
if (spinner) spinner.text = 'Checking IP address...';
|
|
23
23
|
if (info) {
|
|
24
24
|
try {
|
|
25
|
-
const
|
|
25
|
+
const isSystemWide = info.mode === 'wireguard' || info.mode === 'amneziawg';
|
|
26
|
+
const tunnelIp = isSystemWide ? await getPublicIp() : await getProxiedIp(info.port);
|
|
26
27
|
results.ip = true;
|
|
27
28
|
details.ip = `Tunnel active (${(info.mode || 'ssh').toUpperCase()}): ${tunnelIp}`;
|
|
28
29
|
} catch (e) {
|
|
29
30
|
results.ip = false;
|
|
30
|
-
details.ip = `Tunnel
|
|
31
|
+
details.ip = `Tunnel active but IP check failed: ${e.message}`;
|
|
31
32
|
}
|
|
32
33
|
} else {
|
|
33
34
|
const pubIp = await getPublicIp();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import blessed from 'blessed';
|
|
2
2
|
import contrib from 'blessed-contrib';
|
|
3
3
|
import { getActiveTunnel } from '../core/tunnel-service.js';
|
|
4
|
-
import { getProxiedIp } from '../net/ip-check.js';
|
|
4
|
+
import { getProxiedIp, getPublicIp } from '../net/ip-check.js';
|
|
5
5
|
import fetch from 'node-fetch';
|
|
6
6
|
import { spawnSync } from 'child_process';
|
|
7
7
|
import os from 'os';
|
|
@@ -67,8 +67,12 @@ const formatBytes = (bytes) => {
|
|
|
67
67
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
const getWgStats = () => {
|
|
71
|
-
const
|
|
70
|
+
const getWgStats = (isAwg = false) => {
|
|
71
|
+
const cmd = isAwg ? 'awg' : 'wg';
|
|
72
|
+
let dumpRes = spawnSync('sudo', [cmd, 'show', 'all', 'dump'], { encoding: 'utf-8' });
|
|
73
|
+
if (dumpRes.status !== 0 && isAwg) {
|
|
74
|
+
dumpRes = spawnSync('sudo', ['wg', 'show', 'all', 'dump'], { encoding: 'utf-8' });
|
|
75
|
+
}
|
|
72
76
|
if (dumpRes.status !== 0) return null;
|
|
73
77
|
const lines = dumpRes.stdout.trim().split('\n');
|
|
74
78
|
if (lines.length <= 1) return null;
|
|
@@ -201,7 +205,8 @@ export default async () => {
|
|
|
201
205
|
if (!geoFetched) {
|
|
202
206
|
geoFetched = true;
|
|
203
207
|
try {
|
|
204
|
-
|
|
208
|
+
const isSystemWide = info.mode === 'wireguard' || info.mode === 'amneziawg';
|
|
209
|
+
currentIp = isSystemWide ? await getPublicIp() : await getProxiedIp(info.port);
|
|
205
210
|
geoData = await getGeoIp(currentIp);
|
|
206
211
|
if (geoData) {
|
|
207
212
|
mapWidget.addMarker({ lat: geoData.lat, lon: geoData.lon, color: 'red', char: 'X' });
|
|
@@ -227,7 +232,7 @@ export default async () => {
|
|
|
227
232
|
|
|
228
233
|
// 4. Update WG Stats & Chart
|
|
229
234
|
if (info.mode === 'wireguard' || info.mode === 'amneziawg' || info.mode === 'auto') {
|
|
230
|
-
const stats = getWgStats();
|
|
235
|
+
const stats = getWgStats(info.mode === 'amneziawg');
|
|
231
236
|
if (stats) {
|
|
232
237
|
if (!hasInitWg) {
|
|
233
238
|
prevRx = stats.totalRx;
|
package/src/commands/deploy.js
CHANGED
|
@@ -36,7 +36,8 @@ export default async (options) => {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// Automatically trigger local connection
|
|
39
|
-
|
|
39
|
+
const mode = options.mode || 'wireguard';
|
|
40
|
+
await startCommand({ server, mode, json: isJson });
|
|
40
41
|
|
|
41
42
|
} catch (err) {
|
|
42
43
|
if (spinner) spinner.fail('Deployment failed');
|
package/src/commands/monitor.js
CHANGED
|
@@ -49,7 +49,7 @@ export default async (options) => {
|
|
|
49
49
|
const isJson = options.json;
|
|
50
50
|
const info = getActiveTunnel();
|
|
51
51
|
|
|
52
|
-
if (!info || info.mode !== 'wireguard') {
|
|
52
|
+
if (!info || (info.mode !== 'wireguard' && info.mode !== 'amneziawg')) {
|
|
53
53
|
if (isJson) {
|
|
54
54
|
console.log(JSON.stringify({ error: 'WireGuard tunnel is not active' }));
|
|
55
55
|
} else {
|
package/src/commands/start.js
CHANGED
|
@@ -51,8 +51,7 @@ export default async (options) => {
|
|
|
51
51
|
const requestedMode = options.mode || 'auto';
|
|
52
52
|
|
|
53
53
|
if (!server) {
|
|
54
|
-
const active =
|
|
55
|
-
const profiles = config.get('profiles') || {};
|
|
54
|
+
const { profiles, active } = getProfiles();
|
|
56
55
|
|
|
57
56
|
if (active && profiles[active]) {
|
|
58
57
|
server = profiles[active];
|
package/src/commands/status.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getActiveTunnel } from '../core/tunnel-service.js';
|
|
2
|
-
import { getProxiedIp } from '../net/ip-check.js';
|
|
2
|
+
import { getProxiedIp, getPublicIp } from '../net/ip-check.js';
|
|
3
3
|
import { createTable, createSpinner, printError } from '../utils/display.js';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import fetch from 'node-fetch';
|
|
@@ -41,8 +41,12 @@ const formatBytes = (bytes) => {
|
|
|
41
41
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
const getWgStats = () => {
|
|
45
|
-
const
|
|
44
|
+
const getWgStats = (isAwg = false) => {
|
|
45
|
+
const cmd = isAwg ? 'awg' : 'wg';
|
|
46
|
+
let dumpRes = spawnSync('sudo', [cmd, 'show', 'all', 'dump'], { encoding: 'utf-8' });
|
|
47
|
+
if (dumpRes.status !== 0 && isAwg) {
|
|
48
|
+
dumpRes = spawnSync('sudo', ['wg', 'show', 'all', 'dump'], { encoding: 'utf-8' });
|
|
49
|
+
}
|
|
46
50
|
if (dumpRes.status !== 0) return null;
|
|
47
51
|
const lines = dumpRes.stdout.trim().split('\n');
|
|
48
52
|
if (lines.length <= 1) return null;
|
|
@@ -72,10 +76,11 @@ export default async (options) => {
|
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
let currentIp = 'Unknown';
|
|
75
|
-
const
|
|
79
|
+
const isSystemWide = info.mode === 'wireguard' || info.mode === 'amneziawg';
|
|
80
|
+
const spinner = isJson ? null : createSpinner(isSystemWide ? 'Checking public IP...' : 'Checking proxy status...').start();
|
|
76
81
|
|
|
77
82
|
try {
|
|
78
|
-
currentIp = await getProxiedIp(info.port);
|
|
83
|
+
currentIp = isSystemWide ? await getPublicIp() : await getProxiedIp(info.port);
|
|
79
84
|
if (spinner) spinner.stop();
|
|
80
85
|
|
|
81
86
|
let geo = 'N/A';
|
|
@@ -92,8 +97,8 @@ export default async (options) => {
|
|
|
92
97
|
latency = pingServer(serverIp);
|
|
93
98
|
geo = await getGeoIp(currentIp);
|
|
94
99
|
|
|
95
|
-
if (
|
|
96
|
-
const stats = getWgStats();
|
|
100
|
+
if (isSystemWide) {
|
|
101
|
+
const stats = getWgStats(info.mode === 'amneziawg');
|
|
97
102
|
if (stats) {
|
|
98
103
|
dataUsage = `${formatBytes(stats.totalRx)} / ${formatBytes(stats.totalTx)}`;
|
|
99
104
|
}
|
|
@@ -128,8 +133,16 @@ export default async (options) => {
|
|
|
128
133
|
table.push(
|
|
129
134
|
['Status', chalk.green('Connected')],
|
|
130
135
|
['Mode', (info.mode || 'ssh').toUpperCase()],
|
|
131
|
-
['Server', info.server]
|
|
132
|
-
|
|
136
|
+
['Server', info.server]
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
if (isSystemWide) {
|
|
140
|
+
table.push(['Connection', chalk.cyan('System-wide (All OS traffic)')]);
|
|
141
|
+
} else {
|
|
142
|
+
table.push(['Proxy', `socks5://127.0.0.1:${info.port}`]);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
table.push(
|
|
133
146
|
['Current IP', chalk.cyan(currentIp)],
|
|
134
147
|
['Uptime', `${uptimeMin} minutes`],
|
|
135
148
|
['PID', info.pid.toString()]
|
package/src/commands/tui.js
CHANGED
|
@@ -87,8 +87,12 @@ const fmtBytes = (n) => {
|
|
|
87
87
|
return `${(n / Math.pow(k, i)).toFixed(1)} ${s[i]}`;
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
-
const wgStats = () => {
|
|
91
|
-
const
|
|
90
|
+
const wgStats = (isAwg = false) => {
|
|
91
|
+
const cmd = isAwg ? 'awg' : 'wg';
|
|
92
|
+
let r = spawnSync('sudo', [cmd, 'show', 'all', 'dump'], { encoding: 'utf-8' });
|
|
93
|
+
if (r.status !== 0 && isAwg) {
|
|
94
|
+
r = spawnSync('sudo', ['wg', 'show', 'all', 'dump'], { encoding: 'utf-8' });
|
|
95
|
+
}
|
|
92
96
|
if (r.status !== 0) return null;
|
|
93
97
|
const lines = r.stdout.trim().split('\n');
|
|
94
98
|
if (lines.length <= 1) return null;
|
|
@@ -293,7 +297,7 @@ export default async () => {
|
|
|
293
297
|
if (info) {
|
|
294
298
|
const upMin = Math.floor((Date.now() - new Date(info.startTime).getTime()) / 60000);
|
|
295
299
|
const ping = pingServer(info.server.split('@').pop());
|
|
296
|
-
const wg = wgStats();
|
|
300
|
+
const wg = wgStats(info.mode === 'amneziawg');
|
|
297
301
|
L.push(`${t(D.accent, b('◈ Tunnel Status'))} ${t(D.success, '⬤ ACTIVE')}`);
|
|
298
302
|
L.push(hr()); L.push('');
|
|
299
303
|
L.push(` ${mu('Server ')} ${b(info.server)}`);
|
|
@@ -391,7 +395,13 @@ export default async () => {
|
|
|
391
395
|
const renderPeers = () => {
|
|
392
396
|
const L = [];
|
|
393
397
|
L.push(`${t(D.accent, b('≡ WireGuard Peers'))}`); L.push(hr()); L.push('');
|
|
394
|
-
const
|
|
398
|
+
const info = getActiveTunnel();
|
|
399
|
+
const isAwg = info && info.mode === 'amneziawg';
|
|
400
|
+
const cmd = isAwg ? 'awg' : 'wg';
|
|
401
|
+
let r = spawnSync('sudo', [cmd, 'show', 'all', 'dump'], { encoding: 'utf-8' });
|
|
402
|
+
if (r.status !== 0 && isAwg) {
|
|
403
|
+
r = spawnSync('sudo', ['wg', 'show', 'all', 'dump'], { encoding: 'utf-8' });
|
|
404
|
+
}
|
|
395
405
|
if (r.status !== 0 || !r.stdout.trim()) {
|
|
396
406
|
L.push(` ${t(D.warning, '⚠')} No WireGuard interface found.`);
|
|
397
407
|
L.push(` ${mu('Start a WireGuard tunnel first.')}`);
|