How to Use Dnstwist to Catch Typosquatting Domains Before They Catch You
CodexFuse Team · 2026-11-04T11:39:02.510Z · 12 min read min read
Dnstwist generates thousands of typo variants of your domain and checks which ones are registered. This guide covers installation, your first scan, reading the report, and turning the hits into a defensive plan.
Every day, thousands of people mistype your domain name — and a few attackers register those typos on purpose, hoping to catch your users mid-keystroke. This dnstwist tutorial shows you how to use dnstwist, the open-source domain permutation tool, to find look-alike domains targeting your brand before they become phishing pages. One framing note up front: dnstwist is dual-use security tooling, so this guide stays strictly defensive — scan your own brand's domain, or a domain you have explicit permission to test, and use what you find to protect your users.
Dnstwist generates thousands of typo variants of your domain, checks which ones are actually registered, and enriches the hits with DNS, mail, and web-similarity signals. Install it on any Linux machine, point it at your domain, and you walk away with a threat list you can act on the same afternoon.
What Is Dnstwist, Exactly?
Dnstwist is a free, open-source domain name permutation engine that generates look-alike variants of a domain and checks which ones are actually registered — to detect typosquatters, phishing attacks, fraud, and brand impersonation. The man page puts it even more bluntly: "Find similar-looking domain names that adversaries can use to attack you. Detect typosquatters, phishing attacks, fraud and brand impersonation."
The tool was written by Marcin Ulikowski ([email protected]), is released under the Apache 2.0 license, and lives on GitHub at github.com/elceef/dnstwist with 5,774 stars as of November 2026. His own tagline captures the whole pitch: "See what sort of trouble users can get in trying to type your domain name." The README frames the work as DNS fuzzing: "an automated workflow that aims to uncover potentially malicious domains that target your organization. This tool generates a comprehensive list of permutations based on a provided domain name, and subsequently verifies whether any of these permutations are in use."
One useful distinction before we start: dnstwist answers "which domains look like mine?" If your question is instead "what already lives under my domain?" — that's the enumeration lane, and our subdomain finder guide covers it. The two tools complement each other; neither replaces the other.
How Does Dnstwist Dream Up Look-Alike Domains?
Dnstwist applies a battery of fuzzing algorithms to your domain, each one modeling a different way humans — and keyboards — make mistakes, then resolves the resulting variants against DNS. Running it with --format list generates the permutations without any DNS lookups at all, which is handy for a dry run.
Here is real output from dnstwist 20250130 on this machine (captured 2026-11-04), the first 20 of 1,976 permutations it generated for example.com:
$ dnstwist --format list example.com | head -20 example.com example0.com example1.com example2.com example3.com example4.com example5.com example6.com example7.com example8.com example9.com examplea.com exampleb.com examplec.com exampled.com examplee.com examplef.com exampleg.com exampleh.com examplei.com # ... 1,956 more, for a total of 1,976 permutations
The fourteen default fuzzers (names verified in the dnstwist 20250130 source this run) each cover one failure mode:
| Fuzzer | What it models |
|---|---|
| addition | Appending characters — example0.com, examplea.com |
| bitsquatting | Single bit-flip errors in the name (memory-corruption-style typos) |
| cyrillic | Translating Latin characters into Cyrillic homographs |
| homoglyph | Visually similar Unicode characters, like rn vs m — built on a carefully researched Unicode range so generated domains can actually be registered in practice |
| hyphenation | Adding hyphens — exam-ple.com |
| insertion | Inserting characters |
| omission | Removing characters |
| plural | Pluralized variants — examples.com |
| repetition | Repeating characters — exaample.com |
| replacement | Replacing with adjacent keyboard keys |
| subdomain | Inserting dots — creating look-alike subdomain structures |
| transposition | Swapping adjacent characters — exmaple.com |
| vowel-swap | Swapping vowels — eximple.com |
| dictionary | Appending common words from dictionary files (English, French, and Polish ship in the repo) |
Two more are always applied: tld-swap (only active when you supply a TLD dictionary via --tld — off by default) and various, plus the *original entry. A note on coverage from the README keeps expectations honest: "Checking every possible domain permutation is impractical, especially for longer input domains, which would require millions of DNS lookups." Dnstwist covers the realistic subset — the mistakes attackers actually register — not the exhaustive space.
How Do You Install Dnstwist?
On most systems, one command installs it — and you get to choose between the bare minimum and the full feature set. pip install dnstwist pulls zero hard dependencies (the project's setup.py literally ships install_requires=[]), while pip install dnstwist[full] adds dnspython, geoip2, idna, ppdeep, py-tlsh, and tld. As threat-intelligence engineer David Kasabji writes: "The difference is that the full version will install all the requirements, while others will just install the bare minimum."
The project declares only "Python 3" as its requirement — no minor version pinned — and it installed and ran cleanly on Python 3.12 this run. If you would rather use your distro's package manager, the README lists the routes: sudo apt install dnstwist on Debian/Ubuntu/Kali, sudo dnf install dnstwist on Fedora, yay -S dnstwist on Arch, brew install dnstwist on macOS, or docker run -it elceef/dnstwist if you prefer containers.
Verify the install with dnstwist --version — this run reported dnstwist 20250130, the January 30, 2025 release, which is the newest on PyPI. Many defenders install dnstwist on a small server and re-scan weekly; if you don't have a box for that yet, our VPS hosting explainer covers the concept.
How Do You Run Your First Dnstwist Scan?
Install it, run it with --registered against your domain, read the registered hits, then export the list — four steps and you are threat-hunting. Substitute your own domain everywhere below; never scan a domain you don't own without the owner's permission.
- Run the baseline scan.
dnstwist --registered yourdomain.comshows only the permutations that are actually registered. As Kasabji notes: "We are using an option registered in order to track only registered domains. You could also omit that, and the tool will output all the permutations to your input, even if they are not registered. That could be useful to you to track which similar domains are still available for purchase." - Narrow to the highest-signal fuzzers.
dnstwist --fuzzers "homoglyph,hyphenation" yourdomain.comrestricts generation to those two algorithms — a straight example from the official README. Verified working on the current release this run. - Export the results.
dnstwist --format json yourdomain.com | jqgives machine-readable output for pipelines;dnstwist --format csv yourdomain.com | column -t -s,gives a readable table. Both are verbatim README recipes. - Re-run on a schedule. New look-alike registrations appear constantly, so a one-off scan is a snapshot, not a program. Weekly is a sane default for an active brand.
Two practical knobs worth knowing now: scans need working DNS resolution, and --nameservers 8.8.8.8,1.1.1.1 lets you pick upstream resolvers (the man page notes DNS-over-HTTPS servers are accepted too). Threading defaults to 8 (-t/--threads) — the README says the default "strikes a cautious balance" based on your CPU cores, so raise it deliberately rather than reflexively.
How Do You Read a Dnstwist Report?
Each row is one permutation with the fuzzer that produced it and the signals dnstwist collected — the only rows that matter at first are the registered ones, which you triage by DNS, mail, and web-similarity signals. Here's what each signal column tells you:
| Signal | What it means | How it's collected |
|---|---|---|
| fuzzer / permutation | Which algorithm generated the variant and the variant itself | Always shown |
| dns-a / dns-aaaa | Whether the variant resolves — a live squat | Default DNS lookups |
| mx | Mail exchanger record for the variant | With -m/--mxcheck, dnstwist checks whether the MX host could intercept misdirected e-mails |
| lsh (ssdeep/tlsh) | Fuzzy-hash similarity between the squat's page HTML and your own page | With --lsh: "able to detect similar HTML source code. For each generated domain, the tool will fetch content from the responding HTTP server, normalize HTML code and compare its fuzzy hash with the one for the original domain" |
| phash | Perceptual-hash similarity of page screenshots — catches visual clones | With -p/--phash; requires Chromium installed |
| geoip | Country of the resolving IP | With -g/--geoip; uses GeoIP2 with the $GEOLITE2_MMDB database path, falling back to GeoIP Legacy |
| whois | Creation date and registrar of the variant | With -w/--whois |
One anti-false-positive detail from the man page is worth knowing: "In cases when the effective URL is the same as for the original domain, the fuzzy hash is not calculated at all in order to reject false positive indications." And the triage mindset, again from Kasabji: "If we assume that you are Google and you find on this list a registered domain, such as goog1e.com and you can verify that it is not registered by yourself – this is then a potential suspect for typosquatting or domain abuse."
Want to double-check a suspicious variant's records by hand before escalating? Our DNS lookup tool resolves them in the browser with nothing to install.
What Do the Opt-In Flags Actually Add?
Almost everything beyond permutation generation is opt-in — TLD swapping, dictionary fuzzing, GeoIP, MX checks, WHOIS, web-similarity, and banner grabbing only run when you ask, which keeps default scans fast and polite. The full flag list runs to 22 options in the current release; the ones that change what you learn are:
| Flag | What it does | Use it when… |
|---|---|---|
-g, --geoip | Looks up GeoIP location for resolving IPs | You want to spot squats hosted in unexpected countries |
-m, --mxcheck | Checks if the variant's MX host could intercept misdirected e-mails | You worry about typo'd e-mails leaking to attackers |
-w, --whois | Looks up WHOIS creation date and registrar | You need registration timelines for a takedown case |
--lsh [ssdeep|tlsh] | Evaluates web-page similarity with a fuzzy hash (ssdeep default) | You suspect a cloned phishing page |
-p, --phash | Renders pages and compares screenshots with perceptual hashing | The clone defeats HTML comparison with heavy JavaScript |
-b, --banners | Determines HTTP and SMTP service banners | You want infrastructure fingerprints |
--tld FILE | Swaps the TLD from a dictionary (the repo's common_tlds.dict holds 100 entries) | You want example.net / example.org style coverage — remember it's off by default |
-d, --dictionary FILE | Generates more domains from a word list | Phishing campaigns in your niche reuse predictable keywords |
One gotcha that bites people copying old tutorials: the --ssdeep flag no longer exists. The changelog records that it was "Replaced --ssdeep with new --lsh argument allowing to request particular fuzzy hash (ssdeep or tlsh)" — so use --lsh (ssdeep remains the default algorithm). A popular third-party guide still shows the dead flag, so if a command errors on --ssdeep, that's the fix.
How Do You Turn a Scan Into a Defensive Plan?
Triage the registered hits, then monitor, defensively register the cheapest high-risk variants, and prepare takedown requests for anything actively abusive. The standard workflow, as one practitioner guide summarizes it: "generate domain permutations -> resolve DNS records -> check for registered domains -> compare web page similarity -> flag suspicious domains -> alert security team -> request takedown."
For the variants that are registered but not yet weaponized, defensive registration is the cheapest insurance — Bolster's take: "Dnstwist helps you identify domain variations that closely resemble your legitimate domain. By proactively registering or blocking these variations, you can protect your brand reputation and prevent domain hijacking attempts." The --unregistered flag conveniently lists exactly the variants still available to buy.
For live abuse, the WHOIS creation date and the LSH screenshot/page-similarity evidence give you the core of a takedown request to the registrar or host. And then the scan becomes a habit: re-run it weekly, because attackers register new look-alikes all the time. CodexFuse doesn't ship a dnstwist tool of its own — the CLI and the browser version below are the routes.
Dnstwist vs a Subdomain Scanner: What's the Difference?
Dnstwist finds domains that look like yours (permutation); a subdomain scanner finds subdomains that live under yours (enumeration). Same recon family, opposite questions — run both if you run either. Our free subdomain scanner handles the enumeration side in the browser, and the subdomain finder guide explains the technique in depth.
Can You Try Dnstwist Without Installing Anything?
Yes — dnstwist.it runs the scanner in your web browser. The README's own pitch is: "In a hurry? Try it in your web browser: dnstwist.it". The honest caveat, from Kasabji: "If you are not keen on CLI tools, you can try the browser version, but keep in mind that it does not allow for any advanced usage." For a first look at what typosquatting looks like against your domain, it's fine; for scheduled defensive monitoring, the CLI is the real tool.
Sources
- dnstwist README — github.com/elceef/dnstwist (fetched 2026-11-04): tool description, install commands, fuzzer notes, GeoIP/LSH details, coverage note, dnstwist.it
- PyPI dnstwist release history (fetched 2026-11-04): latest release 20250130
- dnstwist 20250130
--helpoutput and installed source, captured on a local install (2026-11-04): 22 flags, default threads 8, fuzzer names, opt-in behaviors - dnstwist man page — mankier.com (December 2022 edition): description, flag reference, fuzzy-hash false-positive note
- dnstwist GitHub releases page (fetched 2026-11-04): --ssdeep → --lsh change, cyrillic/plural fuzzers, dictionary files
- David Kasabji, "How to detect Typosquatting?" — nil.com (updated 2026-04-23): install commands, --registered example, ssdeep explanation, defensive framing
- David Kasabji, "Typosquatting — Abusing known domains. Learn how to detect it" — conscia.com (updated 2025-09-19): same technique lineage
- "DNSTwist And How It Boosts Domain Monitoring" — bolster.ai (fetched 2026-11-04): defensive registration framing
- "Analyzing Typosquatting Domains with DNSTwist" — eliteai.tools (fetched 2026-11-04): fuzzer definitions, defensive workflow (with the dead --ssdeep flag corrected to --lsh)
Frequently Asked Questions
Is dnstwist free?
Yes. Dnstwist is open-source under the Apache License 2.0 — free to download, use, and modify, including commercially. Both pip install dnstwist and pip install dnstwist[full] cost nothing; the difference is only which optional libraries come along.
Is it legal to run dnstwist against a domain?
Scanning your own domain, or one you have explicit permission to test, is the intended defensive use — dnstwist only queries public DNS and fetches publicly served web pages, the same things any browser does. Scanning someone else's domain without their consent is where you cross into territory you don't want to be in, so keep it to your own brand.
What's the difference between dnstwist and a subdomain scanner?
Dnstwist generates permutations — domains that look like yours, like exmaple.com for example.com. A subdomain scanner enumerates subdomains — hosts that live under yours, like mail.example.com. One catches typosquatters; the other maps your own attack surface.
Why does my dnstwist command fail with an error about --ssdeep?
The --ssdeep flag was removed in newer releases and replaced with --lsh, which accepts ssdeep or tlsh as its algorithm. Replace --ssdeep with --lsh in any old tutorial command — ssdeep is still the default algorithm, only the flag name changed.
Do I need pip install dnstwist[full], or is the bare install enough?
The bare install (zero dependencies) is enough for the core workflow: permutation generation, DNS resolution, and the --registered/--unregistered filters. You need [full] for the extras that make triage powerful — GeoIP lookups, WHOIS, and the ssdeep/tlsh page-similarity hashing.

