Page 1 of 1

Add openvpn user using API or terminal

Posted: Tue May 23, 2017 11:16 pm
by Krisken
Hello,
At this moment I add a VPN user using winbox : http://imgur.com/a/NYBDS
Do somebody know how I can do this using PHP (API) or using the Terminal window?

Kris

Re: Add openvpn user using API or terminal

Posted: Tue May 23, 2017 11:35 pm
by boen_robot
Using the API client from my signature:
<?php
use PEAR2\Net\RouterOS;
require_once 'PEAR2_Net_RouterOS-1.0.0b6.phar';

$util = new RouterOS\Util($client = new RouterOS\Client('44.144.126.80', 'admin', 'mypassword'));

$util->setMenu('/ppp secret')->add(array(
'name' => 'kris-homeoffice',
'password' => 'mypassword',
'service' => 'ovpn',
'remote-address' => '127.27.0.3'
));
or from a terminal window:
/ppp secret add name="kris-homeoffice" password="mypassword" service="ovpn" remote-address="127.27.0.3"

Re: Add openvpn user using API or terminal

Posted: Fri May 26, 2017 4:53 pm
by Krisken
Thanks for your reply!
Another question : how can i figure out what the next ip is that I have to use for the VPN connection, using PHP?

Please see http://imgur.com/a/Kp7ne

As you can see, the latest used Remote Address IP is 172.28.1.46, with 172.29.46.0/24 as routed range.
Any way that PHP can find this out, and use Remote Address IP 172.28.1.47 (routed range 172.29.47.0/24) for the next user?

Re: Add openvpn user using API or terminal

Posted: Fri May 26, 2017 5:13 pm
by boen_robot
Hmm... I can't think of a "trivial" way to do it, but there are a few non-trivial ones you can try.

The most optimal way would be to keep a known reference with the latest IP, and use that when making the command.

First, run from a terminal
:global OVPNIP 172.28.1.47
to set up a global RouterOS variable, holding the latest IP. This needs to be done from terminal and not from API, because the value needs to be of the scripting type "ip", and last I checked, the API can only create string global variables.

And then, from PHP
$util->setMenu('/ppp secret')->exec('
add name=$name password=$password service="ovpn" remote-address=($OVPNIP+1) routes="172.29.46.0/24";
:set OVPNIP ($OVPNIP+1);
', array(
'name' => 'kris-homeoffice',
'password' => 'mypassword'
));
(the exec() method runs an "actual" terminal script, with local variables supplied in the array at the second argument)

OR

If you want to avoid the burden of keeping track of the latest IP, you can figure it out by looping through the list to find the biggest one and then use that as your basis of computing the next IP. e.g.
$util->setMenu('/ppp secret');

$secrets = $util->getAll(array('.proplist' => 'remote-address'));
$max = ip2long('172.28.1.0');//Start of pool-1
foreach ($secrets as $secret) {
$candidate = ip2long($secret('remote-address'));
if ($candidate > $max) {
$max = $candidate;
}
}

$util->add(array(
'name' => 'kris-homeoffice',
'password' => 'mypassword',
'service' => 'ovpn',
'remote-address' => long2ip($max+1),
'routes' => '172.29.46.0/24'
));
Now... I haven't benchmarked either of those, but I would guess that the second option would be more efficient for a dozen or so users... While the first one may be preferable once you have like 255+ users. The first option makes 3 API calls (add temp script, run temp script, remove temp script), which is not very efficient. The second one makes 2 API calls, but spends big time downloading and looping over the results from the first, meaning that as the results grow, there will be a point where the extra API call is actually more efficient. This tipping point is pushed further away with the ".proplist" part in getAll(), but it still exists.