Explorando registros DNS con PHP

Camilo Herrera
winkhostingla
Published in
13 min readDec 4, 2023

--

Photo by Andrew DesLauriers on Unsplash

Hola!, ya casi termina el año, cómo vas con esas metas propuestas?. Si no las cumpliste ten paciencia, descansa pero no pares.

Esta será una de las últimas publicaciones del año, y quiero proponerte esta aventura de iluminación y crecimiento personal para analizar registros DNS de un dominio desde PHP. Esto es algo que hacemos muy seguido en nuestra compañía y decidimos que sería muy util contar con nuestra propia herramienta para hacer estas consultas.

En Internet existen muchas herramientas para verificar todo tipo de registros de zona DNS, tienen funciones avanzadas y llevan varios años operando, nuestra solución propuesta será inspirada en un servicio que, al parecer, ya fue abandonado pero sigue funcionando, es intodns.

También puedes visitar los siguientes sitios que cuentan con herramientas muy completas:

https://dnschecker.org/ Esta herramienta es muy util para determinar el proceso de propagación de un cambio en los registros DNS.

https://mxtoolbox.com/SuperTool.aspx Esta herramienta te permite consultar todo tipo de registros de zona y te entrega sugerencias en caso tal que encuentre errores.

Los registros a consultar

Para nuestra guía, vamos a consultar los siguientes tipos de registros DNS para un dominio:

  1. Registros tipo A: Este es el tipo de registro DNS fundamental y es el que mapea la dirección del dominio con una IP física (IPv4), el equivalente para IPv6 es el registro AAAA.
  2. Registros MX: Este registro se usa para intercambio de correo (Mail Exchange), esto quiere decir que es el encargado de indicar a los servidores de correo a qué dirección o direcciones de servidores en Internet entregar los mensajes que se dirigen a buzones asociados al dominio.
  3. Registros NS (Nameservers): Este tipo de registro es primordial, y contiene la dirección del servidor o servidores autorizados para gestionar los registros de zona DNS (MX, A, CNAME, PTR, SOA, etc.)
  4. Registros PTR (Reverse DNS lookups): Este registro permite resolver el nombre de un dominio a partir de una IP, esto es, atender peticiones de resolución inversa de IP a nombre, es usado generalmente para validación de correo electrónico y determinar si un servidor de origen de mensajes es quien dice ser.
  5. Registros SOA: Su sigla significa “Start of Authority”, y contiene información básica sobre el dominio o zona DNS asociada, incluyendo la dirección de correo del administrador, última actualización y tiempos de refresco entre cambios.
  6. Registros CNAME: Su sigla significa “Canonical Name” y se encarga de ser un “alias” para un nombre de dominio real (registro tipo A) o un dominio canónico (otro registro de tipo CNAME), por ejemplo, es normal que el registro para la dirección que inicia con www. de un dominio sea un CNAME y apuntará al registro tipo A del dominio.

Para consultar estos registros, usaremos las funcionalidades integradas de PHP, este cuenta con la función dns_get_record que permite consultar los tipos de registro listados.

Importante: dns_get_records permite realizar consultas básicas de DNS, ten presente que si requieres operaciones más avanzadas, como consultar específicamente un servidor DNS o depurar información, esta no sería la mejor opción y vas a sufrir!

Ahora, vamos a implementar nuestra solución.

Requisitos

Los requisitos para este proyecto son los siguientes:

  1. Un entorno de desarrollo para PHP 8.2+ con su respectivo servidor web
  2. Tu editor de código favorito
  3. Una taza de café.
  4. Ummm y es todo, si esperabas algo más complejo ve a estudiar sobre K8s

Nuestros scripts

En la raíz de nuestro directorio público del servidor web vamos a crear un directorio con el nombre “dns-scout”, en él vamos a crear los siguientes archivos:

  • index.html: Encargado de la GUI de nuestro proyecto
  • requestmanager.php: Este script estará encargado de recibir la petición de consulta de un dominio y retornar los resultados en formato JSON
  • Scout.php: nuestro archivo que contendrá la definición de la clase encargada de las operaciones de consulta de DNS.

La estructura del directorio y archivos será la siguiente:

Archivos

Ahora vamos a recorrer cada no de los scripts para conocer su código fuente y funciones.

Scout.php

Esta clase cuenta con ocho métodos, seis de ellos encargados de consultar los tipos de registros DNS listados en la parte inicial (A, MX, NS, PTR, CNAME y SOA), y dos funciones más, una que será nuestro punto inicial de ejecución “scoutDomain()” e “invertIPv4()” encargada de invertir una IP para realizar la consulta de registros PTR.

El contenido del archivo a continuación:

<?php

/**
* Class Scout
*/
class Scout
{
/**
* @var array For storing result.
*/
private array $result;

/**
* @var string PTR suffix.
*/
private string $PTRsuffix;

/**
* @var string CNAME Prefix.
*/
private string $CNAMEPreffix;

/**
* Constructing initial settings.
*/
public function __construct()
{
$this->result = array("dnsinfo" => array());
$this->PTRsuffix = ".in-addr.arpa";
$this->CNAMEPreffix = "www.";
}

/**
* Scout domain to get DNS details.
*
* @param string $domain
* @return array result
*/
public function scoutDomain(string $domain): array
{

$this->result["dnsinfo"]["NS"] = $this->getNameservers($domain);
$this->result["dnsinfo"]["SOA"] = $this->getSoaRecord($domain);
$this->result["dnsinfo"]["MX"] = $this->getMxRecords($domain);
$this->result["dnsinfo"]["A"] = $this->getARecord($domain);
$this->result["dnsinfo"]["WWW"] = $this->getCnameRecord($this->CNAMEPreffix . $domain);

foreach ($this->result["dnsinfo"]["MX"] as $mxReg) {

$aRecords = $this->getARecord($mxReg["target"]);

foreach ($aRecords as $aRec) {
$invertedIP = $this->invertIPv4($aRec["ip"]);
$this->result["dnsinfo"]["PTR"][] = $this->getPtrRecord($invertedIP . $this->PTRsuffix);
}
}

return $this->result;
}

/**
* Get Nameservers of a domain.
*
* @param string $domain
* @return array $nameservers
*/
private function getNameservers(string $domain)
{
$nameservers = array();
try {

$ns_records = dns_get_record($domain, DNS_NS);

if ($ns_records === false || count($ns_records) == 0) {
$this->result["errors"][] = "Failed to retrieve nameservers for the domain $domain.";
}

$nameservers = [];

foreach ($ns_records as $record) {

$ip_records = dns_get_record($record['target'], DNS_A);

if ($ip_records !== false && count($ip_records) > 0) {
$nameservers[] = [
'nameserver' => $record['target'],
'ipv4' => $ip_records[0]['ip']
];
} else {
$nameservers[] = [
'nameserver' => $record['target'],
'ipv4' => null
];
}
}
} catch (Exception $e) {
$this->result["errors"][] = "An error occurred: {$e->getMessage()}";
} finally {
return $nameservers;
}
}

/**
* Get the SOA record of a domain.
*
* @param string $domain
* @return array SOA record data
*/
private function getSoaRecord(string $domain): array
{
$result = array();

try {
$result = dns_get_record($domain, DNS_SOA);
if (!$result) {
$this->result["errors"][] = "Failed to retrieve SOA record for the domain $domain.";
}
} catch (Throwable $e) {
$this->result["errors"][] = "An error occurred: {$e->getMessage()}";
} finally {
return $result;
}
}

/**
* Get the MX records of a domain.
*
* @param string $domain
* @return array $records
*/
private function getMxRecords(string $domain): array
{
$records = array();

try {
$records = dns_get_record($domain, DNS_MX);
if (!$records) {
$this->result["errors"][] = "Failed to retrieve MX records for: $domain. If you see this message PTR records won't be shown.";
}
} catch (Throwable $e) {
$this->result["errors"][] = "An error occurred: {$e->getMessage()}";
} finally {
return $records;
}
}

/**
* Get PTR record of an IP.
*
* @param string $ip
* @return array $result
*/
private function getPtrRecord(string $ip): array
{
$result = array();
try {
$result = dns_get_record($ip, DNS_PTR);
if (!$result) {
$this->result["errors"][] = "Failed to retrieve PTR record for the IP $ip.";
}
} catch (Throwable $e) {
$this->result["errors"][] = "An error occurred: {$e->getMessage()}";
} finally {
return $result[0];
}
}

/**
* Get A record of a domain.
*
* @param string $domain
* @return array $result
*/
private function getARecord(string $domain): array
{
$result = array();
try {
$result = dns_get_record($domain, DNS_A);
if (!$result) {
$this->result["errors"][] = "Failed to retrieve A record for the domain $domain.";
}
} catch (Throwable $e) {
$this->result["errors"][] = "An error occurred: {$e->getMessage()}";
} finally {
return $result;
}
}

/**
* Get CNAME record of a domain.
*
* @param string $domain
* @return array $result
*/
private function getCnameRecord(string $domain): array
{
try {
$result = dns_get_record($domain, DNS_CNAME);

if (!$result) {
$this->result["errors"][] = "Failed to retrieve CNAME record for the domain $domain.";
}
} catch (Throwable $e) {
$this->result["errors"][] = "An error occurred: {$e->getMessage()}";
} finally {
return $result;
}
}

/**
* Reverse given IP address.
*
* @param string $ip
* @return string $result
*/
function invertIPv4(string $ip): string
{
$parts = explode(".", $ip);

// reverse the array
$parts = array_reverse($parts);

$result = implode(".", $parts);

return $result;
}
}

requestmanager.php

Nuestro archivo requestmanager.php será el encargado de la ejecución de las consultas de DNS y retornar su resultado de la siguiente forma:

// The class to be used in our query is included.
require("Scout.php");

// We decode the parameters received from the index.html file and store them in the $paramsFetch array
$paramsFetch = json_decode(
file_get_contents("php://input"),
true
);

// We create an instance of our class
$scout = new Scout();
// We send the domain name to retrieve its DNS records
$result = $scout->scoutDomain($paramsFetch["domain"]);

// Here we return the response in JSON format and end the execution.
$jsonResponse = json_encode($result);
echo $jsonResponse;
exit;

En él incluimos la clase Scout, recibimos los parámetros de la consulta a través de una petición fetch desde javascript en index.html, a continuación creamos una instancia de la clase y hacemos un llamado al método “scoutDomain()” enviando como parámetro el nombre del dominio recibido.

Una vez es procesada la petición retornamos el resultado en formato JSON.

Ahora vamos al archivo de GUI index.html

index.html

Nuestra interfaz HTML se verá como la siguiente imagen:

DNS Scout GUI

El contenido del archivo a continuación

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DNS Scout</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<script type="module">
window.addEventListener('load', (event) => {

document.querySelector(".search").addEventListener('click', (event) => {

event.currentTarget.classList.add('is-loading');
event.currentTarget.disabled = true;

document.querySelector(".result").parentElement.classList.add("is-hidden");
document.querySelector(".error").parentElement.classList.add("is-hidden");

const payload = JSON.stringify({
"domain": document.querySelector(".domain").value
});

fetch('requestmanager.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: payload,
})
.then(response => response.json())
.then(data => {

console.log(data.errors);
if (data.errors != undefined) {
document.querySelector(".error").parentElement.classList.remove("is-hidden");
document.querySelector(".error").innerText = "";

for (const item in data.errors) {
document.querySelector(".error").innerText += data.errors[item] + "\n";
}

}

document.querySelector(".result").parentElement.classList.remove("is-hidden");
//document.querySelector(".result").innerText = data.dnsinfo;

document.querySelector(".a-records").innerHTML = "";
document.querySelector(".mx-records").innerHTML = "";
document.querySelector(".ns-records").innerHTML = "";
document.querySelector(".ptr-records").innerHTML = "";
document.querySelector(".soa-records").innerHTML = "";
document.querySelector(".www-records").innerHTML = "";

for (const record in data.dnsinfo.A) {

document.querySelector(".a-records").innerHTML += `
<div class="columns is-mobile">
<div class="column pb-0 is-one-fifth">
<h5 class="title is-6">host:</h5>
</div>
<div class="column pb-0">
${data.dnsinfo.A[record].host}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">class:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.A[record].class}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">ttl:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.A[record].ttl}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">type:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.A[record].type}
</div>
</div>
<div class="columns is-mobile">
<div class="column pt-1 is-one-fifth">
<h5 class="title is-6">ip:</h5>
</div>
<div class="column pt-1">
${data.dnsinfo.A[record].ip}
</div>
</div>`;
}

for (const record in data.dnsinfo.MX) {

document.querySelector(".mx-records").innerHTML += `
<div class="columns is-mobile">
<div class="column pb-0 is-one-fifth">
<h5 class="title is-6">host:</h5>
</div>
<div class="column pb-0">
${data.dnsinfo.MX[record].host}
</div>

</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">priority:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.MX[record].pri}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">target:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.MX[record].target}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">ttl:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.MX[record].ttl}
</div>
</div>
<div class="columns is-mobile">
<div class="column pt-1 is-one-fifth">
<h5 class="title is-6">type:</h5>
</div>
<div class="column pt-1">
${data.dnsinfo.MX[record].type}
</div>
</div>`;
}

for (const record in data.dnsinfo.NS) {

document.querySelector(".ns-records").innerHTML += `
<div class="columns is-mobile">
<div class="column pb-0 is-one-fifth">
<h5 class="title is-6">nameserver:</h5>
</div>
<div class="column pb-0">
${data.dnsinfo.NS[record].nameserver}
</div>

</div>
<div class="columns is-mobile">
<div class="column pt-1 is-one-fifth">
<h5 class="title is-6">ipv4:</h5>
</div>
<div class="column pt-1">
${data.dnsinfo.NS[record].ipv4}
</div>
</div>`;
}


for (const record in data.dnsinfo.PTR) {

document.querySelector(".ptr-records").innerHTML += `
<div class="columns is-mobile">
<div class="column is-one-fifth pb-0">
<h5 class="title is-6">host:</h5>
</div>
<div class="column pb-0">
${data.dnsinfo.PTR[record].host}
</div>

</div>
<div class="columns is-mobile">
<div class="column is-one-fifth pb-0 pt-1">
<h5 class="title is-6">class:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.PTR[record].class}
</div>
</div>
<div class="columns is-mobile">
<div class="column is-one-fifth pb-0 pt-1">
<h5 class="title is-6">target:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.PTR[record].target}
</div>
</div>
<div class="columns is-mobile">
<div class="column is-one-fifth pb-0 pt-1">
<h5 class="title is-6">ttl:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.PTR[record].ttl}
</div>
</div>
<div class="columns is-mobile">
<div class="column is-one-fifth pt-1">
<h5 class="title is-6">type:</h5>
</div>
<div class="column pt-1">
${data.dnsinfo.PTR[record].type}
</div>
</div>`;
}


for (const record in data.dnsinfo.SOA) {

document.querySelector(".soa-records").innerHTML += `
<div class="columns is-mobile">
<div class="column pb-0 is-one-fifth">
<h5 class="title is-6">host:</h5>
</div>
<div class="column pb-0">
${data.dnsinfo.SOA[record].host}
</div>

</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">class:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record].class}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">expire:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record].expire}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">minimum-ttl:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record]["minimum-ttl"]}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">mname:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record].mname}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">refresh:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record].refresh}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">retry:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record].retry}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">rname:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record].rname}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">serial:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record].serial}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">ttl:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.SOA[record].ttl}
</div>
</div>
<div class="columns is-mobile">
<div class="column pt-1 is-one-fifth">
<h5 class="title is-6">type:</h5>
</div>
<div class="column pt-1">
${data.dnsinfo.SOA[record].type}
</div>
</div>`;
}


for (const record in data.dnsinfo.WWW) {

document.querySelector(".www-records").innerHTML += `
<div class="columns is-mobile">
<div class="column pb-0 is-one-fifth">
<h5 class="title is-6">host:</h5>
</div>
<div class="column pb-0">
${data.dnsinfo.WWW[record].host}
</div>

</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">class:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.WWW[record].class}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">target:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.WWW[record].target}
</div>
</div>
<div class="columns is-mobile">
<div class="column pb-0 pt-1 is-one-fifth">
<h5 class="title is-6">ttl:</h5>
</div>
<div class="column pb-0 pt-1">
${data.dnsinfo.WWW[record]["ttl"]}
</div>
</div>
<div class="columns is-mobile">
<div class="column pt-1 is-one-fifth">
<h5 class="title is-6">type:</h5>
</div>
<div class="column pt-1">
${data.dnsinfo.WWW[record].type}
</div>
</div>`;
}

})
.catch((error) => {
document.querySelector(".error").parentElement.classList.remove("is-hidden");
document.querySelector(".error").innerText = error;
console.error('Error:', error);
}).finally(() => {
document.querySelector(".search").classList.remove('is-loading');
document.querySelector(".search").disabled = false;
});
});

});
</script>
</head>

<body>
<section class="section">
<div class="container">
<div class="columns">
<div class="column">
<div class="columns">
<div class="column"></div>
<div class="column has-text-centered">
<h1 class="title">
DNS Scout
</h1>
</div>
<div class="column"></div>
</div>
<div class="columns">
<div class="column has-text-centered">
<div class="field is-grouped is-grouped-centered">
<div class="control">
<input class="input domain" type="text" placeholder="Domain">
</div>
<div class="control">
<button class="button is-info search">
Go!
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="columns is-hidden">
<div class="column result">

<div class="columns">
<div class="column">

<article class="message" style="height: 100%;">
<div class="message-header">
<p>A Records</p>
</div>
<div class="message-body">
<div class="columns">
<div class="column a-records">

</div>
</div>
</div>
</article>

</div>
<div class="column">

<article class="message" style="height: 100%;">
<div class="message-header">
<p>MX Records</p>
</div>
<div class="message-body">
<div class="columns">
<div class="column mx-records">

</div>
</div>
</div>
</article>

</div>

</div>

<div class="columns">
<div class="column">

<article class="message" style="height: 100%;">
<div class="message-header">
<p>NS Records</p>
</div>
<div class="message-body">
<div class="columns">
<div class="column ns-records">

</div>
</div>
</div>
</article>

</div>
<div class="column">

<article class="message" style="height: 100%;">
<div class="message-header">
<p>PTR Records</p>
</div>
<div class="message-body">
<div class="columns">
<div class="column ptr-records">

</div>
</div>
</div>
</article>

</div>

</div>

<div class="columns">
<div class="column">

<article class="message" style="height: 100%;">
<div class="message-header">
<p>SOA Records</p>
</div>
<div class="message-body">
<div class="columns">
<div class="column soa-records">

</div>
</div>
</div>
</article>

</div>
<div class="column">

<article class="message" style="height: 100%;">
<div class="message-header">
<p>WWW Records</p>
</div>
<div class="message-body">
<div class="columns">
<div class="column www-records">

</div>
</div>
</div>
</article>

</div>
</div>

</div>
</div>
<div class="columns box is-hidden">
<div class="column notification is-danger error has-text-centered">
</div>
</div>
</div>
</section>
</body>

</html>

Como puedes ver, hacemos una petición fetch a través de POST al archivo “requestmanager.php”, esto al hacer click en el botón “Go!” del formulario.

La respuesta retornada contiene un arreglo asociativo en la entrada “data.dnsinfo” con los registros DNS, usando la siguiente estructura JSON:

{
"NS": [
{
"nameserver": "c.ns.instagram.com",
"ipv4": "185.89.218.12"
},
{
"nameserver": "d.ns.instagram.com",
"ipv4": "185.89.219.12"
},
{
"nameserver": "b.ns.instagram.com",
"ipv4": "129.134.31.12"
},
{
"nameserver": "a.ns.instagram.com",
"ipv4": "129.134.30.12"
}
],
"SOA": [
{
"host": "instagram.com",
"class": "IN",
"ttl": 1234,
"type": "SOA",
"mname": "a.ns.instagram.com",
"rname": "dns.facebook.com",
"serial": 1678373413,
"refresh": 14400,
"retry": 1800,
"expire": 604800,
"minimum-ttl": 3600
}
],
"MX": [
{
"host": "instagram.com",
"class": "IN",
"ttl": 1265,
"type": "MX",
"pri": 10,
"target": "mxb-00082601.gslb.pphosted.com"
},
{
"host": "instagram.com",
"class": "IN",
"ttl": 1265,
"type": "MX",
"pri": 10,
"target": "mxa-00082601.gslb.pphosted.com"
}
],
"A": [
{
"host": "instagram.com",
"class": "IN",
"ttl": 298,
"type": "A",
"ip": "157.240.6.174"
}
],
"WWW": [
{
"host": "www.instagram.com",
"class": "IN",
"ttl": 1916,
"type": "CNAME",
"target": "geo-p42.instagram.com"
}
],
"PTR": [
{
"host": "42.145.231.67.in-addr.arpa",
"class": "IN",
"ttl": 1297,
"type": "PTR",
"target": "mx0a-00082601.pphosted.com"
},
{
"host": "42.145.231.67.in-addr.arpa",
"class": "IN",
"ttl": 1297,
"type": "PTR",
"target": "mx0a-00082601.pphosted.com"
}
]
}

Adicionalmente se incluye un arreglo en la posición “data.errors” que contiene los mensajes de error presentados durante la ejecución de las consultas.

Esta respuesta es procesada por tipo de registro DNS y se agregan los elementos a cada sección en la interfaz usando template literals, son bastante útiles para inyectar información en elementos HTML desde javascript, te los recomiendo si aún no los usas.

Y es todo, recuerda que en Winkhosting.co somos mucho más que hosting.

Te deseo una muy feliz navidad, no olvides compartir con tus seres queridos y agradecer por cada logro que tuviste en este año. Vive una vida que valga la pena ser vivida.

--

--