How to Perform Wildcard DNS Lookups Using nslookup and dig for Hostname Searches


2 views

When managing enterprise networks, we often need to find hostnames containing specific patterns (like employee names in hostnames). Standard DNS tools don't directly support wildcard searches in the way we might expect from SQL or file system operations.

The DNS protocol itself doesn't support wildcard queries in the middle of hostnames. DNS wildcards (*) only work at the leftmost label (e.g., *.example.com). This is a fundamental protocol limitation, not just a tool restriction.

Here are practical solutions to achieve similar results:

1. Zone Transfers (If Possible)

If you have access to zone transfers, you can dump and grep:

dig axfr localdomain.com | grep -i "miller"

Note: Zone transfers are typically restricted for security reasons.

2. Using Reverse DNS

For smaller networks, scan the IP range and check PTR records:

for ip in {1..254}; do 
  host 10.10.10.$ip | grep -i "miller" 
done

3. LDAP Integration

Since hostnames contain usernames, querying LDAP might be more efficient:

ldapsearch -x -H ldap://dc.localdomain.com -b "dc=localdomain,dc=com" "(&(sn=miller)(objectClass=user))" dn

4. PowerShell Alternative (Windows Networks)

For Active Directory environments:

Get-ADComputer -Filter "Name -like '*miller*'" -Properties IPv4Address | 
Select-Object Name,IPv4Address

Here's a Python example using tkinter that combines DNS and LDAP:

import tkinter as tk
from tkinter import ttk
import subprocess
import ldap

def search_hostnames():
    last_name = entry.get()
    # LDAP search
    l = ldap.initialize('ldap://dc.localdomain.com')
    l.simple_bind_s()
    results = l.search_s('dc=localdomain,dc=com', ldap.SCOPE_SUBTREE,
                        f'(sn={last_name})', ['sAMAccountName'])
    
    # DNS verification
    hosts = []
    for dn, entry in results:
        username = entry['sAMAccountName'][0].decode()
        try:
            output = subprocess.check_output(['nslookup', f'sf-{username}.localdomain.com'], 
                                           stderr=subprocess.STDOUT)
            hosts.append(f'sf-{username}.localdomain.com')
        except subprocess.CalledProcessError:
            continue
    
    # Update dropdown
    combo['values'] = hosts

root = tk.Tk()
tk.Label(root, text="Last Name:").pack()
entry = tk.Entry(root)
entry.pack()
tk.Button(root, text="Search", command=search_hostnames).pack()
combo = ttk.Combobox(root)
combo.pack()
root.mainloop()

For large networks, these approaches can be slow. Consider:

  • Caching results
  • Implementing a background worker
  • Using dedicated network inventory tools

Be cautious with:

  • Exposing internal hostnames through GUIs
  • Rate limiting to prevent DNS flooding
  • Credential handling in scripts

When managing enterprise networks, helpdesk teams frequently need to locate devices by partial hostname patterns (e.g., finding all machines containing "miller" in their FQDNs). Standard DNS tools like nslookup and dig don't natively support wildcard searches in the middle of hostnames (*miller* pattern). Here's how to implement this functionality using built-in macOS tools.

Since DNS doesn't support mid-string wildcards, consider these workarounds:

# Method 1: Leveraging DNS zone transfers (if allowed)
dig axfr localdomain.com | grep miller

# Method 2: Using LDAP (when hostnames are in directory services)
ldapsearch -x -H ldap://dc.localdomain.com -b "dc=localdomain,dc=com" "(cn=*miller*)" dn ipHostNumber

For environments without zone transfer access, here's a script that emulates wildcard search by enumerating forward and reverse DNS records:

#!/bin/bash

# DNS Wildcard Search Tool
search_term=$1
dns_suffix=".localdomain.com"

# Get all PTR records in subnet
for ip in $(seq 1 254); do 
  host 10.10.10.$ip | grep "$search_term" | awk '{print $1,$5}'
done | grep -i "$search_term" | sort -u

# Alternative: Check pre-populated host list
grep -i "$search_term" /var/cache/dns/hosts.all

For a more user-friendly approach with pulldown selection:

import subprocess
import tkinter as tk
from tkinter import ttk

def dns_search():
    results = []
    raw_output = subprocess.check_output(
        ["dig", "+noall", "+answer", "axfr", "localdomain.com"],
        text=True
    )
    for line in raw_output.splitlines():
        if search_var.get().lower() in line.lower():
            results.append(line.split()[0])
    
    dropdown['values'] = results

root = tk.Tk()
search_var = tk.StringVar()
ttk.Entry(root, textvariable=search_var).pack()
ttk.Button(root, text="Search", command=dns_search).pack()
dropdown = ttk.Combobox(root)
dropdown.pack()
root.mainloop()

For large networks, these methods can be slow. Consider:

  • Maintaining a local hosts cache updated hourly
  • Using PowerShell for Windows-integrated environments
  • Implementing a Redis cache for frequent queries