ลองต่อ Mikrotik API ด้วย PEAR2/Net_RouterOS กันเถอะ
บอกตรง ๆ คือเราสาย Engineer ไม่ค่อยได้เขียน app จริง ๆ จัง ๆ คราวนี้อยากจะพัฒนา Chat Bot ให้ทำอย่างอื่นได้ด้วยนอกจากแค่แจ้ง Alert จาก servers หรือ devices ต่าง ๆ ได้โจทย์จากอาจารย์ศุภชัย อยากได้ bot ดึงข้อมูลหรือสั่งงาน Mikrotik ได้ เลยเป็นที่มาของบทความนี้
จริง ๆ แล้ว Mikrotik เองมี API ให้ใช้ตรง ๆ เลยสามารถหาอ่านได้ >>ที่นี่ << ครับ แต่มันจะต้องเขียน rest ทุกอย่างเอง แล้วตัวบอทเราทำงานด้วยภาษา PHP อยู่ (เพิ่งเปลี่ยนจาก structure file มากเป็น framework ด้วย) ดังนั้นเลยหา Library สำเร็จแล้วจนมาเจอ PEAR2/Net_RouterOS นี้เอง :D
เอาละมาดู requirement ของ PEAR2/Net_RouterOS กัน
- PHP ≥ 5.3.0
- PEAR2/Net_Transmitter
- prce extention
ต่อไปมาดูขั้นตอนการติดตั้งกัน มันก็มีหลายวิธีนะครับ ตั้งแต่ใช้คำสั่ง pear install หรือไม่ก็โหลดไฟล์ .phar จากหน้าเว็บ project มาแล้วก็ require ไฟล์ได้เลย แต่วันนี้จะนำเสนอการติดตั้งผ่าน composer (กำลังเห่อ) อย่างแรกก็ต้องไปติด composer ก่อนไปดูที่นี่เลย >> https://getcomposer.org/ เริ่มขี้เกียจละ ฮ่า
สร้างไฟล์ composer.json ใน project folder ได้เลยครับ
{
"description": "Mikrotik API project",
"name": "icyland/mikrotik",
"type": "project",
"homepage": "https://qooblog.com",
"license": "MIT",
"require": {
"php": ">=5.3.0",
"monolog/monolog": "*",
"pear2/net_routeros": ">=1.0.0b6",
"pear2/net_transmitter": ">=1.0.0b1",
"pear2/cache_shm": "*@alpha",
"pear2/console_commandline": "*@alpha",
"pear2/console_color": "*"
}
}
ประมาณนี้ แล้วก็สั่ง composer install ได้เลย จะได้ output ประมาณนี้
ต่อไปเรามาเปิด API ให้กับ request ให้กับ mikrotik กัน ให้ shell ไปที่ mikrotik แล้วใช้คำสั่งประมาณนี้ครับ และนำแนะให้เปลี่ยน port ด้วยนะครับไม่ควรใช้ port default ที่ให้มา ถ้าใครมี SSL Certificate ยิ่งดีเลยครับ ใช้ api-ssl แทนได้เลย
/ip service enable api
/ip service set api port=18728
การเปลี่ยน Port นี้ผมเปลี่ยจากเดิม 8728 เป็น 18728 ถ้าใครทำ firewall ไว้อย่าลืมไปเปิดกัน
ข้อแนะนำการเปิด service ผ่าน public IP ไม่ควรใช้ default port นะครับ ช่วยจะลดการ brute-force ได้ในระดับหนึ่ง
จบจากการเตรียมการมาเริ่มเขียน script กันเลย ให้เราสร้างไฟล์ script-mikrotik.php ใน folder project ของเราครับ
ขั้นแรกให้เรา require autoload แล้วเรียก class ที่เราจะใช้งานดังนี้ครับ
<?php
require_once './vendor/autoload.php';
use PEAR2\Net\RouterOS;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler;
เอ่าละมาดูในส่วนของการเปิด connection ไปหา mikrotik กันดีกว่า
try {
$client = new RouterOS\Client('192.168.88.1', 'admin', 'password, 18728);
} catch (Exception $e) {
error_log("Cannot create connection => ". var_export($e, true));
die();
}
อธิบายในส่วนของ connection นิดนึงก่อน
$client = new RouterOS\Client('192.168.88.1', 'admin', 'password, 18728);
คือการเปิด connection string ไปหา mikrotik IP 192.168.88.1 ด้วย username admin และรหัสผ่านว่า password และต่อไปที่ Port 18728 ครับ ถ้าใครใช้ port default ก็จะมารูปแบบนี้
$client = new RouterOS\Client('192.168.88.1', 'admin', 'password');
เรามาดู error ถ้าเกิดใส่ connection ผิดอย่างเช่น รหัสผ่านกันดีกว่า
คำอธิบาย error เข้าใจได้ง่ายดีนะครับ มาดูตัวอย่างในกรณี connect mikrotik ไม่ หรือใส่ IP และ Port ผิดกันดีกว่า
ในส่วนของ error ที่ไม่สามารถเชื่อมต่อได้นี้จะยาวไปหน่อย แต่ก็สามารถอ่านได้ง่ายเหมือนกัน :D
ต่อไปเรามาสร้าง request string และ query กันแบบนี้
$request = new RouterOS\Request('/system/resource/print');
try {
$responses = $client->sendSync($request);
} catch (Exception $e) {
error_log("Cannot query your request => " . var_export($e, true));
die();
}
อธิบายในส่วนของการสั่ง command ไปยัง mikrotik ในตัวอย่างที่ทำคือการเรียกดูข้อมูล resources ของ mikrotik ด้วย command /system request print นั้นเอง ถ้าสั่งผ่าน shell ของ mikrotik จะได้ตามรูปข้างล่างนี้
มาดูตัวแปร $request กัน โดยที่ตัวแปรนี้จะเป็นการเรียก library มาสร้างเป็น command string ไปยัง API โดยที่
$request = new RouterOS\Request('/system/resource/print');
จะแปลง cli command /system resource print ให้เป็น ‘/system/resoure/print’ โดยที่จะเปลี่ยน {space} ให้เป็น / แทน
และมาดูที่ $responses กัน โดยที่ $responses จะเป็นการส่ง query string ที่ได้จาก $request ไปยัง connection ได้ผลที่เราต้องการออกมาครับ มาดูการดึง query ออกมากัน
foreach ($responses as $response) {
foreach ($response as $name => $value) {
echo "{$name}: {$value}\n";
}
}
พอเสร็จแล้วก็ใช้คำสั่ง php script-mikrotik.php แล้วจะได้ output ออกมาตามรูปครับ
เป็นอย่างไรบ้างครับ ง่ายเนอะ ต่อไปจะเอาดัดแปลงยังไงก็ตามแต่เลยครับ :D ตามดู code เต็ม ๆ ได้ที่ github ครับ
Ref.
https://wiki.mikrotik.com/wiki/Manual:API
http://pear2.php.net/PEAR2_Net_RouterOS
https://github.com/pear2/Net_RouterOS/wiki/Getting-started