• Stars
    star
    391
  • Rank 110,003 (Top 3 %)
  • Language
    PHP
  • License
    MIT License
  • Created about 6 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Mikrotik RouterOS API PHP client for your applications

Latest Stable Version Build Status Total Downloads License Code Climate Code Coverage Scrutinizer CQ

RouterOS API Client

composer require evilfreelancer/routeros-api-php

This library is partly based on this old project, but unlike it has many innovations to ease development. In addition, the project designed to work with PHP7/8 in accordance with the PSR standards.

You can use this library with pre-6.43 and post-6.43 versions of RouterOS firmware, it will be detected automatically on connection stage.

Table of Contents

Minimum requirements

  • php >= 7.2|8.0
  • ext-sockets

Laravel framework support

RouterOS API client is optimized for usage as normal Laravel package, all functional is available via \RouterOS facade, for access to client object you need instead:

$config = new \RouterOS\Config([
    'host' => '192.168.1.3',
    'user' => 'admin',
    'pass' => 'admin',
    'port' => 8728,
]);
$client = new \RouterOS\Client($config);

Use the facade and pass array of parameters to client method:

$client = \RouterOS::client([
    'host' => '192.168.1.3',
    'user' => 'admin',
    'pass' => 'admin',
    'port' => 8728,
]);

You also may get array with all configs which was obtained from routeros-api.php file:

$config = \RouterOS::config([
    'host' => '192.168.1.3',
    'user' => 'admin',
    'pass' => 'admin',
    'port' => 8728,
]);

dump($config);

$client = \RouterOS::client($config);

Laravel installation

By default, the package will automatically register its service provider, but if you are a happy owner of Laravel version less than 5.5, then in a project, which is using the package (after composer require is done, of course), add intoproviders block of your config/app.php:

'providers' => [
    // ...
    RouterOS\Laravel\ServiceProvider::class,
],

Optionally, publish the configuration file if you want to change any defaults:

php artisan vendor:publish --provider="RouterOS\\Laravel\\ServiceProvider"

How to use

Basic example, analogue via command line is /ip hotspot ip-binding print:

use \RouterOS\Client;
use \RouterOS\Query;

// Initiate client with config object
$client = new Client([
    'host' => '192.168.1.3',
    'user' => 'admin',
    'pass' => 'admin',
    'port' => 8728,
]);

// Create "where" Query object for RouterOS
$query =
    (new Query('/ip/hotspot/ip-binding/print'))
        ->where('mac-address', '00:00:00:00:40:29');

// Send query and read response from RouterOS
$response = $client->query($query)->read();

var_dump($response);

Basic example for update/create/delete types of queries:

use \RouterOS\Client;
use \RouterOS\Query;

// Initiate client with config object
$client = new Client([
    'host' => '192.168.1.3',
    'user' => 'admin',
    'pass' => 'admin'
]);

// Send "equal" query with details about IP address which should be created
$query =
    (new Query('/ip/hotspot/ip-binding/add'))
        ->equal('mac-address', '00:00:00:00:40:29')
        ->equal('type', 'bypassed')
        ->equal('comment', 'testcomment');

// Send query and read response from RouterOS (ordinary answer from update/create/delete queries has empty body)
$response = $client->query($query)->read();

var_dump($response);

If you need export all settings from router:

use \RouterOS\Client;

// Initiate client with config object
$client = new Client([
    'host'        => '192.168.1.3',
    'user'        => 'admin',
    'pass'        => 'admin',
    'ssh_port'    => 22222,
    'ssh_timeout' => 60, // if not set then 30 seconds by default 
]);

// Execute export command via ssh
$response = $client->query('/export');
// or
$response = $client->export();

var_dump($response);

Examples with "where" conditions, "operations" and "tag":

use \RouterOS\Query;

/**
 * Simple "where" query will be generated by default 
 */

$client->query('/ip/address/print')->read();

/**
 * Send advanced "where" query with parameters to RouterOS 
 */

// If only one "where" condition
$client->query('/queue/simple/print', ['target', '192.168.1.1/32']);

// If multiple "where" conditions and need merge (operation "|") results
$client->query('/interface/print', [
    ['type', 'ether'],  // same as ['type', '=', 'ether']
    ['type', 'vlan'],   // same as ['type', '=', 'vlan']
], '|');

/**
 * Or in OOP style
 */

// If you need create query for "create/update/delete" operations
$query = new Query('/ip/hotspot/ip-binding/add');
$query->equal('mac-address', '00:00:00:00:40:29');
$query->equal('type', 'bypassed');
$query->equal('comment', 'testcomment');

// If multiple "where" conditions and need merge (operation "|") results
$query = new Query('/interface/print');
$query->where('type', 'ether');
$query->where('type', 'vlan');
$query->operations('|');

// If multiple "where" conditions and need append tag
$query = new Query('/interface/set');
$query->where('disabled', 'no');
$query->where('.id', 'ether1');
$query->tag(4);

/**
 * Write Query object to RouterOS and read response from it
 */

$response = $client->query($query)->read();

All available examples you can find here.

How to configure the client

You just need create object of Client class with required parameters in array format:

use \RouterOS\Client;

$client = new Client([
    'host' => '192.168.1.3',
    'user' => 'admin',
    'pass' => 'admin'
]);
ℹ️ Advanced examples of Config and Client classes usage
use \RouterOS\Config;
use \RouterOS\Client;

/**
 * You can create object of Config class
 */

$config = new Config();

// Then set parameters of config
$config->set('host', '192.168.1.3');
$config->set('user', 'admin');
$config->set('pass', 'admin');

// By the way, `->set()` method is support inline style of syntax
$config
    ->set('host', '192.168.1.3')
    ->set('user', 'admin')
    ->set('pass', 'admin');

/**
 * Or just create preconfigured Config object
 */

$config = new Config([
    'host' => '192.168.1.3',
    'user' => 'admin',
    'pass' => 'admin'
]);

/**
 * Then send Config object to Client constructor
 */

$client = new Client($config);

List of available configuration parameters

Parameter Type Default Description
host string (required) Address of Mikrotik RouterOS
user string (required) Username
pass string (required) Password
port int RouterOS API port number for access (if not set use 8728 or 8729 if SSL enabled)
ssl bool false Enable ssl support (if port is not set this parameter must change default port to ssl port)
ssl_options array details See https://www.php.net/manual/en/context.ssl.php
legacy bool false Deprecated, will be removed from 1.5.0: Support of legacy login scheme (true - pre 6.43, false - post 6.43)
timeout int 10 Max timeout for connecting to RouterOS (in seconds)
socket_timeout int 30 Max read timeout from RouterOS (in seconds)
socket_blocking bool true Set blocking mode on a socket stream
socket_options array details See https://www.php.net/manual/en/context.socket.php
attempts int 10 Count of attempts to establish TCP session
delay int 1 Delay between attempts in seconds
ssh_port int 22 Number of SSH port for exporting configuration
ssh_timeout int 30 Max timeout from router via SSH (in seconds)
ssh_private_key string ~/.ssh/id_rsa Full path to required private key

How to enable support of legacy login schema (RouterOS pre-6.43)

From 0.8.1 this is not important, version of firmware will be detected automatically. Deprecated, will be removed from 1.5.0

<?php
require_once __DIR__ . '/vendor/autoload.php';

use \RouterOS\Client;

// Initiate client with config object
$client = new Client([
    'host'   => '192.168.1.3',
    'user'   => 'admin',
    'pass'   => 'admin',
    'legacy' => true // you need set `legacy` parameter with `true` value
]);

// Your code below...

How to write queries

You can write absolutely any queries to your router, for this you need to create a "Query" object whose first argument is the required command, after this you can add the attributes of the command to "Query" object.

More about attributes and "words" from which these attributes should be created here.

More about "expressions", "where", "equal" and other filters/modifications of your query you can find here.

Simple usage examples of Query class:

use \RouterOS\Query;

// Get all installed packages (it may be enabled or disabled)
$query = new Query('/system/package/getall');

// Send "equal" query with details about IP address which should be created
$query =
    (new Query('/ip/hotspot/ip-binding/add'))
        ->equal('mac-address', '00:00:00:00:40:29')
        ->equal('type', 'bypassed')
        ->equal('comment', 'testcomment');

// Set where interface is disabled and ID is ether1 (with tag 4)
$query = 
    (new Query('/interface/set'))
        ->where('disabled', 'no')
        ->where('.id', 'ether1')
        ->tag(4);

// Get all ethernet and VLAN interfaces
$query = 
    (new Query('/interface/print'))
        ->where('type', 'ether')
        ->where('type', 'vlan')
        ->operations('|');

// Get all routes that have non-empty comment
$query =
    (new Query('/ip/route/print'))
        ->where('comment', '>', null);
ℹ️ Advanced examples of Query class usage
use \RouterOS\Query;
use \RouterOS\Client;

// Initiate connection to RouterOS
$client = new Client([
    'host'   => '192.168.1.3',
    'user'   => 'admin',
    'pass'   => 'admin'
]);

/**
 * Execute query directly through "->query()" method of Client class 
 */

// If your query has no "where" conditions
$client->query('/ip/arp/print');

// If you have only one where condition, you may use one dimensional array as second parameter of query method
$client->query('/queue/simple/print', ['target', '192.168.1.250/32']);

// If you need set few where conditions then need use multi dimensional array
$client->query('/interface/bridge/add', [
    ['name', 'vlan100-bridge'],
    ['vlan-filtering', 'no']
]);

/**
 * By some reason you may need restrict scope of RouterOS response,
 * for this need to use third attribute of "->query()" method
 */

// Get all ethernet and VLAN interfaces
$client->query('/interface/print', [
    ['type', 'ether'],
    ['type', 'vlan']
], '|');

/** 
 * If you want set tag of your query then you need to use fourth 
 * attribute of "->query()" method, but third attribute may be null
 */

// Enable interface (tag is 4)
$client->query('/interface/set', [
    ['disabled', 'no'],
    ['.id', 'ether1']
], null, 4);

/**
 * Or in OOP style  
 */

// Get all ethernet and VLAN interfaces
$query = new Query('/interface/print');
$query->where('type', 'ether');
$query->where('type', 'vlan');
$query->operations('|');

// Enable interface (tag is 4)
$query = new Query('/interface/set');
$query->equal('disabled', 'no');
$query->equal('.id', 'ether1');
$query->tag(4);

// Or, RAW mode

$query = new Query('/interface/set');
$query->add('=disabled=no');
$query->add('=.id=ether1');
$query->add('.tag=4');

// Or, RAW mode in format of array
    
$query = new Query('/interface/set', [
    '=disabled=no',
    '=.id=ether1',
    '.tag=4'
]);

// Or

$query = new Query([
    '/interface/set',
    '=disabled=no',
    '=.id=ether1',
    '.tag=4'
]);

/**
 * Write Query object to RouterOS and read response from it
 */

$response = $client->query($query)->read();

Read response as Iterator

By default, original solution of this client is not optimized for work with a large amount of results, only for small count of lines in response from RouterOS API.

But some routers may have (for example) 30000+ records in their firewall list. Specifically for such tasks, a method readAsIterator has been added that converts the results obtained from the router into a resource, with which it will later be possible to work.

You could treat response as an array except using any array_* functions

$response = $client->query($query)->readAsIterator();
var_dump($response);

// The following for loop allows you to skip elements for which
// $iterator->current() throws an exception, rather than breaking
// the loop.
for ($response->rewind(); $response->valid(); $response->next()) {
    try {
        $value = $response->current();
    } catch (Exception $exception) {
        continue;
    }

    # ...
}

Short methods

You can simplify your code and send then read from socket in one line:

/** 
 * Execute query and read response in ordinary mode 
 */
$response = $client->query($query)->read();
var_dump($response);

// Or
$response = $client->q($query)->r();
var_dump($response);

// Single method analog of lines above is
$response = $client->qr($query);
var_dump($response);

/**
 * Execute query and read response as Iterator 
 */
$response = $client->query($query)->readAsIterator();
var_dump($response);

// Or
$response = $client->q($query)->ri();
var_dump($response);

// Single method analog of lines above is
$response = $client->qri($query);
var_dump($response);

/**
 * By the way, you can send few queries to your router without result: 
 */
$client->query($query1)->query($query2)->query($query3);

// Or
$client->q($query1)->q($query2)->q($query3);

Known issues

Unable to establish socket session, Operation timed out

This error means that the library cannot connect to your router, it may mean router turned off (then need turn on), or the API service not enabled.

Go to Mikrotik Router OS -> IP -> Services and enable api service.

Or via command line:

/ip service enable api 

How to update/remove/create something via API?

Instead of ->where() method of Query class you need to use ->equal() method:

// Create query which should remove security profile
$query = new \RouterOS\Query('/interface/wireless/security-profiles/remove');

// It will generate queries, which stared from "?" symbol:
$query->where('.id', '*1');

/*
// Sample with ->where() method
RouterOS\Query Object
(
    [_attributes:RouterOS\Query:private] => Array
        (
            [0] => ?.id=*1
        )

    [_operations:RouterOS\Query:private] => 
    [_tag:RouterOS\Query:private] => 
    [_endpoint:RouterOS\Query:private] => /interface/wireless/security-profiles/remove
)
*/

// So, as you can see, instead of `->where()` need to use `->equal()`
// It will generate queries, which stared from "=" symbol:
$query->equal('.id', '*1');

/*
// Sample with ->equal() method
RouterOS\Query Object
(
    [_attributes:RouterOS\Query:private] => Array
        (
            [0] => =.id=*1
        )

    [_operations:RouterOS\Query:private] => 
    [_tag:RouterOS\Query:private] => 
    [_endpoint:RouterOS\Query:private] => /interface/wireless/security-profiles/remove
)
*/

Undefined character (any non-English languages)

RouterOS does not support national languages, only English (and API of RouterOS too).

You can try to reproduce it via web, for example add the comment to any element of your system, then save and reload the page, you will see unreadable characters.

Testing

You can use my other project with RouterOS in Docker container for running unit testing on your computer, for this you just need to have Expect, Docker and Docker Compose.

Next clone the repo with RouterOS in Docker and exec docker-compose up -d, then you need preconfigure virtual routers via preconf.tcl script from root of routeros-api-php:

./preconf.tcl 12223
./preconf.tcl 22223

And after this you can run tests:

./vendor/bin/phpunit

Links

More Repositories

1

docker-routeros

Mikrotik RouterOS inside Docker container
Shell
346
star
2

openvpn-php

OpenVPN config generator/importer written on PHP
PHP
28
star
3

docker-nextcloud

Composition of containers for using Nextcloud
24
star
4

docker-lfs-build

Linux From Scratch build environment
Shell
24
star
5

laravel-manticoresearch

An easy way to use the official ManticoreSearch client in your Laravel or Lumen applications.
PHP
20
star
6

kubernetes-cluster-on-arm

Project of simple Kubernetes cluster on NanoPi NEO3 ARM64 nodes
Shell
19
star
7

docker-openvpn-admin

Docker composition for OpenVPN Admin web interface
Shell
18
star
8

laravel-swagger-example

Small example application with basic realization of Swagger on Laravel Framework
PHP
18
star
9

docker-lamp

LAMP is abbreviate of Linux + Apache + MySQL/MariaDB + PHP and this project is composition of Docker containers for creating a local LAMP
Dockerfile
17
star
10

ruGPT-3.5-training

Jupyter Notebook
13
star
11

saiga-custom

Bunch of notebooks for pre-training custom Saiga-like LLM
Jupyter Notebook
13
star
12

benchmarking-llms

Comprehensive benchmarks and evaluations of Large Language Models (LLMs) with a focus on hardware usage, generation speed, and memory requirements.
Python
12
star
13

php-dev-env

Dockerfile
10
star
14

laravel-lighthouse-example

PHP
7
star
15

easyrsa-php

EasyRSA wrapper for PHP
PHP
7
star
16

rugpt3-custom

Pre-training custom ruGPT3 model on books written by F.M. Dostoevski
Python
7
star
17

docker-telegram-bot-api

Simple Docker image with Telegram Bot API server inside
Shell
7
star
18

xhprof-ui-js

Modern, flexible and mobile friendly application for analyzing PHP XHProf dumps
JavaScript
6
star
19

dockavel

Docker + Laravel
Shell
6
star
20

composer-json-generator

Small PHP library for generating/importing composer.json file with validation by composer's schema
PHP
6
star
21

rss-to-telegram-bot

Simple bot for reading posts from rss and
PHP
5
star
22

docker-whisper-server

whisper.cpp HTTP transcription server with OpenAI-like API in Docker
Python
5
star
23

docker-nexus

Docker composition for Nexus 3 by Sonartype
4
star
24

app-yopta

Mobile application written on yoptascript
Java
4
star
25

docker-compose-matomo

Basic repo with composition of docker containers required for Matomo (formerly Piwik)
4
star
26

enbeddrus

Collection of scripts for training bert-based embedder for Russian<>English embeddings extraction
Jupyter Notebook
4
star
27

pihole-api-php

Pi-Hole API PHP7 client
PHP
4
star
28

docker-lfs

Linux From Scratch in Docker container
4
star
29

docker-craftcms

Extra small image with basic CraftCMS inside Docker container
Shell
4
star
30

alpine-apache-php7

Docker image for LAP stack - Alpine + Apache2 + PHP7
Shell
3
star
31

bookeo-api-php

Bookeo API PHP7 client
PHP
3
star
32

characters-ai

Python
3
star
33

alpine-apache-php5

Docker image for LAP stack - Alpine + Apache2 + PHP5
Shell
3
star
34

ruMorpheme

Python
3
star
35

docker-compose-jenkins

Jenkins in Docker container via docker-compose.yml (example)
Dockerfile
3
star
36

rugpt-api

Small API reserver for interacting with RuGPT-3
Python
3
star
37

socket-yrslf

Bot for Twitch <-> Discord chats messaging
TypeScript
2
star
38

samp-api-php

GTA San Andreas Multiplayer PHP client for work with remote console
PHP
2
star
39

docker-compose-jira

Jira Cora and Jira Software in Docker container via docker-compose.yml (example)
Shell
2
star
40

yaml-php

Small PHP library for importing and exporting with validation of YAML configuration files.
PHP
2
star
41

discord-bot

Small bot prototype for a DiscordApp
PHP
2
star
42

toxicator-ru

A playful project that cleverly transforms everyday sentences into their mischievous "toxic" counterparts. 😈
Jupyter Notebook
2
star
43

merklion-chat

Merklion demo chat application
PHP
2
star
44

xl2tp-php

XL2TP configuration manager written on PHP
PHP
2
star
45

resova-api-php

Resova API PHP7 client
PHP
2
star
46

yalm-100b-quantization

This experimental project aims to adapt the YaLM-100B language model to run on consumer-grade GPUs, making advanced AI capabilities more accessible to individual users.
Python
2
star
47

craftcms-routeros-manager

WORK IN PROGRESS: A CraftCMS plugin for Mikrotik RouterOS devices management
PHP
2
star
48

1c-repository-maker

A collection of scripts to create a repository of deb or rpm packages 1C thin client.
Shell
1
star
49

codeline-laravel

The solution of a simple test task for Codeline.io
PHP
1
star
50

funpay-yandex-wallet

Test task by FunPay
PHP
1
star
51

simplegqlient

The simplest GraphQL client written in PHP
PHP
1
star
52

youtube-chill

Library for work with YouTube live chats
JavaScript
1
star
53

rugpt3-langchain

Python
1
star
54

chatgpt-notebooks

Collection of small notebooks for pretraining ChatGPT
Jupyter Notebook
1
star
55

hex-standoff

Programmable Hex Standoff
OpenSCAD
1
star
56

awesome-ubuntu

A curated list of awesome Ubuntu (and Ubuntu-based) operation systems
1
star
57

sum-project

Smart Utility Meter (SUM) is a collection of tools for collecting metrics from different devices like electricity meters
JavaScript
1
star
58

steam-api-client

The SteamAPI PHP Client is a PHP library for interacting with the Steam API. It provides an easy way to fetch data from the Steam platform, such as user profiles, games, and reviews.
PHP
1
star
59

translation-key-helper

Laravel plugin for displaying translation key inside HTML comments nearby translated text strings
PHP
1
star
60

docker-compose-manticoresearch

Composition of docker containers with ManticoreSearch via docker-compose.yml (example)
1
star