Skip to content

FarisZR/knocker-cli

Repository files navigation

knocker-cli

knocker-cli is a static Go CLI service that automatically requests a whitelist for the external IP of the device on IP address changes or when the whitelist expires. It runs in the background to ensure you always have access.

Features

  • Automatic IP Whitelisting: Automatically detects IP changes and requests a new whitelist.
  • Background Service: Runs as a background service on Linux, macOS, and Windows.
  • Cross-Platform: Built to be cross-platform with priority for Linux and macOS.
  • Docker Support: Can be run in a Docker container.
  • Manual Whitelisting: Manually trigger a whitelist request at any time.
  • Structured journald events: Emits machine-readable journald events alongside human logs for desktop integrations.

How It Works

knocker-cli operates in two distinct modes for handling IP changes:

When the service starts it immediately performs a scheduled knock before arming its cadence timer, so a restart refreshes the whitelist without waiting for the next interval.

Simple Mode (Default)

This is the default and recommended mode of operation.

  1. The knocker-cli service starts and sends a "knock" request based on the best-known TTL. It begins with the configured TTL and adjusts to the TTL returned by the API response, aiming to refresh the whitelist when roughly 90% of the TTL has elapsed (falling back to a 5-minute cadence if the TTL is unknown or unset).
  2. The service does not check its own IP address.
  3. Your API server receives the "knock" request, inspects the source IP address of the request, and updates its whitelist accordingly.

In this mode, knocker-cli acts as a simple, periodic "pinger" to keep your whitelist entry fresh.

Comparison Mode (Optional)

This mode is for more advanced use cases where you want the client to be responsible for detecting IP changes.

  1. To enable this mode, you must provide an ip_check_url in your configuration. This URL should point to a service that returns the client's public IP in plain text (e.g., https://ifconfig.me).
  2. The knocker-cli service starts and fetches its public IP from the ip_check_url. It stores this IP in memory.
  3. At each check_interval, it fetches the IP again.
  4. It compares the new IP with the one stored in memory.
  5. If the IP address has changed, and only if it has changed, the service will send a "knock" request to your API server to whitelist the new address.

At startup the service logs the calculated cadence along with its source (source: ttl or source: check_interval) so you can confirm which mechanism is driving the schedule.

Installation

From Source

To install from source, you will need to have Go installed.

git clone https://github.com/FarisZR/knocker-cli.git
cd knocker-cli
go install ./...

Using Docker

You can also run Knocker using Docker.

docker build -t knocker-cli .
docker run -d --name knocker-cli -e KNOCKER_API_URL=... -e KNOCKER_API_KEY=... knocker-cli

Configuration

Knocker can be configured via a configuration file or environment variables.

Configuration File

Create a file named .knocker.yaml in your home directory with the following content:

api_url: "http://your-knocker-api-url"
api_key: "your-api-key"
check_interval: 5 # The interval in minutes to poll for IP changes when ip_check_url is set.
ip_check_url: "" # optional, e.g. "https://ifconfig.me"
ttl: 0 # optional, time to live in seconds for the knock request (0 for server default)

Environment Variables

You can also configure knocker-cli using environment variables:

  • KNOCKER_API_URL: The URL of the Knocker API.
  • KNOCKER_API_KEY: Your API key.
  • KNOCKER_CHECK_INTERVAL: The interval in minutes to poll for IP changes when ip_check_url is set.
  • KNOCKER_IP_CHECK_URL: Optional URL of the external IP checker service.
  • KNOCKER_TTL: Optional time to live in seconds for the knock request (0 for server default).

When running as the packaged systemd user service, these variables can be placed in ~/.config/knocker/env using the standard KEY=value format.

When ip_check_url is unset, the service automatically schedules knocks so that roughly 10% of the TTL remains before expiry. It starts with the configured TTL but updates the cadence whenever the API returns a TTL, falling back to a 5-minute cadence only when no TTL is known. When ip_check_url is provided, the check_interval controls how frequently the client polls for IP changes and only knocks when the IP actually changes.

Structured journald events

When the service runs under systemd (for example as knocker.service), every operational log is mirrored to journald with a human-friendly MESSAGE and a stable set of KNOCKER_* fields. These events let desktop integrations such as GNOME shell extensions consume Knocker state without polling a separate API.

  • Stream the events: journalctl --user -u knocker.service -o json -f | jq 'select(.KNOCKER_EVENT != null)' to follow only structured entries, or pin to a specific type with KNOCKER_EVENT=StatusSnapshot as needed (journalctl only supports FIELD=value comparisons per its manual).
  • Schema version: All entries include KNOCKER_SCHEMA_VERSION=1 for forward compatibility.
  • Event types:
    • ServiceState — lifecycle notifications (started, stopping, stopped) with optional KNOCKER_VERSION.
    • StatusSnapshot — current whitelist, TTL, and next scheduled knock.
    • WhitelistApplied / WhitelistExpired — whitelist changes with expiry metadata.
    • NextKnockUpdated — upcoming knock timestamp (or 0 when cleared).
    • KnockTriggered — manual (cli) and scheduled (schedule) knocks with success/failure result.
    • Error — surfaced issues that should be shown in the UI.

Manual invocations of knocker knock produce the same KnockTriggered and WhitelistApplied events so external consumers stay in sync even when the background service is idle.

Usage

Run as a foreground process

knocker run

Manually trigger a whitelist

Even if the background service is running, you can manually trigger a whitelist request at any time.

knocker knock

Install as a service

knocker install

Note: On Linux the installer registers a per-user systemd unit at ~/.config/systemd/user/knocker.service. Start it immediately with systemctl --user enable --now knocker. On macOS the installer writes ~/Library/LaunchAgents/knocker.plist; load it with launchctl bootstrap gui/$UID ~/Library/LaunchAgents/knocker.plist.

Start the installed service

knocker start

Stop the running service

knocker stop

Uninstall the service

knocker uninstall

Check service status

knocker status

Development

Building

To build the binary for your current platform, run:

go build -o knocker ./cmd/knocker

Cross-Platform Releases (with GoReleaser)

To create cross-platform builds, archives, and releases, you can use GoReleaser.

# This will create builds for all platforms defined in .goreleaser.yml
goreleaser release --snapshot --clean

About

knocker cli client.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors 3

  •  
  •  
  •