diff --git a/net/cloudflared/LICENSE b/net/cloudflared/LICENSE new file mode 100644 index 0000000000..7aef97141f --- /dev/null +++ b/net/cloudflared/LICENSE @@ -0,0 +1,24 @@ +BSD 2-Clause License + +Copyright (c) 2026, Alan Martines + +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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. diff --git a/net/cloudflared/Makefile b/net/cloudflared/Makefile new file mode 100644 index 0000000000..5c7f11aa64 --- /dev/null +++ b/net/cloudflared/Makefile @@ -0,0 +1,8 @@ +PLUGIN_NAME= cloudflared +PLUGIN_VERSION= 0.1.0 +PLUGIN_REVISION= 1 +PLUGIN_COMMENT= Cloudflare Tunnel (cloudflared) integration +PLUGIN_MAINTAINER= alancpmartines@hotmail.com +PLUGIN_DEPENDS= fetch + +.include "../../Mk/plugins.mk" diff --git a/net/cloudflared/pkg-descr b/net/cloudflared/pkg-descr new file mode 100644 index 0000000000..99a12e8f1b --- /dev/null +++ b/net/cloudflared/pkg-descr @@ -0,0 +1,17 @@ +Cloudflare Tunnel (cloudflared) integration for OPNsense. + +Provides a native MVC interface to manage token-based Cloudflare Zero +Trust tunnels without opening firewall ports or requiring a static IP. +Follows Method 1: Token-based Setup using binaries from the kjake +FreeBSD fork of cloudflared. + +Features: +- Token-based tunnel authentication via Cloudflare Zero Trust +- Integrated binary installer with automatic FreeBSD version and + architecture detection +- QUIC kernel tuning (kern.ipc.maxsockbuf, net.inet.udp.recvspace) +- Post-quantum encryption support (--post-quantum) +- Real-time tunnel health status in the UI +- Appears in System: Diagnostics: Services + +WWW: https://github.com/AlanMartines/os-cloudflared diff --git a/net/cloudflared/src/etc/inc/plugins.inc.d/cloudflared.inc b/net/cloudflared/src/etc/inc/plugins.inc.d/cloudflared.inc new file mode 100644 index 0000000000..4a5de3d572 --- /dev/null +++ b/net/cloudflared/src/etc/inc/plugins.inc.d/cloudflared.inc @@ -0,0 +1,53 @@ + + * 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. + */ + +function cloudflared_enabled() +{ + $model = new \OPNsense\Cloudflared\Cloudflared(); + return (string)$model->general->enabled == '1'; +} + +function cloudflared_services() +{ + $services = []; + + if (cloudflared_enabled()) { + $services[] = [ + 'description' => gettext('Cloudflare Tunnel'), + 'configd' => [ + 'restart' => ['cloudflared restart'], + 'start' => ['cloudflared start'], + 'stop' => ['cloudflared stop'], + ], + 'name' => 'cloudflared', + 'pidfile' => '/var/run/cloudflared.pid', + ]; + } + + return $services; +} diff --git a/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/Api/ServiceController.php b/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/Api/ServiceController.php new file mode 100644 index 0000000000..82220a87c5 --- /dev/null +++ b/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/Api/ServiceController.php @@ -0,0 +1,56 @@ +request->isPost()) { + $backend = new Backend(); + $backend->configdRun("cloudflared reconfigure"); + return ['status' => 'ok']; + } + return ['status' => 'failed']; + } + + public function tunnelStatusAction() + { + $backend = new Backend(); + $response = $backend->configdRun("cloudflared tunnel_status"); + $data = json_decode(trim($response), true); + if ($data === null) { + return ['tunnel' => 'unknown']; + } + return $data; + } + + public function installAction() + { + if ($this->request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun("cloudflared install_binary"); + if ($response === null) { + return ['response' => 'ERROR: configd did not respond. Run "service configd restart" on OPNsense.']; + } + $response = trim($response); + if ($response === '' || $response === 'FAILED') { + return ['response' => 'ERROR: Action not found. Run "service configd restart" on OPNsense to reload actions.']; + } + return ['response' => $response]; + } + return ['response' => 'error']; + } +} diff --git a/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/Api/SettingsController.php b/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/Api/SettingsController.php new file mode 100644 index 0000000000..1f9668ca1a --- /dev/null +++ b/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/Api/SettingsController.php @@ -0,0 +1,12 @@ + + * 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\Cloudflared; + +use OPNsense\Base\IndexController as BaseIndexController; + +class IndexController extends BaseIndexController +{ + public function indexAction() + { + $this->view->generalForm = $this->getForm("general"); + $this->view->pick('OPNsense/Cloudflared/index'); + } +} diff --git a/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/forms/general.xml b/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/forms/general.xml new file mode 100644 index 0000000000..6625d4c0cf --- /dev/null +++ b/net/cloudflared/src/opnsense/mvc/app/controllers/OPNsense/Cloudflared/forms/general.xml @@ -0,0 +1,38 @@ +
diff --git a/net/cloudflared/src/opnsense/mvc/app/languages/en_US.po b/net/cloudflared/src/opnsense/mvc/app/languages/en_US.po new file mode 100644 index 0000000000..9c2029b08d --- /dev/null +++ b/net/cloudflared/src/opnsense/mvc/app/languages/en_US.po @@ -0,0 +1,93 @@ +msgid "" +msgstr "" +"Project-Id-Version: os-cloudflared\n" +"Language: en_US\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# Menu & ACL +msgid "Cloudflare Tunnel" +msgstr "Cloudflare Tunnel" + +msgid "Settings" +msgstr "Settings" + +msgid "Allow access to Cloudflare Tunnel settings" +msgstr "Allow access to Cloudflare Tunnel settings" + +msgid "Allow access to Cloudflare Tunnel service status/control" +msgstr "Allow access to Cloudflare Tunnel service status/control" + +# General Form +msgid "General Settings" +msgstr "General Settings" + +msgid "Enable" +msgstr "Enable" + +msgid "Tunnel Token" +msgstr "Tunnel Token" + +msgid "Disable Auto-Update" +msgstr "Disable Auto-Update" + +msgid "Enable Post-Quantum Encryption" +msgstr "Enable Post-Quantum Encryption" + +msgid "Max Socket Buffer (kern.ipc.maxsockbuf)" +msgstr "Max Socket Buffer (kern.ipc.maxsockbuf)" + +msgid "UDP Recv Space (net.inet.udp.recvspace)" +msgstr "UDP Recv Space (net.inet.udp.recvspace)" + +msgid "Enable Cloudflare Tunnel" +msgstr "Enable Cloudflare Tunnel" + +msgid "The token for your Cloudflare Tunnel. Get it from one.dash.cloudflare.com > Access > Tunnels." +msgstr "The token for your Cloudflare Tunnel. Get it from one.dash.cloudflare.com > Access > Tunnels." + +msgid "Pass --no-autoupdate to cloudflared. Recommended when managing updates manually via the Install/Update Binary button." +msgstr "Pass --no-autoupdate to cloudflared. Recommended when managing updates manually via the Install/Update Binary button." + +msgid "Pass --post-quantum to enable post-quantum cryptography for the tunnel connection." +msgstr "Pass --post-quantum to enable post-quantum cryptography for the tunnel connection." + +msgid "Recommended value for QUIC performance. Default is 16777216." +msgstr "Recommended value for QUIC performance. Default is 16777216." + +msgid "Recommended value for QUIC performance. Default is 8388608." +msgstr "Recommended value for QUIC performance. Default is 8388608." + +# UI Buttons +msgid "Apply" +msgstr "Apply" + +msgid "Install/Update Binary" +msgstr "Install/Update Binary" + +msgid "Start" +msgstr "Start" + +msgid "Stop" +msgstr "Stop" + +msgid "Restart" +msgstr "Restart" + +msgid "Running" +msgstr "Running" + +msgid "Stopped" +msgstr "Stopped" + +msgid "No response from server. Check if configd is running." +msgstr "No response from server. Check if configd is running." + +msgid "Tunnel" +msgstr "Tunnel" + +msgid "Healthy" +msgstr "Healthy" + +msgid "Connecting" +msgstr "Connecting" diff --git a/net/cloudflared/src/opnsense/mvc/app/languages/pt_BR.po b/net/cloudflared/src/opnsense/mvc/app/languages/pt_BR.po new file mode 100644 index 0000000000..f4f4a06628 --- /dev/null +++ b/net/cloudflared/src/opnsense/mvc/app/languages/pt_BR.po @@ -0,0 +1,93 @@ +msgid "" +msgstr "" +"Project-Id-Version: os-cloudflared\n" +"Language: pt_BR\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +# Menu & ACL +msgid "Cloudflare Tunnel" +msgstr "Cloudflare Tunnel" + +msgid "Settings" +msgstr "Configurações" + +msgid "Allow access to Cloudflare Tunnel settings" +msgstr "Permitir acesso às configurações do Cloudflare Tunnel" + +msgid "Allow access to Cloudflare Tunnel service status/control" +msgstr "Permitir acesso ao status/controle do serviço Cloudflare Tunnel" + +# General Form +msgid "General Settings" +msgstr "Configurações Gerais" + +msgid "Enable" +msgstr "Habilitar" + +msgid "Tunnel Token" +msgstr "Token do Túnel" + +msgid "Disable Auto-Update" +msgstr "Desativar Atualização Automática" + +msgid "Enable Post-Quantum Encryption" +msgstr "Habilitar Criptografia Pós-Quântica" + +msgid "Max Socket Buffer (kern.ipc.maxsockbuf)" +msgstr "Buffer Máximo de Socket (kern.ipc.maxsockbuf)" + +msgid "UDP Recv Space (net.inet.udp.recvspace)" +msgstr "Espaço de Recebimento UDP (net.inet.udp.recvspace)" + +msgid "Enable Cloudflare Tunnel" +msgstr "Habilitar Cloudflare Tunnel" + +msgid "The token for your Cloudflare Tunnel. Get it from one.dash.cloudflare.com > Access > Tunnels." +msgstr "O token do seu Cloudflare Tunnel. Obtenha em one.dash.cloudflare.com > Access > Tunnels." + +msgid "Pass --no-autoupdate to cloudflared. Recommended when managing updates manually via the Install/Update Binary button." +msgstr "Passa --no-autoupdate ao cloudflared. Recomendado quando as atualizações são gerenciadas manualmente pelo botão Instalar/Atualizar Binário." + +msgid "Pass --post-quantum to enable post-quantum cryptography for the tunnel connection." +msgstr "Passa --post-quantum para habilitar criptografia pós-quântica na conexão do túnel." + +msgid "Recommended value for QUIC performance. Default is 16777216." +msgstr "Valor recomendado para desempenho do QUIC. O padrão é 16777216." + +msgid "Recommended value for QUIC performance. Default is 8388608." +msgstr "Valor recomendado para desempenho do QUIC. O padrão é 8388608." + +# UI Buttons +msgid "Apply" +msgstr "Aplicar" + +msgid "Install/Update Binary" +msgstr "Instalar/Atualizar Binário" + +msgid "Start" +msgstr "Iniciar" + +msgid "Stop" +msgstr "Parar" + +msgid "Restart" +msgstr "Reiniciar" + +msgid "Running" +msgstr "Executando" + +msgid "Stopped" +msgstr "Parado" + +msgid "No response from server. Check if configd is running." +msgstr "Sem resposta do servidor. Verifique se o configd está em execução." + +msgid "Tunnel" +msgstr "Túnel" + +msgid "Healthy" +msgstr "Saudável" + +msgid "Connecting" +msgstr "Conectando" diff --git a/net/cloudflared/src/opnsense/mvc/app/models/OPNsense/Cloudflared/ACL/ACL.xml b/net/cloudflared/src/opnsense/mvc/app/models/OPNsense/Cloudflared/ACL/ACL.xml new file mode 100644 index 0000000000..164256e3d6 --- /dev/null +++ b/net/cloudflared/src/opnsense/mvc/app/models/OPNsense/Cloudflared/ACL/ACL.xml @@ -0,0 +1,9 @@ +| + {{ lang._('Cloudflare Tunnel') }} + + + + | ++ + + + | +