{"id":4361,"date":"2025-08-12T15:18:00","date_gmt":"2025-08-12T13:18:00","guid":{"rendered":"https:\/\/ba.be\/non-categorise\/dnspector\/"},"modified":"2025-11-24T21:12:49","modified_gmt":"2025-11-24T20:12:49","slug":"dnspector","status":"publish","type":"post","link":"https:\/\/ba.be\/fr\/lab-fr\/dnspector\/","title":{"rendered":"DNSpector"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"4361\" class=\"elementor elementor-4361 elementor-3858\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-043862c e-flex e-con-boxed e-con e-parent\" data-id=\"043862c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-fcae26d elementor-widget elementor-widget-text-editor\" data-id=\"fcae26d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<h2>V\u00e9rifiez votre nom de domaine pour les d\u00e9fauts courants<\/h2><p>Un nom de domaine correctement configur\u00e9 offre de nombreuses possibilit\u00e9s pour augmenter consid\u00e9rablement la s\u00e9curit\u00e9 et pr\u00e9venir les abus, tels que le phishing et l&rsquo;usurpation d&rsquo;e-mails (e-mail spoofing).<\/p><p>Il est donc frappant de constater que de nombreuses organisations n\u00e9gligent souvent la configuration de leur nom de domaine \u2013 leur identit\u00e9 num\u00e9rique. Pour vous aider, nous avons d\u00e9velopp\u00e9 un test qui v\u00e9rifie la configuration de base de votre domaine sur 10 points cruciaux et donne des conseils concrets d&rsquo;am\u00e9lioration. <\/p><p>Testez d\u00e8s maintenant la qualit\u00e9 de votre nom de domaine et traitez directement les points en suspens.<br>Avez-vous des difficult\u00e9s \u00e0 r\u00e9soudre ces probl\u00e8mes, ou souhaitez-vous porter la s\u00e9curit\u00e9 de votre domaine \u00e0 un niveau sup\u00e9rieur ? Alors contactez-nous. Nous ne vous aidons pas seulement avec les bases, mais nous effectuons \u00e9galement 15 contr\u00f4les sp\u00e9cialis\u00e9s suppl\u00e9mentaires pour s\u00e9curiser de mani\u00e8re optimale l&rsquo;identit\u00e9 en ligne de votre entreprise.  <\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5166d81 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"5166d81\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<html>\n    <head>\n    <style>\n     .bla-container{ background-color: #fff; padding: 5px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); }\n        input[type=\"text\"], input[type=\"email\"] { width: calc(100% - 20px); padding: 10px; margin-bottom: 15px; border: 1px solid #ccc; border-radius: 0px; }\n        button { background-color: #2E82B5; color: white; padding: 12px 10px; border: none; border-radius: 0px; cursor: pointer; font-size: 16px; width: 100%; }\n        button:hover { background-color: #204359; }\n        button:disabled { background-color: #a0a0a0; cursor: not-allowed; }\n        #results { margin-top: 25px; }\n        .result-item { padding: 15px; margin-bottom: 10px; border-left-width: 5px; border-left-style: solid; background-color: #f8f9fa; }\n        .pass { border-color: #28a745; }\n        .fail { border-color: #dc3545; }\n        .info { border-color: #17a2b8; }\n        .warn { border-color: #ffc107; } \n        code { background-color: #e9ecef; padding: 2px 2E82B5px; border-radius: 4px; font-family: \"Courier New\", Courier, monospace; display: block; white-space: pre-wrap; word-break: break-all; margin-top: 5px; } \n     .spinner { border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 1s linear infinite; margin: 20px auto; display: none; }\n        @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } \n    <\/style>\n\n<\/head>\n<body>\n\n    <div class=\"bla-container\">\n        <h1>Outil de V\u00e9rification de Domaine & E-mail<\/h1>\n        <p>Entrez un nom de domaine et une adresse e-mail optionnelle pour tester la configuration.<\/p>\n\n        <label for=\"domain\">Nom de domaine:<\/label>\n        <input type=\"text\" id=\"domain\" name=\"domain\" placeholder=\"ex. google.com\" required>\n\n        <label for=\"email\">Adresse e-mail (optionnel):<\/label>\n        <input type=\"email\" id=\"email\" name=\"email\" placeholder=\"ex. info @google.com\">\n\n        <div style=\"margin-top: 15px; margin-bottom: 15px;\">\n            <input type=\"checkbox\" id=\"contactUsCheckbox\" name=\"contactUsCheckbox\">\n            <label for=\"contactUsCheckbox\">Contactez-nous pour nous aider \u00e0 mieux s\u00e9curiser nos noms de domaine.<\/label>\n        <\/div>\n\n        <button id=\"checkBtn\" onclick=\"runChecks()\">D\u00e9marrer l\\'Analyse<\/button>\n        \n        <div id=\"spinner\" class=\"spinner\"><\/div>\n        <div id=\"results\"><\/div>\n    <\/div>\n\n    <script>\n        const resultsDiv = document.getElementById('results');\n        const checkBtn = document.getElementById('checkBtn');\n        const spinner = document.getElementById('spinner');\n        const COMMON_DKIM_SELECTORS = ['google', 'selector1', 'selector2', 'default', 'k1', 'dkim', 'default', 'dkim', 'mail', 'selector1', 'selector2', 'selector3', 'selector4','key1', 'key2', 'key3', 'k1', 'k2', 'k3', 'm1', 'm2', 'm3', 's1', 's2', 'mandril', 'sm', 'smtp','amazonses', 'cm', 'constantcontact', 'everlytickey1', 'everlytickey2','hubspot', 'mailjet', 'mxvault', 'protonmail', 'sendinblue', 'sig1', 'zendesk1', 'zendesk2'];\n        const MAX_SPF_LOOKUPS = 10;\n\n        const lang = {\n            TOOL_TITLE: 'Outil de V\u00e9rification de Domaine & E-mail',\n            TOOL_DESCRIPTION: 'Entrez un nom de domaine et une adresse e-mail optionnelle pour tester la configuration.',\n            LABEL_DOMAIN: 'Nom de domaine:',\n            PLACEHOLDER_DOMAIN: 'ex. google.com',\n            LABEL_EMAIL: 'Adresse e-mail (optionnel):',\n            PLACEHOLDER_EMAIL: 'ex. info @google.com',\n            BUTTON_START_ANALYSIS: 'D\u00e9marrer l\\'Analyse',\n            ALERT_ENTER_DOMAIN: 'Veuillez entrer un nom de domaine.',\n\n            A_RECORD_PASS_TITLE: '\u2705 Le Domaine Existe (Enregistrement A)',\n            A_RECORD_PASS_TECHDATA_IPS: 'Adresses IP trouv\u00e9es:',\n            A_RECORD_PASS_TIP: 'Le domaine pointe correctement vers un ou plusieurs serveurs.',\n            A_RECORD_FAIL_TITLE: '\u274c Le Domaine n\\'Existe Pas (Enregistrement A)',\n            A_RECORD_FAIL_TECHDATA: 'Aucun enregistrement A trouv\u00e9.',\n            A_RECORD_FAIL_TIP: 'Assurez-vous que le nom de domaine est correct et qu\\'un enregistrement A est configur\u00e9 dans vos param\u00e8tres DNS.',\n\n            AAAA_RECORD_PASS_TITLE: '\u2705 Le Domaine Existe (Enregistrement AAAA)',\n            AAAA_RECORD_PASS_TECHDATA_IPS: 'Adresses IPv6 trouv\u00e9es:',\n            AAAA_RECORD_PASS_TIP: 'Le domaine pointe correctement vers un ou plusieurs serveveurs IPv6.',\n            AAAA_RECORD_INFO_TITLE: '\u2139\ufe0f Le Domaine Existe (Enregistrement AAAA)',\n            AAAA_RECORD_INFO_TECHDATA: 'Aucun enregistrement AAAA trouv\u00e9.',\n            AAAA_RECORD_INFO_TIP: 'Le domaine n\\'a pas d\\'adresse IPv6. Envisagez le support IPv6 pour l\\'avenir.',\n\n            SOA_RECORD_PASS_TITLE: '\u2705 Enregistrement SOA',\n            SOA_RECORD_PASS_TIP: 'L\\'enregistrement SOA a \u00e9t\u00e9 trouv\u00e9 correctement.',\n            SOA_RECORD_FAIL_TITLE: '\u274c Enregistrement SOA',\n            SOA_RECORD_FAIL_TECHDATA: 'Aucun enregistrement SOA trouv\u00e9.',\n            SOA_RECORD_FAIL_TIP: 'Chaque domaine doit avoir un enregistrement SOA (Start of Authority).',\n\n            NS_REDUNDANCY_PASS_TITLE: '\u2705 Redondance des Serveurs de Noms',\n            NS_REDUNDANCY_PASS_TECHDATA_FOUND: 'Trouv\u00e9:',\n            NS_REDUNDANCY_PASS_TECHDATA_RANGES: 'serveurs de noms. IP sur {uniqueRanges} plages \/24 diff\u00e9rentes.',\n            NS_REDUNDANCY_PASS_TIP: 'Excellente redondance : serveurs de noms sur diff\u00e9rents r\u00e9seaux.',\n            NS_REDUNDANCY_WARN_TITLE: '\u26a0\ufe0f Redondance des Serveurs de Noms',\n            NS_REDUNDANCY_WARN_TIP: 'Envisagez un fournisseur DNS secondaire pour une meilleure tol\u00e9rance aux pannes.',\n            NS_REDUNDANCY_FAIL_TITLE: '\u274c Redondance des Serveurs de Noms',\n            NS_REDUNDANCY_FAIL_TECHDATA_COUNT: 'Nombre de serveurs de noms:',\n            NS_REDUNDANCY_FAIL_TIP: 'Ajoutez au moins un deuxi\u00e8me serveur de noms pour la redondance.',\n\n            DNSSEC_PASS_TITLE: '\u2705 DNSSEC',\n            DNSSEC_PASS_TECHDATA: 'Enregistrements DNSKEY trouv\u00e9s.',\n            DNSSEC_PASS_TIP: 'DNSSEC est correctement configur\u00e9.',\n            DNSSEC_WARN_TITLE: '\u26a0\ufe0f DNSSEC',\n            DNSSEC_WARN_TECHDATA: 'Aucun enregistrement DNSKEY trouv\u00e9.',\n            DNSSEC_WARN_TIP: 'Activez DNSSEC aupr\u00e8s de votre registraire pour emp\u00eacher l\\'usurpation DNS.',\n\n            MX_RECORD_PASS_TITLE: '\u2705 Enregistrement MX',\n            MX_RECORD_PASS_TECHDATA_MAILSERVERS: 'Serveurs de messagerie:',\n            MX_RECORD_PASS_TECHDATA_PRIORITY: '(Priorit\u00e9:',\n            MX_RECORD_PASS_TIP: 'Les enregistrements MX sont correctement configur\u00e9s pour la r\u00e9ception des e-mails.',\n            MX_RECORD_FAIL_TITLE: '\u274c Enregistrement MX',\n            MX_RECORD_FAIL_TECHDATA: 'Aucun enregistrement MX trouv\u00e9.',\n            MX_RECORD_FAIL_TIP: 'Configurez les enregistrements MX si vous souhaitez recevoir des e-mails sur ce domaine.',\n\n            SPF_RECORD_INVALID_TITLE: '\u274c Enregistrement SPF (INVALIDE)',\n            SPF_RECORD_STRICT_TITLE: '\u2705 Enregistrement SPF (Strict)',\n            SPF_RECORD_SOFTFAIL_TITLE: '\u26a0\ufe0f Enregistrement SPF (Softfail)',\n            SPF_RECORD_TECHDATA_RECORD: 'Enregistrement:',\n            SPF_RECORD_TECHDATA_IPS: 'Nombre calcul\u00e9 d\\'IP:',\n            SPF_RECORD_TECHDATA_LOOKUPS: 'Recherches DNS:',\n            SPF_RECORD_TIP_AUTH_IPS: 'L\\'enregistrement autorise environ {ipCount} adresses IP. La cha\u00eene d\\'inclusion est : {chain}.',\n            SPF_RECORD_TIP_CRITICAL_LOOKUPS: '**CRITIQUE:** L\\'enregistrement est invalide car il d\u00e9passe la limite de {maxLookups} recherches DNS. Les serveurs de messagerie ignoreront cet enregistrement. Simplifiez l\\'enregistrement en supprimant les \\'includes\\' inutiles ou en \\'aplatissant\\' les adresses IP.',\n            SPF_RECORD_TIP_SOFTFAIL: 'L\\'enregistrement utilise \\'~all\\' (softfail). Envisagez \\'-all\\' (fail) pour une politique plus stricte.',\n            SPF_RECORD_TIP_STRICT: 'L\\'enregistrement utilise \\'-all\\' (fail), ce qui est la configuration stricte recommand\u00e9e.',\n            SPF_RECORD_FAIL_TITLE: '\u274c Enregistrement SPF',\n            SPF_RECORD_FAIL_TECHDATA: 'Aucun enregistrement SPF trouv\u00e9.',\n            SPF_RECORD_FAIL_TIP: 'Cr\u00e9ez un enregistrement SPF pour emp\u00eacher l\\'usurpation d\\'e-mails.',\n\n            DKIM_RECORD_PASS_TITLE: '\u2705 Enregistrement DKIM Trouv\u00e9',\n            DKIM_RECORD_PASS_TECHDATA_SELECTOR: 'S\u00e9lecteur \\'{selector}\\' trouv\u00e9.',\n            DKIM_RECORD_PASS_TIP: 'DKIM a \u00e9t\u00e9 trouv\u00e9 et aide \u00e0 v\u00e9rifier l\\'authenticit\u00e9 de vos e-mails.',\n            DKIM_RECORD_FAIL_TITLE: '\u274c Enregistrement DKIM',\n            DKIM_RECORD_FAIL_TECHDATA: 'Aucun enregistrement DKIM trouv\u00e9 avec des s\u00e9lecteurs connus.',\n            DKIM_RECORD_FAIL_TIP: 'Configurez DKIM avec votre fournisseur de messagerie.',\n\n            DMARC_RECORD_PASS_TITLE: '\u2705 Enregistrement DMARC',\n            DMARC_RECORD_TIP_FOUND: 'Enregistrement DMARC trouv\u00e9 avec la politique : <strong>{policy}<\/strong> (sous-domaines : <strong>{subdomainPolicy}<\/strong>).',\n            DMARC_RECORD_TIP_MONITORING: 'La politique autorise la surveillance. Envisagez \\'quarantine\\' ou \\'reject\\' pour une meilleure protection.',\n            DMARC_RECORD_TIP_QUARANTINE: 'La politique met en quarantaine les e-mails non authentifi\u00e9s. Bon pour une mise en \u0153uvre progressive.',\n            DMARC_RECORD_TIP_REJECT: 'La politique rejette les e-mails non authentifi\u00e9s. C\\'est le plus haut niveau de protection.',\n            DMARC_RECORD_TIP_RUA: 'Rapports (RUA) : {rua}.',\n            DMARC_RECORD_TIP_RUF: 'Rapports forensiques (RUF) : {ruf}.',\n            DMARC_RECORD_FAIL_TITLE: '\u274c Enregistrement DMARC',\n            DMARC_RECORD_FAIL_TECHDATA: 'Aucun enregistrement DMARC trouv\u00e9 sur {dmarcDomain}',\n            DMARC_RECORD_FAIL_TIP: 'Publiez un enregistrement DMARC pour prot\u00e9ger votre domaine contre le phishing et l\\'usurpation d\\'identit\u00e9.',\n\n            WEBHOOK_WARN_NOT_CONFIGURED: 'L\\'URL du Webhook n\\'est pas configur\u00e9e. Publication du Webhook ignor\u00e9e.',\n            WEBHOOK_SUCCESS: 'Publication du Webhook r\u00e9ussie !',\n            WEBHOOK_FAILED: 'La publication du Webhook a \u00e9chou\u00e9:',\n            WEBHOOK_ERROR_SENDING: 'Erreur lors de l\\'envoi au webhook:',\n            CHECKBOX_CONTACT_US: 'Contactez-nous pour nous aider \u00e0 mieux s\u00e9curiser nos noms de domaine.'\n        };\n\n        async function queryDns(name, type) {\n            const url = `https:\/\/dns.google\/resolve?name=${encodeURIComponent(name)}&type=${type}`;\n            try {\n                const response = await fetch(url);\n                if (!response.ok) { throw new Error(`Network error for ${name}\/${type}`); }\n                return await response.json();\n            } catch (error) {\n                console.error('DNS Query Error:', error);\n                return { Answer: [] };\n            }\n        }\n\n        function renderResult(status, title, techData, tip) {\n            const item = document.createElement('div');\n            item.className = `result-item ${status}`;\n            item.innerHTML = `<strong>${title}<\/strong><code>${techData || 'N\/A'}<\/code><p>${tip}<\/p>`;\n            resultsDiv.appendChild(item);\n        }\n        \n        async function analyzeSpf(domain) {\n            let dnsLookups = 0;\n            let ipCount = 0;\n            let processedIncludes = new Set();\n            let spfChain = [];\n\n            async function getIpCountForMechanism(mechanism, currentDomain) {\n                dnsLookups++;\n                if (dnsLookups > MAX_SPF_LOOKUPS) return 0;\n                \n                let targetDomain = currentDomain;\n                if (mechanism.includes(':')) {\n                    targetDomain = mechanism.split(':')[1];\n                }\n                \n                const aData = await queryDns(targetDomain, 'A');\n                const aaaaData = await queryDns(targetDomain, 'AAAA');\n                return (aData.Answer?.length || 0) + (aaaaData.Answer?.length || 0);\n            }\n            \n            async function getIpCountForMx(mechanism, currentDomain) {\n                 dnsLookups++;\n                 if (dnsLookups > MAX_SPF_LOOKUPS) return 0;\n\n                 let targetDomain = currentDomain;\n                 if (mechanism.includes(':')) {\n                    targetDomain = mechanism.split(':')[1];\n                 }\n\n                 const mxData = await queryDns(targetDomain, 'MX');\n                 let mxIpCount = 0;\n                 if (mxData.Answer) {\n                     for(const mx of mxData.Answer) {\n                         const exchangeDomain = mx.data.split(' ')[1];\n                         mxIpCount += await getIpCountForMechanism('a:' + exchangeDomain, exchangeDomain);\n                     }\n                 }\n                 return mxIpCount;\n            }\n\n            function countIpsInCidr(cidr) {\n                if (!cidr.includes('\/')) return 1;\n                const [_, prefixStr] = cidr.split('\/');\n                const prefix = parseInt(prefixStr, 10);\n                if (isNaN(prefix)) return 1;\n                \n                if (cidr.includes('.')) {\n                    if (prefix < 0 || prefix > 32) return 1;\n                    return Math.pow(2, 32 - prefix);\n                }\n                if (cidr.includes(':')) {\n                   return 1;\n                }\n                return 1;\n            }\n\n            async function parseSpf(currentDomain) {\n                if (processedIncludes.has(currentDomain)) return;\n                processedIncludes.add(currentDomain);\n                spfChain.push(currentDomain);\n\n                const txtData = await queryDns(currentDomain, 'TXT');\n                const spfRecord = txtData.Answer?.find(ans => ans.data.toLowerCase().includes(\"v=spf1\"));\n\n                if (!spfRecord) return; \n                \n                let recordText = spfRecord.data.replace(\/\"\/g, '');\n                const parts = recordText.split(\/\\s+\/);\n\n                for (const part of parts) {\n                    const mechanism = part.toLowerCase();\n\n                    if(dnsLookups > MAX_SPF_LOOKUPS) break;\n\n                    if (mechanism.startsWith('include:')) {\n                        dnsLookups++;\n                        const includeDomain = mechanism.substring(8);\n                        await parseSpf(includeDomain);\n                    } else if (mechanism.startsWith('redirect=')) {\n                        dnsLookups++;\n                        const redirectDomain = mechanism.substring(9);\n                        spfChain.push(`-> REDIRECT to ${redirectDomain}`);\n                        await parseSpf(redirectDomain);\n                        break;\n                    } else if (mechanism.startsWith('ip4:')) {\n                        ipCount += countIpsInCidr(mechanism.substring(4));\n                    } else if (mechanism.startsWith('ip6:')) {\n                        ipCount += countIpsInCidr(mechanism.substring(4));\n                    }\n                    else if (mechanism === 'a' || mechanism.startsWith('a:')) {\n                        ipCount += await getIpCountForMechanism(mechanism, currentDomain);\n                    } else if (mechanism === 'mx' || mechanism.startsWith('mx:')) {\n                         ipCount += await getIpCountForMx(mechanism, currentDomain);\n                    }\n                }\n            }\n\n            await parseSpf(domain);\n\n            return {\n                ipCount: ipCount,\n                dnsLookups: dnsLookups,\n                isTooManyLookups: dnsLookups > MAX_SPF_LOOKUPS,\n                chain: spfChain.join(' -> ')\n            };\n        }\n\n        async function sendToWebhook(domain, email, contactUs) {\n            const WEBHOOK_URL = 'https:\/\/apipost.ba.be\/webhook\/9fbe371b-502d-4b55-b68c-241206bcda15';\n\n            if (WEBHOOK_URL === 'YOUR_WEBHOOK_URL_HERE') {\n                console.warn(lang.WEBHOOK_WARN_NOT_CONFIGURED);\n                return;\n            }\n\n            const payload = {\n                domain: domain,\n                email: email,\n                contactUs: contactUs\n            };\n\n            try {\n                const response = await fetch(WEBHOOK_URL, {\n                    method: 'POST',\n                    headers: {\n                        'Content-Type': 'application\/json',\n                    },\n                    body: JSON.stringify(payload),\n                });\n\n                if (response.ok) {\n                    console.log(lang.WEBHOOK_SUCCESS);\n                } else {\n                    console.error(`${lang.WEBHOOK_FAILED} ${response.status}, ${response.statusText}`);\n                }\n            } catch (error) {\n                console.error(`${lang.WEBHOOK_ERROR_SENDING} ${error}`);\n            }\n        }\n\n        async function runChecks() {\n            const domain = document.getElementById('domain').value.trim();\n            const email = document.getElementById('email').value.trim();\n            const contactUs = document.getElementById('contactUsCheckbox').checked;\n\n            if (!domain) {\n                alert(lang.ALERT_ENTER_DOMAIN);\n                return;\n            }\n\n            resultsDiv.innerHTML = '';\n            spinner.style.display = 'block';\n            checkBtn.disabled = true;\n\n            const aData = await queryDns(domain, 'A');\n            if (aData.Answer?.length > 0) {\n                renderResult('pass', lang.A_RECORD_PASS_TITLE, `${lang.A_RECORD_PASS_TECHDATA_IPS} ${aData.Answer.map(ans => ans.data).join(', ')}`, lang.A_RECORD_PASS_TIP);\n            } else {\n                renderResult('fail', lang.A_RECORD_FAIL_TITLE, lang.A_RECORD_FAIL_TECHDATA, lang.A_RECORD_FAIL_TIP);\n            }\n\n            const aaaaData = await queryDns(domain, 'AAAA');\n            if (aaaaData.Answer?.length > 0) {\n                renderResult('pass', lang.AAAA_RECORD_PASS_TITLE, `${lang.AAAA_RECORD_PASS_TECHDATA_IPS} ${aaaaData.Answer.map(ans => ans.data).join(', ')}`, lang.AAAA_RECORD_PASS_TIP);\n            } else {\n                renderResult('info', lang.AAAA_RECORD_INFO_TITLE, lang.AAAA_RECORD_INFO_TECHDATA, lang.AAAA_RECORD_INFO_TIP);\n            }\n            \n            const soaData = await queryDns(domain, 'SOA');\n            if (soaData.Answer?.length > 0) {\n                renderResult('pass', lang.SOA_RECORD_PASS_TITLE, soaData.Answer[0].data, lang.SOA_RECORD_PASS_TIP);\n            } else {\n                renderResult('fail', lang.SOA_RECORD_FAIL_TITLE, lang.SOA_RECORD_FAIL_TECHDATA, lang.SOA_RECORD_FAIL_TIP);\n            }\n\n            const nsData = await queryDns(domain, 'NS');\n            if (nsData.Answer?.length > 1) {\n                const nameservers = nsData.Answer.map(ans => ans.data);\n                let ips = [];\n                for (const ns of nameservers) {\n                    const nsIpData = await queryDns(ns, 'A');\n                    if(nsIpData.Answer?.length > 0) ips.push(nsIpData.Answer[0].data);\n                }\n                const uniqueRanges = new Set(ips.map(ip => ip.split('.').slice(0, 3).join('.'))).size;\n                const techInfo = `${lang.NS_REDUNDANCY_PASS_TECHDATA_FOUND} ${nameservers.length} ${lang.NS_REDUNDANCY_PASS_TECHDATA_RANGES.replace('{uniqueRanges}', uniqueRanges)}`;\n                if (uniqueRanges > 1) {\n                    renderResult('pass', lang.NS_REDUNDANCY_PASS_TITLE, techInfo, lang.NS_REDUNDANCY_PASS_TIP);\n                } else {\n                    renderResult('warn', lang.NS_REDUNDANCY_WARN_TITLE, techInfo, lang.NS_REDUNDANCY_WARN_TIP);\n                }\n            } else {\n                 renderResult('fail', lang.NS_REDUNDANCY_FAIL_TITLE, `${lang.NS_REDUNDANCY_FAIL_TECHDATA_COUNT} ${nsData.Answer?.length || 0}`, lang.NS_REDUNDANCY_FAIL_TIP);\n            }\n\n            const dnskeyData = await queryDns(domain, 'DNSKEY');\n            if (dnskeyData.Answer?.length > 0) {\n                renderResult('pass', lang.DNSSEC_PASS_TITLE, lang.DNSSEC_PASS_TECHDATA, lang.DNSSEC_PASS_TIP);\n            } else {\n                renderResult('warn', lang.DNSSEC_WARN_TITLE, lang.DNSSEC_WARN_TECHDATA, lang.DNSSEC_WARN_TIP);\n            }\n\n            const mxData = await queryDns(domain, 'MX');\n            if (mxData.Answer?.length > 0) {\n                const mailServers = mxData.Answer\n                    .map(ans => {\n                        const parts = ans.data.split(' ');\n                        return `${parts[1]} (${lang.MX_RECORD_PASS_TECHDATA_PRIORITY} ${parts[0]})`;\n                    })\n                    .join(', ');\n                renderResult('pass', lang.MX_RECORD_PASS_TITLE, `${lang.MX_RECORD_PASS_TECHDATA_MAILSERVERS} ${mailServers}`, lang.MX_RECORD_PASS_TIP);\n            } else {\n                renderResult('fail', lang.MX_RECORD_FAIL_TITLE, lang.MX_RECORD_FAIL_TECHDATA, lang.MX_RECORD_FAIL_TIP);\n            }\n\n            const txtDataSpf = await queryDns(domain, 'TXT');\n            const spfRecord = txtDataSpf.Answer?.find(ans => ans.data.toLowerCase().includes(\"v=spf1\"));\n            if (spfRecord) {\n                const recordText = spfRecord.data.replace(\/\"\/g, '');\n                \n                const spfAnalysis = await analyzeSpf(domain);\n                \n                let status = 'pass';\n                if (spfAnalysis.isTooManyLookups) status = 'fail';\n                else if (recordText.includes(\"~all\")) status = 'warn';\n\n                let title = '';\n                if (spfAnalysis.isTooManyLookups) title = lang.SPF_RECORD_INVALID_TITLE;\n                else if (status === 'pass') title = lang.SPF_RECORD_STRICT_TITLE;\n                else title = lang.SPF_RECORD_SOFTFAIL_TITLE;\n\n                const techInfo = `${lang.SPF_RECORD_TECHDATA_RECORD} ${recordText}\\n${lang.SPF_RECORD_TECHDATA_IPS} ${spfAnalysis.ipCount.toLocaleString('nl-BE')}\\n${lang.SPF_RECORD_TECHDATA_LOOKUPS} ${spfAnalysis.dnsLookups} \/ ${MAX_SPF_LOOKUPS}`;\n                \n                let tip = lang.SPF_RECORD_TIP_AUTH_IPS.replace('{ipCount}', spfAnalysis.ipCount.toLocaleString('nl-BE')).replace('{chain}', spfAnalysis.chain);\n                if(spfAnalysis.isTooManyLookups) {\n                    tip += ` \\n\\n${lang.SPF_RECORD_TIP_CRITICAL_LOOKUPS.replace('{maxLookups}', MAX_SPF_LOOKUPS)}`;\n                } else if (recordText.includes(\"~all\")) {\n                    tip += ` ${lang.SPF_RECORD_TIP_SOFTFAIL}`;\n                } else {\n                     tip += ` ${lang.SPF_RECORD_TIP_STRICT}`;\n                }\n\n                renderResult(status, title, techInfo, tip);\n\n            } else {\n                renderResult('fail', lang.SPF_RECORD_FAIL_TITLE, lang.SPF_RECORD_FAIL_TECHDATA, lang.SPF_RECORD_FAIL_TIP);\n            }\n\n            let dkimFound = false;\n            for (const selector of COMMON_DKIM_SELECTORS) {\n                 const dkimDomain = `${selector}._domainkey.${domain}`;\n                 const dkimData = await queryDns(dkimDomain, 'TXT');\n                 if(dkimData.Answer?.length > 0) {\n                     renderResult('pass', lang.DKIM_RECORD_PASS_TITLE, lang.DKIM_RECORD_PASS_TECHDATA_SELECTOR.replace('{selector}', selector), lang.DKIM_RECORD_PASS_TIP);\n                     dkimFound = true;\n                     break;\n                 }\n            }\n             if (!dkimFound) {\n                 renderResult('fail', lang.DKIM_RECORD_FAIL_TITLE, lang.DKIM_RECORD_FAIL_TECHDATA, lang.DKIM_RECORD_FAIL_TIP);\n             }\n\n            const dmarcDomain = `_dmarc.${domain}`;\n            const dmarcData = await queryDns(dmarcDomain, 'TXT');\n             const dmarcRecord = dmarcData.Answer?.find(ans => ans.data.toLowerCase().includes(\"v=dmarc1\"));\n             if (dmarcRecord) {\n                const recordText = dmarcRecord.data.replace(\/\"\/g, '');\n                const dmarcParts = recordText.split(';').map(s => s.trim()).filter(s => s);\n                let policy = 'none';\n                let subdomainPolicy = 'none';\n                let rua = '';\n                let ruf = '';\n\n                dmarcParts.forEach(part => {\n                    if (part.startsWith('p=')) policy = part.substring(2);\n                    if (part.startsWith('sp=')) subdomainPolicy = part.substring(3);\n                    if (part.startsWith('rua=')) rua = part.substring(4);\n                    if (part.startsWith('ruf=')) ruf = part.substring(4);\n                });\n\n                let status = 'pass';\n                let tip = lang.DMARC_RECORD_TIP_FOUND.replace('{policy}', policy).replace('{subdomainPolicy}', subdomainPolicy);\n\n                if (policy === 'none') {\n                    status = 'warn';\n                    tip += ` ${lang.DMARC_RECORD_TIP_MONITORING}`;\n                } else if (policy === 'quarantine') {\n                    tip += ` ${lang.DMARC_RECORD_TIP_QUARANTINE}`;\n                } else if (policy === 'reject') {\n                    tip += ` ${lang.DMARC_RECORD_TIP_REJECT}`;\n                }\n\n                if (rua) tip += ` ${lang.DMARC_RECORD_TIP_RUA.replace('{rua}', rua)}`;\n                if (ruf) tip += ` ${lang.DMARC_RECORD_TIP_RUF.replace('{ruf}', ruf)}`;\n\n                renderResult(status, lang.DMARC_RECORD_PASS_TITLE, recordText, tip);\n            } else {\n                 renderResult('fail', lang.DMARC_RECORD_FAIL_TITLE, lang.DMARC_RECORD_FAIL_TECHDATA.replace('{dmarcDomain}', dmarcDomain), lang.DMARC_RECORD_FAIL_TIP);\n             }\n\n            spinner.style.display = 'none';\n            checkBtn.disabled = false;\n\n            sendToWebhook(domain, email, contactUs);\n        }\n\n        document.addEventListener('DOMContentLoaded', () => {\n            \/\/ No language loading needed, as lang object is defined inline\n        });\n    <\/script>\n<\/body>\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a0f233f elementor-widget elementor-widget-text-editor\" data-id=\"a0f233f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Avertissement : Nous effectuons ces tests depuis votre navigateur. Par cons\u00e9quent, les r\u00e9sultats sont enti\u00e8rement bas\u00e9s sur les param\u00e8tres DNS de votre appareil. Des r\u00e9sultats erron\u00e9s peuvent survenir en raison de facteurs tels que les variations de r\u00e9seau ou les limitations du navigateur. Par cons\u00e9quent, veuillez toujours v\u00e9rifier les r\u00e9sultats aupr\u00e8s de nous ou de votre agent DNS pour confirmation.   <\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-10233c4 e-con-full e-flex e-con e-parent\" data-id=\"10233c4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Votre nom de domaine est le fondement de votre pr\u00e9sence en ligne. C&rsquo;est la premi\u00e8re chose que les clients voient et il garantit qu&rsquo;ils peuvent trouver votre site web et que vos e-mails sont livr\u00e9s correctement. Lorsque votre domaine n&rsquo;est pas correctement configur\u00e9, cela a des cons\u00e9quences directes sur votre accessibilit\u00e9 et votre fiabilit\u00e9.  <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[101,98,105],"tags":[],"class_list":["post-4361","post","type-post","status-publish","format-standard","hentry","category-front-fr","category-lab-fr","category-produit"],"_links":{"self":[{"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/posts\/4361","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/comments?post=4361"}],"version-history":[{"count":9,"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/posts\/4361\/revisions"}],"predecessor-version":[{"id":4513,"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/posts\/4361\/revisions\/4513"}],"wp:attachment":[{"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/media?parent=4361"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/categories?post=4361"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ba.be\/fr\/wp-json\/wp\/v2\/tags?post=4361"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}