@ollamawg/cli 0.2.0 → 0.2.1
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 +118 -43
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,48 +1,76 @@
|
|
|
1
1
|
# ollamawg
|
|
2
2
|
|
|
3
|
-
Reach your Ollama server from
|
|
3
|
+
Reach your Ollama server from your laptop and phone without exposing it to the internet.
|
|
4
4
|
|
|
5
|
-
`ollamawg` puts a WireGuard tunnel in front of Ollama
|
|
5
|
+
`ollamawg` puts a WireGuard tunnel in front of Ollama and adds per-device access control. It gives you a dashboard on the host that shows who is connected, what they run, and who is knocking on the port, and a ChatGPT-style chat page for phones. You can block a device or an IP with one click.
|
|
6
6
|
|
|
7
|
-
It is a single Go binary. WireGuard runs in user space through [wireguard-go](https://git.zx2c4.com/wireguard-go) and gVisor's network stack, so
|
|
7
|
+
It is a single Go binary. WireGuard runs in user space through [wireguard-go](https://git.zx2c4.com/wireguard-go) and gVisor's network stack, so the server needs no root, no kernel module and no TUN device. Computers connect with `ollamawg connect`, which needs no admin rights either. Phones use the official WireGuard app, because the keys and protocol are standard WireGuard.
|
|
8
8
|
|
|
9
|
-

|
|
9
|
+

|
|
10
10
|
|
|
11
11
|
<sub>Screenshot taken with simulated devices and traffic.</sub>
|
|
12
12
|
|
|
13
13
|
## How it works
|
|
14
14
|
|
|
15
15
|
```
|
|
16
|
-
|
|
17
|
-
┌──────────────────────────┐
|
|
18
|
-
│
|
|
16
|
+
devices machine running Ollama
|
|
17
|
+
┌──────────────────────────┐ ┌────────────────────────────────────────────────┐
|
|
18
|
+
│ laptop │ UDP 51820 │ │
|
|
19
|
+
│ app → 127.0.0.1:11434 │ WireGuard │ firewall → WireGuard → proxy → 127.0.0.1:11434 │
|
|
19
20
|
│ ollamawg connect ─┼──(encrypted)──►│ (IP rules) (keys) (roles, Ollama │
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
├──────────────────────────┤ │ models, │
|
|
22
|
+
│ phone │ │ rate, │
|
|
23
|
+
│ browser → 10.77.0.1/chat │ │ log, │
|
|
24
|
+
│ WireGuard app ─┼──(encrypted)──►│ /chat) │
|
|
25
|
+
└──────────────────────────┘ │ dashboard on 127.0.0.1:8088 │
|
|
23
26
|
└────────────────────────────────────────────────┘
|
|
24
27
|
```
|
|
25
28
|
|
|
26
29
|
1. **Firewall.** Every UDP packet hitting the WireGuard port is checked against your IP and CIDR rules before WireGuard sees it. Every source is counted, including scanners that never complete a handshake.
|
|
27
30
|
2. **WireGuard.** Only devices whose public key you registered can complete a handshake. Each device gets one tunnel IP, and WireGuard guarantees that traffic from that IP really comes from that key.
|
|
28
|
-
3. **Proxy.** Inside the tunnel, a reverse proxy enforces each device's role, model allowlist and rate limit. It logs every request with its token counts, then streams the request to Ollama on loopback.
|
|
31
|
+
3. **Proxy.** Inside the tunnel, a reverse proxy enforces each device's role, model allowlist and rate limit. It logs every request with its token counts, then streams the request to Ollama on loopback. It also serves the chat page at `/chat`.
|
|
29
32
|
|
|
30
33
|
Ollama itself stays on `127.0.0.1`. Nothing outside the tunnel can talk to it.
|
|
31
34
|
|
|
32
|
-
##
|
|
35
|
+
## Requirements
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
- **[Ollama](https://ollama.com/download)** on the server, listening on `127.0.0.1:11434`, which is its default. Pull at least one model, for example `ollama pull llama3.2`.
|
|
38
|
+
- **A UDP port that devices can reach.** By default this is 51820.
|
|
39
|
+
- At home, forward UDP 51820 on your router to the server.
|
|
40
|
+
- On a cloud VM, open it in the security group.
|
|
41
|
+
- **Behind CGNAT this won't work as-is.** Many home and mobile ISPs put customers behind carrier-grade NAT, where the router's WAN address is private (`10.x`, `100.64.x`) and no port can be forwarded. You can still:
|
|
42
|
+
- use the server's LAN address as the endpoint, which works for devices on the same network;
|
|
43
|
+
- ask your ISP for a public IP;
|
|
44
|
+
- or relay through a small VPS.
|
|
45
|
+
|
|
46
|
+
See [Troubleshooting](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/getting-started.md#troubleshooting).
|
|
47
|
+
|
|
48
|
+
## Install
|
|
35
49
|
|
|
36
50
|
```sh
|
|
37
|
-
npm install -g @ollamawg/cli
|
|
51
|
+
npm install -g @ollamawg/cli # prebuilt binary for Linux, macOS, Windows and FreeBSD
|
|
52
|
+
npx @ollamawg/cli version # or run it without installing
|
|
38
53
|
go install github.com/himanshu-mamgain/ollamawg/cmd/ollamawg@latest
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Standalone binaries are attached to every [GitHub Release](https://github.com/himanshu-mamgain/ollamawg/releases). A `Dockerfile` is included; see [Running as a service](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/deploy.md#docker).
|
|
57
|
+
|
|
58
|
+
## Quickstart
|
|
59
|
+
|
|
60
|
+
On the machine running Ollama:
|
|
39
61
|
|
|
62
|
+
```sh
|
|
40
63
|
ollamawg init --endpoint your-public-ip-or-dns:51820
|
|
41
|
-
ollamawg add-peer --name laptop
|
|
42
64
|
ollamawg serve
|
|
43
65
|
```
|
|
44
66
|
|
|
45
|
-
`init` prints the dashboard password. Open `http://127.0.0.1:8088` on the server, or reach it over SSH with `ssh -L 8088:127.0.0.1:8088 server`.
|
|
67
|
+
`init` writes `server.yaml` and prints the dashboard password. Open `http://127.0.0.1:8088` on the server, or reach it over SSH with `ssh -L 8088:127.0.0.1:8088 server`.
|
|
68
|
+
|
|
69
|
+
### Add a laptop
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
ollamawg add-peer --name laptop # writes laptop.yaml
|
|
73
|
+
```
|
|
46
74
|
|
|
47
75
|
Copy `laptop.yaml` to the laptop, then run:
|
|
48
76
|
|
|
@@ -51,13 +79,36 @@ ollamawg connect --config laptop.yaml
|
|
|
51
79
|
curl http://127.0.0.1:11434/api/tags # any Ollama client works unchanged
|
|
52
80
|
```
|
|
53
81
|
|
|
54
|
-
|
|
82
|
+
The ollama CLI, Open WebUI, LangChain, Continue and any OpenAI-compatible client pointed at `http://127.0.0.1:11434/v1` go through the tunnel. The chat page is at `http://127.0.0.1:11434/chat`.
|
|
83
|
+
|
|
84
|
+
### Add a phone
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
ollamawg add-peer --name phone --qr # prints a QR code
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
You can also use **Add device** in the dashboard, then **Phone**.
|
|
55
91
|
|
|
56
|
-
|
|
92
|
+
1. In the official WireGuard app ([iOS](https://apps.apple.com/app/wireguard/id1441195209), [Android](https://play.google.com/store/apps/details?id=com.wireguard.android)), tap **+ → Create from QR code** and scan it.
|
|
93
|
+
2. Turn the tunnel on and open **`http://10.77.0.1:11434/chat`**.
|
|
94
|
+
3. Use **Share → Add to Home Screen** to open it like an app.
|
|
95
|
+
|
|
96
|
+
Ollama apps such as Enchanted or Reins work too: point them at `http://10.77.0.1:11434`.
|
|
97
|
+
|
|
98
|
+
<img src="https://raw.githubusercontent.com/himanshu-mamgain/ollamawg/v0.2.1/docs/images/chat.png" alt="The chat page on a phone" width="300">
|
|
99
|
+
|
|
100
|
+
<sub>Chat page on a phone, with a simulated model reply.</sub>
|
|
101
|
+
|
|
102
|
+
See [Getting started](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/getting-started.md) for the full walkthrough.
|
|
57
103
|
|
|
58
104
|
## Features
|
|
59
105
|
|
|
60
|
-
- **Userspace WireGuard** on Linux, macOS, Windows and the BSDs, with no admin rights needed on
|
|
106
|
+
- **Userspace WireGuard** on Linux, macOS, Windows and the BSDs, with no admin rights needed on the server or on computers.
|
|
107
|
+
- **Phones.** Any device with the official WireGuard app connects by scanning a QR code. Only the server's tunnel address is routed through it, so the phone's other traffic is unaffected.
|
|
108
|
+
- **Chat page.** A built-in, mobile-friendly chat interface at `/chat`, served inside the tunnel.
|
|
109
|
+
- Streaming replies, Markdown and code blocks, and a model picker limited to what the device is allowed to use.
|
|
110
|
+
- Chat history kept on the device, and Add to Home Screen.
|
|
111
|
+
- It has no separate login: the device's WireGuard key is its identity, and its policy applies.
|
|
61
112
|
- **Per-device policy:**
|
|
62
113
|
- Roles: `user` for inference, `readonly`, `admin` for pull and delete, or custom path rules.
|
|
63
114
|
- A model allowlist, such as `llama3.2,qwen3:*`.
|
|
@@ -68,52 +119,76 @@ See [Getting started](docs/getting-started.md) for the full walkthrough.
|
|
|
68
119
|
- **Default-deny mode,** which admits only allowlisted networks.
|
|
69
120
|
- **Observability:**
|
|
70
121
|
- Access log with device, public IP, model, status, latency and prompt/generated token counts. It can also be written to a JSON Lines file.
|
|
71
|
-
- Security events: connects, roaming, policy denials, firewall drops and admin actions.
|
|
122
|
+
- Security events: connects, roaming, policy denials, firewall drops, logins and admin actions.
|
|
72
123
|
- Traffic graphs per device for 1, 6 or 24 hours, plus token usage per model.
|
|
73
124
|
- Prometheus `/metrics`.
|
|
74
|
-
- **Dashboard:** add devices
|
|
75
|
-
- **
|
|
76
|
-
- **Two-factor login.** Optionally protect the dashboard with an authenticator app (Google Authenticator, Authy, 1Password, ...). Turn it on from the dashboard or with `ollamawg 2fa enable`.
|
|
125
|
+
- **Dashboard:** add devices (as a config file or a phone QR code), edit policy, block and unblock, and manage firewall rules. It is one embedded page with no CDN, so it works offline.
|
|
126
|
+
- **Two-factor login.** Optionally protect the dashboard with an authenticator app, such as Google Authenticator, Authy or 1Password. Turn it on from the dashboard or with `ollamawg 2fa enable`. Scripts and Prometheus then use an API token.
|
|
77
127
|
- **Hot reload.** `add-peer`, `block` or a hand edit of `server.yaml` applies within 2 seconds without dropping sessions.
|
|
78
128
|
- **Safety checks.** The server warns if Ollama is also reachable outside the tunnel or if the config file is world-readable. Configs are written with mode 0600.
|
|
79
129
|
- **Go library.** You can embed the server, or call Ollama from Go code through the tunnel without opening a local port.
|
|
80
130
|
|
|
131
|
+
## Commands
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
Server
|
|
135
|
+
init create server.yaml with keys and a dashboard password
|
|
136
|
+
add-peer register a device; --qr prints a QR code for the WireGuard app
|
|
137
|
+
remove-peer delete a device
|
|
138
|
+
list-peers show devices and rules
|
|
139
|
+
block block --device or --ip
|
|
140
|
+
unblock undo a block
|
|
141
|
+
serve run the tunnel, proxy, chat page and dashboard
|
|
142
|
+
2fa enable, disable or check two-factor dashboard login
|
|
143
|
+
|
|
144
|
+
Client
|
|
145
|
+
connect bring the tunnel up and expose Ollama on 127.0.0.1:11434
|
|
146
|
+
status check the handshake and this device's policy
|
|
147
|
+
|
|
148
|
+
Other
|
|
149
|
+
keygen print a WireGuard key pair
|
|
150
|
+
version print the version
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Run `ollamawg <command> -h` for a command's flags.
|
|
154
|
+
|
|
81
155
|
## Documentation
|
|
82
156
|
|
|
83
157
|
| Guide | What's in it |
|
|
84
158
|
|---|---|
|
|
85
|
-
| [Getting started](docs/getting-started.md) | Install, set up a server, add
|
|
86
|
-
| [Configuration](docs/configuration.md) | Every field in `server.yaml` and client configs, roles, model rules |
|
|
87
|
-
| [Dashboard and admin API](docs/dashboard.md) | The UI, the HTTP API behind it, Prometheus metrics |
|
|
88
|
-
| [Security model](docs/security.md) | What is protected, how, and what is not |
|
|
89
|
-
| [Running as a service](docs/deploy.md) | systemd, launchd, Windows, Docker, port forwarding |
|
|
90
|
-
| [Go library](docs/library.md) | Embedding the server and client in your own programs |
|
|
159
|
+
| [Getting started](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/getting-started.md) | Install, set up a server, add laptops and phones, connect |
|
|
160
|
+
| [Configuration](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/configuration.md) | Every field in `server.yaml` and client configs, roles, model rules |
|
|
161
|
+
| [Dashboard and admin API](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/dashboard.md) | The UI, two-factor login, the HTTP API behind it, Prometheus metrics |
|
|
162
|
+
| [Security model](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/security.md) | What is protected, how, and what is not |
|
|
163
|
+
| [Running as a service](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/deploy.md) | systemd, launchd, Windows, Docker, port forwarding |
|
|
164
|
+
| [Go library](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/library.md) | Embedding the server and client in your own programs |
|
|
91
165
|
|
|
92
|
-
##
|
|
166
|
+
## Limitations
|
|
93
167
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
remove-peer delete a device
|
|
99
|
-
list-peers show devices and rules Other
|
|
100
|
-
block block --device / --ip keygen print a key pair
|
|
101
|
-
unblock undo a block version
|
|
102
|
-
serve run tunnel, proxy, dashboard
|
|
103
|
-
2fa two-factor dashboard login
|
|
104
|
-
```
|
|
168
|
+
- **Devices need to reach one UDP port on the server.** There is no relay or NAT traversal. CGNAT connections need one of the workarounds in [Requirements](#requirements).
|
|
169
|
+
- **The dashboard has one admin account.** Put a reverse proxy with SSO in front if several people manage it.
|
|
170
|
+
- **Chat history lives in each device's browser.** It is not synced between devices or stored on the server.
|
|
171
|
+
- **No independent security audit yet.** The cryptography comes from wireguard-go and gVisor. The policy layer is small and covered by end-to-end tests. See the [Security model](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/docs/security.md).
|
|
105
172
|
|
|
106
173
|
## Building from source
|
|
107
174
|
|
|
108
175
|
```sh
|
|
109
176
|
git clone https://github.com/himanshu-mamgain/ollamawg && cd ollamawg
|
|
110
|
-
go mod tidy # first time only: records dependency checksums in go.sum
|
|
111
177
|
go test -race ./...
|
|
112
178
|
go build -o ollamawg ./cmd/ollamawg
|
|
113
179
|
```
|
|
114
180
|
|
|
115
181
|
Go 1.24 or newer is required. Cross-compiling works out of the box, for example `GOOS=windows GOARCH=amd64 go build ./cmd/ollamawg`.
|
|
116
182
|
|
|
183
|
+
## Releasing
|
|
184
|
+
|
|
185
|
+
Releases are cut from `main` by [`.github/workflows/publish.yml`](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/.github/workflows/publish.yml):
|
|
186
|
+
|
|
187
|
+
1. In a PR, bump `version` (and its `optionalDependencies`) in `npm/cli/package.json` and `Version` in `server.go`. A test fails if they differ.
|
|
188
|
+
2. Merge the PR. The workflow publishes every npm package that's missing that version, using trusted publishing with provenance, then creates the GitHub Release with binaries.
|
|
189
|
+
|
|
190
|
+
A re-run finishes a release that stopped halfway.
|
|
191
|
+
|
|
117
192
|
## License
|
|
118
193
|
|
|
119
|
-
[MIT](LICENSE)
|
|
194
|
+
[MIT](https://github.com/himanshu-mamgain/ollamawg/blob/v0.2.1/LICENSE)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ollamawg/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Reach your Ollama server from anywhere through a user-space WireGuard tunnel, with per-device access control and a dashboard.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ollama",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"node": ">=16"
|
|
29
29
|
},
|
|
30
30
|
"optionalDependencies": {
|
|
31
|
-
"@ollamawg/darwin-arm64": "0.2.
|
|
32
|
-
"@ollamawg/darwin-x64": "0.2.
|
|
33
|
-
"@ollamawg/freebsd-x64": "0.2.
|
|
34
|
-
"@ollamawg/linux-arm64": "0.2.
|
|
35
|
-
"@ollamawg/linux-x64": "0.2.
|
|
36
|
-
"@ollamawg/win32-x64": "0.2.
|
|
31
|
+
"@ollamawg/darwin-arm64": "0.2.1",
|
|
32
|
+
"@ollamawg/darwin-x64": "0.2.1",
|
|
33
|
+
"@ollamawg/freebsd-x64": "0.2.1",
|
|
34
|
+
"@ollamawg/linux-arm64": "0.2.1",
|
|
35
|
+
"@ollamawg/linux-x64": "0.2.1",
|
|
36
|
+
"@ollamawg/win32-x64": "0.2.1"
|
|
37
37
|
}
|
|
38
38
|
}
|