Investigate a Suspicious IP or Host¶
When you see unexpected traffic, a suspicious outbound connection, or a link that doesn't look right, the DNS Toolkit gives you the tools to quickly build a picture of who's behind an IP or URL.
For full parameter and response schema details, see the API reference →
The investigation workflow¶
Start fast and escalate only if needed:
- Blacklist check — is this IP already known-bad?
- Reverse DNS — what hostname does this IP resolve to?
- ASN lookup — what organisation owns this IP block?
- Port scan — what services are exposed?
- Redirect chain — if investigating a URL, follow its redirect chain
# pip install toolkitapi
from toolkitapi import DNS
ip = "198.51.100.42"
with DNS(api_key="YOUR_KEY") as dns:
# 1. Reputation
bl = dns.blacklist(ip)
listed = [r for r in bl.results if r.listed]
print(f"Blacklist: {len(listed)} hit(s) out of {len(bl.results)} lists")
# 2. Reverse DNS
reverse = dns.reverse(ip)
print(f"Hostname: {reverse.hostname or 'no PTR record'}")
# 3. ASN / network owner
asn = dns.asn(ip)
print(f"ASN: {asn.asn} — {asn.org}")
print(f"Country: {asn.country}")
print(f"Network: {asn.network}")
# 4. Open ports
ports = dns.ports(ip)
open_ports = [p for p in ports.ports if p.open]
print(f"Open ports: {[p.port for p in open_ports]}")
Step 1 — Blacklist reputation check¶
Checks the IP against ~30 DNS-based blocklists used by mail servers and security tools. A listing here means the IP has been flagged for spam, malware, or abuse.
from toolkitapi import DNS
with DNS(api_key="YOUR_KEY") as dns:
result = dns.blacklist("198.51.100.42")
listed = [r for r in result.results if r.listed]
if listed:
print(f"Listed on {len(listed)} blocklist(s):")
for entry in listed:
print(f" - {entry.blacklist}")
else:
print(f"Clean across {len(result.results)} lists")
curl "https://dns.toolkitapi.io/v1/blacklist?ip=198.51.100.42" \
-H "X-API-Key: YOUR_KEY"
const params = new URLSearchParams({ ip: "198.51.100.42" });
const r = await fetch(`https://dns.toolkitapi.io/v1/blacklist?${params}`, {
headers: { "X-API-Key": "YOUR_KEY" },
});
const data = await r.json();
const listed = data.results.filter(r => r.listed);
console.log(`Listed on ${listed.length} blocklist(s)`);
You can pass either an IP address or a domain name — the endpoint will resolve the domain to its IP automatically.
Step 2 — Reverse DNS¶
A PTR record maps an IP back to a hostname. Legitimate mail servers and CDN nodes almost always have PTR records. A missing PTR on an IP sending traffic is a yellow flag.
from toolkitapi import DNS
with DNS(api_key="YOUR_KEY") as dns:
result = dns.reverse("198.51.100.42")
print(f"Hostname: {result.hostname or 'no PTR record'}")
curl "https://dns.toolkitapi.io/v1/reverse?ip=198.51.100.42" \
-H "X-API-Key: YOUR_KEY"
const params = new URLSearchParams({ ip: "198.51.100.42" });
const r = await fetch(`https://dns.toolkitapi.io/v1/reverse?${params}`, {
headers: { "X-API-Key": "YOUR_KEY" },
});
const data = await r.json();
console.log(`Hostname: ${data.hostname}`);
Step 3 — ASN lookup¶
Returns the Autonomous System Number, organisation name, country, and CIDR block that contains the IP. Useful for identifying cloud providers, hosting companies, or known bad actor networks.
from toolkitapi import DNS
with DNS(api_key="YOUR_KEY") as dns:
result = dns.asn("198.51.100.42")
print(f"ASN: {result.asn}")
print(f"Org: {result.org}")
print(f"Country: {result.country}")
print(f"Network: {result.network}")
curl "https://dns.toolkitapi.io/v1/asn?ip=198.51.100.42" \
-H "X-API-Key: YOUR_KEY"
const params = new URLSearchParams({ ip: "198.51.100.42" });
const r = await fetch(`https://dns.toolkitapi.io/v1/asn?${params}`, {
headers: { "X-API-Key": "YOUR_KEY" },
});
const data = await r.json();
console.log(`${data.asn} — ${data.org} (${data.country})`);
Step 4 — Open ports¶
Scans common ports on the host and returns which are open. Unexpected open ports (e.g. 3306/MySQL, 6379/Redis exposed to the internet) are a security concern.
from toolkitapi import DNS
with DNS(api_key="YOUR_KEY") as dns:
result = dns.ports("198.51.100.42")
for port in result.ports:
if port.open:
print(f"Port {port.port}/{port.service}: OPEN")
curl "https://dns.toolkitapi.io/v1/ports?ip=198.51.100.42" \
-H "X-API-Key: YOUR_KEY"
const params = new URLSearchParams({ ip: "198.51.100.42" });
const r = await fetch(`https://dns.toolkitapi.io/v1/ports?${params}`, {
headers: { "X-API-Key": "YOUR_KEY" },
});
const data = await r.json();
data.ports.filter(p => p.open).forEach(p => console.log(`${p.port} ${p.service}`));
Step 5 — Trace a redirect chain¶
If you're investigating a suspicious URL rather than a bare IP, redirects follows the full chain of HTTP redirects and returns each hop. Phishing links and malicious ads often use chains of redirects to obscure the final destination.
from toolkitapi import DNS
with DNS(api_key="YOUR_KEY") as dns:
result = dns.redirects("https://short.example.com/abc123")
print(f"Final URL: {result.final_url}")
print(f"Hops: {len(result.chain)}")
for hop in result.chain:
print(f" {hop.status} → {hop.url}")
curl "https://dns.toolkitapi.io/v1/redirects?url=https://short.example.com/abc123" \
-H "X-API-Key: YOUR_KEY"
const params = new URLSearchParams({ url: "https://short.example.com/abc123" });
const r = await fetch(`https://dns.toolkitapi.io/v1/redirects?${params}`, {
headers: { "X-API-Key": "YOUR_KEY" },
});
const data = await r.json();
console.log(`Final: ${data.final_url} (${data.chain.length} hops)`);