Add DNS monitoring and refresh functionality

Introduce DNS monitoring: add DnsService (comprehensive DNS lookup, crt.sh discovery, Cloudflare detection, IP enrichment) and a new DnsRecord model to persist snapshots, manage diffs, and provide queries/stats. Update DomainController to support a dns_monitoring_enabled flag, refactor WHOIS/DNS refresh logic into performWhoisRefresh/performDnsRefresh, and add endpoints for refreshWhois, refreshDns and refreshAll; send notifications when DNS monitoring is toggled. Add UI templates/tabs for DNS, billing, notifications, overview, SSL and WHOIS and wire DNS data into the domain view; expose cached IP details. Add cron/check_dns.php and migration 027_add_dns_monitoring.sql (and include it in installer migration lists). Other tweaks: safer EmailHelper subject handling, TldRegistry search improvements, domain sorting using an effective status (expiring_soon), Discord channel null-safe fields, settings UI additions (domain_view_template and cron staleness warnings), and route/migration updates. This enables scheduled and manual DNS scans with persistent records and notifications.
This commit is contained in:
Hosteroid
2026-03-08 14:32:05 +02:00
parent db094d6d8b
commit 8559e903b9
29 changed files with 4493 additions and 100 deletions

View File

@@ -141,6 +141,7 @@ CREATE TABLE IF NOT EXISTS domains (
updated_date DATE,
abuse_email VARCHAR(255),
last_checked TIMESTAMP NULL,
dns_last_checked TIMESTAMP NULL,
status ENUM('active', 'expiring_soon', 'expired', 'error', 'available', 'redemption_period', 'pending_delete') DEFAULT 'active',
whois_data JSON,
notes TEXT,
@@ -341,6 +342,32 @@ CREATE TABLE IF NOT EXISTS tld_import_logs (
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- =====================================================
-- DNS MONITORING
-- =====================================================
-- DNS records table for tracking DNS record changes
CREATE TABLE IF NOT EXISTS dns_records (
id INT AUTO_INCREMENT PRIMARY KEY,
domain_id INT NOT NULL,
record_type VARCHAR(10) NOT NULL COMMENT 'A, AAAA, MX, TXT, NS, CNAME, SOA',
host VARCHAR(255) NOT NULL DEFAULT '@',
value TEXT NOT NULL,
ttl INT NULL,
priority INT NULL COMMENT 'MX priority',
is_cloudflare BOOLEAN DEFAULT FALSE,
raw_data JSON NULL COMMENT 'Full record data from dns_get_record()',
first_seen_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_seen_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (domain_id) REFERENCES domains(id) ON DELETE CASCADE,
INDEX idx_domain_id (domain_id),
INDEX idx_record_type (record_type),
INDEX idx_domain_type (domain_id, record_type),
INDEX idx_last_seen (last_seen_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- =====================================================
-- SYSTEM SETTINGS
-- =====================================================
@@ -397,6 +424,13 @@ INSERT INTO settings (setting_key, setting_value, `type`, `description`) VALUES
-- User isolation settings
('user_isolation_mode', 'shared', 'string', 'User data visibility mode: shared (all users see all data) or isolated (users see only their own data)'),
-- Domain view settings
('domain_view_template', 'detailed', 'string', 'Domain view template: detailed or default'),
-- DNS monitoring settings
('dns_check_interval_hours', '24', 'string', 'DNS record check interval in hours'),
('last_dns_check_run', NULL, 'datetime', 'Last time DNS cron job ran'),
-- Update system settings
('update_channel', 'stable', 'string', 'Update channel: stable (releases only) or latest (releases + hotfixes)'),
('update_badge_enabled', '1', 'string', 'Show update available badge in top menu when an update is available (1=yes, 0=no)')

View File

@@ -0,0 +1,39 @@
-- DNS Monitoring - Add dns_records table for tracking DNS record changes
CREATE TABLE IF NOT EXISTS dns_records (
id INT AUTO_INCREMENT PRIMARY KEY,
domain_id INT NOT NULL,
record_type VARCHAR(10) NOT NULL COMMENT 'A, AAAA, MX, TXT, NS, CNAME, SOA',
host VARCHAR(255) NOT NULL DEFAULT '@',
value TEXT NOT NULL,
ttl INT NULL,
priority INT NULL COMMENT 'MX priority',
is_cloudflare BOOLEAN DEFAULT FALSE,
raw_data JSON NULL COMMENT 'Full record data from dns_get_record()',
first_seen_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_seen_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (domain_id) REFERENCES domains(id) ON DELETE CASCADE,
INDEX idx_domain_id (domain_id),
INDEX idx_record_type (record_type),
INDEX idx_domain_type (domain_id, record_type),
INDEX idx_last_seen (last_seen_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Track when DNS was last checked per domain
ALTER TABLE domains ADD COLUMN dns_last_checked TIMESTAMP NULL AFTER last_checked;
-- crt.sh subdomain fetch tracking
ALTER TABLE domains ADD COLUMN crtsh_last_fetched DATETIME NULL DEFAULT NULL COMMENT 'Last time crt.sh subdomains were fetched for this domain';
-- Toggle DNS monitoring per domain (WHOIS and DNS are separate)
ALTER TABLE domains ADD COLUMN dns_monitoring_enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT '1=DNS monitoring active, 0=disabled' AFTER is_active;
-- Add DNS check interval setting
INSERT INTO settings (setting_key, setting_value, `type`, `description`) VALUES
('dns_check_interval_hours', '24', 'string', 'DNS record check interval in hours'),
('last_dns_check_run', NULL, 'datetime', 'Last time DNS cron job ran')
ON DUPLICATE KEY UPDATE setting_key=setting_key;
INSERT INTO migrations (migration) VALUES ('027_add_dns_monitoring.sql')
ON DUPLICATE KEY UPDATE migration=migration;