Hi Cedrik,
sadly, I habe a dynamic IPv6 prefix and my ISP (1&1) is not willing to change that.
I looked through the forum and found you mentioning that it might be possible to use the API via a PHP script to add the dynamic prefix to the access list.
I chatgpted my way through the API documentation, but I couldn't figure out how to update the access list. My problem is that I could not find a unique UUID for the access list. When I looked through the caddy file, I noticed that the UUID is always attached to the subdomain, for example "@cff47bd5-bb15-4551-89bc-9eef1b952b06_pagedomainnet"
My first guess is that I use the script to update the caddy config, but I think that's a stupid idea because then I would no longer be able to use the GUI if my understanding is correct.
Here is the script "I" created with the help of ChatGPT, sadly I am not a programmer, but I work in IT, so I am a little bit familiar with scripting (PowerShell).
Github Link
sadly, I habe a dynamic IPv6 prefix and my ISP (1&1) is not willing to change that.
I looked through the forum and found you mentioning that it might be possible to use the API via a PHP script to add the dynamic prefix to the access list.
I chatgpted my way through the API documentation, but I couldn't figure out how to update the access list. My problem is that I could not find a unique UUID for the access list. When I looked through the caddy file, I noticed that the UUID is always attached to the subdomain, for example "@cff47bd5-bb15-4551-89bc-9eef1b952b06_pagedomainnet"
My first guess is that I use the script to update the caddy config, but I think that's a stupid idea because then I would no longer be able to use the GUI if my understanding is correct.
Here is the script "I" created with the help of ChatGPT, sadly I am not a programmer, but I work in IT, so I am a little bit familiar with scripting (PowerShell).
Github Link
Code Select
#!/usr/local/bin/php
<?php// === Konfiguration ===$interface = "pppoe0"; // Name des Netzwerkinterfaces$prefixLength = 64; // Prefix-Länge (z. B. 56)$accessListUUID = "cff47bd5-bb15-4551-89bc-9eef1b952b06"; // UUID des Access-List-Eintrags// API-Zugangsdaten$api_base_url = "https://opnsense.domain.net/api/caddy/"; // Basis-URL$api_key = "xxx";$api_secret = "xxx";// Statische IPv4-Bereiche$ipv4_allowed = [ "192.168.0.0/16", "172.16.0.0/12", "10.0.0.0/8"];// === Funktionen ===function callApi($endpoint, $method = "GET", $data = null) { global $api_base_url, $api_key, $api_secret; $url = $api_base_url . $endpoint; $ch = curl_init($url); if ($ch === false) { echo "Fehler bei curl_init(): " . curl_error($ch) . "\n"; return null; } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $headers = [ "Content-Type: application/json", "X-API-Key: $api_key", "X-API-Secret: $api_secret" ]; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); if ($data !== null) { $jsonData = json_encode($data, JSON_PRETTY_PRINT); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData); } $response = curl_exec($ch); if ($response === false) { echo "Fehler beim Curl-Request: " . curl_error($ch) . "\n"; curl_close($ch); return null; } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpCode != 200) { echo "HTTP-Fehler: " . $httpCode . "\n"; echo "Antwort: " . $response . "\n"; curl_close($ch); return null; } curl_close($ch); $decodedResponse = json_decode($response, true); if (json_last_error() !== JSON_ERROR_NONE) { echo "Ungültige JSON-Antwort: " . json_last_error_msg() . "\n"; return null; } return $decodedResponse;}function getIPv6Address($interface) { $cmd = "ifconfig " . escapeshellarg($interface) . " | awk '/inet6 / && !/fe80/ && /prefixlen/ {print $2; exit}'"; $ipv6 = trim(shell_exec($cmd)); if (empty($ipv6)) { echo "Fehler: Keine IPv6-Adresse gefunden oder Befehl fehlgeschlagen.\n"; return false; } return $ipv6;}function calculateIPv6Prefix($ipv6, $prefixLength) { $groups = explode(":", $ipv6); if (count($groups) < 4) { return false; } $g1 = $groups[0]; $g2 = $groups[1]; $g3 = $groups[2]; $g4 = $groups[3]; $g4 = str_pad($g4, 4, "0", STR_PAD_LEFT); $prefixPart = substr($g4, 0, 2) . "00"; $networkPrefix = "$g1:$g2:$g3:$prefixPart::"; return $networkPrefix;}// === Hauptlogik ===$ipv6_address = getIPv6Address($interface);if ($ipv6_address === false) { echo "Fehler: Keine IPv6-Adresse auf Interface $interface gefunden.\n"; exit(1);}echo "Gefundene IPv6-Adresse: $ipv6_address\n";$dynamicPrefix = calculateIPv6Prefix($ipv6_address, $prefixLength);if ($dynamicPrefix === false) { echo "Fehler beim Berechnen des IPv6-Netzwerk-Prefix aus $ipv6_address\n"; exit(1);}$dynamicPrefixWithCIDR = $dynamicPrefix . "/" . $prefixLength;echo "Berechneter dynamischer IPv6-Prefix: $dynamicPrefixWithCIDR\n";$allowedNetworks = array_merge($ipv4_allowed, [$dynamicPrefixWithCIDR]);$updateData = [ "uuid" => $accessListUUID, "client_ip" => $allowedNetworks];$jsonData = json_encode($updateData, JSON_PRETTY_PRINT);var_dump($jsonData);echo "Sende Update an die Access-Liste (UUID: $accessListUUID)...\n";$updateResponse = callApi("reverseproxy/setAccessList/" . $accessListUUID, "POST", $updateData);if ($updateResponse === null) { echo "Fehler beim Aktualisieren der Access-Liste.\n"; exit(1);}// Überprüfe die API-Antwort auf Erfolgif (isset($updateResponse['status']) && $updateResponse['status'] !== 'success') { echo "Fehlerhafte API-Antwort: " . $updateResponse['message'] . "\n"; var_dump($updateResponse); exit(1);}echo "Access-Liste erfolgreich aktualisiert.\n";echo "Löse Neukonfiguration von Caddy aus...\n";$reconfigResponse = callApi("reverseproxy/service/reconfigure", "POST", []);if ($reconfigResponse === null) { echo "Fehler beim Auslösen der Neukonfiguration.\n"; exit(1);}echo "Caddy wurde erfolgreich neu konfiguriert.\n";exit(0);?>