From 144d8a23b3474d1f294ce29b01c89de80d4d0267 Mon Sep 17 00:00:00 2001 From: Matthew Saunders Brown Date: Tue, 13 Feb 2024 14:41:15 -0800 Subject: [PATCH] add vdns code --- panel/classes/Panel/Vdns.php | 106 +++++++++++++++++++++++ panel/classes/Panel/Vdns/Zones.php | 73 ++++++++++++++++ panel/classes/Panel/Vdns/ZonesAdd.php | 69 +++++++++++++++ panel/classes/Panel/Vdns/ZonesDelete.php | 46 ++++++++++ panel/config/config.ini | 66 +++++++------- panel/config/maps-vdns.ini | 11 +++ panel/config/maps-vpanel.ini | 1 - panel/index.php | 5 ++ panel/ui/header.html | 1 + panel/ui/vdns/zones-add.html | 20 +++++ panel/ui/vdns/zones-delete.html | 17 ++++ panel/ui/vdns/zones-zone.html | 86 ++++++++++++++++++ panel/ui/vdns/zones.html | 47 ++++++++++ 13 files changed, 517 insertions(+), 31 deletions(-) create mode 100644 panel/classes/Panel/Vdns.php create mode 100644 panel/classes/Panel/Vdns/Zones.php create mode 100644 panel/classes/Panel/Vdns/ZonesAdd.php create mode 100644 panel/classes/Panel/Vdns/ZonesDelete.php create mode 100644 panel/config/maps-vdns.ini create mode 100644 panel/ui/vdns/zones-add.html create mode 100644 panel/ui/vdns/zones-delete.html create mode 100644 panel/ui/vdns/zones-zone.html create mode 100644 panel/ui/vdns/zones.html diff --git a/panel/classes/Panel/Vdns.php b/panel/classes/Panel/Vdns.php new file mode 100644 index 0000000..a644392 --- /dev/null +++ b/panel/classes/Panel/Vdns.php @@ -0,0 +1,106 @@ + + * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + */ + +namespace Panel; + +class Vdns extends \Panel { + + function beforeRoute($f3) { + + parent::beforeRoute($f3); + + if ($f3->get('PDNSADMIN') != '1') { + $f3->reroute('/'); + } + + } + + public static function verifyZoneExists($zone) { + + global $f3; + + exec("/usr/local/bin/vdns-zone-ext.sh -z $zone", $output, $result_code); + if ($result_code == 0 && $output[0] == 'true') { + return TRUE; + } else { + return FALSE; + } + + } + + public static function returnZoneDefaultsArray($zone) { + + global $f3; + + if ($defaults_array = $f3->call('\Panel::vGet', array("vdns-zone-def.sh -z $zone -c", FALSE))) { + return $defaults_array; + } else { + return FALSE; + } + + } + + public static function returnZoneDefaultsNameserverArray($zone) { + + global $f3; + + if ($defaults_array = $f3->call('\Panel\Vdns::returnZoneDefaultsArray', $zone)) { + $defaults_ns_array = array(); + foreach($defaults_array as $record_array) { + if ($record_array['type'] == "NS") { + $defaults_ns_array[] = $record_array['content']; + } + } + sort($defaults_ns_array); + return $defaults_ns_array; + } else { + return FALSE; + } + + } + + public static function returnNameserverArray($zone) { + + global $f3; + + $ns_array = array(); + if ($dns_ns_array = dns_get_record("$zone", DNS_NS)) { + foreach ($dns_ns_array as $record_array) { + $ns_array[] = $record_array['target']; + } + sort($ns_array); + return $ns_array; + } else { + return FALSE; + } + + + } + + public static function returnNameserverStatus($zone) { + + global $f3; + + if ($defaults_ns_array = $f3->call('\Panel\Vdns::returnZoneDefaultsNameserverArray', $zone)) { + if ($ns_array = $f3->call('\Panel\Vdns::returnNameserverArray', $zone)) { + if ($defaults_ns_array === $ns_array) { + return "Verified"; + } else { + return "Pending"; + } + } else { + return "Unknown"; + } + } else { + return "Error"; + } + + } + +} diff --git a/panel/classes/Panel/Vdns/Zones.php b/panel/classes/Panel/Vdns/Zones.php new file mode 100644 index 0000000..39509b0 --- /dev/null +++ b/panel/classes/Panel/Vdns/Zones.php @@ -0,0 +1,73 @@ + + * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + */ + +namespace Panel\Vdns; + +class Zones extends \Panel\Vdns { + + /* use this to make query */ + function beforeRoute($f3) { + + parent::beforeRoute($f3); + + if ($f3->exists('PARAMS.zone')) { + $zone = $f3->get('PARAMS.zone'); + if ($f3->call('\Panel\Vdns::verifyZoneExists', $zone)) { + if ($zone_array = $f3->call('\Panel::vGet', array("vdns-zone-exp.sh -z $zone -c", FALSE))) { + $f3->set('zone_array', $zone_array); + } + $ns_info_array = array(); + $ns_info_array['zone'] = $zone; + $ns_info_array['status'] = $f3->call('\Panel\Vdns::returnNameserverStatus', $zone); + if ($ns_info_array['status'] != "Verified") { + $ns_info_array['defaults_ns_array'] = $f3->call('\Panel\Vdns::returnZoneDefaultsNameserverArray', $zone); + $ns_info_array['ns_array'] = $f3->call('\Panel\Vdns::returnNameserverArray', $zone); + } + $f3->set('ns_info_array', $ns_info_array); + } + } else { + if ($zones_array = $f3->call('\Panel::vGet', array("vdns-zone-lst.sh", FALSE))) { + foreach ($zones_array as $k=>$zone_array) { + $zones_array[$k]['ns_status'] = $f3->call('\Panel\Vdns::returnNameserverStatus', $zone_array['zone']); + } + $f3->set('zones_array', $zones_array); + } + } + + } + + static function get($f3) { + + if ($f3->exists('PARAMS.zone')) { + + $zone = $f3->get('PARAMS.zone'); + + if (is_array($f3->get('zone_array'))) { + + $f3->set('page_header', "DNS Zone records for $zone"); + echo \Template::instance()->render('vdns/zones-zone.html'); + + } else { + + $messages[] = "Zone $zone not found."; + $f3->set('SESSION.messages', $messages); + $f3->reroute("/DNS"); + + } + + } else { + + $f3->set('page_header', "DNS Zones"); + echo \Template::instance()->render('vdns/zones.html'); + + } + + } + +} diff --git a/panel/classes/Panel/Vdns/ZonesAdd.php b/panel/classes/Panel/Vdns/ZonesAdd.php new file mode 100644 index 0000000..271db32 --- /dev/null +++ b/panel/classes/Panel/Vdns/ZonesAdd.php @@ -0,0 +1,69 @@ + + * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + */ + +namespace Panel\Vdns; + +class ZonesAdd extends \Panel\Vdns { + + function beforeRoute($f3) { + + parent::beforeRoute($f3); + + } + + static function get($f3) { + + echo \Template::instance()->render('vdns/zones-add.html'); + + } + + function post($f3) { + + // print_r($_POST); + + /* force zone to be all lower case */ + $zone = strtolower($_POST['zone']); + /* strip spaces */ + $zone = trim($zone); + /* remove leading www. */ + $zone = preg_replace('/^www\./', '', $zone); + /* remove trailing . (dot) */ + $zone = rtrim($zone, '.'); + if ($f3->call('\Panel::validateDomain', $zone)) { + /* check if zone exists */ + if ($f3->call('\Panel\Vdns::verifyZoneExists', $zone)) { + $messages[] = "Zone $zone already exists in DNS."; + $messages[] = "Note if $zone should be associated with this server but it's now showing up in the list below please contact support."; + $f3->set('SESSION.messages', $messages); + $f3->call('\Panel\Vdns\ZonesAdd::get', $f3); + } else { + $hostname = $f3->get('NAV.hostname'); + exec("/usr/local/bin/vdns-zone-add.sh -z $zone -w hostname=$hostname/$zone", $output, $result_code); + if ($result_code == 0) { + $messages[] = "Zone (Domain Name) $zone has been added to DNS."; + $f3->set('SESSION.messages', $messages); + $f3->reroute("/DNS"); + } else { + if (count($output) > 0) { + foreach ($output as $k=>$output_message) { + $messages[] = "$output_message"; + } + } else { + $messages[] = "Unknown error adding Zone $zone to DNS."; + } + $f3->set('SESSION.messages', $messages); + $f3->call('\Panel\Vdns\ZonesAdd::get', $f3); + } + } + } else { + $f3->call('\Panel\Vdns\ZonesAdd::get', $f3); + } + } + +} diff --git a/panel/classes/Panel/Vdns/ZonesDelete.php b/panel/classes/Panel/Vdns/ZonesDelete.php new file mode 100644 index 0000000..6aa74d7 --- /dev/null +++ b/panel/classes/Panel/Vdns/ZonesDelete.php @@ -0,0 +1,46 @@ + + * GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + */ + +namespace Panel\Vdns; + +class ZonesDelete extends \Panel\Vdns { + + function beforeRoute($f3) { + + parent::beforeRoute($f3); + + /* verify zone exists */ + $zone = $f3->get('PARAMS.zone'); + if (!$f3->call('\Panel\Vdns::verifyZoneExists', $zone)) { + $messages[] = "Zone '$zone' does not exist."; + $f3->set('SESSION.messages', $messages); + $f3->reroute("/DNS"); + } + + } + + static function get($f3) { + + $f3->set('confirm', 'true'); + echo \Template::instance()->render('vdns/zones-delete.html'); + + } + + function post($f3) { + + /* run delete command here */ + $zone = $f3->get('PARAMS.zone'); + exec("/usr/local/bin/vdns-zone-del.sh -z $zone -x", $output, $result_code); + $messages[] = "Zone '$zone' has been deleted from DNS."; + $f3->set('SESSION.messages', $messages); + $f3->reroute("/DNS"); + + } + +} diff --git a/panel/config/config.ini b/panel/config/config.ini index 7ccd7ad..989f3b8 100644 --- a/panel/config/config.ini +++ b/panel/config/config.ini @@ -1,30 +1,36 @@ -; vpanel-stack -; https://git.stack-source.com/msb/vpanel-stack -; Copyright (c) 2022 Matthew Saunders Brown -; GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -[globals] -DEBUG=0 -UI=ui/ -AUTOLOAD=classes/ -TEMP=tmp/ -LOGS=tmp/logs/ -UPLOADS=tmp/uploads/ -PACKAGE=Stack-Panel -AUTHOR=Matthew Saunders Brown -LICENSE=GPL-3.0 -LICENSEURL=https://www.gnu.org/licenses/gpl-3.0.txt -CASELESS=FALSE -CACHE=TRUE -; Session lifetime in seconds -TIMEOUT=900 -; Remote IP address that is automatically logged in without auth -ADMINIP= -; Jail new users by default. 1 = Yes, blank or 0 = No -JAILUSER=1 -; PHP-FPM pm.max_children. Recommended range 2-12 on Shared Server -FPMMAX=4 -; Write user info to /home/username/.passwd. 1 = Yes, blank or 0 = No -WRITEUSERINFO=1 -; Show "Write User Info" & "Write DB Info" options. If no then just use defaults above without giving users the option to change. 1 = Yes, blank or 0 = No -SHOWWRITEINFO=0 +; vpanel-stack +; https://git.stack-source.com/msb/vpanel-stack +; Copyright (c) 2022 Matthew Saunders Brown +; GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +[globals] +DEBUG=0 +UI=ui/ +AUTOLOAD=classes/ +TEMP=tmp/ +LOGS=tmp/logs/ +UPLOADS=tmp/uploads/ +PACKAGE=Stack-Panel +AUTHOR=Matthew Saunders Brown +LICENSE=GPL-3.0 +LICENSEURL=https://www.gnu.org/licenses/gpl-3.0.txt +CASELESS=FALSE +CACHE=TRUE +; Session lifetime in seconds +TIMEOUT=900 +; Remote IP address that is automatically logged in without auth +ADMINIP= +; Jail new users by default. 1 = Yes, blank or 0 = No +JAILUSER=1 +; PHP-FPM pm.max_children. Recommended range 2-12 on Shared Server +FPMMAX=4 +; Write user info to /home/username/.passwd. 1 = Yes, blank or 0 = No +WRITEUSERINFO=1 +; Show "Write User Info" & "Write DB Info" options. If no then just use defaults above without giving users the option to change. 1 = Yes, blank or 0 = No +SHOWWRITEINFO=0 +; DNS admin. 1 = Yes, blank or 0 = No +PDNSADMIN=0 +; Maximum number of results returned for DNS listings. Defaults to 100 if unspecified. +;PDNSMAX=100 +; URL to phpMyPDNS. If this is set, and PDNSADMIN is enabled, show link to phpMyPDNS +PHPMYPDNSURL= diff --git a/panel/config/maps-vdns.ini b/panel/config/maps-vdns.ini new file mode 100644 index 0000000..7a8e5ec --- /dev/null +++ b/panel/config/maps-vdns.ini @@ -0,0 +1,11 @@ +; vpanel-stack +; https://git.stack-source.com/msb/vpanel-stack +; Copyright (c) 2024 Matthew Saunders Brown +; GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +[maps] +; Vdns +/DNS [sync] = Panel\Vdns\Zones +/DNS/@zone [sync] = Panel\Vdns\Zones +/DNS/Add [sync] = Panel\Vdns\ZonesAdd +/DNS/@zone/Delete [sync] = Panel\Vdns\ZonesDelete diff --git a/panel/config/maps-vpanel.ini b/panel/config/maps-vpanel.ini index bebb7cb..f1578bd 100644 --- a/panel/config/maps-vpanel.ini +++ b/panel/config/maps-vpanel.ini @@ -84,4 +84,3 @@ /Certs/@cert/Delete [sync] = Panel\Cert\CertsDelete /Databases [sync] = Panel\MySQL\Databases - diff --git a/panel/index.php b/panel/index.php index 13b092f..5542533 100644 --- a/panel/index.php +++ b/panel/index.php @@ -38,6 +38,11 @@ if ($f3->get('HOST') == $f3->get('NAV.hostname')) { $f3->set('NAV.mapping', $mapping); $f3->config("config/maps-$mapping.ini"); +/* load DNS mapping, if enabled */ +if ($f3->get('PDNSADMIN') == '1') { + $f3->config("config/maps-vdns.ini"); +} + /* custom error page */ $f3->set('ONERROR',function($f3){ echo \Template::instance()->render('error.html'); diff --git a/panel/ui/header.html b/panel/ui/header.html index 74e9ce0..04f23b1 100644 --- a/panel/ui/header.html +++ b/panel/ui/header.html @@ -33,6 +33,7 @@ Databases | Certificates | Users | + DNS | Logout diff --git a/panel/ui/vdns/zones-add.html b/panel/ui/vdns/zones-add.html new file mode 100644 index 0000000..36add0d --- /dev/null +++ b/panel/ui/vdns/zones-add.html @@ -0,0 +1,20 @@ + + +
+

Add New Zone

+
+ Domain name to be added to DNS + + +
+ + + +
+
+ +

+Zone Enter the Domain Name that will be added to DNS.
+

+ + diff --git a/panel/ui/vdns/zones-delete.html b/panel/ui/vdns/zones-delete.html new file mode 100644 index 0000000..85afa9e --- /dev/null +++ b/panel/ui/vdns/zones-delete.html @@ -0,0 +1,17 @@ + + + + +
+
+ Really Delete Zone {{ @PARAMS.zone }} from DNS +
+ +
+ CAUTION: This will permanently remove the zone {{ @PARAMS.zone }} and all associated records from DNS. There is no undo after this! +
+
+ +
+ + diff --git a/panel/ui/vdns/zones-zone.html b/panel/ui/vdns/zones-zone.html new file mode 100644 index 0000000..fa993bc --- /dev/null +++ b/panel/ui/vdns/zones-zone.html @@ -0,0 +1,86 @@ + + + + +

+ + + + Nameservers for {{ @ns_info_array.zone }} verified. The DNS records below are active.
+ + You can manage these DNS entries here: {{ @PHPMYPDNSURL }} + +
+ +

NOTICE:
+ +
+ + The Nameservers for {{ @ns_info_array.zone }} are not pointing to this DNS system.
+ To make this DNS active update the Nameservers at your current Domain Name Registrar to:
+ + {{ @nameserver }}
+
+ Note that after making this change it can take up to 24 hours for the changes to go through.
+
+ If you are intentionally using another provider for DNS you can reference the records below for what should be added to your DNS (excluding the NS & SOA records). +
+ + The Nameserver verification system could not find nameserver information for {{ @ns_info_array.zone }}.
+ Make sure the domain name is registered and has the folowing nameservers set:
+ + {{ @nameserver }}
+
+
+ + There was an error verifying the Namservers for {{ @ns_info_array.zone }}.
+ If this persists please contact tech support. +
+
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTTLClassTypeValue
{{ @record_array.name }}{{ @record_array.ttl }}{{ @record_array.class }}{{ @record_array.type }}"{{ @record_array.value }}"{{ @record_array.value }}
+ +

Notes:
+

    +
  • Zone info is displayed in BIND format.
    You should be able to cut-and-past above records directly into a BIND file, if desired.
  • +
  • MX & SRV records will show the Priority as part of the record.
    e.g. "10 mail.example.com" indicates a Priority of "10" for "mail.example.com".
    Only MX & SRV records use Priority, all other records have an unused priority of "0".
  • +
+

+ + +

phpMyPDNS can be used to manage DNS entries here: {{ @PHPMYPDNSURL }}

+
+ +
+ +

No Zone info.

+
+ + + diff --git a/panel/ui/vdns/zones.html b/panel/ui/vdns/zones.html new file mode 100644 index 0000000..f9cc369 --- /dev/null +++ b/panel/ui/vdns/zones.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
ZoneNameserversAction
{{ @zone.zone }}✓ {{ @zone.ns_status }}{{ @zone.ns_status }} - click view for details →View Delete
+
+ +

There are no DNS Zones on this server.

+
+
+ +

+Zone is what a Domain Name is called in DNS.
+View zone to see list of all DNS entries.
+Delete will remove the zone from DNS entirely.
+

+ + +

phpMyPDNS can be used to manage DNS entries here: {{ @PHPMYPDNSURL }}

+
+ +

+Add new DNS Zone +

+ +