Automate your Keenetic (Netcraze) router management with ease
1729780892144387.mp4
Tired of clicking through Keenetic (Netcraze) web interface? Automate your Keenetic (Netcraze) router management with simple CLI commands.
π Quick Start β’ π Documentation β’ π Config Reference β’ π¨ GUI Version β’ π€ Contributing
gokeenapi is a CLI tool for automating Keenetic (Netcraze) router management. It handles routes, DNS records, DNS-routing, WireGuard connections, known hosts, and scheduled tasks β all via a YAML config file, with no changes required on the router side. Works over LAN or remotely via KeenDNS.
The easiest way to get started is by using Docker or by downloading the latest release.
Using Docker is the recommended way to run gokeenapi.
Two image tags are available on Docker Hub:
| Tag | Description |
|---|---|
stable |
Latest stable release (updated on every release) |
1.7.0, 1.7.1, β¦ |
Pinned version tag β available starting from v1.7.0 |
# Pull the latest stable image
export GOKEENAPI_IMAGE="noksa/gokeenapi:stable"
# Or pin to a specific version (available since v1.7.0)
# export GOKEENAPI_IMAGE="noksa/gokeenapi:1.7.0"
docker pull "${GOKEENAPI_IMAGE}"
# Run a command
docker run --rm -ti -v "$(pwd)/config_example.yaml":/gokeenapi/config.yaml \
"${GOKEENAPI_IMAGE}" show-interfaces --config /gokeenapi/config.yamlDownload the latest release for your platform:
gokeenapi is configured using a yaml file. You can find an example here. For a complete description of every field, see the Config Reference.
To use your configuration file, pass the --config <path> flag with your command.
When managing multiple routers with the same routing configuration, you can create a shared YAML file containing bat-file paths, bat-url paths, or both, and reference it across multiple configs.
batfiles/common.yaml:
bat-file:
- /path/to/discord.bat
- /path/to/youtube.bat
bat-url:
- https://example.com/instagram.bat
- https://example.com/extra.batRouter config:
routes:
- interfaceId: Wireguard0
bat-file:
- batfiles/common.yaml # Expanded: only bat-file entries are used
- /path/to/router-specific.bat # Can mix with regular paths
bat-url:
- batfiles/common.yaml # Expanded: only bat-url entries are used
- https://example.com/other.batThe tool automatically detects .yaml/.yml files in the bat-file and bat-url arrays and expands them to their respective list entries. When a YAML file is referenced in bat-file, only its bat-file list is used; when referenced in bat-url, only its bat-url list is used. Relative paths in YAML list files are resolved relative to the YAML file's directory.
All configuration options can be set via environment variables:
| Variable | Description |
|---|---|
GOKEENAPI_CONFIG |
Path to config file (alternative to --config) |
GOKEENAPI_KEENETIC_LOGIN |
Router admin login |
GOKEENAPI_KEENETIC_PASSWORD |
Router admin password |
GOKEENAPI_INSIDE_DOCKER |
When set, uses /etc/gokeenapi as the data directory |
GOKEENAPI_KEENETIC_LOGIN and GOKEENAPI_KEENETIC_PASSWORD are particularly useful for keeping sensitive credentials out of config files. GOKEENAPI_INSIDE_DOCKER is set automatically in the official Docker image.
Security recommendation: Store credentials using environment variables instead of writing them directly into the config file. Config files stored with world-readable permissions (e.g.
0644) will trigger a runtime warning. Restrict permissions withchmod 600 config.yamland useGOKEENAPI_KEENETIC_LOGIN/GOKEENAPI_KEENETIC_PASSWORDto pass credentials. Addconfig.yamlandconfig_*.yamlto your.gitignoreto prevent accidental commits (the project's default.gitignorealready includes these patterns).
When connecting to a router over HTTPS with a self-signed certificate, set tls_skip_verify: true under the keenetic key:
keenetic:
url: https://192.168.1.1
login: admin
password: secret
tls_skip_verify: true # Disable TLS verification for self-signed certificatesNote: Only use
tls_skip_verifyon trusted local networks. Disabling certificate verification exposes the connection to man-in-the-middle attacks.
For the complete reference of all config.yaml fields, see docs/config-reference.md.
See also config_example.yaml for a fully annotated example.
gokeenapi has been tested with the following Keenetic (Netcraze) router models:
- Keenetic (Netcraze) Start
- Keenetic (Netcraze) Viva
- Keenetic (Netcraze) Giga
Since the utility works with Keenetic (Netcraze) Start (the most affordable model in the lineup), it should be compatible with all Keenetic (Netcraze) router models.
Check out these video demonstrations (in Russian) to see gokeenapi in action:
The scheduler allows you to automate router management by running tasks at specified intervals or fixed times. This is perfect for keeping routes and DNS records up-to-date automatically.
- Interval-based execution: Run tasks every N hours/minutes (e.g., every 3 hours)
- Time-based execution: Run tasks at specific times (e.g., at 02:00, 06:00, 12:00)
- Command chaining: Execute multiple commands sequentially (e.g., delete-routes β add-routes)
- Multi-router support: Manage multiple routers with a single task
- Retry mechanism: Automatically retry failed tasks with configurable delay
- Sequential execution: Tasks run in a queue to avoid conflicts
# Run scheduler with config
./gokeenapi scheduler --config scheduler.yamltasks:
- name: "Update routes every 3 hours"
commands:
- add-routes
configs:
- /path/to/router1.yaml
- /path/to/router2.yaml
- /path/to/router3.yaml
interval: "3h"
- name: "Refresh routes daily with retry"
commands:
- delete-routes
- add-routes
configs:
- /path/to/router1.yaml
times:
- "02:00"
retry: 3 # Retry up to 3 times on failure
retryDelay: "30s" # Wait 30 seconds between retriesπ Read full Scheduler documentation β
See also: scheduler_example.yaml
Here are some of the things you can do with gokeenapi. For a full list of commands and options, use the --help flag.
./gokeenapi --helpAliases: showinterfaces, si, showinterface, show-interface
Displays all available interfaces on your Keenetic (Netcraze) router.
# Show all interfaces
./gokeenapi show-interfaces --config my_config.yaml
# Show only WireGuard interfaces
./gokeenapi show-interfaces --config my_config.yaml --type WireguardAliases: addroutes, ar
Adds static routes to your router.
./gokeenapi add-routes --config my_config.yamlAliases: deleteroutes, dr
Deletes static routes for a specific interface.
# Delete routes for all interfaces in the config file
./gokeenapi delete-routes --config my_config.yaml
# Delete routes for a specific interface
./gokeenapi delete-routes --config my_config.yaml --interface-id <your-interface-id>
# Delete routes without confirmation prompt
./gokeenapi delete-routes --config my_config.yaml --forceTip: To find interface IDs, run
show-interfaces.
Aliases: deleteallroutes, dar
Deletes all static routes from the router in a single request, regardless of interface.
# Delete all routes (with confirmation prompt)
./gokeenapi delete-all-routes --config my_config.yaml
# Delete all routes without confirmation
./gokeenapi delete-all-routes --config my_config.yaml --forceWarning: This removes every user-defined static route on the router at once. Use with caution.
Aliases: adddnsrecords, adr
Adds static DNS records.
./gokeenapi add-dns-records --config my_config.yamlAliases: deletednsrecords, ddr
Deletes static DNS records based on your configuration file.
./gokeenapi delete-dns-records --config my_config.yamlAliases: adddnsrouting, adnsr, adddnsroutes, add-dns-routes
Adds DNS-routing rules (policy-based routing by domain) to your router. This feature allows you to route traffic for specific domains through designated network interfaces.
Requirements: Keenetic firmware version 5.0.1 or higher
./gokeenapi add-dns-routing --config my_config.yamlHow it works:
- Loads domains from local .txt files and remote URLs
- Creates domain groups (object-groups) containing your specified domains and IP addresses
- Associates each group with a network interface via dns-proxy routes
- Traffic for domains in a group is automatically routed through the specified interface
Domain sources:
- Local .txt files with one domain per line (supports comments with #)
- Remote URLs serving domain lists
- YAML files containing lists of domain-file or domain-url paths (for organization)
YAML expansion: The tool automatically detects .yaml/.yml files in the domain-file and domain-url arrays and expands them to their contained domain paths (similar to bat-file/bat-url expansion).
Key rule: when a
.yamlfile is referenced indomain-file, only itsdomain-filelist is extracted; when referenced indomain-url, only itsdomain-urllist is extracted. To use both files and remote URLs from a single YAML manifest, reference it in both keys:# domains/social.yaml domain-file: - social.txt # local domains domain-url: - https://example.com/social-extra.txt # remote domains# Router config group - name: social domain-file: - domains/social.yaml # extracts domain-file list β social.txt domain-url: - domains/social.yaml # extracts domain-url list β remote URL interfaceId: Wireguard0If you reference the YAML only in
domain-file, the remote URLs inside it are silently ignored β and vice versa.
NEW: Reusable DNS Routing Groups
You can now create shared YAML files containing complete DNS routing group definitions and import them across multiple router configs. This is different from domain-file/domain-url expansion - you're importing entire group definitions, not just domain lists.
custom/common_dns_groups.yaml:
groups:
- name: youtube
domain-url:
- domains/youtube.yaml
interfaceId: Wireguard0
- name: telegram
domain-url:
- domains/telegram.yaml
interfaceId: Wireguard0
- name: trackers
domain-file:
- domains/trackers.yaml
interfaceId: Wireguard0Router config:
dns:
routes:
groups:
- common_dns_groups.yaml # Import all groups from file
- name: router-specific # Mix with router-specific groups
domain-file:
- domains/local.txt
interfaceId: GigabitEthernet0This allows you to maintain common DNS routing rules in one place and share them across all your routers. When you add telegram to one router, just update common_dns_groups.yaml and all routers using it will get the update.
There are two ways to import a shared groups file:
groups:
# Simple string β import all groups as-is
- common_dns_groups.yaml
# Object with file: key β same import, but with interfaceId override
# All groups from the file will use Wireguard1 instead of their original interface
- file: common_dns_groups.yaml
interfaceId: Wireguard1The file: + interfaceId form is useful when the same common groups file is shared across routers that use different WireGuard interfaces (e.g., Wireguard0 on one router, Wireguard1 on another) β you define interface names once per router config rather than duplicating the entire groups file.
Example use cases:
- Route social media traffic through a VPN (Wireguard0)
- Route streaming services through a different connection
- Split traffic by domain for load balancing or privacy
- Use community-maintained domain lists from URLs
Aliases: deletednsrouting, ddnsr, deletednsroutes, delete-dns-routes
Deletes DNS-routing rules that match your configuration file.
# Delete DNS-routing rules with confirmation prompt
./gokeenapi delete-dns-routing --config my_config.yaml
# Delete DNS-routing rules without confirmation prompt
./gokeenapi delete-dns-routing --config my_config.yaml --forceThe command will:
- Identify dns-proxy routes and object-groups matching your configuration
- Display the rules to be deleted
- Request confirmation (unless
--forceflag is used) - Remove dns-proxy routes first, then object-groups
Aliases: deletealldnsrouting, dadnsr
Deletes all DNS-routing groups from the router in a single operation, regardless of what is defined in the config file. Useful for fully resetting DNS-routing before re-applying a new or updated configuration.
# Delete all DNS-routing groups (with confirmation prompt)
./gokeenapi delete-all-dns-routing --config my_config.yaml
# Delete all DNS-routing groups without confirmation
./gokeenapi delete-all-dns-routing --config my_config.yaml --forceWarning: This removes every DNS-routing group on the router. Use before re-applying after renaming or reorganising groups.
Requirements: Keenetic firmware version 5.0.1 or higher
Aliases: addawg, aawg
Adds a new WireGuard connection from a .conf file.
./gokeenapi add-awg --config my_config.yaml --conf-file <path-to-conf> --name MySuperInterfaceAliases: updateawg, uawg
Updates an existing WireGuard connection from a .conf file. Supports AmneziaWG (AWG 2.0) parameters.
./gokeenapi update-awg --config my_config.yaml --conf-file <path-to-conf> --interface-id <interface-id>
# Preview changes without applying them
./gokeenapi update-awg --config my_config.yaml --conf-file <path-to-conf> --interface-id <interface-id> --dry-runTip: To find interface IDs, run
show-interfaces. Use--dry-runto see a unified diff of what would change before applying.
Aliases: deleteknownhosts, dkh
Deletes known hosts by name or MAC using regex pattern.
# Delete hosts by name pattern
./gokeenapi delete-known-hosts --config my_config.yaml --name-pattern "pattern"
# Delete hosts by MAC pattern
./gokeenapi delete-known-hosts --config my_config.yaml --mac-pattern "pattern"
# Delete hosts without confirmation prompt
./gokeenapi delete-known-hosts --config my_config.yaml --name-pattern "pattern" --forceAliases: schedule, sched
Runs automated tasks at specified intervals or fixed times. See Scheduler documentation for the full configuration reference.
./gokeenapi scheduler --config scheduler.yamlAliases: e
Execute custom Keenetic (Netcraze) CLI commands directly on your router.
# Show system information
./gokeenapi exec --config my_config.yaml show version
# Display interface statistics
./gokeenapi exec --config my_config.yaml show interface
# Show routing table
./gokeenapi exec --config my_config.yaml show ip routeContributions are welcome! If you have any ideas, suggestions, or bug reports, please open an issue or create a pull request.
This project is licensed under the MIT License. See the LICENSE file for details.