mirror of
https://github.com/fosrl/olm.git
synced 2025-12-05 19:17:35 -06:00
305 lines
9.2 KiB
Markdown
305 lines
9.2 KiB
Markdown
# Olm
|
|
|
|
Olm is a [WireGuard](https://www.wireguard.com/) tunnel client designed to securely connect your computer to Newt sites running on remote networks.
|
|
|
|
### Installation and Documentation
|
|
|
|
Olm is used with Pangolin and Newt as part of the larger system. See documentation below:
|
|
|
|
- [Full Documentation](https://docs.pangolin.net)
|
|
|
|
## Key Functions
|
|
|
|
### Registers with Pangolin
|
|
|
|
Using the Olm ID and a secret, the olm will make HTTP requests to Pangolin to receive a session token. Using that token, it will connect to a websocket and maintain that connection. Control messages will be sent over the websocket.
|
|
|
|
### Receives WireGuard Control Messages
|
|
|
|
When Olm receives WireGuard control messages, it will use the information encoded (endpoint, public key) to bring up a WireGuard tunnel on your computer to a remote Newt. It will ping over the tunnel to ensure the peer is brought up.
|
|
|
|
## CLI Args
|
|
|
|
- `endpoint`: The endpoint where both Gerbil and Pangolin reside in order to connect to the websocket.
|
|
- `id`: Olm ID generated by Pangolin to identify the olm.
|
|
- `secret`: A unique secret (not shared and kept private) used to authenticate the olm ID with the websocket in order to receive commands.
|
|
- `mtu` (optional): MTU for the internal WG interface. Default: 1280
|
|
- `dns` (optional): DNS server to use to resolve the endpoint. Default: 8.8.8.8
|
|
- `log-level` (optional): The log level to use (DEBUG, INFO, WARN, ERROR, FATAL). Default: INFO
|
|
- `ping-interval` (optional): Interval for pinging the server. Default: 3s
|
|
- `ping-timeout` (optional): Timeout for each ping. Default: 5s
|
|
- `interface` (optional): Name of the WireGuard interface. Default: olm
|
|
- `enable-http` (optional): Enable HTTP server for receiving connection requests. Default: false
|
|
- `http-addr` (optional): HTTP server address (e.g., ':9452'). Default: :9452
|
|
- `holepunch` (optional): Enable hole punching. Default: false
|
|
|
|
## Environment Variables
|
|
|
|
All CLI arguments can also be set via environment variables:
|
|
|
|
- `PANGOLIN_ENDPOINT`: Equivalent to `--endpoint`
|
|
- `OLM_ID`: Equivalent to `--id`
|
|
- `OLM_SECRET`: Equivalent to `--secret`
|
|
- `MTU`: Equivalent to `--mtu`
|
|
- `DNS`: Equivalent to `--dns`
|
|
- `LOG_LEVEL`: Equivalent to `--log-level`
|
|
- `INTERFACE`: Equivalent to `--interface`
|
|
- `HTTP_ADDR`: Equivalent to `--http-addr`
|
|
- `PING_INTERVAL`: Equivalent to `--ping-interval`
|
|
- `PING_TIMEOUT`: Equivalent to `--ping-timeout`
|
|
- `HOLEPUNCH`: Set to "true" to enable hole punching (equivalent to `--holepunch`)
|
|
- `CONFIG_FILE`: Set to the location of a JSON file to load secret values
|
|
|
|
Examples:
|
|
|
|
```bash
|
|
olm \
|
|
--id 31frd0uzbjvp721 \
|
|
--secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6 \
|
|
--endpoint https://example.com
|
|
```
|
|
|
|
You can also run it with Docker compose. For example, a service in your `docker-compose.yml` might look like this using environment vars (recommended):
|
|
|
|
```yaml
|
|
services:
|
|
olm:
|
|
image: fosrl/olm
|
|
container_name: olm
|
|
restart: unless-stopped
|
|
network_mode: host
|
|
devices:
|
|
- /dev/net/tun:/dev/net/tun
|
|
environment:
|
|
- PANGOLIN_ENDPOINT=https://example.com
|
|
- OLM_ID=31frd0uzbjvp721
|
|
- OLM_SECRET=h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6
|
|
```
|
|
|
|
You can also pass the CLI args to the container:
|
|
|
|
```yaml
|
|
services:
|
|
olm:
|
|
image: fosrl/olm
|
|
container_name: olm
|
|
restart: unless-stopped
|
|
network_mode: host
|
|
devices:
|
|
- /dev/net/tun:/dev/net/tun
|
|
command:
|
|
- --id 31frd0uzbjvp721
|
|
- --secret h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6
|
|
- --endpoint https://example.com
|
|
```
|
|
|
|
**Docker Configuration Notes:**
|
|
|
|
- `network_mode: host` brings the olm network interface to the host system, allowing the WireGuard tunnel to function properly
|
|
- `devices: - /dev/net/tun:/dev/net/tun` is required to give the container access to the TUN device for creating WireGuard interfaces
|
|
|
|
## Loading secrets from files
|
|
|
|
You can use `CONFIG_FILE` to define a location of a config file to store the credentials between runs.
|
|
|
|
```
|
|
$ cat ~/.config/olm-client/config.json
|
|
{
|
|
"id": "spmzu8rbpzj1qq6",
|
|
"secret": "f6v61mjutwme2kkydbw3fjo227zl60a2tsf5psw9r25hgae3",
|
|
"endpoint": "https://app.pangolin.net",
|
|
"tlsClientCert": ""
|
|
}
|
|
```
|
|
|
|
This file is also written to when newt first starts up. So you do not need to run every time with --id and secret if you have run it once!
|
|
|
|
Default locations:
|
|
|
|
- **macOS**: `~/Library/Application Support/olm-client/config.json`
|
|
- **Windows**: `%PROGRAMDATA%\olm\olm-client\config.json`
|
|
- **Linux/Others**: `~/.config/olm-client/config.json`
|
|
|
|
## Hole Punching
|
|
|
|
In the default mode, olm "relays" traffic through Gerbil in the cloud to get down to newt. This is a little more reliable. Support for NAT hole punching is also EXPERIMENTAL right now using the `--holepunch` flag. This will attempt to orchestrate a NAT hole punch between the two sites so that traffic flows directly. This will save data costs and speed. If it fails it should fall back to relaying.
|
|
|
|
Right now, basic NAT hole punching is supported. We plan to add:
|
|
|
|
- [ ] Birthday paradox
|
|
- [ ] UPnP
|
|
- [ ] LAN detection
|
|
|
|
## Windows Service
|
|
|
|
On Windows, olm has to be installed and run as a Windows service. When running it with the cli args live above it will attempt to install and run the service to function like a cli tool. You can also run the following:
|
|
|
|
### Service Management Commands
|
|
|
|
```
|
|
# Install the service
|
|
olm.exe install
|
|
|
|
# Start the service
|
|
olm.exe start
|
|
|
|
# Stop the service
|
|
olm.exe stop
|
|
|
|
# Check service status
|
|
olm.exe status
|
|
|
|
# Remove the service
|
|
olm.exe remove
|
|
|
|
# Run in debug mode (console output) with our without id & secret
|
|
olm.exe debug
|
|
|
|
# Show help
|
|
olm.exe help
|
|
```
|
|
|
|
Note running the service requires credentials in `%PROGRAMDATA%\olm\olm-client\config.json`.
|
|
|
|
### Service Configuration
|
|
|
|
When running as a service, Olm will read configuration from environment variables or you can modify the service to include command-line arguments:
|
|
|
|
1. Install the service: `olm.exe install`
|
|
2. Set the credentials in `%PROGRAMDATA%\olm\olm-client\config.json`. Hint: if you run olm once with --id and --secret this file will be populated!
|
|
3. Start the service: `olm.exe start`
|
|
|
|
### Service Logs
|
|
|
|
When running as a service, logs are written to:
|
|
|
|
- Windows Event Log (Application log, source: "OlmWireguardService")
|
|
- Log files in: `%PROGRAMDATA%\olm\logs\olm.log`
|
|
|
|
You can view the Windows Event Log using Event Viewer or PowerShell:
|
|
|
|
```powershell
|
|
Get-EventLog -LogName Application -Source "OlmWireguardService" -Newest 10
|
|
```
|
|
|
|
## HTTP Endpoints
|
|
|
|
Olm can be controlled with an embedded http server when using `--enable-http`. This allows you to start it as a daemon and trigger it with the following endpoints:
|
|
|
|
### POST /connect
|
|
Initiates a new connection request.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"id": "string",
|
|
"secret": "string",
|
|
"endpoint": "string"
|
|
}
|
|
```
|
|
|
|
**Required Fields:**
|
|
- `id`: Connection identifier
|
|
- `secret`: Authentication secret
|
|
- `endpoint`: Target endpoint URL
|
|
|
|
**Response:**
|
|
- **Status Code:** `202 Accepted`
|
|
- **Content-Type:** `application/json`
|
|
|
|
```json
|
|
{
|
|
"status": "connection request accepted"
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
- `405 Method Not Allowed` - Non-POST requests
|
|
- `400 Bad Request` - Invalid JSON or missing required fields
|
|
|
|
### GET /status
|
|
Returns the current connection status and peer information.
|
|
|
|
**Response:**
|
|
- **Status Code:** `200 OK`
|
|
- **Content-Type:** `application/json`
|
|
|
|
```json
|
|
{
|
|
"status": "connected",
|
|
"connected": true,
|
|
"tunnelIP": "100.89.128.3/20",
|
|
"version": "version_replaceme",
|
|
"peers": {
|
|
"10": {
|
|
"siteId": 10,
|
|
"connected": true,
|
|
"rtt": 145338339,
|
|
"lastSeen": "2025-08-13T14:39:17.208334428-07:00",
|
|
"endpoint": "p.fosrl.io:21820",
|
|
"isRelay": true
|
|
},
|
|
"8": {
|
|
"siteId": 8,
|
|
"connected": false,
|
|
"rtt": 0,
|
|
"lastSeen": "2025-08-13T14:39:19.663823645-07:00",
|
|
"endpoint": "p.fosrl.io:21820",
|
|
"isRelay": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Fields:**
|
|
- `status`: Overall connection status ("connected" or "disconnected")
|
|
- `connected`: Boolean connection state
|
|
- `tunnelIP`: IP address and subnet of the tunnel (when connected)
|
|
- `version`: Olm version string
|
|
- `peers`: Map of peer statuses by site ID
|
|
- `siteId`: Peer site identifier
|
|
- `connected`: Boolean peer connection state
|
|
- `rtt`: Peer round-trip time (integer, nanoseconds)
|
|
- `lastSeen`: Last time peer was seen (RFC3339 timestamp)
|
|
- `endpoint`: Peer endpoint address
|
|
- `isRelay`: Whether the peer is relayed (true) or direct (false)
|
|
|
|
**Error Responses:**
|
|
- `405 Method Not Allowed` - Non-GET requests
|
|
|
|
## Usage Examples
|
|
|
|
### Connect to a peer
|
|
```bash
|
|
curl -X POST http://localhost:8080/connect \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"id": "31frd0uzbjvp721",
|
|
"secret": "h51mmlknrvrwv8s4r1i210azhumt6isgbpyavxodibx1k2d6",
|
|
"endpoint": "https://example.com"
|
|
}'
|
|
```
|
|
|
|
### Check connection status
|
|
```bash
|
|
curl http://localhost:8080/status
|
|
```
|
|
|
|
## Build
|
|
|
|
### Binary
|
|
|
|
Make sure to have Go 1.23.1 installed.
|
|
|
|
```bash
|
|
make local
|
|
```
|
|
|
|
## Licensing
|
|
|
|
Olm is dual licensed under the AGPLv3 and the Fossorial Commercial license. For inquiries about commercial licensing, please contact us.
|
|
|
|
## Contributions
|
|
|
|
Please see [CONTRIBUTIONS](./CONTRIBUTING.md) in the repository for guidelines and best practices.
|