API php и работа с ним.

Здесь выкладываем скрипты
Правила форума
Уважаемые Пользователи форума, обратите внимание!
Ни при каких обстоятельствах, Администрация форума, не несёт ответственности за какой-либо, прямой или косвенный, ущерб причиненный в результате использования материалов, взятых на этом Сайте или на любом другом сайте, на который имеется гиперссылка с данного Сайта. Возникновение неисправностей, потерю программ или данных в Ваших устройствах, даже если Администрация будет явно поставлена в известность о возможности такого ущерба.
Просим Вас быть предельно осторожными и внимательными, в использовании материалов раздела. Учитывать не только Ваши пожелания, но и границы возможностей вашего оборудования.
Ответить
Аватара пользователя
podarok66
Модератор
Сообщения: 4355
Зарегистрирован: 11 фев 2012, 18:49
Откуда: МО

Рано или поздно каждый админ сталкивается в теми пользователями, которые очень хотят управлять какими-то функциями подотчётного вам оборудования, а скилованность имеют только для клика мышкой. И всё бы ничего, но иногда административный уровень данного пользователя бывает настолько высок, что высказывать ему претензии по поводу его грамотности и отказывать в его желаниях может выходить здорово дороже, чем сделать так, чтобы и ты был спокоен и начальничек считал, что у него вполне достаточно контроля над ситуацией. Или иной аспект – вам нужно научить кого-то из домашних уровня «дедушка» включать-выключать какие-нибудь правила на домашнем роутере. И в том и в другом из описанных случаев крайне нежелательно видеть кого-либо постороннего в системе управления маршрутизатором.
В Routeros система прав у юзеров меня не устраивает никак, поэтому в очередной раз столкнувшись с ситуацией, я вспомнил об API и о серваке, на котором можно будет решать среди других задач и эту. Приступаем…
Есть Миротик с «белым» IP-адресом. Другие способы (например через Cloud) приконнектиться через API не пробовал.
Есть сервер с Debian 9, на нём развёрнут вебсервер nginx + php-fpm +MariaDB с сайтиком, Zabbix’ом и тому подобной сопутствующей чепухой. В качестве подопытного самое то. Заходим на сервер в директорию с сайтом и создаём там директорию, где и будем ставить опыты.

Код: Выделить всё

cd /var/www/mysite.biz
mkdir mybutton
cd mybutton
В ней создаем файл index.php с минимальным пока содержимым

Код: Выделить всё

touch index.php
nano index.php
Вставляем туда этот минимум (я применяю вариант со входом на страницу по паролю. Это ещё десятка два-три строчек, не слишком сложно, но не тащить же всё в одну статью…)

Код: Выделить всё

<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="css/style.css">
</head>
<!-- Скрипт с функциями. Каждая для определённой кнопки. В поле url ссылка на файл с исполняемым скриптом -->
<script>
function example1() {

            $.ajax({
                type: 'POST',
                url: 'scripts/example1.php',
            });
};

function example2() {

            $.ajax({
                type: 'POST',
                url: 'scripts/example2.php',
            });
};

function example3() {

            $.ajax({
                type: 'POST',
                url: 'scripts/example3.php',

            });
};
function example4() {

            $.ajax({
                type: 'POST',
                url: 'scripts/example4.php',
            });
};
function example5() {

            $.ajax({
                type: 'POST',
                url: 'scripts/example5.php',
            });
};
function example6() {

            $.ajax({
                type: 'POST',
                url: 'scripts/example6.php',
            });
};

</script>
<body>
<div class="wrap">
  <button onclick="example1()"><span><i aria-hidden="true"></i>Первый скрипт</span></button>
  <button onclick="example2()"><span><i aria-hidden="true"></i>Второй скрипт</span></button>
  <button onclick="example3()"><span><i aria-hidden="true"></i>Третий скрипт</span></button>
  <button onclick="example4()"><span><i aria-hidden="true"></i>Четвёртый скрипт</span></button>
  <button onclick="example5()"><span><i aria-hidden="true"></i>Пятый скрипт</span></button>
  <button onclick="example6()"><span><i aria-hidden="true"></i>Шестой скрипт</span></button>
</div>
</body>
</html>
Создаём дополнительные директории, под таблицу стилей и скрипты

Код: Выделить всё

mkdir css
mkdir scripts
Начинаем набивать содержимым

Код: Выделить всё

cd css
touch style.css
nano style.css
Вставляем

Код: Выделить всё

button {
  position: relative;
  display: inline-block;
  background: none;
  outline: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: #800080;
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: .05em;
}
button span {
  position: relative;
  z-index: 1;
  display: block;
  min-width: 1em;
  padding: 1em;
  border-radius: 2em;
  background-color: #8FBC8F;
  border: 1px solid #008080;
  -webkit-box-shadow: -5px 5px 10px rgba(0, 0, 0, 0.2);
          box-shadow: -5px 5px 10px rgba(0, 0, 0, 0.2);
  -webkit-transition: background-color .2s, -webkit-transform .1s, -webkit-box-shadow .2s;
  transition: background-color .2s, -webkit-transform .1s, -webkit-box-shadow .2s;
  transition: transform .1s, box-shadow .2s, background-color .2s;
  transition: transform .1s, box-shadow .2s, background-color .2s, -webkit-transform .1s, -webkit-box-shadow .2s;
}
button::after {
  content: '';
  position: absolute;
  top: -1em;
  bottom: -1em;
  left: -1em;
  right: -1em;
  border-radius: 4em;
  -webkit-box-shadow: 0 0 0px rgba(0, 0, 0, 0.2), inset 0 0 0px rgba(0, 0, 0, 0.2);
          box-shadow: 0 0 0px rgba(0, 0, 0, 0.2), inset 0 0 0px rgba(0, 0, 0, 0.2);
  -webkit-transition: -webkit-box-shadow .1s;
  transition: -webkit-box-shadow .1s;
  transition: box-shadow .1s;
  transition: box-shadow .1s, -webkit-box-shadow .1s;
}
button:hover span, button:focus span {
  background-color: #4682B4;
}
button:active span {
  background-color: #8FBC8F;
  -webkit-transform: scale(0.97);
          transform: scale(0.97);
  -webkit-box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2);
          box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2);
}
button:active::after {
  -webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.2), inset -3px 3px 1em rgba(0, 0, 0, 0.2);
          box-shadow: 0 0 2px rgba(0, 0, 0, 0.2), inset -3px 3px 1em rgba(0, 0, 0, 0.2);
}

body {
  background-color: #8FBC8F;
}

.wrap {
  width: 100%;
  text-align: center;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
}
.wrap button {
  margin: 1em;
}
Таблица стилей пусть будет без объяснений и комментариев, речь не о том сейчас.
Теперь переходим в директорию скриптов и первым делом создаём файл библиотеки api , без которой нам никак

Код: Выделить всё

cd ../scripts
nano routeros_api.class.php
Вставляем

Код: Выделить всё

<?php
/*****************************
 *
 * RouterOS PHP API class v1.6
 * Author: Denis Basta
 * Contributors:
 *    Nick Barnes
 *    Ben Menking (ben [at] infotechsc [dot] com)
 *    Jeremy Jefferson (http://jeremyj.com)
 *    Cristian Deluxe (djcristiandeluxe [at] gmail [dot] com)
 *    Mikhail Moskalev (mmv.rus [at] gmail [dot] com)
 *
 * http://www.mikrotik.com
 * http://wiki.mikrotik.com/wiki/API_PHP_class
 *
 ******************************/
class RouterosAPI
{
    var $debug     = false; //  Show debug information
    var $connected = false; //  Connection state
    var $port      = 8728;  //  Port to connect to (default 8729 for ssl)
    var $ssl       = false; //  Connect using SSL (must enable api-ssl in IP/Services)
    var $timeout   = 3;     //  Connection attempt timeout and data read timeout
    var $attempts  = 5;     //  Connection attempt count
    var $delay     = 3;     //  Delay between connection attempts in seconds
    var $socket;            //  Variable for storing socket resource
    var $error_no;          //  Variable for storing connection error number, if any
    var $error_str;         //  Variable for storing connection error text, if any
    /* Check, can be var used in foreach  */
    public function isIterable($var)
    {
        return $var !== null
                && (is_array($var)
                || $var instanceof Traversable
                || $var instanceof Iterator
                || $var instanceof IteratorAggregate
                );
    }
    /**
     * Print text for debug purposes
     *
     * @param string      $text       Text to print
     *
     * @return void
     */
    public function debug($text)
    {
        if ($this->debug) {
            echo $text . "\n";
        }
    }
    /**
     *
     *
     * @param string        $length
     *
     * @return void
     */
    public function encodeLength($length)
    {
        if ($length < 0x80) {
            $length = chr($length);
        } elseif ($length < 0x4000) {
            $length |= 0x8000;
            $length = chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
        } elseif ($length < 0x200000) {
            $length |= 0xC00000;
            $length = chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
        } elseif ($length < 0x10000000) {
            $length |= 0xE0000000;
            $length = chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
        } elseif ($length >= 0x10000000) {
            $length = chr(0xF0) . chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
        }
        return $length;
    }
    /**
     * Login to RouterOS
     *
     * @param string      $ip         Hostname (IP or domain) of the RouterOS server
     * @param string      $login      The RouterOS username
     * @param string      $password   The RouterOS password
     *
     * @return boolean                If we are connected or not
     */
    public function connect($ip, $login, $password)
    {
        for ($ATTEMPT = 1; $ATTEMPT <= $this->attempts; $ATTEMPT++) {
            $this->connected = false;
            $PROTOCOL = ($this->ssl ? 'ssl://' : '' );
            $context = stream_context_create(array('ssl' => array('ciphers' => 'ADH:ALL', 'verify_peer' => false, 'verify_peer_name' => false)));
            $this->debug('Connection attempt #' . $ATTEMPT . ' to ' . $PROTOCOL . $ip . ':' . $this->port . '...');
            $this->socket = @stream_socket_client($PROTOCOL . $ip.':'. $this->port, $this->error_no, $this->error_str, $this->timeout, STREAM_CLIENT_CONNECT,$context);
            if ($this->socket) {
                socket_set_timeout($this->socket, $this->timeout);
                $this->write('/login', false);
                $this->write('=name=' . $login, false);
                $this->write('=password=' . $password);
                $RESPONSE = $this->read(false);
                if (isset($RESPONSE[0])) {
                    if ($RESPONSE[0] == '!done') {
                        if (!isset($RESPONSE[1])) {
                            // Login method post-v6.43
                            $this->connected = true;
                            break;
                        } else {
                            // Login method pre-v6.43
                            $MATCHES = array();
                            if (preg_match_all('/[^=]+/i', $RESPONSE[1], $MATCHES)) {
                                if ($MATCHES[0][0] == 'ret' && strlen($MATCHES[0][1]) == 32) {
                                    $this->write('/login', false);
                                    $this->write('=name=' . $login, false);
                                    $this->write('=response=00' . md5(chr(0) . $password . pack('H*', $MATCHES[0][1])));
                                    $RESPONSE = $this->read(false);
                                    if (isset($RESPONSE[0]) && $RESPONSE[0] == '!done') {
                                        $this->connected = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                fclose($this->socket);
            }
            sleep($this->delay);
        }
        if ($this->connected) {
            $this->debug('Connected...');
        } else {
            $this->debug('Error...');
        }
        return $this->connected;
    }
    /**
     * Disconnect from RouterOS
     *
     * @return void
     */
    public function disconnect()
    {
        // let's make sure this socket is still valid.  it may have been closed by something else
        if( is_resource($this->socket) ) {
            fclose($this->socket);
        }
        $this->connected = false;
        $this->debug('Disconnected...');
    }
    /**
     * Parse response from Router OS
     *
     * @param array       $response   Response data
     *
     * @return array                  Array with parsed data
     */
    public function parseResponse($response)
    {
        if (is_array($response)) {
            $PARSED      = array();
            $CURRENT     = null;
            $singlevalue = null;
            foreach ($response as $x) {
                if (in_array($x, array('!fatal','!re','!trap'))) {
                    if ($x == '!re') {
                        $CURRENT =& $PARSED[];
                    } else {
                        $CURRENT =& $PARSED[$x][];
                    }
                } elseif ($x != '!done') {
                    $MATCHES = array();
                    if (preg_match_all('/[^=]+/i', $x, $MATCHES)) {
                        if ($MATCHES[0][0] == 'ret') {
                            $singlevalue = $MATCHES[0][1];
                        }
                        $CURRENT[$MATCHES[0][0]] = (isset($MATCHES[0][1]) ? $MATCHES[0][1] : '');
                    }
                }
            }
            if (empty($PARSED) && !is_null($singlevalue)) {
                $PARSED = $singlevalue;
            }
            return $PARSED;
        } else {
            return array();
        }
    }
    /**
     * Parse response from Router OS
     *
     * @param array       $response   Response data
     *
     * @return array                  Array with parsed data
     */
    public function parseResponse4Smarty($response)
    {
        if (is_array($response)) {
            $PARSED      = array();
            $CURRENT     = null;
            $singlevalue = null;
            foreach ($response as $x) {
                if (in_array($x, array('!fatal','!re','!trap'))) {
                    if ($x == '!re') {
                        $CURRENT =& $PARSED[];
                    } else {
                        $CURRENT =& $PARSED[$x][];
                    }
                } elseif ($x != '!done') {
                    $MATCHES = array();
                    if (preg_match_all('/[^=]+/i', $x, $MATCHES)) {
                        if ($MATCHES[0][0] == 'ret') {
                            $singlevalue = $MATCHES[0][1];
                        }
                        $CURRENT[$MATCHES[0][0]] = (isset($MATCHES[0][1]) ? $MATCHES[0][1] : '');
                    }
                }
            }
            foreach ($PARSED as $key => $value) {
                $PARSED[$key] = $this->arrayChangeKeyName($value);
            }
            return $PARSED;
            if (empty($PARSED) && !is_null($singlevalue)) {
                $PARSED = $singlevalue;
            }
        } else {
            return array();
        }
    }
    /**
     * Change "-" and "/" from array key to "_"
     *
     * @param array       $array      Input array
     *
     * @return array                  Array with changed key names
     */
    public function arrayChangeKeyName(&$array)
    {
        if (is_array($array)) {
            foreach ($array as $k => $v) {
                $tmp = str_replace("-", "_", $k);
                $tmp = str_replace("/", "_", $tmp);
                if ($tmp) {
                    $array_new[$tmp] = $v;
                } else {
                    $array_new[$k] = $v;
                }
            }
            return $array_new;
        } else {
            return $array;
        }
    }
    /**
     * Read data from Router OS
     *
     * @param boolean     $parse      Parse the data? default: true
     *
     * @return array                  Array with parsed or unparsed data
     */
    public function read($parse = true)
    {
        $RESPONSE     = array();
        $receiveddone = false;
        while (true) {
            // Read the first byte of input which gives us some or all of the length
            // of the remaining reply.
            $BYTE   = ord(fread($this->socket, 1));
            $LENGTH = 0;
            // If the first bit is set then we need to remove the first four bits, shift left 8
            // and then read another byte in.
            // We repeat this for the second and third bits.
            // If the fourth bit is set, we need to remove anything left in the first byte
            // and then read in yet another byte.
            if ($BYTE & 128) {
                if (($BYTE & 192) == 128) {
                    $LENGTH = (($BYTE & 63) << 8) + ord(fread($this->socket, 1));
                } else {
                    if (($BYTE & 224) == 192) {
                        $LENGTH = (($BYTE & 31) << 8) + ord(fread($this->socket, 1));
                        $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
                    } else {
                        if (($BYTE & 240) == 224) {
                            $LENGTH = (($BYTE & 15) << 8) + ord(fread($this->socket, 1));
                            $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
                            $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
                        } else {
                            $LENGTH = ord(fread($this->socket, 1));
                            $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
                            $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
                            $LENGTH = ($LENGTH << 8) + ord(fread($this->socket, 1));
                        }
                    }
                }
            } else {
                $LENGTH = $BYTE;
            }
            $_ = "";
            // If we have got more characters to read, read them in.
            if ($LENGTH > 0) {
                $_      = "";
                $retlen = 0;
                while ($retlen < $LENGTH) {
                    $toread = $LENGTH - $retlen;
                    $_ .= fread($this->socket, $toread);
                    $retlen = strlen($_);
                }
                $RESPONSE[] = $_;
                $this->debug('>>> [' . $retlen . '/' . $LENGTH . '] bytes read.');
            }
            // If we get a !done, make a note of it.
            if ($_ == "!done") {
                $receiveddone = true;
            }
            $STATUS = socket_get_status($this->socket);
            if ($LENGTH > 0) {
                $this->debug('>>> [' . $LENGTH . ', ' . $STATUS['unread_bytes'] . ']' . $_);
            }
            if ((!$this->connected && !$STATUS['unread_bytes']) || ($this->connected && !$STATUS['unread_bytes'] && $receiveddone)) {
                break;
            }
        }
        if ($parse) {
            $RESPONSE = $this->parseResponse($RESPONSE);
        }
        return $RESPONSE;
    }
    /**
     * Write (send) data to Router OS
     *
     * @param string      $command    A string with the command to send
     * @param mixed       $param2     If we set an integer, the command will send this data as a "tag"
     *                                If we set it to boolean true, the funcion will send the comand and finish
     *                                If we set it to boolean false, the funcion will send the comand and wait for next command
     *                                Default: true
     *
     * @return boolean                Return false if no command especified
     */
    public function write($command, $param2 = true)
    {
        if ($command) {
            $data = explode("\n", $command);
            foreach ($data as $com) {
                $com = trim($com);
                fwrite($this->socket, $this->encodeLength(strlen($com)) . $com);
                $this->debug('<<< [' . strlen($com) . '] ' . $com);
            }
            if (gettype($param2) == 'integer') {
                fwrite($this->socket, $this->encodeLength(strlen('.tag=' . $param2)) . '.tag=' . $param2 . chr(0));
                $this->debug('<<< [' . strlen('.tag=' . $param2) . '] .tag=' . $param2);
            } elseif (gettype($param2) == 'boolean') {
                fwrite($this->socket, ($param2 ? chr(0) : ''));
            }
            return true;
        } else {
            return false;
        }
    }
    /**
     * Write (send) data to Router OS
     *
     * @param string      $com        A string with the command to send
     * @param array       $arr        An array with arguments or queries
     *
     * @return array                  Array with parsed
     */
    public function comm($com, $arr = array())
    {
        $count = count($arr);
        $this->write($com, !$arr);
        $i = 0;
        if ($this->isIterable($arr)) {
            foreach ($arr as $k => $v) {
                switch ($k[0]) {
                    case "?":
                        $el = "$k=$v";
                        break;
                    case "~":
                        $el = "$k~$v";
                        break;
                    default:
                        $el = "=$k=$v";
                        break;
                }
                $last = ($i++ == $count - 1);
                $this->write($el, $last);
            }
        }
        return $this->read();
    }
    /**
     * Standard destructor
     *
     * @return void
     */
    public function __destruct()
    {
        $this->disconnect();
    }
}
По ссылке https://github.com/BenMenking/routeros-api есть и библиотека и примеры использования. К сожалению, ссылка на страницу в Микротиковскую Вики устарела.
Теперь создадим файл example1.php , который станет своеобразным шаблоном для наших файлов-скриптов

Код: Выделить всё

touch example1.php
nano example1.php
Содержание шаблона во многом взято с официального форума, кое-что переделано под личные нужды. Главное, это понимание, что обратиться к скрипту на Микротике просто по имени не получится. Поэтому делаем финт ушами с определением id скрипта.

Код: Выделить всё

<?php

require_once('routeros_api.class.php');

$API = new RouterosAPI();

$API->debug = false;

if ($API->connect('Your_IP', 'api_login', 'api_password')) {

$API->write('/system/script/getall', false);
$API->write('=.proplist=.id',false);
$API->write('?name=Script name in Mikrotik');
$READ = $API->read(false);
$ARRAY = $API->parseResponse($READ);
if(isset($ARRAY['0']) && isset($ARRAY['0']['.id'])){
	$API->write('/system/script/run',false);
	$API->write('=.id='. $ARRAY['0']['.id']);
	$READ = $API->read(false);
}
$API->disconnect();
}
?>
Теперь, вставляя в строку

Код: Выделить всё

if ($API->connect('Your_IP', 'api_login', 'api_password')) { 
свои данные авторизации на Микротике, и в строку

Код: Выделить всё

$API->write('?name=Script name in Mikrotik');
вместо слов Script name in Mikrotik нужное имя скрипта в Микротике, можно создавать файлы-скрипты для исполнения скриптов на Микротике.
На сервере пока всё. Идём на Микротик. Создаём нового пользователя в группе full (потом экспериментально можно подобрать нужный набор разрешений)

Код: Выделить всё

/user add name=testapi group=full password=apitestapi
К сервису api разрешаем доступ с адреса сервера, остальные нам ни к чему.

Код: Выделить всё

/ip service set api disabled=no address=IP_Mikrotik port=8728
Осталось создать скрипт с именем Script name in Mikrotik (ну или какое там вы выбрали, главное, чтобы имя совпадало с именем, указываемым в файле example1.php)

Код: Выделить всё

/system script add name="Script name in Mikrotik" owner=testapi source=":log info \"Script run!!!\""
Теперь идём по адресу http://mysite.biz/mybutton/index.php и видим кнопочки. Нажимаем на первую и в логе Микротика должно выскочить сообщение Script run!!! Теперь по аналогии можно запускать любые скрипты на этом Микротике. Только пишите, привязывайте к кнопкам и следите за ошибками. Количество Микротиков , кстати, тоже может быть разное.
Искренне надеюсь, что у вас получится с первого раза.
Изображение
Теперь самое время заняться безопасностью. Забрать лишние права у пользователя, переведя его в отдельную группу. Работоспособность проверяйте пошагово. Страницу сайта надо бы закрыть паролем, если кому-то очень надо, у меня есть простейший вариант, я покажу.
На этом всё. Всем спокойствия и удачи в настройках. Ваш podarok66.
P. S.: Посмотрел нужную группу прав, вышло немного непонятно

Код: Выделить всё

add name=api policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,api,romon,!local,!telnet,!ssh,!winbox,!web,!dude,!tikapp
Причём в политиках romon должен быть включен обязательно, без него не работает. А вот сам Tool->RoMON может быть и выключен. Странновато...
Ну и самое главное. Не всё опубликованное авторский код. Часть честно взята из свободного доступа в сети и перелопачена под себя. Выражаю бесконечную признательность illinory за помощь с ajax, библиотекой и вообще за интеллектуальную и моральную поддержку. Без его багажа знаний всё было бы неизмеримо сложнее.


Мануалы изучил и нигде не ошибся? Фаервол отключил? Очереди погасил? Витая пара проверена? ... Тогда Netinstal'ом железку прошей и настрой ее заново. Что, все равно не фурычит? Тогда к нам. Если не подскажем, хоть посочувствуем...
Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Вот вот. Отлично !
А ещё хорошо бы для этих целей в Winbox разрабы сделали бы Dashboard, куды можно было бы вынести свои кнопочки со своими названиями и под них подставить действия и/или скрипты. И отдельную галку для users "dashboard". Тогда можно было бы дать юзеру права "только dashboard" и "тупой" юзер мог бы в Winbox видеть только настроенную панель с кнопочками и тыкать в них ...


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Inner
Сообщения: 248
Зарегистрирован: 01 июл 2020, 16:02

Пробовал сделать строго по инструкции с одной лишь разницей. У меня была ubuntu. И не работает. Если верить самому микротику, то до него даже соединение не доходит. Где я мог ошибиться? Разжуйте пожалуйста поподробнее что куда вписывать. Подозреваю что какую-то банальную и просту вещь не учел, которая даже в инструкции не оговаривалась


Inner
Сообщения: 248
Зарегистрирован: 01 июл 2020, 16:02

После кучи тестов, появилось подозрение что что-то не так с routeros_api.class.php. При любых тестах он не инициирует подключение к микротику. Попробовал взять с гитхаба (там вроде как посвежее ибо строк кода больше, но могу и ошибаться), но всё тщетно. Не работает. Ещё подумал что беда с присоединением в example1.php, но оно вроде как отрабатывает должным образом. Как посмотреть где именно затык происходит, я так и не понял.


Inner
Сообщения: 248
Зарегистрирован: 01 июл 2020, 16:02

Был бы я внимательнее, то заметил бы раньше. API микротикп на проштвках новее чем 6.45 не работает с php как раньше. В вики микротикп об этом подробно описано и рекомендуют использовать python


Ответить