feat: log eddydev.ink via EuroDynDNS in WAN IP Guard

- Voeg EURODYNDNS_HOSTS/USER/PASS config toe en update de A-records van
  EuroDNS-zone-domeinen via de EuroDynDNS dyndns2 endpoint bij IP-wijziging.
- Resultaten mee in rapport; state alleen saven als ALLE updates (DirectAdmin
  + EuroDynDNS) slagen.
- Voor eddydev.ink/www.eddydev.ink na stale DNS -> failed certbot renew
  (HTTP-01 via oud WAN IP); zie vault Nginx notitie.
This commit is contained in:
Eddy de Vink 2026-09-25 10:03:28 +02:00
commit b8e865c83e
3 changed files with 48 additions and 2 deletions

View file

@ -19,6 +19,9 @@ const CONFIG = {
matrixTokenFile: process.env.MATRIX_TOKEN_FILE || '/home/aiaiaiaiagent/whatsed-new/secrets/sherpa-token',
matrixRoomFile: process.env.MATRIX_ROOM_FILE || '/home/aiaiaiaiagent/whatsed-new/secrets/eddy-report-room',
dnsRecords: (process.env.DNS_RECORDS || '').split(',').map(s => s.trim()).filter(Boolean),
euroDynDnsUser: process.env.EURODYNDNS_USER,
euroDynDnsPass: process.env.EURODYNDNS_PASS,
euroDynDnsHosts: (process.env.EURODYNDNS_HOSTS || '').split(',').map(s => s.trim()).filter(Boolean),
};
function log(msg) {
@ -117,6 +120,17 @@ async function addDnsRecord(name, ip) {
await daRequest(endpoint);
}
async function updateEuroDynDns(hostname, ip) {
const url = `https://update.eurodyndns.org/update/?hostname=${encodeURIComponent(hostname)}&myip=${encodeURIComponent(ip)}`;
const auth = Buffer.from(`${CONFIG.euroDynDnsUser}:${CONFIG.euroDynDnsPass}`).toString('base64');
const resp = await fetchWithTimeout(url, {
headers: { Authorization: `Basic ${auth}` },
});
const text = (await resp.text()).trim();
const ok = resp.ok && /^(good|nochg)\b/.test(text);
return { ok, text };
}
async function sendWhatsApp(message) {
const url = `${CONFIG.whatsappApi}/client/sendMessage/${CONFIG.whatsappSession}`;
const chatId = `${CONFIG.adminPhone}@c.us`;
@ -205,6 +219,28 @@ async function main() {
}
}
// EuroDynDNS (domeinen in de EuroDNS-zone, bv. eddydev.ink)
if (CONFIG.euroDynDnsHosts.length > 0 && !(CONFIG.euroDynDnsUser && CONFIG.euroDynDnsPass)) {
logError('EURODYNDNS_HOSTS is set but EURODYNDNS_USER/PASS are missing. Skipping EuroDynDNS updates.');
results.push(`❌ EuroDynDNS: missing EURODYNDNS_USER/PASS`);
} else {
for (const hostname of CONFIG.euroDynDnsHosts) {
try {
const { ok, text } = await updateEuroDynDns(hostname, currentIp);
if (ok) {
results.push(`✅ ${hostname} (EuroDynDNS)`);
log(`EuroDynDNS updated ${hostname} -> ${currentIp}: ${text}`);
} else {
results.push(`❌ ${hostname} (EuroDynDNS): ${text}`);
logError(`EuroDynDNS failed for ${hostname}: ${text}`);
}
} catch (e) {
results.push(`❌ ${hostname} (EuroDynDNS): ${e.message}`);
logError(`EuroDynDNS error for ${hostname}: ${e.message}`);
}
}
}
const successCount = results.filter(r => r.startsWith('✅')).length;
const failCount = results.filter(r => r.startsWith('❌')).length;