mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
net/wireguard - remove wg-quick dependency and drop go support (#3556)
net/wireguard - removing wg-quick and go support. This commits adds the following: * Remove wireguard-go support and cleanup some go specific code as it's not being used anymore anyway * Service control handler similar to OpenVPN, which offers control per instance/interface and keeps track of changed interfaces (configure only restarts the changed ones). * Add some basic logging for the service handling and a view to inspect it. * Configuration logs are being flushed to the correct log automatically as mwexecf() sends errors to syslog (which in this scope sends to wireguard) * Reimplement https://github.com/WireGuard/wireguard-tools/tree/master/contrib/reresolve-dns using Python in reresolve-dns.py * Enforce wireguard-tools rc script to be disabled when still installed, this should prevent bootup issues * Move 'interface' calculated field to model for easy reusability * Change plugin maintainer --------- Co-authored-by: Franco Fichtner <franco@opnsense.org>
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
PLUGIN_NAME= wireguard
|
||||
PLUGIN_VERSION= 1.13
|
||||
PLUGIN_REVISION= 7
|
||||
PLUGIN_VERSION= 2.0.d
|
||||
PLUGIN_COMMENT= WireGuard VPN service kernel implementation
|
||||
PLUGIN_DEPENDS= wireguard-kmod wireguard-tools
|
||||
PLUGIN_DEPENDS= wireguard-kmod
|
||||
PLUGIN_CONFLICTS= wireguard-go
|
||||
PLUGIN_MAINTAINER= m.muenz@gmail.com
|
||||
PLUGIN_MAINTAINER= ad@opnsense.org
|
||||
|
||||
.include "../../Mk/plugins.mk"
|
||||
|
||||
@@ -16,6 +16,17 @@ WWW: https://www.wireguard.com/
|
||||
Changelog
|
||||
---------
|
||||
|
||||
2.0
|
||||
|
||||
* Remove wireguard-go support and cleanup some go specific code as it's not being used anymore anyway
|
||||
* Service control handler similar to OpenVPN, which offers control per instance/interface and keeps track of changed interfaces (configure only restarts the changed ones).
|
||||
* Add some basic logging for the service handling and a view to inspect it.
|
||||
* Configuration logs are being flushed to the correct log automatically as mwexecf() sends errors to syslog (which in this scope sends to wireguard)
|
||||
* Reimplement https://github.com/WireGuard/wireguard-tools/tree/master/contrib/reresolve-dns using Python in reresolve-dns.py
|
||||
* Enforce wireguard-tools rc script to be disabled when still installed, this should prevent bootup issues
|
||||
* Move 'interface' calculated field to model for easy reusability
|
||||
* Change plugin maintainer
|
||||
|
||||
1.13
|
||||
|
||||
* Reworked widget and assorted cleanups (contributed by Patrik Kernstock)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
* Copyright (C) 2018 Michael Muenz <m.muenz@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -28,8 +29,7 @@
|
||||
|
||||
function wireguard_enabled()
|
||||
{
|
||||
$model = new \OPNsense\Wireguard\General();
|
||||
return (string)$model->enabled == '1';
|
||||
return (string)(new \OPNsense\Wireguard\General())->enabled == '1';
|
||||
}
|
||||
|
||||
function wireguard_services()
|
||||
@@ -40,26 +40,32 @@ function wireguard_services()
|
||||
return $services;
|
||||
}
|
||||
|
||||
$service = [
|
||||
'description' => gettext('WireGuard VPN'),
|
||||
'configd' => [
|
||||
'restart' => ['wireguard restart'],
|
||||
'start' => ['wireguard start'],
|
||||
'stop' => ['wireguard stop'],
|
||||
],
|
||||
'name' => 'wireguard-go',
|
||||
];
|
||||
|
||||
if (file_exists('/boot/modules/if_wg.ko') || file_exists('/boot/kernel/if_wg.ko')) {
|
||||
$service['name'] = 'wireguard';
|
||||
$service['nocheck'] = true;
|
||||
foreach ((new OPNsense\Wireguard\Server())->servers->server->iterateItems() as $key => $node) {
|
||||
if (!empty((string)$node->enabled)) {
|
||||
$services[] = [
|
||||
'description' => "Wireguard " . htmlspecialchars($node->name),
|
||||
'configd' => [
|
||||
'start' => ["wireguard start {$key}"],
|
||||
'restart' => ["wireguard restart {$key}"],
|
||||
'stop' => ["wireguard stop {$key}"],
|
||||
],
|
||||
'nocheck' => true, /* no daemon to check */
|
||||
'id' => $key,
|
||||
'name' => "wireguard"
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$services[] = $service;
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
function wireguard_syslog()
|
||||
{
|
||||
return [
|
||||
'wireguard' => ['facility' => ['wireguard']]
|
||||
];
|
||||
}
|
||||
|
||||
function wireguard_interfaces()
|
||||
{
|
||||
$interfaces = [];
|
||||
@@ -87,11 +93,7 @@ function wireguard_xmlrpc_sync()
|
||||
$result['id'] = 'wireguard';
|
||||
$result['section'] = 'OPNsense.wireguard';
|
||||
$result['description'] = gettext('WireGuard');
|
||||
$result['services'] = ['wireguard-go'];
|
||||
|
||||
if (file_exists('/boot/modules/if_wg.ko') || file_exists('/boot/kernel/if_wg.ko')) {
|
||||
$result['services'] = ['wireguard'];
|
||||
}
|
||||
$result['services'] = ['wireguard'];
|
||||
|
||||
return [$result];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
#!/bin/sh
|
||||
|
||||
# start again to fix problems with failed name resolution (no need to restart)
|
||||
configctl -dq wireguard start
|
||||
configctl -dq wireguard configure
|
||||
|
||||
+5
-2
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
* Copyright (C) 2018 Michael Muenz <m.muenz@gmail.com>
|
||||
*
|
||||
* All rights reserved.
|
||||
@@ -39,12 +40,14 @@ class ClientController extends ApiMutableModelControllerBase
|
||||
|
||||
public function searchClientAction()
|
||||
{
|
||||
return $this->searchBase('clients.client', array("enabled", "name", "pubkey", "tunneladdress", "serveraddress", "serverport"));
|
||||
return $this->searchBase(
|
||||
'clients.client',
|
||||
["enabled", "name", "pubkey", "tunneladdress", "serveraddress", "serverport"]
|
||||
);
|
||||
}
|
||||
|
||||
public function getClientAction($uuid = null)
|
||||
{
|
||||
$this->sessionClose();
|
||||
return $this->getBase('client', 'clients.client', $uuid);
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
* Copyright (C) 2018 Michael Muenz <m.muenz@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -38,17 +39,15 @@ class ServerController extends ApiMutableModelControllerBase
|
||||
|
||||
public function searchServerAction()
|
||||
{
|
||||
$search = $this->searchBase('servers.server', array("enabled", "instance", "peers", "name", "networks", "pubkey", "port", "tunneladdress"));
|
||||
// prepend "wg" to all instance IDs to use as interface name
|
||||
foreach ($search["rows"] as $key => $server) {
|
||||
$search["rows"][$key]["interface"] = "wg" . $server["instance"];
|
||||
}
|
||||
$search = $this->searchBase(
|
||||
'servers.server',
|
||||
["enabled", "instance", "peers", "name", "networks", "pubkey", "port", "tunneladdress", 'interface']
|
||||
);
|
||||
return $search;
|
||||
}
|
||||
|
||||
public function getServerAction($uuid = null)
|
||||
{
|
||||
$this->sessionClose();
|
||||
return $this->getBase('server', 'servers.server', $uuid);
|
||||
}
|
||||
|
||||
|
||||
+20
-4
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
* Copyright (C) 2018 Michael Muenz <m.muenz@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -52,14 +53,30 @@ class ServiceController extends ApiMutableServiceControllerBase
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function reconfigureAction()
|
||||
{
|
||||
if (!$this->request->isPost()) {
|
||||
return ['result' => 'failed'];
|
||||
}
|
||||
|
||||
$this->sessionClose();
|
||||
$backend = new Backend();
|
||||
$backend->configdRun('template reload ' . escapeshellarg(static::$internalServiceTemplate));
|
||||
$backend->configdpRun('wireguard configure');
|
||||
|
||||
return ['result' => 'ok'];
|
||||
}
|
||||
|
||||
/**
|
||||
* show wireguard config
|
||||
* @return array
|
||||
*/
|
||||
public function showconfAction()
|
||||
{
|
||||
$backend = new Backend();
|
||||
$response = $backend->configdRun("wireguard showconf");
|
||||
$response = (new Backend())->configdRun("wireguard showconf");
|
||||
return array("response" => $response);
|
||||
}
|
||||
|
||||
@@ -69,8 +86,7 @@ class ServiceController extends ApiMutableServiceControllerBase
|
||||
*/
|
||||
public function showhandshakeAction()
|
||||
{
|
||||
$backend = new Backend();
|
||||
$response = $backend->configdRun("wireguard showhandshake");
|
||||
$response = (new Backend())->configdRun("wireguard showhandshake");
|
||||
return array("response" => $response);
|
||||
}
|
||||
}
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Wireguard\FieldTypes;
|
||||
|
||||
use OPNsense\Base\FieldTypes\ArrayField;
|
||||
use OPNsense\Base\FieldTypes\TextField;
|
||||
|
||||
class ServerField extends ArrayField
|
||||
{
|
||||
/**
|
||||
* push internal reusable properties as virtuals
|
||||
*/
|
||||
protected function actionPostLoadingEvent()
|
||||
{
|
||||
foreach ($this->internalChildnodes as $node) {
|
||||
if (!$node->getInternalIsVirtual()) {
|
||||
$files = [
|
||||
'cnfFilename' => "/usr/local/etc/wireguard/wg{$node->instance}.conf",
|
||||
'statFilename' => "/usr/local/etc/wireguard/wg{$node->instance}.stat",
|
||||
'interface' => "wg{$node->instance}",
|
||||
];
|
||||
foreach ($files as $name => $payload) {
|
||||
$new_item = new TextField();
|
||||
$new_item->setInternalIsVirtual();
|
||||
$new_item->setValue($payload);
|
||||
$node->addChildNode($name, $new_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return parent::actionPostLoadingEvent();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
<menu>
|
||||
<VPN>
|
||||
<WireGuard cssClass="fa fa-lock fa-fw" url="/ui/wireguard/general/index" order="150" />
|
||||
<WireGuard cssClass="fa fa-lock fa-fw" order="150">
|
||||
<Settings order="10" url="/ui/wireguard/general/index"/>
|
||||
<LogFile order="70" VisibleName="Log File" url="/ui/diagnostics/log/core/wireguard"/>
|
||||
</WireGuard>
|
||||
</VPN>
|
||||
</menu>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<version>0.0.4</version>
|
||||
<items>
|
||||
<servers>
|
||||
<server type="ArrayField">
|
||||
<server type=".\ServerField">
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{#
|
||||
# OPNsense (c) 2014-2018 by Deciso B.V.
|
||||
# OPNsense (c) 2014-2023 by Deciso B.V.
|
||||
# OPNsense (c) 2018 Michael Muenz <m.muenz@gmail.com>
|
||||
# All rights reserved.
|
||||
#
|
||||
@@ -25,6 +25,66 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#}
|
||||
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
var data_get_map = {'frm_general_settings':"/api/wireguard/general/get"};
|
||||
mapDataToFormUI(data_get_map).done(function(data){
|
||||
formatTokenizersUI();
|
||||
$('.selectpicker').selectpicker('refresh');
|
||||
});
|
||||
|
||||
$("#grid-clients").UIBootgrid(
|
||||
{
|
||||
'search':'/api/wireguard/client/searchClient',
|
||||
'get':'/api/wireguard/client/getClient/',
|
||||
'set':'/api/wireguard/client/setClient/',
|
||||
'add':'/api/wireguard/client/addClient/',
|
||||
'del':'/api/wireguard/client/delClient/',
|
||||
'toggle':'/api/wireguard/client/toggleClient/'
|
||||
}
|
||||
);
|
||||
|
||||
$("#grid-servers").UIBootgrid(
|
||||
{
|
||||
'search':'/api/wireguard/server/searchServer',
|
||||
'get':'/api/wireguard/server/getServer/',
|
||||
'set':'/api/wireguard/server/setServer/',
|
||||
'add':'/api/wireguard/server/addServer/',
|
||||
'del':'/api/wireguard/server/delServer/',
|
||||
'toggle':'/api/wireguard/server/toggleServer/'
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
$("#reconfigureAct").SimpleActionButton({
|
||||
onPreAction: function() {
|
||||
const dfObj = new $.Deferred();
|
||||
saveFormToEndpoint("/api/wireguard/general/set", 'frm_general_settings', function(){
|
||||
dfObj.resolve();
|
||||
});
|
||||
return dfObj;
|
||||
}
|
||||
});
|
||||
|
||||
// Put API call into a function, needed for auto-refresh
|
||||
function update_showconf() {
|
||||
ajaxCall(url="/api/wireguard/service/showconf", sendData={}, callback=function(data,status) {
|
||||
$("#listshowconf").text(data['response']);
|
||||
setTimeout(update_showconf, 5000);
|
||||
});
|
||||
}
|
||||
|
||||
function update_showhandshake() {
|
||||
ajaxCall(url="/api/wireguard/service/showhandshake", sendData={}, callback=function(data,status) {
|
||||
$("#listshowhandshake").text(data['response']);
|
||||
setTimeout(update_showhandshake, 5000);
|
||||
});
|
||||
}
|
||||
// Call update funcs once when page loaded
|
||||
update_showconf();
|
||||
update_showhandshake();
|
||||
});
|
||||
</script>
|
||||
<!-- Navigation bar -->
|
||||
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
|
||||
<li class="active"><a data-toggle="tab" href="#general">{{ lang._('General') }}</a></li>
|
||||
@@ -38,10 +98,6 @@
|
||||
<div id="general" class="tab-pane fade in active">
|
||||
<div class="content-box" style="padding-bottom: 1.5em;">
|
||||
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_general_settings'])}}
|
||||
<div class="col-md-12">
|
||||
<hr />
|
||||
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Apply') }}</b> <i id="saveAct_progress"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="clients" class="tab-pane fade in">
|
||||
@@ -68,11 +124,6 @@
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="col-md-12">
|
||||
<hr />
|
||||
<button class="btn btn-primary" id="saveAct_client" type="button"><b>{{ lang._('Apply') }}</b> <i id="saveAct_client_progress"></i></button>
|
||||
<br /><br />
|
||||
</div>
|
||||
</div>
|
||||
<div id="servers" class="tab-pane fade in">
|
||||
<table id="grid-servers" class="table table-responsive" data-editDialog="dialogEditWireguardServer">
|
||||
@@ -99,11 +150,6 @@
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="col-md-12">
|
||||
<hr />
|
||||
<button class="btn btn-primary" id="saveAct_server" type="button"><b>{{ lang._('Apply') }}</b> <i id="saveAct_server_progress"></i></button>
|
||||
<br /><br />
|
||||
</div>
|
||||
</div>
|
||||
<div id="showconf" class="tab-pane fade in">
|
||||
<pre id="listshowconf"></pre>
|
||||
@@ -113,87 +159,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="page-content-main">
|
||||
<div class="content-box">
|
||||
<div class="col-md-12">
|
||||
<br/>
|
||||
<button class="btn btn-primary" id="reconfigureAct"
|
||||
data-endpoint='/api/wireguard/service/reconfigure'
|
||||
data-label="{{ lang._('Apply') }}"
|
||||
data-error-title="{{ lang._('Error reconfiguring Wireguard') }}"
|
||||
type="button"
|
||||
></button>
|
||||
<br/><br/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditWireguardClient,'id':'dialogEditWireguardClient','label':lang._('Edit Endpoint')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditWireguardServer,'id':'dialogEditWireguardServer','label':lang._('Edit Local Configuration')])}}
|
||||
|
||||
<script>
|
||||
|
||||
// Put API call into a function, needed for auto-refresh
|
||||
function update_showconf() {
|
||||
ajaxCall(url="/api/wireguard/service/showconf", sendData={}, callback=function(data,status) {
|
||||
$("#listshowconf").text(data['response']);
|
||||
});
|
||||
}
|
||||
|
||||
function update_showhandshake() {
|
||||
ajaxCall(url="/api/wireguard/service/showhandshake", sendData={}, callback=function(data,status) {
|
||||
$("#listshowhandshake").text(data['response']);
|
||||
});
|
||||
}
|
||||
|
||||
$( document ).ready(function() {
|
||||
var data_get_map = {'frm_general_settings':"/api/wireguard/general/get"};
|
||||
mapDataToFormUI(data_get_map).done(function(data){
|
||||
formatTokenizersUI();
|
||||
$('.selectpicker').selectpicker('refresh');
|
||||
});
|
||||
|
||||
$("#grid-clients").UIBootgrid(
|
||||
{
|
||||
'search':'/api/wireguard/client/searchClient',
|
||||
'get':'/api/wireguard/client/getClient/',
|
||||
'set':'/api/wireguard/client/setClient/',
|
||||
'add':'/api/wireguard/client/addClient/',
|
||||
'del':'/api/wireguard/client/delClient/',
|
||||
'toggle':'/api/wireguard/client/toggleClient/'
|
||||
}
|
||||
);
|
||||
|
||||
$("#grid-servers").UIBootgrid(
|
||||
{
|
||||
'search':'/api/wireguard/server/searchServer',
|
||||
'get':'/api/wireguard/server/getServer/',
|
||||
'set':'/api/wireguard/server/setServer/',
|
||||
'add':'/api/wireguard/server/addServer/',
|
||||
'del':'/api/wireguard/server/delServer/',
|
||||
'toggle':'/api/wireguard/server/toggleServer/'
|
||||
}
|
||||
);
|
||||
|
||||
// Call update funcs once when page loaded
|
||||
update_showconf();
|
||||
update_showhandshake();
|
||||
|
||||
// Call function update_neighbor with a auto-refresh of 5 seconds
|
||||
setInterval(update_showconf, 5000);
|
||||
setInterval(update_showhandshake, 5000);
|
||||
|
||||
$("#saveAct").click(function(){
|
||||
saveFormToEndpoint(url="/api/wireguard/general/set", formid='frm_general_settings',callback_ok=function(){
|
||||
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
|
||||
ajaxCall(url="/api/wireguard/service/reconfigure", sendData={}, callback=function(data,status) {
|
||||
$("#saveAct_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$("#saveAct_client").click(function(){
|
||||
saveFormToEndpoint(url="/api/wireguard/client/set", formid='frm_general_settings',callback_ok=function(){
|
||||
$("#saveAct_client_progress").addClass("fa fa-spinner fa-pulse");
|
||||
ajaxCall(url="/api/wireguard/service/reconfigure", sendData={}, callback=function(data,status) {
|
||||
$("#saveAct_client_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$("#saveAct_server").click(function(){
|
||||
saveFormToEndpoint(url="/api/wireguard/server/set", formid='frm_general_settings',callback_ok=function(){
|
||||
$("#saveAct_server_progress").addClass("fa fa-spinner fa-pulse");
|
||||
ajaxCall(url="/api/wireguard/service/reconfigure", sendData={}, callback=function(data,status) {
|
||||
$("#saveAct_server_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -f /etc/rc.conf.d/wireguard ]; then
|
||||
. /etc/rc.conf.d/wireguard
|
||||
fi
|
||||
|
||||
for interface in ${wireguard_interfaces}; do
|
||||
ifconfig ${interface} group wireguard
|
||||
done
|
||||
|
||||
/usr/local/etc/rc.routing_configure
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/usr/local/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
|
||||
set -e
|
||||
shopt -s nocasematch
|
||||
shopt -s extglob
|
||||
export LC_ALL=C
|
||||
|
||||
for CONFIG_FILE in /usr/local/etc/wireguard/*.conf; do
|
||||
|
||||
[[ $CONFIG_FILE =~ /?([a-zA-Z0-9_=+.-]{1,15})\.conf$ ]]
|
||||
INTERFACE="${BASH_REMATCH[1]}"
|
||||
|
||||
process_peer() {
|
||||
[[ $PEER_SECTION -ne 1 || -z $PUBLIC_KEY || -z $ENDPOINT ]] && return 0
|
||||
[[ $(wg show "$INTERFACE" latest-handshakes) =~ ${PUBLIC_KEY//+/\\+}\ ([0-9]+) ]] || return 0
|
||||
(( ($EPOCHSECONDS - ${BASH_REMATCH[1]}) > 135 )) || return 0
|
||||
wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT"
|
||||
reset_peer_section
|
||||
}
|
||||
|
||||
reset_peer_section() {
|
||||
PEER_SECTION=0
|
||||
PUBLIC_KEY=""
|
||||
ENDPOINT=""
|
||||
}
|
||||
|
||||
reset_peer_section
|
||||
while read -r line || [[ -n $line ]]; do
|
||||
stripped="${line%%\#*}"
|
||||
key="${stripped%%=*}"; key="${key##*([[:space:]])}"; key="${key%%*([[:space:]])}"
|
||||
value="${stripped#*=}"; value="${value##*([[:space:]])}"; value="${value%%*([[:space:]])}"
|
||||
[[ $key == "["* ]] && { process_peer; reset_peer_section; }
|
||||
[[ $key == "[Peer]" ]] && PEER_SECTION=1
|
||||
if [[ $PEER_SECTION -eq 1 ]]; then
|
||||
case "$key" in
|
||||
PublicKey) PUBLIC_KEY="$value"; continue ;;
|
||||
Endpoint) ENDPOINT="$value"; continue ;;
|
||||
esac
|
||||
fi
|
||||
done < "$CONFIG_FILE"
|
||||
process_peer
|
||||
done
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
mkdir -p /var/run/wireguard
|
||||
chmod 755 /var/run/wireguard
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
"""
|
||||
Copyright (c) 2023 Ad Schellevis <ad@opnsense.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
# Python implementation to re-resolve dns entries, for reference see:
|
||||
# https://github.com/WireGuard/wireguard-tools/tree/master/contrib/reresolve-dns
|
||||
import glob
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
for filename in glob.glob('/usr/local/etc/wireguard/*.conf'):
|
||||
this_peer = {}
|
||||
ifname = os.path.basename(filename).split('.')[0]
|
||||
with open(filename, 'r') as fhandle:
|
||||
for line in fhandle:
|
||||
if line.startswith('[Peer]'):
|
||||
this_peer = {}
|
||||
elif line.startswith('PublicKey'):
|
||||
this_peer['PublicKey'] = line.split('=', 1)[1].strip()
|
||||
elif line.startswith('Endpoint'):
|
||||
this_peer['Endpoint'] = line.split('=', 1)[1].strip()
|
||||
|
||||
if 'Endpoint' in this_peer and 'PublicKey' in this_peer:
|
||||
subprocess.run(
|
||||
[
|
||||
'/usr/bin/wg',
|
||||
'set',
|
||||
ifname,
|
||||
'peer',
|
||||
this_peer['PublicKey'],
|
||||
'endpoint',
|
||||
this_peer['Endpoint']
|
||||
],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
this_peer = {}
|
||||
@@ -0,0 +1,180 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
require_once('script/load_phalcon.php');
|
||||
require_once('util.inc');
|
||||
require_once('interfaces.inc');
|
||||
|
||||
/**
|
||||
* mimic wg-quick behaviour, but bound to our config
|
||||
*/
|
||||
function wg_start($server, $fhandle)
|
||||
{
|
||||
if (!does_interface_exist($server->interface)) {
|
||||
mwexecf('/sbin/ifconfig wg create name %s', [$server->interface]);
|
||||
mwexecf('/sbin/ifconfig %s group wireguard', [$server->interface]);
|
||||
}
|
||||
mwexecf('/usr/bin/wg setconf %s %s', [$server->interface, $server->cnfFilename]);
|
||||
|
||||
foreach (explode(',', (string)$server->tunneladdress) as $alias) {
|
||||
mwexecf('/sbin/ifconfig %s %s alias', [$server->interface, $alias]);
|
||||
}
|
||||
if (!empty((string)$server->mtu)) {
|
||||
mwexecf('/sbin/ifconfig %s mtu %s', [$server->interface, $server->mtu]);
|
||||
}
|
||||
mwexecf('/sbin/ifconfig %s up', [$server->interface]);
|
||||
|
||||
if (empty((string)$server->disableroutes)) {
|
||||
/**
|
||||
* Add routes for all configured peers, wg-quick seems to parse 'wg show wgX allowed-ips' for this,
|
||||
* but this should logically congtain the same networks.
|
||||
*
|
||||
* XXX: For some reason these routes look a bit off, not very well integrated into OPNsense.
|
||||
* In the long run it might make sense to have some sort of pluggable model facility
|
||||
* where these (and maybe other) static routes hook into.
|
||||
**/
|
||||
$peers = explode(',', $server->peers);
|
||||
$routes_to_add = ['inet'=> [], 'inet6' => []];
|
||||
foreach ((new OPNsense\Wireguard\Client())->clients->client->iterateItems() as $key => $client) {
|
||||
if (empty((string)$client->enabled) || !in_array($key, $peers)) {
|
||||
continue;
|
||||
}
|
||||
foreach (explode(',', (string)$client->tunneladdress) as $tunneladdress) {
|
||||
$ipproto = strpos($tunneladdress, ":") === false ? "inet" : "inet6 ";
|
||||
/* wg-quick seems to prevent /0 being routed and translates this automatically */
|
||||
if (str_ends_with(trim($tunneladdress), '/0')) {
|
||||
if ($ipproto == 'inet') {
|
||||
array_push($routes_to_add[$ipproto], '0.0.0.0/1', '128.0.0.0/1');
|
||||
} else {
|
||||
array_push($routes_to_add[$ipproto], '::/1', '8000::/1');
|
||||
}
|
||||
} else {
|
||||
$routes_to_add[$ipproto][] = $tunneladdress;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($routes_to_add as $ipproto => $routes) {
|
||||
foreach (array_unique($routes) as $route) {
|
||||
mwexecf('/sbin/route -q -n add -%s %s -interface %s', [$ipproto, $route, $server->interface]);
|
||||
}
|
||||
}
|
||||
} elseif (!empty((string)$server->gateway)) {
|
||||
/* Only bind the gateway ip to the tunnel */
|
||||
$ipprefix = strpos($tunneladdress, ":") === false ? "-4" : "-6 ";
|
||||
mwexecf('/sbin/route -q -n add -%s %s -iface %s', [$ipprefix, $server->gateway, $server->interface]);
|
||||
}
|
||||
|
||||
// flush checksum to ease change detection
|
||||
fseek($fhandle, 0);
|
||||
ftruncate($fhandle, 0);
|
||||
fwrite($fhandle, @md5_file($server->cnfFilename));
|
||||
syslog(LOG_NOTICE, "Wireguard interface {$server->name} ({$server->interface}) started");
|
||||
}
|
||||
|
||||
/**
|
||||
* stop wireguard tunnel, kill the device, the routes should drop automatically.
|
||||
*/
|
||||
function wg_stop($server)
|
||||
{
|
||||
if (does_interface_exist($server->interface)) {
|
||||
legacy_interface_destroy($server->interface);
|
||||
}
|
||||
syslog(LOG_NOTICE, "Wireguard interface {$server->name} ({$server->interface}) stopped");
|
||||
}
|
||||
|
||||
|
||||
$opts = getopt('ah', [], $optind);
|
||||
$args = array_slice($argv, $optind);
|
||||
|
||||
/* setup syslog logging */
|
||||
openlog("wireguard", LOG_ODELAY, LOG_AUTH);
|
||||
|
||||
if (isset($opts['h']) || empty($args) || !in_array($args[0], ['start', 'stop', 'restart', 'configure'])) {
|
||||
echo "Usage: wg-service-control.php [-a] [-h] [stop|start|restart|configure] [uuid]\n\n";
|
||||
echo "\t-a all instances\n";
|
||||
} elseif (isset($opts['a']) || !empty($args[1])) {
|
||||
$server_id = $args[1] ?? null;
|
||||
$action = $args[0];
|
||||
|
||||
$server_devs = [];
|
||||
if (!empty((string)(new OPNsense\Wireguard\General())->enabled)) {
|
||||
foreach ((new OPNsense\Wireguard\Server())->servers->server->iterateItems() as $key => $node) {
|
||||
if (empty((string)$node->enabled)) {
|
||||
continue;
|
||||
}
|
||||
if ($server_id != null && $key != $server_id) {
|
||||
continue;
|
||||
}
|
||||
$server_devs[] = (string)$node->interface;
|
||||
$statHandle = fopen($node->statFilename, "a+");
|
||||
if (flock($statHandle, LOCK_EX)) {
|
||||
switch ($action) {
|
||||
case 'stop':
|
||||
wg_stop($node);
|
||||
break;
|
||||
case 'start':
|
||||
wg_start($node, $statHandle);
|
||||
break;
|
||||
case 'restart':
|
||||
wg_stop($node);
|
||||
wg_start($node, $statHandle);
|
||||
break;
|
||||
case 'configure':
|
||||
if (
|
||||
@md5_file($node->cnfFilename) != @file_get_contents($node->statFilename) ||
|
||||
!does_interface_exist((string)$node->interface)
|
||||
) {
|
||||
wg_stop($node);
|
||||
wg_start($node, $statHandle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
flock($statHandle, LOCK_UN);
|
||||
}
|
||||
fclose($statHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When -a is specified, cleaup up old or disabled instances (files and interfaces)
|
||||
*/
|
||||
if ($server_id == null) {
|
||||
foreach (glob('/usr/local/etc/wireguard/wg*') as $filename) {
|
||||
$this_dev = explode('.', basename($filename))[0];
|
||||
if (!in_array($this_dev, $server_devs)) {
|
||||
@unlink($filename);
|
||||
if (does_interface_exist($this_dev)) {
|
||||
legacy_interface_destroy($this_dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mwexecf('/usr/local/etc/rc.routing_configure');
|
||||
}
|
||||
closelog();
|
||||
@@ -1,31 +1,36 @@
|
||||
[start]
|
||||
command:/usr/local/etc/rc.d/wireguard start; /usr/local/opnsense/scripts/OPNsense/Wireguard/post.sh
|
||||
parameters:
|
||||
command:/usr/local/opnsense/scripts/Wireguard/wg-service-control.php
|
||||
parameters: start %s
|
||||
type:script
|
||||
message:Starting WireGuard
|
||||
message: start wireguard instance %s
|
||||
|
||||
[stop]
|
||||
command:/usr/local/etc/rc.d/wireguard stop
|
||||
parameters:
|
||||
command:/usr/local/opnsense/scripts/Wireguard/wg-service-control.php
|
||||
parameters: stop %s
|
||||
type:script
|
||||
message:Stopping WireGuard
|
||||
message: stop wireguard instance %s
|
||||
|
||||
[restart]
|
||||
command:/usr/local/etc/rc.d/wireguard restart; /usr/local/opnsense/scripts/OPNsense/Wireguard/post.sh
|
||||
parameters:
|
||||
command:/usr/local/opnsense/scripts/Wireguard/wg-service-control.php
|
||||
parameters: restart %s
|
||||
type:script
|
||||
message:Restarting WireGuard
|
||||
description: Restart WireGuard
|
||||
message: restart wireguard instance %s
|
||||
|
||||
[configure]
|
||||
command:/usr/local/opnsense/scripts/Wireguard/wg-service-control.php
|
||||
parameters: -a configure
|
||||
type:script
|
||||
message: configure wireguard instances
|
||||
|
||||
[renew]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/Wireguard/resolve-dns.bash
|
||||
command:/usr/local/opnsense/scripts/Wireguard/reresolve-dns.py
|
||||
parameters:
|
||||
type:script
|
||||
message:Renew DNS for WireGuard
|
||||
description:Renew DNS for WireGuard on stale connections
|
||||
|
||||
[genkey]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/Wireguard/genkey.sh
|
||||
command:/usr/local/opnsense/scripts/Wireguard/genkey.sh
|
||||
parameters: %s
|
||||
type:script_output
|
||||
message:Generating WireGuard keys
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
###################################################################
|
||||
# Local syslog-ng configuration filter definition [wireguard].
|
||||
###################################################################
|
||||
filter f_local_wireguard {
|
||||
program("wireguard");
|
||||
};
|
||||
@@ -1,15 +1,2 @@
|
||||
{% if helpers.exists('OPNsense.wireguard.general.enabled') and OPNsense.wireguard.general.enabled == '1' %}
|
||||
wireguard_setup="/usr/local/opnsense/scripts/OPNsense/Wireguard/setup.sh"
|
||||
wireguard_enable="YES"
|
||||
{% if helpers.exists('OPNsense.wireguard.server.servers.server') %}
|
||||
{% set activeservers=[] %}
|
||||
{% for servers in helpers.toList('OPNsense.wireguard.server.servers.server') %}
|
||||
{% if servers.enabled == '1' %}
|
||||
{% do activeservers.append("wg" + servers.instance) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
wireguard_interfaces="{{ activeservers | join(' ') }}"
|
||||
{% else %}
|
||||
# disable the wireguard rc scripts when installed, bootup handled via rc.syshook
|
||||
wireguard_enable="NO"
|
||||
{% endif %}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user