UNPKG

@underpostnet/underpost

Version:
135 lines (116 loc) 4.83 kB
import axios from 'axios'; import dotenv from 'dotenv'; import fs from 'fs'; import validator from 'validator'; import { publicIp, publicIpv4, publicIpv6 } from 'public-ip'; import { loggerFactory } from './logger.js'; import UnderpostRootEnv from '../cli/env.js'; import dns from 'node:dns'; import os from 'node:os'; import { shellExec } from './process.js'; dotenv.config(); const logger = loggerFactory(import.meta); const ip = { public: { get: async () => await publicIp(), // => 'fe80::200:f8ff:fe21:67cf' ipv4: async () => await publicIpv4(), // => '46.5.21.123' ipv6: async () => await publicIpv6(), // => 'fe80::200:f8ff:fe21:67cf' }, }; const isInternetConnection = (domain = 'google.com') => new Promise((resolve) => dns.lookup(domain, {}, (err) => resolve(err ? false : true))); // export INTERFACE=$(ip route | grep default | cut -d ' ' -f 5) // export IP_ADDRESS=$(ip -4 addr show dev $INTERFACE | grep -oP '(?<=inet\s)\d+(\.\d+){3}') const getLocalIPv4Address = () => os.networkInterfaces()[ shellExec(`ip route | grep default | cut -d ' ' -f 5`, { stdout: true, silent: true, disableLog: true, }).trim() ].find((i) => i.family === 'IPv4').address; class Dns { static callback = async function (deployList) { // Network topology configuration: // LAN -> [NAT-VPS](modem/router device) -> WAN // enabled DMZ Host to proxy IP 80-443 (79-444) sometimes router block first port // Enabling DHCP // Navigate to Subnets > VLAN > Configure DHCP. // Select the appropriate DHCP options (Managed or Relay). // Save and apply changes. // verify inet ip proxy server address // DHCP (Dynamic Host Configuration Protocol) LAN reserver IP -> MAC ID // LAN server or device's local servers port -> 3000-3100 (2999-3101) // DNS Records: [ANAME](Address Dynamic) -> [A](ipv4) host | [AAAA](ipv6) host -> [public-ip] // Forward the router's TCP/UDP ports to the LAN device's IP address const isOnline = await isInternetConnection(); if (!isOnline) return; let testIp; try { testIp = await ip.public.ipv4(); } catch (error) { logger.error(error, { testIp, stack: error.stack }); } const currentIp = UnderpostRootEnv.API.get('ip'); if (validator.isIP(testIp) && currentIp !== testIp) { logger.info(`new ip`, testIp); UnderpostRootEnv.API.set('monitor-input', 'pause'); for (const _deployId of deployList.split(',')) { const deployId = _deployId.trim(); const privateCronConfPath = `./engine-private/conf/${deployId}/conf.cron.json`; const confCronPath = fs.existsSync(privateCronConfPath) ? privateCronConfPath : './conf/conf.cron.json'; const confCronData = JSON.parse(fs.readFileSync(confCronPath, 'utf8')); for (const recordType of Object.keys(confCronData.records)) { switch (recordType) { case 'A': for (const dnsProvider of confCronData.records[recordType]) { if (typeof Dns.services.updateIp[dnsProvider.dns] === 'function') await Dns.services.updateIp[dnsProvider.dns]({ ...dnsProvider, ip: testIp }); } break; default: break; } } try { const ipUrlTest = `https://${process.env.DEFAULT_DEPLOY_HOST}`; const response = await axios.get(ipUrlTest); const verifyIp = response.request.socket.remoteAddress; logger.info(ipUrlTest + ' verify ip', verifyIp); if (verifyIp === testIp) { logger.info('ip updated successfully', testIp); UnderpostRootEnv.API.set('ip', testIp); UnderpostRootEnv.API.delete('monitor-input'); } else logger.error('ip not updated', testIp); } catch (error) { logger.error(error, error.stack); logger.error('ip not updated', testIp); } } } }; static services = { updateIp: { dondominio: (options) => { const { user, api_key, host, dns, ip } = options; const url = `https://dondns.dondominio.com/json/?user=${user}&password=${api_key}&host=${host}&ip=${ip}`; logger.info(`${dns} update ip url`, url); if (process.env.NODE_ENV !== 'production') return false; return new Promise((resolve) => { axios .get(url) .then((response) => { logger.info(`${dns} update ip success`, response.data); return resolve(true); }) .catch((error) => { logger.error(error, `${dns} update ip error`); return resolve(false); }); }); }, }, }; } export default Dns; export { Dns, ip, isInternetConnection, getLocalIPv4Address };