Open-source project
bootmortis/iran-hosted-domains avatar
bootmortis/iran-hosted-domains

Iran Hosted Domains, a routing ruleset built for the Iran traffic split

"Iran Hosted Domains" is a comprehensive list of Iranian domains and services that are hosted within the country.

1,040 stars129 forksPythonMIT

At a glance

What is it?
Iran Hosted Domains is a Python generator that compiles public lists of Iranian domains into ready-made rule files for Clash, Surge, Shadowrocket, sing-box, v2ray, Hysteria, Fortinet and SwitchyOmega. The point of the dataset is a split routing decision: Iranian services go direct, Iran-related proxy domains get proxied, and Iran-related advertising domains get blocked.
Who is it for?
Adopt this dataset if you run a split routing client inside or outside Iran and want the direct, proxied and blocked decisions expressed as ready-made rule files rather than your own maintenance, and skip it if you need a fresh per-domain lookup service, since the output is a set of files regenerated on a schedule rather than a query endpoint.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 11 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The traffic problem this dataset is built around

The repository states the problem plainly. Many services and domains are outside Iran and are restricted or blocked, so reaching them needs a VPN or a proxy with a tunneling option. But the same proxy breaks the other half of the traffic: once your address is not in Iran, domestic services become unreachable. The list exists to break that deadlock by telling a routing client which side of the split each domain belongs to. The repository is a compiled list of public information about websites hosted in Iran, and it carries an explicit disclaimer that it is for informational purposes and is not guidance on how to connect to, create or manage a VPN, with no warranties about completeness or accuracy. The topic tags on the repository mention the Great Firewall and v2ray, and the data has an obvious second audience: anyone running a proxy client in the other direction who wants Iranian services to bypass the tunnel.

Six categories, and the routing action each one implies

The categories carry the routing instruction with them, which is the useful part of the design. `all` is a combination of `other` and `tld-ir` and is meant to be used as `direct`. `tld-ir` covers all `.ir` domains and is also used as `direct`. `other` is the non-`.ir` domains and is used as `direct` as well. `ir` is a handpicked set of `.ir` domains, also `direct`. `proxy` is the Iran-related domains that are blocked inside Iran and need to be `proxied`. `ads` is Iran-related advertising services that need to be `blocked`. So four categories resolve to direct, one to proxied and one to blocked, and the naming is consistent enough that a client configuration reads as a set of category references rather than a list of thousands of domains. Note that `all` is explicitly a union, not a separate source, so a client that uses both `all` and `tld-ir` is duplicating coverage rather than adding information.

One dataset, a dozen file formats

The generator writes the same underlying data into a long list of file shapes, because routing clients disagree about everything. Clash gets `clash_rules_ads.txt` and `clash_rules_other.yaml` along with text variants, and for sing-box there is `iran-geosite.db` for the sing-box core, while the `geosite-*.srs` files for sing-box v1.8 and later live in a separate repository, the sing-geosite releases page. v2ray and xray get `iran.dat`, which carries the hosted domains together with the advertising and proxy related domains. Shadowrocket gets an importable `shadowrocket.conf`, Qv2ray gets an importable `qv2ray_schema.json`, SwitchyOmega gets `switchy_omega.sorl`, and Hysteria gets `hysteria_client.acl` and `hysteria_server.acl`. Surge and Surfboard get both domain set and ruleset variants for ads and other domains, and Fortinet gets `fortinet_domainset_ads.txt` and `fortinet_domainset_other.txt`. `domains.txt` is the plain list of all websites hosted in Iran. The trade-off is real: a broader client reach means a per-client file format to maintain, and each new client needs its own generator path.

A scheduled Python generator, not a hand-edited list

Nothing in the repository is edited by hand at scale. A Python script is executed by a GitHub Action, and the files it produces are published on the release page. The project also exposes `src/data/custom_domains.py`, the file a contributor is asked to edit to add a specific website, and the README asks for an issue or a pull request when a site is missing. The dependency set is short and pinned, which is what you would expect from a script that scrapes a handful of public lists and rewrites them into many output formats:

python
requests==2.28.1
beautifulsoup4==4.11.1
tldextract~=3.4.0

`requests` and `beautifulsoup4` cover fetching and parsing the source pages, and `tldextract` handles the public suffix list, which is what lets the generator decide whether a host is under `.ir` rather than merely containing that string. The repository root holds `src/`, `scripts/`, `docs/` and `requirements.txt`, plus a `CONTRIBUTING.md`, a `CODE_OF_CONDUCT.md` and a `SECURITY.md`. The source pages it draws on are the ITO GOV ip list, the Enamad domain list, the ADSL TCI site panel, the V2fly domain list community and the Iran Web and Mobile Festival directory, with mirrors for several of them, plus a custom hand-kept list for the remainder.

Releases carry the files, and each file carries a hash

The README is explicit that the latest version of these files is on the release page, and that a `.sha256` file exists for each one containing the sha256 hash of that file. The release tags follow a timestamp pattern, and the recent ones show a steady cadence: a release on 2026-10-12, one on 2026-10-05 and one on 2026-09-28, with the last push to the repository on 2026-10-12. The repository is not archived. For a consumer, the practical reading is that the branch you clone is not the artifact you want. You take the files from the latest release and you can check them against the published hash, which is a stronger guarantee than trusting a raw file path. The client guides have been moved out of the repository to a documentation site, and the README says to check that site for per-client instructions, since the same category maps to a different file in each client.

Where the list falls short

The gaps are documented rather than hidden. The disclaimer says there are no representations or warranties about the completeness, accuracy, reliability, suitability or availability of the information, and that reliance on it is at the reader's own risk. That is a normal thing to read in a data disclaimer, but here it matters more than usual: a stale domain entry means a request that either fails to route or routes the wrong way, and a domain list cannot tell you the difference between a site that moved abroad and one that never existed in the list. The `proxy` category is the one that is hardest to keep right, since it depends on the current filtering behaviour of Iranian networks rather than on a published registry. Coverage also has a shape: the sources are Iranian registries and directories, so a service hosted in Iran but absent from every one of them will not appear. The `ir` category being handpicked rather than generated means it is also the category most likely to be out of date.

Picking the right file for your client

The decision for a user is mechanical once the format list is known. Clash users take the `clash_rules_*` files, sing-box users on the current core take `iran-geosite.db` while users on sing-box v1.8 or later are pointed to the `geosite-*.srs` files in the sing-geosite releases, v2ray and xray users take `iran.dat`, and Surge, Surfboard, Shadowrocket, Qv2ray, Hysteria, Fortinet and SwitchyOmega users each have a named importable file. A `direct` category and a `proxied` category both need to land in the right place in the client configuration, and that mapping is the part the documentation site exists to explain. Two details are easy to get wrong. First, `all` already contains both `other` and `tld-ir`, so a configuration that lists all three pulls in the same hosts three times. Second, the advertising category is described as needing to be `blocked`, not merely kept out of the direct path, so it belongs in a reject rule rather than in a direct list. The file names are the same across releases, so a scheduled job can re-download and verify them by hash without re-reading the documentation.

Editorial conclusion

Adopt this dataset if you run a split routing client inside or outside Iran and want the direct, proxied and blocked decisions expressed as ready-made rule files rather than your own maintenance, and skip it if you need a fresh per-domain lookup service, since the output is a set of files regenerated on a schedule rather than a query endpoint. Check three things first: that your client is on the list of supported formats, since each one expects a different file shape; that you download from the release page and verify the accompanying `.sha256` file, because the branch content is not the shipped artifact; and that the category you assign to a domain matches the behaviour you actually want, because `all` is a combination of `other` and `tld-ir` and points at `direct`.

Frequently asked questions

What does the Iran Hosted Domains repository provide?

A compiled list of public information about websites hosted in Iran, published as ready-made rule files for clients such as Clash, Surge, Shadowrocket, sing-box, v2ray, Hysteria, Fortinet and SwitchyOmega. The files are generated by a Python script run by a GitHub Action and published on the release page.

How do I install or use the Iran Hosted Domains rulesets?

You download the files from the release page rather than cloning the repository, then import the file that matches your client, such as `clash_rules_ads.yaml` for Clash, `iran.dat` for v2ray and xray, or `shadowrocket.conf` for Shadowrocket. Each file has a matching `.sha256` file containing its hash.

What is the difference between the all, other and tld-ir categories?

`tld-ir` is every `.ir` domain, `other` is the non-`.ir` domains, and `all` is a combination of the two. All three are used as `direct`, and `ir` is a separate handpicked set of `.ir` domains also used as `direct`.

Which categories does Iran Hosted Domains mark as proxied or blocked?

The `proxy` category holds Iran-related domains that are blocked inside Iran and need to be `proxied`, while the `ads` category holds Iran-related advertising services that need to be `blocked`.

Where do the domains in the list come from?

The generator draws on the ITO GOV ip list, the Enamad domain list, the ADSL TCI site panel, the V2fly domain list community, the Iran Web and Mobile Festival directory and a custom list kept in `src/data/custom_domains.py`. The advertising entries come from the uBOPa uBO Parsi filter list.

Official sources

  1. bootmortis/iran-hosted-domains on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bootmortis-iran-hosted-domains.svg)](https://hysenlabs.com/projects/bootmortis-iran-hosted-domains)