Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a plugin for Netbird #4531

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions net/netbird/+POST_INSTALL.post
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
chmod +x /usr/local/etc/rc.syshook.d/carp/30-netbird
chmod +x /usr/local/opnsense/scripts/OPNsense/netbird/initialup.sh
/etc/rc.d/os-release start
10 changes: 10 additions & 0 deletions net/netbird/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
PLUGIN_NAME= netbird
PLUGIN_VERSION= 0.8
PLUGIN_REVISION= 1
PLUGIN_DEPENDS= netbird
PLUGIN_COMMENT= Netbird plugin
PLUGIN_MAINTAINER= opn-netbird@sun-ri.se
PLUGIN_WWW= https:/netbird.io
PLUGIN_DEVEL= no
PLUGIN_SUFFIX=
.include "../../Mk/plugins.mk"
1 change: 1 addition & 0 deletions net/netbird/pkg-descr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Netbird plugin for OPNSense
30 changes: 30 additions & 0 deletions net/netbird/src/etc/inc/plugins.inc.d/netbird.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

function netbird_enabled()
{
$mdlNetbird = new \OPNsense\netbird\Netbird();
return $mdlNetbird->general->Enabled->__toString() == 1;
}

function netbird_services()
{
$services = array();

if (!netbird_enabled()) {
return $services;
}

$services[] = array(
'description' => gettext('Netbird'),
'configd' => array(
'restart' => array('netbird restart'),
'start' => array('netbird start'),
'stop' => array('netbird stop'),
),
'name' => 'netbird',
'pidfile' => '/var/run/netbird.pid'
);

return $services;
}

52 changes: 52 additions & 0 deletions net/netbird/src/etc/rc.syshook.d/carp/30-netbird
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/local/bin/php
<?php


require_once('config.inc');
require_once('util.inc');
require_once('interfaces.inc');


$model = new \OPNsense\netbird\Netbird();
$enabled = $model->general->Enabled->__toString();


if(!$enabled) {
exit(0);
}

$carpif = $model->general->CarpIf->__toString();

if($carpif == '') {
exit(0);
}

$target_vhid = $model->general->VHID;
$subsystem = !empty($argv[1]) ? $argv[1] : '';
$type = !empty($argv[2]) ? $argv[2] : '';

if ($type != 'MASTER' && $type != 'BACKUP') {
exit(1);
}

if (!strstr($subsystem, '@')) {
exit(1);
}

list ($vhid, $iface) = explode('@', $subsystem);
$friendly = convert_real_interface_to_friendly_interface_name($iface);


if ($carpif != $friendly || $vhid != $target_vhid) {
exit(0);
}

switch ($type) {
case 'MASTER':
shell_exec('/usr/local/bin/netbird up');
break;
case 'BACKUP':
shell_exec('/usr/local/bin/netbird down');
break;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php


namespace OPNsense\netbird\Api;

use OPNsense\Base\ApiMutableModelControllerBase;

/**
* netbird settings controller
* @package OPNsense\netbird
*/
class InitialController extends ApiMutableModelControllerBase
{
protected static $internalModelName = 'netbird';
protected static $internalModelClass = 'OPNsense\netbird\Initial';

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
<?php

namespace OPNsense\netbird\Api;

use OPNsense\Base\ApiMutableServiceControllerBase;
use OPNsense\Core\Backend;
use OPNsense\Core\Config;
use OPNsense\netbird\Initial;
use OPNsense\netbird\Netbird;


/**
* Class ServiceController
* @package OPNsense\netbird
*/
class ServiceController extends ApiMutableServiceControllerBase
{
const NETBIRD_CONFIG_JSON = '/usr/local/etc/netbird/config.json';
protected static $internalServiceClass = '\OPNsense\netbird\Netbird';
protected static $internalServiceEnabled = 'general.Enabled';
protected static $internalServiceTemplate = 'OPNsense/netbird';
protected static $internalServiceName = 'netbird';

public function conStatusAction(): string
{
$backend = new Backend();
$bckResult = $backend->configdRun("netbird con-status");
if ($bckResult !== null) {
return nl2br(htmlspecialchars($bckResult));
}
return "Error retrieving connection status";
}

public function searchFilter($array, $value): bool
{
foreach ($array as $val) {
if (str_contains(strval($val), strtolower($value))) {
return true;
}
}
return false;
}

public function upDownStatusAction(): string
{
$backend = new Backend();
$bckResult = $backend->configdRun("netbird status");
if (!str_contains($bckResult, "is running")) {
return json_encode(array('updown' => "NOT RUNNING", 'status' => "Netbird is not running"));
}
$bckResult = $backend->configdRun("netbird short-con-status");
$txtStatus = nl2br(htmlspecialchars($bckResult));
$bckResult = $backend->configdRun("netbird con-status-json");
$status = json_decode($bckResult, true);
if (!$status['publicKey']) {
return json_encode(array('updown' => "DOWN", 'status' => $txtStatus));
}
return json_encode(array('updown' => "UP", 'status' => $txtStatus));
}

public function searchAction(): string
{
$request = $this->request;
$backend = new Backend();
$bckResult = $backend->configdRun("netbird status");
if (!str_contains($bckResult, "is running")) {
return json_encode(array('current' => 1, 'rowCount' => 0, 'total' => 0, 'rows' => array()));
}
$bckResult = $backend->configdRun("netbird con-status-json");
$status = json_decode($bckResult, true);
$itemsPerPage = $request->get('rowCount', 'int', -1);
$currentPage = $request->get('current', 'int', 1);
$sortBy = array('status');
$sortDescending = false;


$searchPhrase = strtolower($request->get('searchPhrase', 'string', ''));
if (!$status['peers']['details']) {
return json_encode(array('current' => 1, 'rowCount' => 0, 'total' => 0, 'rows' => array()));
}
$details = $status['peers']['details'];
$details = array_filter($details, function ($item) use ($searchPhrase) {
return $this->searchFilter($item, $searchPhrase);
});
$detailsFlat = array();
foreach ($details as $detail) {
$detailsFlat[] = $this->flattenOneLevel($detail);
}
if ($request->hasPost('sort') && is_array($request->get("sort")) && !empty($request->get("sort"))) {
$sortBy = array_keys($request->get("sort"));
if (!empty($sortBy) && $request->get("sort")[$sortBy[0]] == "desc") {
$sortDescending = true;
}

}
$sortValues = array();
foreach ($detailsFlat as $detail) {
$sortValues[] = $detail[$sortBy[0]];
}
array_multisort($sortValues, $sortDescending ? SORT_DESC : SORT_ASC, $detailsFlat);
$page = array_slice($detailsFlat, ($currentPage - 1) * $itemsPerPage, $itemsPerPage);
$page = $this->convertFieldsToDisplay($page);
$result = array('current' => $currentPage, 'rowCount' => count($page), 'total' => count($detailsFlat), 'rows' => $page);
return json_encode($result);
}

private function flattenOneLevel($array): array
{
$result = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
foreach ($value as $subkey => $subvalue) {
if ($key == "routes") {
$result[$key] = implode("<br />", $value);
}
else {
$result[$key . "." . $subkey] = $subvalue;
}
}
} else {
$result[$key] = $value;
}
}
return $result;
}

public function setUpAction(): string
{
$backend = new Backend();
try {
return $backend->configdRun("netbird set-up");
} catch (\Exception $e) {
return "Error running netbird up" . "\n" . $e->getMessage();
}
}

public function initialUpAction(): string
{
$backend = new Backend();
$mdlInitial = new Initial();
$key = $mdlInitial->initial->setupkey->__toString();
$api = $mdlInitial->initial->mgmtservice->__toString();
$hostname = $mdlInitial->initial->hostname->__toString();
if ($hostname == "") {
$hostname = gethostname();
if(!$hostname){
$hostname = "OPNsense";
}else{
if(str_contains($hostname, ".")){
$hostname = explode(".", $hostname)[0];
}
}

$mdlInitial->initial->hostname = $hostname;
}
$mdlInitial->initial->setupkey = "00000000-0000-0000-0000-000000000000";
$mdlInitial->initial->initsure = 0;

$mdlInitial->serializeToConfig();
$cnf = Config::getInstance();
$cnf->save();

$bckresult = $backend->configdRun("netbird set-up-initial " . escapeshellarg($api) . " " . escapeshellarg($key) . " " . escapeshellarg($hostname));
return nl2br(htmlspecialchars($bckresult));
}

public function setDownAction(): string
{
$backend = new Backend();
try {
return $backend->configdRun("netbird set-down");
} catch (\Exception $e) {
return "Error running netbird down" . "\n" . $e->getMessage();
}
}

public function reloadAction()
{
$status = "failed";
if ($this->request->isPost()) {
try {
$mdlNetbird = new Netbird();
$backend = new Backend();
if (trim($backend->configdRun('template reload OPNsense/netbird')) == "OK") {
$status = "ok";
}

$enabled = $mdlNetbird->general->Enabled->__toString() == 1;
$carpEnabled = $mdlNetbird->general->CarpIf->__toString() != '';
$disableClientRoutes = $mdlNetbird->general->DisableClientRoutes->__toString() == 1;
$disableServerRoutes = $mdlNetbird->general->DisableServerRoutes->__toString() == 1;
$disableDNS = $mdlNetbird->general->DisableDNS->__toString() == 1;
$rpEnabled = $mdlNetbird->general->QuantumEnabled->__toString() == 1;
$rpPermissive = $mdlNetbird->general->QuantumPermissive->__toString() == 1;
$wgPort = $mdlNetbird->general->WgPort->__toString();
$netbirdConfigJson = file_get_contents(self::NETBIRD_CONFIG_JSON);
$netbirdConfig = json_decode($netbirdConfigJson, true);
$netbirdConfig["DisableAutoConnect"] = $carpEnabled;
$netbirdConfig["DisableClientRoutes"] = $disableClientRoutes;
$netbirdConfig["DisableServerRoutes"] = $disableServerRoutes;
$netbirdConfig["DisableDNS"] = $disableDNS;
$netbirdConfig["RosenpassEnabled"] = $rpEnabled;
$netbirdConfig["RosenpassPermissive"] = $rpPermissive;
$netbirdConfig["WgPort"] = intval($wgPort);
$netbirdConfigJson = json_encode($netbirdConfig);
file_put_contents(self::NETBIRD_CONFIG_JSON, $netbirdConfigJson);
$action = $enabled ? "restart" : "stop";
$backend->configdRun("netbird $action");
} catch (\Exception $e) {
$status = "failed";
syslog(LOG_ERR, "netbird: failed to reload configuration: " . $e->getMessage());
}
}
return array("status" => $status);
}

/**
* @param array $page
* @return array
*/
public function convertFieldsToDisplay(array $page): array
{
for ($i = 0; $i < count($page); $i++) {
$page[$i]['latency'] = round($page[$i]['latency'] / 1000000, 2) . " ms";
$received = $page[$i]['transferReceived'];
$rcvUnit = "KiB";
$received /= 1024;
if ($received > 1024) {
$received /= 1024;
$rcvUnit = "MiB";
}
if ($received > 1024) {
$received /= 1024;
$rcvUnit = "GiB";
}

$sent = $page[$i]['transferSent'];
$sentUnit = "KiB";
$sent /= 1024;
if ($sent > 1024) {
$sent /= 1024;
$sentUnit = "MiB";
}
if ($sent > 1024) {
$sent /= 1024;
$sentUnit = "GiB";
}
$page[$i]['transferReceived'] = round($received, 2) . " " . $rcvUnit;
$page[$i]['transferSent'] = round($sent, 2) . " " . $sentUnit;
$page[$i]['lastStatusUpdate'] = date("Y-m-d H:i:s", strtotime($page[$i]['lastStatusUpdate']));
$page[$i]['lastWireguardHandshake'] = date("Y-m-d H:i:s", strtotime($page[$i]['lastWireguardHandshake']));
foreach ($page[$i] as $key => $value) {
if ($value == "true") {
$page[$i][$key] = 1;
} elseif ($value == "false") {
$page[$i][$key] = 0;
}

}
}
return $page;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php


namespace OPNsense\netbird\Api;

use OPNsense\Base\ApiMutableModelControllerBase;

/**
* netbird settings controller
* @package OPNsense\netbird
*/
class SettingsController extends ApiMutableModelControllerBase
{
protected static $internalModelName = 'netbird';
protected static $internalModelClass = 'OPNsense\netbird\Netbird';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace OPNsense\netbird;

/**
* Class ConstatusController
* @package OPNsense\netbird
*/
class ConstatusController extends \OPNsense\Base\IndexController
{
public function indexAction()
{
$this->view->pick('OPNsense/netbird/constatus');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace OPNsense\netbird;

/**
* Class IndexController
* @package OPNsense\netbird
*/
class IndexController extends \OPNsense\Base\IndexController
{
public function indexAction()
{
$this->view->generalForm = $this->getForm("general");
$this->view->initialUpForm = $this->getForm("initialup");
$this->view->pick('OPNsense/netbird/index');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<form>
<field>
<id>netbird.general.Enabled</id>
<label>Enabled</label>
<type>checkbox</type>
<help>Enable Netbird</help>
</field>
<field>
<id>netbird.general.WgPort</id>
<label>Wireguard Port</label>
<type>text</type>
</field>
<field>
<id>netbird.general.DisableDNS</id>
<label>Disable Netbird DNS lookups</label>
<type>checkbox</type>
<help>Disables DNS lookups for the Netbird network.</help>
</field>
<field>
<id>netbird.general.DisableServerRoutes</id>
<label>Disable Server Routes</label>
<type>checkbox</type>
<help>Prevents Netbird from being a routing peer for other Netbird peers.</help>
</field>
<field>
<id>netbird.general.DisableClientRoutes</id>
<label>Disable Client Routes</label>
<type>checkbox</type>
<help>Prevents Netbird from setting client routes to other remote peers.</help>
</field>
<field>
<id>netbird.general.QuantumEnabled</id>
<label>Rosenpass Enabled</label>
<type>checkbox</type>
<help>Enable Rosenpass</help>
</field>
<field>
<id>netbird.general.QuantumPermissive</id>
<label>Rosenpass Permissive Mode</label>
<type>checkbox</type>
<help>Enable Rosenpass permissive mode</help>
</field>
<field>
<id>netbird.general.CarpIf</id>
<label>CARP Interface</label>
<type>dropdown</type>
<help>If set to none Netbird up is executed and auto connect is enabled. If an interface is selected auto
connect is disabled. Please trigger a CARP event or execute Netbird up manually on the MASTER node.
</help>
</field>
<field>
<id>netbird.general.VHID</id>
<label>CARP VHID</label>
<type>text</type>
</field>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<form>
<field>
<id>netbird.initial.mgmtservice</id>
<label>Management Service URL</label>
<type>text</type>
</field>
<field>
<id>netbird.initial.setupkey</id>
<label>Setup Key</label>
<type>text</type>
</field>
<field>
<id>netbird.initial.hostname</id>
<label>Hostname</label>
<type>text</type>
<help>If empty the system hostname excluding the domain part will be used.</help>
</field>
<field>
<id>netbird.initial.initsure</id>
<label>I know what I'm doing</label>
<type>checkbox</type>
<help>If you enable this checkbox and submit the form your old netbird config will be deleted. In case of an error it will get restored. Should something go terribly wrong you can find the backups
in the configuration folder. (/usr/local/etc/netbird)</help>
</field>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<acl>
<page-vpn-netbird>
<name>VPN: Netbird</name>
<patterns>
<pattern>ui/netbird/*</pattern>
<pattern>api/netbird/*</pattern>
</patterns>
</page-vpn-netbird>
</acl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace OPNsense\netbird;

use OPNsense\Base\BaseModel;

class Initial extends BaseModel
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<model>
<mount>//OPNsense/netbird-initial</mount>
<description>
Netbird initial setup
</description>
<items>
<!-- container -->
<initial>
<!-- fields -->
<setupkey type="TextField">
<Required>N</Required>
<default>00000000-0000-0000-0000-000000000000</default>
<Mask>/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i</Mask>
<ValidationMessage>Please specify a valid setup key.</ValidationMessage>
</setupkey>
<mgmtservice type="UrlField">
<Required>Y</Required>
<default>https://api.netbird.io:443</default>
</mgmtservice>
<hostname type="HostnameField">
<Required>N</Required>
<IpAllowed>N</IpAllowed>
<HostWildcardAllowed>N</HostWildcardAllowed>
<FqdnWildcardAllowed>N</FqdnWildcardAllowed>
<ZoneRootAllowed>N</ZoneRootAllowed>
<ValidationMessage>Please specify a valid hostname.</ValidationMessage>
</hostname>
<initsure type="BooleanField">
<default>0</default>
<Required>Y</Required>
</initsure>
</initial>
</items>
</model>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<menu>
<VPN>
<netbird order="200" VisibleName="Netbird" cssClass="fa fa-lock fa-fw">
<Settings order="40" VisibleName="Settings" url="/ui/netbird"/>
<ConStatus order="50" VisibleName="Connection Status" url="/ui/netbird/constatus"/>
<LogFile VisibleName="Log File" order="60" url="/ui/diagnostics/log/core/netbird"/>
</netbird>
</VPN>
</menu>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace OPNsense\netbird;

use OPNsense\Base\BaseModel;

class Netbird extends BaseModel
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<model>
<mount>//OPNsense/netbird</mount>
<version>0.8.1</version>
<description>Netbird plugin</description>
<items>
<!-- container -->
<general>
<!-- fields -->
<Enabled type="BooleanField">
<default>0</default>
<Required>Y</Required>
</Enabled>
<WgPort type="IntegerField">
<Required>Y</Required>
<default>51820</default>
</WgPort>
<QuantumEnabled type="BooleanField">
<default>0</default>
<Required>Y</Required>
</QuantumEnabled>
<DisableDNS type="BooleanField">
<default>1</default>
<Required>Y</Required>
</DisableDNS>
<DisableServerRoutes type="BooleanField">
<default>1</default>
<Required>Y</Required>
</DisableServerRoutes>
<DisableClientRoutes type="BooleanField">
<default>1</default>
<Required>Y</Required>
</DisableClientRoutes>
<QuantumPermissive type="BooleanField">
<default>0</default>
<Required>Y</Required>
</QuantumPermissive>
<CarpIf type="InterfaceField">
<Required>N</Required>
</CarpIf>
<VHID type="IntegerField">
<Required>N</Required>
<default>1</default>
</VHID>
</general>
</items>
</model>
136 changes: 136 additions & 0 deletions net/netbird/src/opnsense/mvc/app/views/OPNsense/netbird/constatus.volt
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<script>

$(document).ready(function () {

function refreshConStatus() {
$("#refreshAct_progress").addClass("fa fa-spinner fa-pulse");

ajaxCall(url = "/api/netbird/service/upDownStatus", sendData = {}, callback = function (data, status) {
if (data['updown'] == "UP") {
$("#setUpAct").prop('disabled', true);
$("#setDownAct").prop('disabled', false);
$("#peers").prop('hidden', false);
} else if (data['updown'] == "DOWN") {
$("#setUpAct").prop('disabled', false);
$("#setDownAct").prop('disabled', true);
$("#peers").prop('hidden', true);
} else {
$("#setUpAct").prop('disabled', true);
$("#setDownAct").prop('disabled', true);
$("#peers").prop('hidden', true);
}
$("#updown").html(data['updown']);
$("#constatustxt").html(data['status']);
std_bootgrid_reload('grid-peers');
$("#refreshAct_progress").removeClass("fa fa-spinner fa-pulse");
});
}

$("#refreshAct").click(function () {
refreshConStatus();
});

$("#setUpAct").click(function () {
$("#setUp_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url = "/api/netbird/service/setup", sendData = {}, callback = function (data, status) {
setTimeout(function () {
refreshConStatus();
$("#setUp_progress").removeClass("fa fa-spinner fa-pulse");
}, 3000);

});
});

$("#setDownAct").click(function () {
$("#setDown_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url = "/api/netbird/service/setdown", sendData = {}, callback = function (data, status) {
setTimeout(function () {
refreshConStatus();
$("#setDown_progress").removeClass("fa fa-spinner fa-pulse");
}, 500);

});
});

$("#service_status_container").click(function () {
setTimeout(function () {
refreshConStatus();
}, 2000);
});

$("#grid-peers").UIBootgrid(
{
search: '/api/netbird/service/search'
}
);

refreshConStatus();
updateServiceControlUI('netbird');

});
</script>
<div class="col-md-12">
<h2>Netbird Connection</h2>
<span id="updown"></span>
</div>
<div class="col-md-12">
<button class="btn" id="setUpAct" type="button"><b>{{ lang._('Set UP') }}</b><i id="setUp_progress"></i></button>
<button class="btn" id="setDownAct" type="button"><b>{{ lang._('Set DOWN') }}</b><i id="setDown_progress"></i>
</button>
</div>

<div id="peers" class="col-md-12">
<h2>Peers</h2>
<table id="grid-peers" class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th data-column-id="fqdn" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('FQDN') }}</th>
<th data-column-id="routes" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('Routes') }}</th>
<th data-width="8%" data-column-id="netbirdIp" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('IP') }}</th>
<th data-width="5%" data-column-id="direct" data-type="string" data-identifier="false"
data-formatter="boolean"
data-visible="true">{{ lang._('Direct') }}</th>
<th data-width="5%" data-column-id="status" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('Status') }}</th>
<th data-width="8%" data-column-id="lastWireguardHandshake" data-type="date" data-identifier="false"
data-visible="true">{{ lang._('Last Handshake') }}</th>
<th data-width="8%" data-column-id="lastStatusUpdate" data-type="date" data-identifier="false"
data-visible="true">{{ lang._('Last Status Update') }}</th>
<th data-width="5%" data-column-id="transferReceived" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('Received') }}</th>
<th data-width="5%" data-column-id="transferSent" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('Sent') }}</th>
<th data-width="5%" data-column-id="latency" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('Latency') }}</th>
<th data-width="5%" data-column-id="connectionType" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('Connection Type') }}</th>
<th data-width="5%" data-column-id="quantumResistance" data-type="string" data-identifier="false"
data-formatter="boolean"
data-visible="true">{{ lang._('QR') }}</th>
<th data-width="5%" data-column-id="iceCandidateType.local" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('ICE TL') }}</th>
<th data-width="5%" data-column-id="iceCandidateType.remote" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('ICE TR') }}</th>
<th data-width="8%" data-column-id="iceCandidateEndpoint.local" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('ICE EP Local') }}</th>
<th data-width="8%" data-column-id="iceCandidateEndpoint.remote" data-type="string" data-identifier="false"
data-visible="true">{{ lang._('ICE EP Remote') }}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="col-md-12">
<h2>{{ lang._('Status Output') }}</h2>
<section id="constatustxt" class="col-xs-11">
</section>
</div>

<div class="col-md-12">
<button class="btn" id="refreshAct" type="button"><b>{{ lang._('Refresh') }}</b><i id="refreshAct_progress"></i>
</button>
</div>
79 changes: 79 additions & 0 deletions net/netbird/src/opnsense/mvc/app/views/OPNsense/netbird/index.volt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<script>

$(document).ready(function () {

$("#netbird\\.initial\\.initsure").click(function () {
if ($("#netbird\\.initial\\.initsure").prop('checked')) {
$("#initialAct").prop('disabled', false);
} else {
$("#initialAct").prop('disabled', true);
}
});

$("#saveAct").click(function () {
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
saveFormToEndpoint(url = "/api/netbird/settings/set", formid = 'frm_GeneralSettings', callback_ok = function () {
ajaxCall(url = "/api/netbird/service/reload", sendData = {}, callback = function (data, status) {
updateServiceControlUI('netbird');
$("#saveAct_progress").removeClass("fa fa-spinner fa-pulse");
});
});
});

$("#initialAct").click(function () {
saveFormToEndpoint(url = "/api/netbird/initial/set", formid = 'frm_InitialUp', callback_ok = function () {
$("#initialAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url = "/api/netbird/service/initialup", sendData = {}, callback = function (data, status) {
$("#initialtxt").html(data.responseText);
$("#resultdiv").prop('hidden', false);
$("#initialAct").prop('disabled', true);
var data_get_map_initial = {'frm_InitialUp': "/api/netbird/initial/get"};
mapDataToFormUI(data_get_map_initial)
ajaxCall(url = "/api/netbird/service/reload", sendData = {}, callback = function (data, status) {
updateServiceControlUI('netbird');
$("#initialAct_progress").removeClass("fa fa-spinner fa-pulse");
});
});
}, true);
});


let data_get_map = {'frm_GeneralSettings': "/api/netbird/settings/get"};
mapDataToFormUI(data_get_map).done(function (data) {
updateServiceControlUI('netbird');
$('.selectpicker').selectpicker('refresh');
});

let data_get_map_initial = {'frm_InitialUp': "/api/netbird/initial/get"};
mapDataToFormUI(data_get_map_initial)
});
</script>

<div class="alert alert-info hidden" role="alert" id="responseMsg">

</div>

<div class="col-md-12">
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_GeneralSettings']) }}
</div>

<div class="col-md-12">
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b><i id="saveAct_progress"></i>
</button>
</div>

<div class="col-md-12">
{{ partial("layout_partials/base_form",['fields':initialUpForm,'id':'frm_InitialUp']) }}
</div>

<div class="col-md-12">
<button disabled="true" class="btn" id="initialAct" type="button"><b>{{ lang._('Setup') }}</b><i
id="initialAct_progress"></i>
</button>
</div>

<div class="col-md-12" id="resultdiv" hidden="true">
<h2>{{ lang._('Result') }}</h2>
<section id="initialtxt" class="col-xs-11">
</section>
</div>
16 changes: 16 additions & 0 deletions net/netbird/src/opnsense/scripts/OPNsense/netbird/initialup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
timestamp=$(date +%s)
/usr/local/etc/rc.d/netbird stop
echo "Deleting old configuration file"
mv /usr/local/etc/netbird/config.json /usr/local/etc/netbird/config.json.$timestamp
/usr/local/etc/rc.d/netbird start
/usr/local/bin/netbird up $@ 2>&1
if [ $? -ne 0 ]; then
/usr/local/etc/rc.d/netbird stop
echo "Failed to bring up netbird"
echo "Restoring old configuration file"
mv /usr/local/etc/netbird/config.json /usr/local/etc/netbird/config.json.$timestamp.fail
mv /usr/local/etc/netbird/config.json.$timestamp /usr/local/etc/netbird/config.json
/usr/local/etc/rc.d/netbird start
fi
exit 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
[start]
command:/usr/local/etc/rc.d/netbird start
parameters:
type:script
message:starting netbird

[stop]
command:/usr/local/etc/rc.d/netbird stop
parameters:
type:script
message:stopping netbird

[restart]
command:/usr/local/etc/rc.d/netbird restart
parameters:
type:script
message:restarting netbird

[status]
command:/usr/local/etc/rc.d/netbird status; exit 0
type:script_output
message:get netbird status

[con-status]
command:/usr/local/bin/netbird status -d; exit 0
type:script_output
message:get netbird connection status

[set-up]
command:/usr/local/bin/netbird up
type:script
message:set netbird up

[set-up-initial]
command:/usr/local/opnsense/scripts/OPNsense/netbird/initialup.sh
parameters: -m %s -k %s -n %s
type:script_output
message:setup netbird

[set-down]
command:/usr/local/bin/netbird down
type:script
message:set netbird down

[short-con-status]
command:/usr/local/bin/netbird status; exit 0
type:script_output
message:get short netbird connection status

[con-status-json]
command:/usr/local/bin/netbird status --json; exit 0
type:script_output
message:get netbird connection status
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
###################################################################
# Local syslog-ng configuration filter definition [netbird].
###################################################################
filter f_local_netbird {
program("netbird");
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
netbird:/etc/rc.conf.d/netbird
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% if helpers.exists('OPNsense.netbird.general.Enabled') and OPNsense.netbird.general.Enabled|default("0") == '1' %}
netbird_enable="YES"
{% else %}
netbird_enable="NO"
{% endif %}
osrelease_enable="YES"