feat: add PowerDNS reverse DNS (PTR) integration
Introduces an opt-in reverse DNS management subsystem backed by a PowerDNS
Authoritative HTTP API. Runs via a companion WHMCS addon module
(modules/addons/VirtFusionDns) that holds settings and a Test Connection
page; the server module reads those settings from tbladdonmodules and
short-circuits when the addon is absent or disabled, so provisioning is
unaffected for operators who don't use the feature.
Lifecycle hooks:
- createAccount creates PTRs for every assigned IP (forward DNS must
already resolve to the IP — FCrDNS enforcement)
- renameServer updates only PTRs whose content matched the old hostname,
preserving client-custom records
- terminateAccount deletes all PTRs before the local state is purged
- TestConnection merges PowerDNS health check with the existing VirtFusion
check
- A DailyCronJob hook reconciles missing PTRs additive-only (never
overwrites)
Client UI: new "Reverse DNS" panel on the service overview with one
editable PTR input per assigned IP, per-row status badges, and
forward-DNS rejection on save. Admin services tab gets a parallel
widget with Reconcile (additive) and Reconcile (force reset) buttons.
New subsystem at lib/PowerDns/:
- Client.php PowerDNS API wrapper (X-API-Key, listZones/getZone/
patchRRset/notifyZone), auto-NOTIFY on successful PATCH
- Config.php Loads + decrypts addon settings from tbladdonmodules
- IpUtil.php PTR-name generation (IPv4 + IPv6), zone matching,
RFC 2317 classless parsing
- Resolver.php FCrDNS verification via dns_get_record with CNAME-chain
following and per-(hostname,ip) caching
- PtrManager.php Orchestrator: syncServer, deleteForServer, listPtrs,
setPtr, reconcile, reconcileAll
Security hardening helpers added to Module and applied to the rDNS
endpoints:
- requirePost() HTTP method gate (405 on non-POST mutations)
- requireSameOrigin() Origin/Referer check against WHMCS host (CSRF
defence against cross-site form POST)
- requireServiceStatus() tblhosting.domainstatus filter (Active for
writes, Active+Suspended for reads)
RFC 2317 classless delegations (e.g. 64/64.113.0.203.in-addr.arpa.)
supported with alignment validation: rejects misaligned start addresses
that don't correspond to any real delegation boundary.
PowerDNS zone IDs containing '/' are URL-encoded as '=2F' per the
PowerDNS API convention. PATCH success triggers PUT /zones/{id}/notify
so slaves pick up the SOA-bumped serial immediately.
Includes IPv4 + IPv6 support, per-IP write rate limit (10s), fresh
IP-ownership re-verification on every client write (defends against
stale-ownership after IP reassignment), and audit logging of every
successful edit to the WHMCS module log.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* VirtFusion Direct Provisioning Module — WHMCS server module entry point.
|
||||
*
|
||||
* This file contains the non-namespaced functions WHMCS calls via its reflection-
|
||||
* based module dispatcher. They follow the naming convention:
|
||||
*
|
||||
* {ModuleDirectoryName}_{FunctionName}(...)
|
||||
*
|
||||
* WHMCS looks for these on every relevant event (provisioning, UI rendering,
|
||||
* daily cron, test connection, etc.). Every function here is a thin shim that
|
||||
* instantiates ModuleFunctions (or Module) and delegates to a method — keeping
|
||||
* the dispatch surface small and the business logic in unit-exercisable classes.
|
||||
*
|
||||
* DO NOT add significant logic directly in these shims. If you need a new
|
||||
* lifecycle behaviour, add it as a method on ModuleFunctions and point the
|
||||
* shim at it. This makes the module predictable: one public function, one method.
|
||||
*
|
||||
* RESERVED NAMES — DO NOT CHANGE
|
||||
* ------------------------------
|
||||
* WHMCS looks up these specific function names by convention; renaming them
|
||||
* disables the corresponding feature in WHMCS silently:
|
||||
* VirtFusionDirect_MetaData → Displayed name + API version
|
||||
* VirtFusionDirect_ConfigOptions → Product-level settings fields
|
||||
* VirtFusionDirect_TestConnection → Admin "Test Connection" button
|
||||
* VirtFusionDirect_CreateAccount → Provisioning on order-activation
|
||||
* VirtFusionDirect_SuspendAccount → Suspension
|
||||
* VirtFusionDirect_UnsuspendAccount → Unsuspension
|
||||
* VirtFusionDirect_TerminateAccount → Termination
|
||||
* VirtFusionDirect_ChangePackage → Package change on upgrade/downgrade
|
||||
* VirtFusionDirect_AdminServicesTabFields → Admin services tab renderer
|
||||
* VirtFusionDirect_AdminServicesTabFieldsSave → Admin services tab save handler
|
||||
* VirtFusionDirect_ClientArea → Client-area template + vars
|
||||
* VirtFusionDirect_ServiceSingleSignOn → SSO button handler
|
||||
* VirtFusionDirect_AdminCustomButtonArray → Custom admin action buttons
|
||||
* VirtFusionDirect_UsageUpdate → Daily cron bandwidth/disk usage sync
|
||||
*/
|
||||
if (! defined('WHMCS')) {
|
||||
exit('This file cannot be accessed directly');
|
||||
}
|
||||
@@ -9,6 +45,8 @@ use WHMCS\Module\Server\VirtFusionDirect\Database;
|
||||
use WHMCS\Module\Server\VirtFusionDirect\Log;
|
||||
use WHMCS\Module\Server\VirtFusionDirect\Module;
|
||||
use WHMCS\Module\Server\VirtFusionDirect\ModuleFunctions;
|
||||
use WHMCS\Module\Server\VirtFusionDirect\PowerDns\Client as PowerDnsClient;
|
||||
use WHMCS\Module\Server\VirtFusionDirect\PowerDns\Config as PowerDnsConfig;
|
||||
|
||||
/**
|
||||
* Returns module metadata consumed by WHMCS.
|
||||
@@ -97,6 +135,20 @@ function VirtFusionDirect_TestConnection(array $params)
|
||||
$httpCode = $request->getRequestInfo('http_code');
|
||||
|
||||
if ($httpCode == 200) {
|
||||
// Also verify PowerDNS health when the DNS addon is activated, so the
|
||||
// admin's Test Connection button reflects the full provisioning path.
|
||||
if (PowerDnsConfig::isEnabled()) {
|
||||
$pdns = (new PowerDnsClient)->ping();
|
||||
if (! $pdns['ok']) {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'VirtFusion OK; PowerDNS unreachable — '
|
||||
. ($pdns['error'] ?? 'unknown')
|
||||
. ' (HTTP ' . (int) $pdns['http'] . '). Fix the VirtFusion DNS addon settings.',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return ['success' => true, 'error' => ''];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user