Jump to content

WHOIS & DNS check


Steve75

Recommended Posts

Hey Steve,

I just built this on my own WHMCS and it works well. It's a custom client area page that shows the domain status, DNS records and full WHOIS, all inside your theme's header, footer and menu. WHOIS goes through WHMCS's own DomainWhois API, so it uses the same lookup servers your domain checker already uses. DNS uses PHP's dns_get_record().

You need two files.

1. dnscheck.php in your WHMCS root folder:

<?php
use WHMCS\ClientArea;

define('CLIENTAREA', true);
require __DIR__ . '/init.php';

$ca = new ClientArea();
$ca->setPageTitle('WHOIS & DNS Lookup');
$ca->addToBreadCrumb('index.php', Lang::trans('globalsystemname'));
$ca->addToBreadCrumb('dnscheck.php', 'WHOIS & DNS Lookup');
$ca->initPage();

$domain = strtolower(trim($_POST['domain'] ?? ''));
$records = [];
$whois = '';
$status = '';
$error = '';

if ($domain !== '') {
    if (!filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) || strpos($domain, '.') === false) {
        $error = 'Please enter a valid domain name.';
    } else {
        $result = localAPI('DomainWhois', ['domain' => $domain]);
        if (($result['result'] ?? '') === 'success') {
            $status = $result['status'];
            $whois = html_entity_decode(strip_tags(urldecode($result['whois'] ?? '')), ENT_QUOTES);
        }
        $records = @dns_get_record($domain, DNS_A | DNS_AAAA | DNS_CNAME | DNS_MX | DNS_NS | DNS_TXT) ?: [];
    }
}

$ca->assign('domain', $domain);
$ca->assign('records', $records);
$ca->assign('whois', $whois);
$ca->assign('status', $status);
$ca->assign('error', $error);
$ca->setTemplate('dnscheck');
$ca->output();

 

2. dnscheck.tpl in your active theme folder (templates/yourtheme/):

<form method="post" action="dnscheck.php">
  <div class="input-group mb-3">
    <input type="text" name="domain" class="form-control" value="{$domain|escape}" placeholder="example.com">
    <button class="btn btn-primary" type="submit">Look Up</button>
  </div>
</form>

{if $error}<div class="alert alert-warning">{$error}</div>{/if}

{if $status}
<p><strong>Status:</strong> {if $status == 'available'}Available to register{else}Registered{/if}</p>
{/if}

{if $records}
<h4>DNS Records</h4>
<table class="table table-striped">
  <tr><th>Type</th><th>Host</th><th>Value</th><th>TTL</th></tr>
  {foreach $records as $r}
  <tr>
    <td>{$r.type}</td>
    <td>{$r.host|escape}</td>
    <td>{if $r.ip}{$r.ip}{elseif $r.ipv6}{$r.ipv6}{elseif $r.target}{if $r.pri}{$r.pri} {/if}{$r.target|escape}{elseif $r.txt}{$r.txt|escape}{/if}</td>
    <td>{$r.ttl}</td>
  </tr>
  {/foreach}
</table>
{/if}

{if $whois}
<h4>WHOIS</h4>
<pre style="white-space:pre-wrap;color:inherit;background:rgba(255,255,255,.05);padding:15px;border-radius:4px;">{$whois|escape}</pre>
{/if}

 

Then go to yourwhmcs.com/dnscheck.php and you're set. You can add it to your menu with a navbar hook, or just link to it from your site.

A couple of notes:
- The color:inherit on the WHOIS box makes it readable on both dark and light themes.
- Since it's a public page, I'd add a captcha or rate limit so bots don't hammer it.
- A lot of WHOIS records hide owner details now because of privacy rules, so you'll mostly see the registrar, dates and nameservers.

Hope that helps!

Rob
K & K Web Services

Link to comment
Share on other sites

Nice write-up, Rob — thanks for sharing the full working example. One thing I would add from my own experience is to validate and sanitise the domain input on the server side before passing it to any WHOIS or DNS lookup, since it is a public form and people will try all sorts of input in it. I also found it worth caching results briefly, because repeated lookups for the same domain can get slow and some WHOIS servers start throttling you. And on the captcha point, I agree — even a simple rate limit made a big difference for me when I ran something similar. Did you find the WHOIS output reliable across different TLDs, or did some registrars return very thin results?

Link to comment
Share on other sites

>  Since it's a public page, I'd add a captcha or rate limit so bots don't hammer it.

> One thing I would add from my own experience is to validate and sanitise the domain input on the server side before passing it to any WHOIS or DNS lookup, since it is a public form and people will try all sorts of input in it.

How do I do this, please (I am not a programmer)?

Link to comment
Share on other sites

Steve, the first part is already done in Rob's code. This line checks that what was typed is a real domain name before any lookup runs, and shows "Please enter a valid domain name" if it isn't:

if (!filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) || strpos($domain, '.') === false) {

For the rate limit, you only need to change one part of dnscheck.php. Find this block:

    } else {
        $result = localAPI('DomainWhois', ['domain' => $domain]);
        if (($result['result'] ?? '') === 'success') {
            $status = $result['status'];
            $whois = html_entity_decode(strip_tags(urldecode($result['whois'] ?? '')), ENT_QUOTES);
        }
        $records = @dns_get_record($domain, DNS_A | DNS_AAAA | DNS_CNAME | DNS_MX | DNS_NS | DNS_TXT) ?: [];
    }

and replace it with this:

    } else {
        // At most 10 lookups per visitor IP in 10 minutes
        $key = 'dnscheck_' . md5($_SERVER['REMOTE_ADDR']);
        $store = \WHMCS\TransientData::getInstance();
        $count = (int) $store->retrieve($key);
        if ($count >= 10) {
            $error = 'Too many lookups. Please wait a few minutes and try again.';
        } else {
            $store->store($key, $count + 1, 600);
            $result = localAPI('DomainWhois', ['domain' => $domain]);
            if (($result['result'] ?? '') === 'success') {
                $status = $result['status'];
                $whois = html_entity_decode(strip_tags(urldecode($result['whois'] ?? '')), ENT_QUOTES);
            }
            $records = @dns_get_record($domain, DNS_A | DNS_AAAA | DNS_CNAME | DNS_MX | DNS_NS | DNS_TXT) ?: [];
        }
    }

It uses WHMCS's own temporary storage, so there is no new table or setting to create. Change 10 and 600 (seconds) to suit your site.

One thing to check: if your site is behind Cloudflare, every visitor reaches you from a Cloudflare address, so they would all share one limit. In that case use $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['REMOTE_ADDR'] in place of $_SERVER['REMOTE_ADDR'].

Link to comment
Share on other sites

Hi Steve, good news: you don’t need to write code for the first part. Rob’s dnscheck.php already checks the domain on the server side (the filter_var(...) line), so random text or odd characters get rejected before any lookup runs. If you want it a bit stricter, you can add this line right after $domain = ...:

if (strlen($domain) > 253) { $domain = ''; }

For the bots/rate-limit part, the easiest options without programming, from simplest to most flexible:

  1. Make the page login-only. In dnscheck.php, add $ca->requireLogin(); right after $ca = new ClientArea();. Then only logged-in clients can use it, and bots can’t hit it. (If you want it public for visitors, skip this.)
  2. Cloudflare, if your site is on it. Free plan: Security → WAF → Rate limiting rules (or a Turnstile challenge) on the URL path /dnscheck.php, e.g. a limit of about 10 requests per minute per IP. No code needed.
  3. Server-level rate limit. If your host uses ModSecurity or CSF/LFD, ask your host to rate-limit that one URL.

I haven’t tested these exact lines on your setup, so try it on a staging copy (or at least back up dnscheck.php first) before putting it live. Hope that helps.

Link to comment
Share on other sites

Hey Steve,

Good news, the validation is already in the code I posted. This line is what does it:

if (!filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) || strpos($domain, '.') === false) {

It only lets through letters, numbers, dots and dashes in a real domain format. Anything else (spaces, code, symbols, junk) gets stopped with "Please enter a valid domain name" before it ever gets to the WHOIS or DNS lookup. So you don't need to add anything for that part.

For bots, two easy things:

1. Make it logged-in clients only. In dnscheck.php, right under this line:

$ca->initPage();

add:

$ca->requireLogin();

Now anyone not logged in gets sent to the login page. That's what I did on mine and it stops pretty much all the bot traffic.

2. Simple rate limit (10 lookups every 10 minutes per client). Find the block that starts with if ($domain !== '') { and replace that whole block, down to its closing }, with this:

if ($domain !== '') {
    $_SESSION['dnscheck'] = array_filter($_SESSION['dnscheck'] ?? [], function ($t) { return $t > time() - 600; });
    if (count($_SESSION['dnscheck']) >= 10) {
        $error = 'Too many lookups. Please wait a few minutes and try again.';
    } elseif (!filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) || strpos($domain, '.') === false) {
        $error = 'Please enter a valid domain name.';
    } else {
        $_SESSION['dnscheck'][] = time();
        $result = localAPI('DomainWhois', ['domain' => $domain]);
        if (($result['result'] ?? '') === 'success') {
            $status = $result['status'];
            $whois = html_entity_decode(strip_tags(urldecode($result['whois'] ?? '')), ENT_QUOTES);
        }
        $records = @dns_get_record($domain, DNS_A | DNS_AAAA | DNS_CNAME | DNS_MX | DNS_NS | DNS_TXT) ?: [];
    }
}

Save it and you're done. If you want more or less than 10, just change the 10. The 600 is the time window in seconds.

@carlpeeter32 thanks, good points. On the WHOIS question, most of the common TLDs come back fine. Some country TLDs and a few registrars hide most of it for privacy, so you just get status and dates on those. Since it goes through WHMCS's own WHOIS servers it's as good as your domain checker is.

Rob

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated