### QEMU CHR TZSP Example Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-sniffer/references/tzsp-receivers.md End-to-end example demonstrating TZSP setup with QEMU user-mode networking. It involves starting a tshark listener, configuring the CHR via REST API, and generating traffic. ```sh # Terminal 1: Start tshark listener tshark -i any -f "udp port 37008" ``` ```sh # Terminal 2: Configure CHR via REST API curl -u admin: -X POST http:///rest/tool/sniffer/set \ -H 'Content-Type: application/json' \ -d '{"streaming-enabled":"yes","streaming-server":"10.0.2.2:37008"}' curl -u admin: -X POST http:///rest/tool/sniffer/start ``` ```sh # Terminal 2: Generate traffic curl -u admin: -X POST http:///rest/ping \ -H 'Content-Type: application/json' \ -d '{"address":"8.8.8.8","count":"5"}' ``` -------------------------------- ### Download and Run Netinstall CLI on Linux Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-netinstall/SKILL.md Example of downloading the netinstall-cli tarball, extracting it, and running the netinstall-cli command to install RouterOS packages. ```sh wget https://download.mikrotik.com/routeros/7.22/netinstall-7.22.tar.gz tar -xzf netinstall-7.22.tar.gz sudo ./netinstall-cli -r -i eth0 \ routeros-7.22-arm64.npk \ container-7.22-arm64.npk ``` -------------------------------- ### Netinstall with Persistent Setup Script Source: https://context7.com/tikoci/routeros-skills/llms.txt This command installs RouterOS and applies a persistent setup script that survives upgrades and replaces the default configuration stage. This script runs after the mode script and persists even after a '/system reset-configuration'. ```bash # Configure script (-s): persistent, survives upgrades, replaces default-config stage # Runs AFTER mode script; survives /system reset-configuration sudo ./netinstall-cli -r -s setup.rsc -i eth0 routeros-7.22-arm64.npk ``` -------------------------------- ### Complete DHCP Server Setup Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-networking-rest.md This comprehensive snippet illustrates the complete process of setting up a DHCP server, including prerequisite IP address configuration, IP pool creation, network setup, and server creation. ```APIDOC ## Complete DHCP Server Setup ### Description This sequence of API calls sets up a fully functional DHCP server, including the necessary IP address, IP pool, network, and server configurations. ### Steps 1. **Configure IP Address on Interface** ```bash curl -s -u admin: http://127.0.0.1:9100/rest/ip/address \ -X PUT -H "Content-Type: application/json" \ -d '{"address":"192.168.1.1/24","interface":"ether2"}' ``` 2. **Create IP Pool** ```bash curl -s -u admin: http://127.0.0.1:9100/rest/ip/pool \ -X PUT -H "Content-Type: application/json" \ -d '{"name":"dhcp-pool","ranges":"192.168.1.100-192.168.1.200"}' ``` 3. **Create DHCP Server Network** ```bash curl -s -u admin: http://127.0.0.1:9100/rest/ip/dhcp-server/network \ -X PUT -H "Content-Type: application/json" \ -d '{"address":"192.168.1.0/24","gateway":"192.168.1.1","dns-server":"8.8.8.8"}' ``` 4. **Create DHCP Server** ```bash curl -s -u admin: http://127.0.0.1:9100/rest/ip/dhcp-server \ -X PUT -H "Content-Type: application/json" \ -d '{"name":"dhcp1","interface":"ether2","address-pool":"dhcp-pool","lease-time":"1h","disabled":"no"}' ``` ``` -------------------------------- ### Quick Network Setup Sequence Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-networking-rest.md A sequence of REST API calls for a basic network setup: finding interfaces, assigning IPs, adding routes, and configuring DNS. ```bash 1. GET /rest/interface → find available interfaces 2. PUT /rest/ip/address {address, interface} → assign IP 3. PUT /rest/ip/route {dst-address, gateway} → add default route (if no DHCP) 4. POST /rest/ip/dns/set {servers} → configure DNS ``` -------------------------------- ### Download and Install RouterOS Packages Source: https://context7.com/tikoci/routeros-skills/llms.txt These commands demonstrate downloading the netinstall tool and RouterOS packages, then performing a reinstall with default configuration. Ensure the system package is listed first for a successful installation. ```bash # Download netinstall tool and packages wget https://download.mikrotik.com/routeros/7.22/netinstall-7.22.tar.gz tar -xzf netinstall-7.22.tar.gz wget https://download.mikrotik.com/routeros/7.22/routeros-7.22-arm64.npk wget https://download.mikrotik.com/routeros/7.22/container-7.22-arm64.npk # Reinstall with default config (system package MUST be listed first) sudo ./netinstall-cli -r -i eth0 \ routeros-7.22-arm64.npk \ container-7.22-arm64.npk ``` -------------------------------- ### Add SSH Key for User (CLI Example) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-users-rest.md This is an example of adding an SSH public key for a specific user via the RouterOS command line. It's recommended to use the serial console for initial installation as it commits synchronously. ```bash /user/ssh-keys/add user="quickchr" key="ssh-ed25519 AAAA..." ``` -------------------------------- ### Install External RouterOS Packages Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/extra-packages.md Install third-party .npk files by uploading them to the router and then applying the changes. Ensure you use `/system/package/apply-changes` to activate the new package. ```routeros # 1. Upload .npk files via SCP (or Winbox drag-and-drop, or WebFig file upload) # scp my-package-7.22-arm64.npk admin@router:/ # 2. Apply changes (NOT /system/reboot!) /system/package/apply-changes ``` -------------------------------- ### List Address List Entries Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-firewall-rest.md This example demonstrates how to retrieve a list of all entries in the address list using a GET request to the `/ip/firewall/address-list` endpoint. ```APIDOC ## GET /ip/firewall/address-list ### Description Retrieves a list of all entries in the address list. ### Method GET ### Endpoint /ip/firewall/address-list ### Parameters None ### Response #### Success Response (200) - **addresses** (array) - An array of address list entries, where each entry is an object containing details like 'list', 'address', and 'comment'. #### Response Example ```json { "addresses": [ { "id": "*10", "list": "blocked", "address": "10.0.0.100", "comment": "blocked host" } ] } ``` ``` -------------------------------- ### Install QEMU for RouterOS CHR Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-qemu-chr/references/github-actions-ci.md Installs QEMU system emulator and utilities required for running RouterOS CHR on Ubuntu-based GitHub Actions runners. ```yaml - name: Install QEMU run: | sudo apt-get update sudo apt-get install -y qemu-system-x86 qemu-utils ``` -------------------------------- ### Authentication Patterns Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/rest-api-patterns.md Examples of how to construct authentication headers for API requests. ```APIDOC ## Basic Authentication (No Password) ### Description Used for connecting to a router with the default 'admin' user and no password. ### Headers - **Authorization**: `Basic YWRtaW46` (Base64 encoded 'admin:') ## Basic Authentication (With Password) ### Description Used for connecting to a router with a username and password. ### Headers - **Authorization**: `Basic YWRtaW46bXlwYXNzd29yZA==` (Base64 encoded 'admin:mypassword') ``` -------------------------------- ### Basic Authentication for RouterOS API Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/rest-api-patterns.md Provides examples for setting up Basic Authentication headers for the RouterOS REST API. Covers both fresh installs with an empty password and authenticated sessions with a password. ```typescript // Basic auth — empty password (fresh install) const auth = { headers: { Authorization: `Basic ${btoa("admin:")}` }, }; // With password const auth = { headers: { Authorization: `Basic ${btoa("admin:mypassword")}` }, }; ``` -------------------------------- ### RouterOS Command Tree Structure Example Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-command-tree/SKILL.md Illustrates the hierarchical organization of RouterOS commands, showing directories, paths, commands, and their arguments. ```text / (root dir) ├── ip/ (dir) │ ├── address/ (path) │ │ ├── add (cmd) │ │ │ ├── address (arg) — "IP address" │ │ │ ├── interface (arg) — "Interface name" │ │ │ └── disabled (arg) — "yes | no" │ │ ├── set (cmd) │ │ ├── remove (cmd) │ │ ├── get (cmd) │ │ ├── print (cmd) │ │ └── export (cmd) │ ├── route/ (path) │ │ └── ... │ └── dns/ (path) │ ├── set (cmd) │ ├── cache/ (path) │ │ ├── print (cmd) │ │ └── flush (cmd) │ └── ... ├── interface/ (dir) │ └── ... ├── system/ (dir) │ └── ... └── ... ``` -------------------------------- ### Install Container Package (Offline) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-container/SKILL.md Installs the container package by uploading the .npk file and applying changes. This method requires a reboot and activation. ```sh # Upload via SCP (or Winbox drag-and-drop, or WebFig file upload) scp container-7.22-arm64.npk admin@router:/ ``` ```routeros # Apply changes (triggers reboot AND activates — /system/reboot does NOT work!) /system/package/apply-changes ``` -------------------------------- ### Netinstall with First-Boot Mode Script Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-netinstall/SKILL.md Installs RouterOS and applies a mode script during the first boot to configure device mode and container settings. ```sh sudo ./netinstall-cli -r -sm modescript.rsc -i eth0 \ routeros-7.22-arm64.npk \ container-7.22-arm64.npk ``` -------------------------------- ### List All Interfaces (JSON Response) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-networking-rest.md Example JSON response when listing all network interfaces. ```json [ { ".id": "*1", "name": "ether1", "type": "ether", "mtu": "1500", "actual-mtu": "1500", "mac-address": "52:54:00:12:34:56", "running": "true", "disabled": "false", "dynamic": "false" }, { ".id": "*2", "name": "ether2", "type": "ether", "mtu": "1500", "actual-mtu": "1500", "mac-address": "52:54:00:12:34:57", "running": "false", "disabled": "false", "dynamic": "false" } ] ``` -------------------------------- ### Netinstall CLI Flags Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-netinstall/SKILL.md Common flags for netinstall-cli, detailing their function for controlling the installation process. ```text -r : Reinstall and apply the default-configuration stage ``` ```text -e : Reinstall with empty configuration ``` ```text -b : Discard the currently installed branding package ``` ```text -m : Enable repeated installs in one run ``` ```text -o : With -m, only reinstall a given MAC once per run; by itself it behaves like a normal single install ``` ```text -f : Ignore storage-size checks ``` ```text -v : Verbose output ``` ```text -c : Allow multiple netinstall instances on the same host ``` ```text -k : Install a license key (.KEY) ``` ```text -s : Install a persistent configure script that replaces the RouterOS-supplied default configuration script ``` ```text -sm : Install a one-time mode script for the first boot after install ``` ```text --mac : Only respond to this MAC address ``` ```text -i : Bind to a specific interface ``` ```text -a : Assign a specific client IP; if -i is used, server IP is auto-detected ``` -------------------------------- ### App Store File Examples Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-app-yaml/references/examples.md Defines multiple applications within a single app store file, each with its own services, descriptions, and categories. ```yaml # my-store.tikappstore.yaml - name: app-one descr: First app in the store category: networking services: main: image: nginx:alpine ports: - "8080:80/tcp" - name: app-two descr: Second app in the store category: monitoring services: grafana: image: grafana/grafana:latest ports: - "3000:3000/tcp:web" environment: GF_SECURITY_ADMIN_PASSWORD: admin volumes: - grafana-data:/var/lib/grafana volumes: grafana-data: {} ``` -------------------------------- ### POST Commands (Actions) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/rest-api-patterns.md Examples of executing actions or commands on the router using the POST method. ```APIDOC ## Reboot System ### Description Initiates a system reboot. ### Method POST ### Endpoint /rest/system/reboot ## Check for Updates ### Description Checks for available software updates for installed packages. ### Method POST ### Endpoint /rest/system/package/update/check-for-updates ## Flush DNS Cache ### Description Clears the router's DNS cache. ### Method POST ### Endpoint /rest/ip/dns/cache/flush ## Run Script ### Description Executes a system script identified by its ID. ### Method POST ### Endpoint /rest/system/script/run ### Request Body - **.id** (string) - Required - The ID of the script to run (e.g., "*1"). ``` -------------------------------- ### Filtering and Query Parameters Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/rest-api-patterns.md Examples demonstrating how to filter API responses and select specific properties. ```APIDOC ## Filter by Property Value ### Description Retrieves interfaces that match a specific type. ### Method GET ### Endpoint /rest/interface?type=ether ## Multiple Filters (AND) ### Description Retrieves IP addresses associated with a specific interface and that are not disabled. ### Method GET ### Endpoint /rest/ip/address?interface=ether1&disabled=false ## Proplist (Select Properties) ### Description Retrieves only the 'name', 'type', and 'running' properties for interfaces, reducing response size. ### Method GET ### Endpoint /rest/interface?.proplist=name,type,running ``` -------------------------------- ### Common Endpoints Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/rest-api-patterns.md Examples of common API calls for retrieving system information and configuration. ```APIDOC ## Health Check ### Description Checks if the RouterOS API is accessible. ### Method GET ### Endpoint / ### Response #### Success Response (200) Returns HTTP 200 OK if the API is alive. ## System Identity ### Description Retrieves the system identity (hostname) of the router. ### Method GET ### Endpoint /rest/system/identity ## System Resource ### Description Fetches system resource information including CPU, memory, uptime, and version. ### Method GET ### Endpoint /rest/system/resource ## Interfaces ### Description Lists all network interfaces on the router. ### Method GET ### Endpoint /rest/interface ## IP Addresses ### Description Retrieves all configured IP addresses on the router. ### Method GET ### Endpoint /rest/ip/address ## Firewall Filter Rules ### Description Lists all configured firewall filter rules. ### Method GET ### Endpoint /rest/ip/firewall/filter ## DNS Cache ### Description Retrieves the contents of the DNS cache. ### Method GET ### Endpoint /rest/ip/dns/cache ## Files ### Description Lists all files stored on the router's file system. ### Method GET ### Endpoint /rest/file ## Installed Packages ### Description Lists all installed software packages on the router. ### Method GET ### Endpoint /rest/system/package ``` -------------------------------- ### Enable a Package Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/packages-rest.md Schedules a package to be enabled or installed. The response is an empty array on success, and the package's `scheduled` field will be updated. ```bash curl -s -u admin: http://127.0.0.1:9100/rest/system/package/enable \ -X POST -H "Content-Type: application/json" -d '{"numbers":"container"}' ``` -------------------------------- ### Install extra packages in RouterOS CHR Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-qemu-chr/references/github-actions-ci.md Downloads and installs additional RouterOS packages (like container, iot, zerotier) into the CHR instance. It downloads the 'all_packages' bundle, unzips it, uploads each .npk file via SCP to the CHR, and then reboots the instance to apply the new packages. A subsequent wait loop ensures the router is ready after the reboot. ```yaml - name: Install extra packages env: ROSVER: ${{ inputs.rosver }} run: | # Download all_packages bundle wget -q "https://download.mikrotik.com/routeros/${ROSVER}/all_packages-x86-${ROSVER}.zip" \ || wget -q "https://cdn.mikrotik.com/routeros/${ROSVER}/all_packages-x86-${ROSVER}.zip" unzip -o "all_packages-x86-${ROSVER}.zip" # Upload each .npk via SCP (RouterOS SSH on port 9122) for pkg in *.npk; do sshpass -p '' scp -P 9122 -o StrictHostKeyChecking=no "$pkg" admin@127.0.0.1:/ done # Reboot to activate packages curl -sf -u admin: -X POST http://127.0.0.1:9180/rest/system/reboot || true sleep 5 # Wait for reboot completion for i in $(seq 1 30); do if curl -sf --connect-timeout 5 http://127.0.0.1:9180/ > /dev/null 2>&1; then echo "RouterOS rebooted with extra packages" exit 0 fi sleep 10 done exit 1 ``` -------------------------------- ### Conditional Syntax Example Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-hotspot/references/template-variables.md Demonstrates the basic conditional syntax using $(if), $(elif), $(else), and $(endif) for displaying content based on variable values. ```html $(if VAR) shown when VAR is non-empty $(elif VAR == "value") shown when VAR equals "value" $(elif VAR != "other") shown when VAR not equal "other" $(else) fallback $(endif) ``` -------------------------------- ### RouterOS Container Subsystem Setup Source: https://context7.com/tikoci/routeros-skills/llms.txt Steps to enable and configure the container subsystem in RouterOS 7.x, including networking and basic container management. ```routeros # 1. Enable container support (requires physical button press/power cycle after) /system/device-mode/update mode=advanced container=yes ``` ```routeros # 2. Install container package (7.18+: use apply-changes, NOT reboot) # Upload container-7.22-arm64.npk via SCP, then: /system/package/apply-changes ``` ```routeros # 3. Set up VETH + bridge networking /interface/veth/add name=veth-myapp address=172.17.0.2/24 gateway=172.17.0.1 /interface/bridge/add name=containers /interface/bridge/port/add bridge=containers interface=veth-myapp /ip/address/add address=172.17.0.1/24 interface=containers /ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24 ``` ```routeros # 4. Pull from registry /container/config/set registry-url=https://registry-1.docker.io tmpdir=disk1/pull /container/add remote-image=library/alpine:latest interface=veth-myapp \ env="TZ=Europe/Riga,MY_VAR=hello" \ mount="src=disk1/appdata,dst=/data" \ root-dir=disk1/myapp logging=yes start-on-boot=yes ``` ```routeros # 5. Lifecycle /container/start [find tag~"myapp"] /container/stop [find tag~"myapp"] /container/print /log/print where topics~"container" /container/remove [find tag~"myapp"] ``` -------------------------------- ### List All Visible Packages Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/packages-rest.md Retrieves a JSON array of all packages currently visible in the system. This includes installed, disabled, and available optional packages after a check-for-updates. ```bash curl -s -u admin: http://127.0.0.1:9100/rest/system/package ``` -------------------------------- ### Verify SSH Key Presence (REST API) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-users-rest.md After installing an SSH key, poll this endpoint to verify its presence for the user. This is part of the `quickchr` provisioning pattern. ```bash GET /rest/user/ssh-keys ``` -------------------------------- ### netinstall-cli Command Syntax Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-netinstall/SKILL.md The general command syntax for the netinstall-cli tool. Use this as a reference for constructing commands. ```text netinstall-cli [-r] [-e] [-b] [-m [-o]] [-f] [-v] [-c] [-k ] [-s ] [-sm ] [--mac ] {-i | -a } [PACKAGES...] ``` -------------------------------- ### Netinstall with Empty Configuration Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-netinstall/SKILL.md Initiates a netinstall process that results in an empty configuration on the target device. ```sh sudo ./netinstall-cli -e -b -i eth0 \ routeros-7.22-arm64.npk ``` -------------------------------- ### Get Package Update Information Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/packages-rest.md Fetches the current update channel and installed version. After a check-for-updates, it also includes the latest available version and the system status. ```bash curl -s -u admin: http://127.0.0.1:9100/rest/system/package/update ``` ```json {"channel":"stable","installed-version":"7.22.1"} ``` ```json {"channel":"stable","installed-version":"7.22.1","latest-version":"7.22.1","status":"System is already up to date"} ``` -------------------------------- ### Monitor Traffic Once Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/async-commands-rest.md This example shows how to use the `/rest/interface/monitor-traffic` endpoint with the `once` parameter to get a single data sample immediately. The response is a single-element JSON array without a `.section` field. ```APIDOC ## POST /rest/interface/monitor-traffic with once ### Description Retrieves a single, immediate sample of traffic data for a specified interface. ### Method POST ### Endpoint /rest/interface/monitor-traffic ### Parameters #### Request Body - **interface** (string) - Required - The name of the interface to monitor. - **once** (string) - Optional - Any value (e.g., "") enables single sample mode. `"false"` disables it. ### Request Example ```json { "interface": "ether1", "once": "" } ``` ### Response #### Success Response (200) - **Array with one object**: Contains interface traffic data like `name`, `rx-bits-per-second`, `tx-bits-per-second`. ### Response Example ```json [{"name": "ether1", "rx-bits-per-second": "512", "tx-bits-per-second": "336"}] ``` ``` -------------------------------- ### RouterOS CLI Syntax Examples Source: https://context7.com/tikoci/routeros-skills/llms.txt Demonstrates basic RouterOS CLI navigation, configuration, and scripting constructs. Use for managing RouterOS devices via the command line. ```routeros # Navigate and read config /ip/address/print /interface/print /system/resource/print ``` ```routeros # Create an entry /ip/address/add address=192.168.1.1/24 interface=ether1 ``` ```routeros # Update by find expression (no upsert — always explicit set) /ip/address/set [find interface=ether1] address=10.0.0.1/24 ``` ```routeros # Remove /ip/address/remove [find address="192.168.1.1/24"] ``` ```routeros # Variables and control flow in .rsc scripts :local myVar "hello" :if ($myVar = "hello") do={ :log info "matched" } else={ :log info "no match" } ``` ```routeros # Capture a new entry's ID for further use :local newId [/ip/address/add address=10.0.0.1/24 interface=ether1] :put [/ip/address/get $newId address] ``` ```routeros # Inspect hardware (RouterOS equivalent of lspci) /system/resource/hardware/print /system/resource/irq/print ``` -------------------------------- ### List and Add Apps in RouterOS Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-container/SKILL.md Demonstrates how to list available applications and add a new application from a specified URL using the RouterOS CLI. ```routeros # List available apps /app/print ``` ```routeros # Add app from URL /app/add yaml-url=https://example.com/myapp.tikapp.yaml ``` -------------------------------- ### Get Package Update Information Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/packages-rest.md Retrieves information about the current update channel and the installed version of the RouterOS system. After a check-for-updates operation, it also includes the latest available version and the status of the update check. ```APIDOC ## GET /rest/system/package/update ### Description Returns update channel and installed version. ### Method GET ### Endpoint /rest/system/package/update ### Parameters None ### Request Example None ### Response #### Success Response (200) - **channel** (string) - The current update channel (e.g., "stable") - **installed-version** (string) - The currently installed version - **latest-version** (string) - The latest available version (present after check-for-updates) - **status** (string) - The status of the update check (e.g., "System is already up to date") #### Response Example ```json { "channel": "stable", "installed-version": "7.22.1", "latest-version": "7.22.1", "status": "System is already up to date" } ``` ``` -------------------------------- ### Complete DHCP Server Setup Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-networking-rest.md This sequence of commands sets up a complete DHCP server, including assigning an IP address to the interface, creating an IP pool, defining the network, and finally creating the DHCP server itself. Ensure the interface has an IP address in the same subnet. ```bash # Prerequisite: IP address must exist on the interface curl -s -u admin: http://127.0.0.1:9100/rest/ip/address \ -X PUT -H "Content-Type: application/json" \ -d '{"address":"192.168.1.1/24","interface":"ether2"}' # 1. Pool curl -s -u admin: http://127.0.0.1:9100/rest/ip/pool \ -X PUT -H "Content-Type: application/json" \ -d '{"name":"dhcp-pool","ranges":"192.168.1.100-192.168.1.200"}' # 2. Network curl -s -u admin: http://127.0.0.1:9100/rest/ip/dhcp-server/network \ -X PUT -H "Content-Type: application/json" \ -d '{"address":"192.168.1.0/24","gateway":"192.168.1.1","dns-server":"8.8.8.8"}' # 3. Server curl -s -u admin: http://127.0.0.1:9100/rest/ip/dhcp-server \ -X PUT -H "Content-Type: application/json" \ -d '{"name":"dhcp1","interface":"ether2","address-pool":"dhcp-pool","lease-time":"1h","disabled":"no"}' ``` -------------------------------- ### Verify Installed Packages Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/packages-rest.md Retrieves a list of currently installed packages on the RouterOS system. ```APIDOC ## GET /rest/system/package ### Description Retrieves a list of all installed packages on the system. ### Method GET ### Endpoint /rest/system/package ### Response #### Success Response (200) - **packages** (array) - A list of installed packages, each with details like name, version, and status. ``` -------------------------------- ### Launch aarch64 VM with UEFI Source: https://context7.com/tikoci/routeros-skills/llms.txt Use this command to launch a QEMU virtual machine with aarch64 architecture, UEFI firmware, and virtio-blk-pci for storage. Ensure the necessary firmware and disk images are available. ```bash cp /opt/homebrew/share/qemu/edk2-arm-vars.fd /tmp/my-vars.fd qemu-system-aarch64 -M virt -cpu cortex-a710 -m 256 \ -accel hvf -cpu host \ -drive if=pflash,format=raw,readonly=on,unit=0,file=/opt/homebrew/share/qemu/edk2-aarch64-code.fd \ -drive if=pflash,format=raw,unit=1,file=/tmp/my-vars.fd \ -drive file=chr-7.22-arm64.img,format=raw,if=none,id=drive0 \ -device virtio-blk-pci,drive=drive0 \ -netdev user,id=net0,hostfwd=tcp::9180-:80 \ -device virtio-net-pci,netdev=net0 \ -display none -serial stdio ``` -------------------------------- ### Check Container Package Installation Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-container/SKILL.md Verifies if the container package is already installed on the RouterOS device. ```routeros # Check if container package is already installed /system/package/print where name=container ``` -------------------------------- ### tshark Installation Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-sniffer/references/tzsp-receivers.md Commands to install tshark (part of Wireshark) on macOS using Homebrew and on Ubuntu/Debian using apt. Includes a verification step. ```sh # macOS brew install wireshark # installs both wireshark and tshark ``` ```sh # Ubuntu/Debian sudo apt install tshark ``` ```sh # Verify tshark --version ``` -------------------------------- ### Port Format Examples (RouterOS 7.23+ style) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-app-yaml/references/examples.md Demonstrates the newer port mapping syntax introduced in RouterOS 7.23+, allowing for label and protocol specification in a different order. ```yaml # === New RouterOS 7.23+ style === ports: - "8080:80:web:tcp" # Label then protocol - "53:53:dns:udp" # UDP with label - "[accessIP]:[accessPort]:80:web:tcp" # With placeholders ``` -------------------------------- ### Install Container Package (Online) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-container/SKILL.md Installs the container package using the online package update feature. This method requires an internet connection. ```routeros /system/package/update check-for-updates /system/package/update install ``` -------------------------------- ### Clone Repository and Set Up Symlinks Source: https://github.com/tikoci/routeros-skills/blob/main/SETUP.md Clone the routeros-skills repository and create symlinks for AI tools to access the skills. This is for setting up a fresh machine. ```sh git clone https://github.com/tikoci/routeros-skills.git ~/GitHub/routeros-skills mkdir -p ~/.copilot/skills ~/.claude/skills # Symlink all routeros-* skills for Copilot for skill in ~/GitHub/routeros-skills/routeros-*/; do ln -sf "$skill" ~/.copilot/skills/"$(basename $skill)" done # Symlink all routeros-* skills for Claude for skill in ~/GitHub/routeros-skills/routeros-*/; do ln -sf "$skill" ~/.claude/skills/"$(basename $skill)" done ``` -------------------------------- ### Inline Configs Example Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-app-yaml/SKILL.md Defines an inline configuration file (`my-config`) and mounts it into an Nginx service container. The `content` block supports multi-line strings and placeholder expansion. ```yaml configs: my-config: content: | server { listen 80; server_name [accessIP]; } services: web: image: nginx:alpine configs: - source: my-config target: /etc/nginx/conf.d/default.conf mode: 0644 ``` -------------------------------- ### GET /rest/system/device-mode Response Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/device-mode-rest.md The GET /rest/system/device-mode endpoint returns a flat JSON object with all values as strings. Booleans are represented as 'true'/'false' and numbers as strings. ```json { "mode": "advanced", "allowed-versions": "", "flagged": "false", "flagging-enabled": "true", "attempt-count": "0", "scheduler": "true", "socks": "true", "fetch": "true", "pptp": "true", "l2tp": "true", "bandwidth-test": "true", "traffic-gen": "false", "sniffer": "true", "ipsec": "true", "romon": "true", "proxy": "true", "hotspot": "true", "smb": "true", "email": "true", "zerotier": "true", "container": "false", "install-any-version": "false", "partitions": "false", "routerboard": "false" } ``` -------------------------------- ### Full-Featured /app Example Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-app-yaml/references/examples.md An extensive RouterOS application configuration showcasing all available properties, including multiple services, environment variables, volumes, configs, health checks, and network definitions. ```yaml name: my-app descr: A full-featured example app page: https://example.com/my-app category: productivity icon: https://example.com/icon.png default-credentials: admin:admin url-path: /dashboard auto-update: true services: web: image: ghcr.io/owner/web-app:latest container_name: my-web hostname: web entrypoint: ["/bin/sh", "-c"] command: "nginx -g 'daemon off;'" ports: - "[accessIP]:[accessPort]:80:web:tcp" - "8443:443/tcp:https" - target: 9090 published: 9090 protocol: tcp name: metrics app_protocol: http environment: APP_HOST: "[accessIP]" APP_PORT: "[accessPort]" DB_HOST: "[containerIP]" ROUTER_IP: "[routerIP]" volumes: - web-data:/var/www/html configs: - source: nginx-conf target: /etc/nginx/nginx.conf mode: 0644 restart: unless-stopped depends_on: - db user: "1000:1000" healthcheck: test: ["CMD", "curl", "-f", "http://localhost/health"] interval: "30s" timeout: "10s" retries: 3 start_period: "15s" shm_size: "256m" ulimits: nofile: soft: 65536 hard: 65536 db: image: postgres:16-alpine container_name: my-db environment: POSTGRES_DB: app POSTGRES_USER: app POSTGRES_PASSWORD: changeme volumes: - db-data:/var/lib/postgresql/data restart: always expose: - "5432" stop_grace_period: "30s" volumes: web-data: {} db-data: {} networks: app-net: name: my-network external: true configs: nginx-conf: content: | worker_processes 1; events { worker_connections 1024; } http { server { listen 80; server_name [accessIP]; location / { proxy_pass http://[containerIP]:3000; } } } ``` -------------------------------- ### Run Bun Integration Tests Individually Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/bun-runtime-gotchas.md This example shows the correct way to run specific Bun integration lab tests to avoid event loop starvation caused by long-blocking HTTP requests in other test files. Running a directory of tests can cause hangs. ```bash # CORRECT QUICKCHR_INTEGRATION=1 bun test test/lab/device-mode/device-mode.test.ts # WRONG — will hang QUICKCHR_INTEGRATION=1 bun test test/lab/ ``` -------------------------------- ### Programmatic QEMU Launch from Bun/TypeScript Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-qemu-chr/SKILL.md Launches RouterOS CHR as a child process using Bun.spawn, enabling full lifecycle control and integration with TypeScript applications. Includes detection of acceleration, serial console, and monitor sockets. ```typescript import { $ } from "bun"; const port = 9180; const accel = await detectAccel(); const proc = Bun.spawn([ "qemu-system-x86_64", "-M", "q35", "-m", "256", "-accel", accel, "-drive", `file=chr.img,format=raw,if=virtio`, "-netdev", `user,id=net0,hostfwd=tcp::${port}-:80`, "-device", "virtio-net-pci,netdev=net0", "-display", "none", "-chardev", `socket,id=serial0,path=/tmp/chr-serial.sock,server=on,wait=off`, "-serial", "chardev:serial0", "-monitor", `unix:/tmp/chr-monitor.sock,server,nowait`, ], { stdio: ["ignore", "pipe", "pipe"] }); // Wait for boot await waitForBoot(`http://127.0.0.1:${port}/`); ``` -------------------------------- ### List Firewall Filter Rules with JSON Response Example Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-firewall-rest.md Example of the JSON response when listing all firewall filter rules, showing the structure of rule objects including their IDs, actions, and comments. ```json [ { ".id": "*1", "action": "accept", "bytes": "50507925242", "chain": "input", "comment": "defconf: accept established,related", "connection-state": "established,related", "disabled": "false", "dynamic": "false", "invalid": "false", "log": "false", "log-prefix": "", "packets": "50048246" }, { ".id": "*5", "action": "drop", "chain": "input", "comment": "defconf: drop all not coming from LAN", "disabled": "false", "in-interface-list": "!LAN" } ] ``` -------------------------------- ### Check Installed Packages via REST API Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/extra-packages.md This TypeScript code snippet demonstrates how to fetch the list of installed packages from a RouterOS device using its REST API and check if a specific package, like 'container', is enabled. ```typescript // Check installed packages via REST const packages = await fetch(`${base}/system/package`, auth).then(r => r.json()); // Returns array: [{name: "routeros", version: "7.22", ...}, {name: "container", ...}] const hasContainer = packages.some(p => p.name === "container" && !p.disabled); ``` -------------------------------- ### Port Format Examples (OCI-style) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-app-yaml/references/examples.md Illustrates various ways to define port mappings using the older OCI-style syntax, applicable across all RouterOS versions. ```yaml # === Old OCI-style (all RouterOS versions) === ports: - "8080:80" # No protocol (defaults to tcp) - "8080:80/tcp" # Explicit tcp - "53:53/udp" # UDP - "8080:80/tcp:web" # With label - "192.168.1.1:8080:80/tcp" # With bind IP - "[accessIP]:[accessPort]:80/tcp" # With placeholders ``` -------------------------------- ### Get Single User Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-users-rest.md Retrieves details for a specific user identified by their ID. ```APIDOC ## GET /rest/user/*ID ### Description Retrieves the details of a single user specified by their unique ID. ### Method GET ### Endpoint /rest/user/*ID ### Response #### Success Response (200) - **User Object**: A single JSON object representing the user. ### Response Example ```json { ".id": "*1", "name": "admin", "group": "full", "address": "0.0.0.0/0", "disabled": "false", "last-logged-in": "jan/15/2025 10:30:00", "comment": "system default user" } ``` ``` -------------------------------- ### CHR QEMU Packet Debugging with TZSP (Shell) Source: https://context7.com/tikoci/routeros-skills/llms.txt This workflow demonstrates setting up a CHR QEMU instance and using curl to configure its sniffer for TZSP streaming. It also shows how to listen for TZSP traffic on the host using tshark. ```sh # CHR QEMU + TZSP: complete zero-hardware packet debugging workflow qemu-system-x86_64 -M q35 -m 256 \ -drive file=chr.img,format=raw,if=virtio \ -netdev user,id=net0,hostfwd=tcp::9180-:80 \ -device virtio-net-pci,netdev=net0 \ -display none -serial stdio & # Configure sniffer via REST (10.0.2.2 is host from QEMU user-mode network) curl -su admin: -X POST http://127.0.0.1:9180/rest/tool/sniffer/set \ -H 'Content-Type: application/json' \ -d '{"streaming-enabled":"yes","streaming-server":"10.0.2.2:37008"}' curl -su admin: -X POST http://127.0.0.1:9180/rest/tool/sniffer/start # Listen on host tshark -i any -f "udp port 37008" -O tzsp ``` -------------------------------- ### Example Output Contract for RouterOS CLI Source: https://github.com/tikoci/routeros-skills/blob/main/BACKLOG.md Illustrates a question and its expected RouterOS CLI output for a skill's output contract. This serves as a specimen for a correct answer, aiding in grounding and regression testing. ```text Q: "Create a VETH interface and bridge for a container with IP 172.17.0.2" Expected: ``` -------------------------------- ### Port Format Examples (Long-form object syntax) Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-app-yaml/references/examples.md Shows how to define port mappings using the long-form object syntax, providing explicit control over target, published port, protocol, name, and app protocol. ```yaml # === Long-form object syntax === ports: - target: 80 published: 8080 protocol: tcp name: web app_protocol: http ``` -------------------------------- ### Create DHCP Server Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-networking-rest.md This command creates a DHCP server instance. Configure the server name, the interface it will run on, the IP address pool, and lease time. ```bash curl -s -u admin: http://127.0.0.1:9100/rest/ip/dhcp-server \ -X PUT -H "Content-Type: application/json" \ -d '{"name":"dhcp1","interface":"ether2","address-pool":"dhcp-pool","lease-time":"1h","disabled":"no"}' ``` -------------------------------- ### Create DHCP Server Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/routeros-networking-rest.md This snippet shows how to create a DHCP server instance using the `/ip/dhcp-server` endpoint. It configures the server's name, interface, address pool, and lease time. ```APIDOC ## PUT /ip/dhcp-server ### Description Creates or updates a DHCP server instance. ### Method PUT ### Endpoint /ip/dhcp-server ### Parameters #### Request Body - **name** (string) - Required - Server name - **interface** (string) - Required - Interface to serve DHCP on - **address-pool** (string / `static-only`) - Optional - IP pool name. `static-only` = only static leases - **lease-time** (time) - Optional - Lease duration (e.g. `1h`, `1d`) - **disabled** (`yes` / `no`) - Optional - Whether the server is disabled - **authoritative** (`yes` / `no` / `after-2sec-delay` / `after-10sec-delay`) - Optional - How to handle unknown clients ### Request Example ```json { "name": "dhcp1", "interface": "ether2", "address-pool": "dhcp-pool", "lease-time": "1h", "disabled": "no" } ``` ``` -------------------------------- ### Renew License Status Source: https://github.com/tikoci/routeros-skills/blob/main/routeros-fundamentals/references/async-commands-rest.md This example shows the sequential status updates when attempting to renew a RouterOS license. ```json [ {".section":"0","status":"connecting"}, {".section":"1","status":"renewing"}, {".section":"2","status":"ERROR: Unauthorized"} ] ```