diff --git a/pyproject.toml b/pyproject.toml
index 78d143d..6112a27 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "pyxray"
-version = "1.0.4"
+version = "1.0.5"
description = "A lightweight Linux xray control plane."
readme = "README.md"
requires-python = ">=3.14"
diff --git a/pyxray/libs/xray_config/generator.py b/pyxray/libs/xray_config/generator.py
index fa89994..a9cefef 100644
--- a/pyxray/libs/xray_config/generator.py
+++ b/pyxray/libs/xray_config/generator.py
@@ -31,6 +31,8 @@ def generate_xray_config(node: Node, settings: XrayConfigSettings | None = None)
log = _build_log(settings)
if log:
config["log"] = log
+ if _fakedns_enabled(settings):
+ config["fakedns"] = [{"ipPool": "198.18.0.0/15", "poolSize": 65535}]
config["routing"]["rules"].extend(_build_dns_routing(settings))
config["routing"]["rules"].append({"type": "field", "inboundTag": _dns_inbound_tags(settings), "outboundTag": "dns-out"})
config["routing"]["rules"].extend(_build_rule_port_routing(settings))
@@ -157,9 +159,12 @@ def _transparent_inbounds(settings: XrayConfigSettings) -> list[dict[str, Any]]:
def _with_sniffing(inbound: dict[str, Any], settings: XrayConfigSettings) -> dict[str, Any]:
if settings.inbounds.inbound_sniffing == "disable":
return inbound
+ dest_override = settings.inbounds.inbound_sniffing.split(",")
+ if _fakedns_enabled(settings) and "fakedns" not in dest_override:
+ dest_override.append("fakedns")
inbound["sniffing"] = {
"enabled": True,
- "destOverride": settings.inbounds.inbound_sniffing.split(","),
+ "destOverride": dest_override,
"domainsExcluded": _split_lines(settings.inbounds.domains_excluded),
"routeOnly": settings.inbounds.route_only,
}
@@ -207,6 +212,9 @@ def _dns_inbound_tags(settings: XrayConfigSettings) -> list[str]:
def _build_dns(settings: XrayConfigSettings, node: Node) -> dict[str, Any]:
servers: list[Any] = []
+ fakedns_domains = _fakedns_domains(settings)
+ if fakedns_domains:
+ servers.append({"address": "fakedns", "domains": fakedns_domains})
routing_domains = _domains_to_lookup(settings, node)
for rule in settings.dns.rules:
domains = _split_lines(rule.domains)
@@ -230,6 +238,16 @@ def _build_dns(settings: XrayConfigSettings, node: Node) -> dict[str, Any]:
return dns
+def _fakedns_enabled(settings: XrayConfigSettings) -> bool:
+ return settings.dns.special_mode == "fakedns"
+
+
+def _fakedns_domains(settings: XrayConfigSettings) -> list[str]:
+ if not _fakedns_enabled(settings):
+ return []
+ return _split_lines(settings.dns.fakedns_domains) or ["geosite:geolocation-!cn"]
+
+
def _dns_server(rule: DnsRuleSettings, domains: list[str]) -> Any:
address, port = _parse_dns_addr(rule.server)
server_address = rule.server if "://" in rule.server else address
diff --git a/pyxray/libs/xray_config/settings.py b/pyxray/libs/xray_config/settings.py
index 5c8e5c1..1363771 100644
--- a/pyxray/libs/xray_config/settings.py
+++ b/pyxray/libs/xray_config/settings.py
@@ -126,6 +126,7 @@ class DnsSettings:
)
antipollution: str = "closed"
special_mode: str = "none"
+ fakedns_domains: str = "geosite:geolocation-!cn"
@dataclass(slots=True)
diff --git a/pyxray/web/templates/configs/dns.html b/pyxray/web/templates/configs/dns.html
index 94d1058..cf7576e 100644
--- a/pyxray/web/templates/configs/dns.html
+++ b/pyxray/web/templates/configs/dns.html
@@ -43,6 +43,10 @@
+