mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-27 03:41:22 +08:00
adapt to sing-box v1.12.0
This commit is contained in:
parent
b522d79619
commit
de1b1385c3
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
func Check(content []byte) error {
|
func Check(content []byte) error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ctx = boxbox.Context(ctx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry())
|
ctx = boxbox.Context(ctx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry(), include.DNSTransportRegistry(), include.ServiceRegistry())
|
||||||
options, err := parseConfig(ctx, content)
|
options, err := parseConfig(ctx, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -69,5 +69,5 @@ func preRun(cmd *cobra.Command, args []string) {
|
|||||||
configPaths = append(configPaths, "config.json")
|
configPaths = append(configPaths, "config.json")
|
||||||
}
|
}
|
||||||
globalCtx = service.ContextWith(globalCtx, deprecated.NewStderrManager(log.StdLogger()))
|
globalCtx = service.ContextWith(globalCtx, deprecated.NewStderrManager(log.StdLogger()))
|
||||||
globalCtx = box.Context(globalCtx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry())
|
globalCtx = box.Context(globalCtx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry(), include.DNSTransportRegistry(), include.ServiceRegistry())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,8 @@ namespace Configs {
|
|||||||
|
|
||||||
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status);
|
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status);
|
||||||
|
|
||||||
|
QJsonObject BuildDnsObject(QString address, bool tunEnabled);
|
||||||
|
|
||||||
QString BuildChain(int chainId, const std::shared_ptr<BuildConfigStatus> &status);
|
QString BuildChain(int chainId, const std::shared_ptr<BuildConfigStatus> &status);
|
||||||
|
|
||||||
QString BuildChainInternal(int chainId, const QList<std::shared_ptr<ProxyEntity>> &ents,
|
QString BuildChainInternal(int chainId, const QList<std::shared_ptr<ProxyEntity>> &ents,
|
||||||
|
|||||||
@ -33,9 +33,7 @@
|
|||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>outbound.domain_strategy
|
<string><html><head/><body><p>Resolve domains to IP before connect, also affects the server address as well</p></body></html></string>
|
||||||
when set, domain destinations are resolved to IP before connect,
|
|
||||||
also if the connection cannot be established with the current address family (ipv4, ipv6), a fallback connection is created shortly after, with the other address family.</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Outbound Domain Strategy</string>
|
<string>Outbound Domain Strategy</string>
|
||||||
@ -62,8 +60,7 @@ also if the connection cannot be established with the current address family (ip
|
|||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_6">
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string notr="true">inbound.domain_strategy
|
<string notr="true"><html><head/><body><p>Enable to resolve domains to IP before routing based on the strategy</p></body></html></string>
|
||||||
when used, domain destinations are resolved to IP before routing.</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Inbound Domain Strategy</string>
|
<string>Inbound Domain Strategy</string>
|
||||||
@ -82,11 +79,6 @@ when used, domain destinations are resolved to IP before routing.</string>
|
|||||||
<string>Sniff result for routing</string>
|
<string>Sniff result for routing</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Sniff result for destination</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
@ -240,6 +232,9 @@ when used, domain destinations are resolved to IP before routing.</string>
|
|||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_9">
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>examples:<br/>tls://8.8.8.8<br/>https://domain/path</p><p>tcp://8.8.8.8:1234</p><p>dhcp://auto</p><p>h3://domain/path</p><p>quic://domain:4632</p><p>etc</p></body></html></string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Remote DNS</string>
|
<string>Remote DNS</string>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
@ -42,5 +42,5 @@ pushd gen
|
|||||||
protoc -I . --go_out=. --protorpc_out=. libcore.proto
|
protoc -I . --go_out=. --protorpc_out=. libcore.proto
|
||||||
popd
|
popd
|
||||||
VERSION_SINGBOX=$(go list -m -f '{{.Version}}' github.com/sagernet/sing-box)
|
VERSION_SINGBOX=$(go list -m -f '{{.Version}}' github.com/sagernet/sing-box)
|
||||||
$GOCMD build -v -o $DEST -trimpath -ldflags "-w -s -X 'github.com/sagernet/sing-box/constant.Version=${VERSION_SINGBOX}'" -tags "with_clash_api,with_gvisor,with_quic,with_wireguard,with_utls,with_ech,with_dhcp"
|
$GOCMD build -v -o $DEST -trimpath -ldflags "-w -s -X 'github.com/sagernet/sing-box/constant.Version=${VERSION_SINGBOX}'" -tags "with_clash_api,with_gvisor,with_quic,with_wireguard,with_utls,with_dhcp"
|
||||||
popd
|
popd
|
||||||
|
|||||||
@ -7,9 +7,6 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
#define BOX_UNDERLYING_DNS_EXPORT dataStore->core_box_underlying_dns.isEmpty() ? (status->forExport ? "local" : "underlying://0.0.0.0") : dataStore->core_box_underlying_dns
|
|
||||||
|
|
||||||
namespace Configs {
|
namespace Configs {
|
||||||
QString genTunName() {
|
QString genTunName() {
|
||||||
auto tun_name = "throne-tun";
|
auto tun_name = "throne-tun";
|
||||||
@ -396,8 +393,6 @@ namespace Configs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// common
|
// common
|
||||||
// apply domain_strategy
|
|
||||||
outbound["domain_strategy"] = dataStore->routing->outbound_domain_strategy;
|
|
||||||
// apply mux
|
// apply mux
|
||||||
if (needMux) {
|
if (needMux) {
|
||||||
auto muxObj = QJsonObject{
|
auto muxObj = QJsonObject{
|
||||||
@ -421,6 +416,88 @@ namespace Configs {
|
|||||||
|
|
||||||
// SingBox
|
// SingBox
|
||||||
|
|
||||||
|
QJsonObject BuildDnsObject(QString address, bool tunEnabled)
|
||||||
|
{
|
||||||
|
bool usingSystemdResolved = false;
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
usingSystemdResolved = ReadFileText("/etc/resolv.conf").contains("systemd-resolved");
|
||||||
|
#endif
|
||||||
|
if (address.startsWith("local"))
|
||||||
|
{
|
||||||
|
if (tunEnabled && usingSystemdResolved)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
{"type", "dhcp"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
{"type", "local"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (address.startsWith("dhcp://"))
|
||||||
|
{
|
||||||
|
auto ifcName = address.replace("dhcp://", "");
|
||||||
|
if (ifcName == "auto") ifcName = "";
|
||||||
|
return {
|
||||||
|
{"type", "dhcp"},
|
||||||
|
{"interface", ifcName},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
QString addr = address;
|
||||||
|
int port = -1;
|
||||||
|
QString type = "udp";
|
||||||
|
QString path = "";
|
||||||
|
if (address.startsWith("tcp://"))
|
||||||
|
{
|
||||||
|
type = "tcp";
|
||||||
|
addr = addr.replace("tcp://", "");
|
||||||
|
}
|
||||||
|
if (address.startsWith("tls://"))
|
||||||
|
{
|
||||||
|
type = "tls";
|
||||||
|
addr = addr.replace("tls://", "");
|
||||||
|
}
|
||||||
|
if (address.startsWith("quic://"))
|
||||||
|
{
|
||||||
|
type = "quic";
|
||||||
|
addr = addr.replace("quic://", "");
|
||||||
|
}
|
||||||
|
if (address.startsWith("https://"))
|
||||||
|
{
|
||||||
|
type = "https";
|
||||||
|
addr = addr.replace("https://", "");
|
||||||
|
if (addr.contains("/"))
|
||||||
|
{
|
||||||
|
path = addr.split("/").last();
|
||||||
|
addr = addr.left(addr.indexOf("/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (address.startsWith("h3://"))
|
||||||
|
{
|
||||||
|
type = "h3";
|
||||||
|
addr = addr.replace("h3://", "");
|
||||||
|
if (addr.contains("/"))
|
||||||
|
{
|
||||||
|
path = addr.split("/").last();
|
||||||
|
addr = addr.left(addr.indexOf("/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addr.contains(":"))
|
||||||
|
{
|
||||||
|
auto spl = addr.split(":");
|
||||||
|
addr = spl[0];
|
||||||
|
port = spl[1].toInt();
|
||||||
|
}
|
||||||
|
QJsonObject res = {
|
||||||
|
{"type", type},
|
||||||
|
{"server", addr},
|
||||||
|
};
|
||||||
|
if (port != -1) res["server_port"] = port;
|
||||||
|
if (!path.isEmpty()) res["path"] = path;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status) {
|
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status) {
|
||||||
// Prefetch
|
// Prefetch
|
||||||
auto routeChain = profileManager->GetRouteChain(dataStore->routing->current_route_id);
|
auto routeChain = profileManager->GetRouteChain(dataStore->routing->current_route_id);
|
||||||
@ -504,7 +581,6 @@ namespace Configs {
|
|||||||
inboundObj["type"] = "mixed";
|
inboundObj["type"] = "mixed";
|
||||||
inboundObj["listen"] = dataStore->inbound_address;
|
inboundObj["listen"] = dataStore->inbound_address;
|
||||||
inboundObj["listen_port"] = dataStore->inbound_socks_port;
|
inboundObj["listen_port"] = dataStore->inbound_socks_port;
|
||||||
inboundObj["domain_strategy"] = dataStore->routing->domain_strategy;
|
|
||||||
status->inbounds += inboundObj;
|
status->inbounds += inboundObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +600,6 @@ namespace Configs {
|
|||||||
auto tunAddress = QJsonArray{"172.19.0.1/24"};
|
auto tunAddress = QJsonArray{"172.19.0.1/24"};
|
||||||
if (dataStore->vpn_ipv6) tunAddress += "fdfe:dcba:9876::1/96";
|
if (dataStore->vpn_ipv6) tunAddress += "fdfe:dcba:9876::1/96";
|
||||||
inboundObj["address"] = tunAddress;
|
inboundObj["address"] = tunAddress;
|
||||||
inboundObj["domain_strategy"] = dataStore->routing->domain_strategy;
|
|
||||||
if (dataStore->enable_tun_routing && routeChain->defaultOutboundID == proxyID)
|
if (dataStore->enable_tun_routing && routeChain->defaultOutboundID == proxyID)
|
||||||
{
|
{
|
||||||
if (!directIPCIDRs.isEmpty()) inboundObj["route_exclude_address"] = directIPCIDRs;
|
if (!directIPCIDRs.isEmpty()) inboundObj["route_exclude_address"] = directIPCIDRs;
|
||||||
@ -582,7 +657,6 @@ namespace Configs {
|
|||||||
if (!status->forTest) QJSONARRAY_ADD(status->inbounds, QString2QJsonObject(dataStore->custom_inbound)["inbounds"].toArray())
|
if (!status->forTest) QJSONARRAY_ADD(status->inbounds, QString2QJsonObject(dataStore->custom_inbound)["inbounds"].toArray())
|
||||||
|
|
||||||
// Routing
|
// Routing
|
||||||
// geopath
|
|
||||||
if (NeedGeoAssets()) {
|
if (NeedGeoAssets()) {
|
||||||
status->result->error = "Geo Assets are missing, please download them through Basic Settings -> Assets";
|
status->result->error = "Geo Assets are missing, please download them through Basic Settings -> Assets";
|
||||||
return;
|
return;
|
||||||
@ -599,15 +673,19 @@ namespace Configs {
|
|||||||
}
|
}
|
||||||
if (!status->forTest) routeObj["final"] = outboundIDToString(routeChain->defaultOutboundID);
|
if (!status->forTest) routeObj["final"] = outboundIDToString(routeChain->defaultOutboundID);
|
||||||
|
|
||||||
|
if (!dataStore->routing->domain_strategy.isEmpty())
|
||||||
|
{
|
||||||
|
auto resolveRule = std::make_shared<RouteRule>();
|
||||||
|
resolveRule->action = "resolve";
|
||||||
|
resolveRule->strategy = dataStore->routing->domain_strategy;
|
||||||
|
resolveRule->inbound = {"mixed-in", "tun-in"};
|
||||||
|
routeChain->Rules.prepend(resolveRule);
|
||||||
|
}
|
||||||
if (dataStore->routing->sniffing_mode != SniffingMode::DISABLE)
|
if (dataStore->routing->sniffing_mode != SniffingMode::DISABLE)
|
||||||
{
|
{
|
||||||
auto sniffRule = std::make_shared<RouteRule>();
|
auto sniffRule = std::make_shared<RouteRule>();
|
||||||
sniffRule->action = "sniff";
|
sniffRule->action = "sniff";
|
||||||
sniffRule->inbound = {"mixed-in", "tun-in"};
|
sniffRule->inbound = {"mixed-in", "tun-in"};
|
||||||
if (dataStore->routing->sniffing_mode == SniffingMode::FOR_DESTINATION)
|
|
||||||
{
|
|
||||||
sniffRule->sniffOverrideDest = true;
|
|
||||||
}
|
|
||||||
routeChain->Rules.prepend(sniffRule);
|
routeChain->Rules.prepend(sniffRule);
|
||||||
}
|
}
|
||||||
auto neededOutbounds = routeChain->get_used_outbounds();
|
auto neededOutbounds = routeChain->get_used_outbounds();
|
||||||
@ -645,7 +723,6 @@ namespace Configs {
|
|||||||
routeObj["rules"] = routeRules;
|
routeObj["rules"] = routeRules;
|
||||||
|
|
||||||
// DNS hijack deps
|
// DNS hijack deps
|
||||||
bool needHijackRules = false;
|
|
||||||
QJsonArray hijackDomains;
|
QJsonArray hijackDomains;
|
||||||
QJsonArray hijackDomainSuffix;
|
QJsonArray hijackDomainSuffix;
|
||||||
QJsonArray hijackDomainRegex;
|
QJsonArray hijackDomainRegex;
|
||||||
@ -665,7 +742,6 @@ namespace Configs {
|
|||||||
if (rule.startsWith("regex:")) {
|
if (rule.startsWith("regex:")) {
|
||||||
hijackDomainRegex << rule.mid(6);
|
hijackDomainRegex << rule.mid(6);
|
||||||
}
|
}
|
||||||
needHijackRules = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto ruleSet : hijackGeoAssets) {
|
for (auto ruleSet : hijackGeoAssets) {
|
||||||
@ -710,59 +786,74 @@ namespace Configs {
|
|||||||
routeObj["rule_set"] = ruleSetArray;
|
routeObj["rule_set"] = ruleSetArray;
|
||||||
|
|
||||||
// DNS settings
|
// DNS settings
|
||||||
// final add DNS
|
|
||||||
QJsonObject dns;
|
QJsonObject dns;
|
||||||
QJsonArray dnsServers;
|
QJsonArray dnsServers;
|
||||||
QJsonArray dnsRules;
|
QJsonArray dnsRules;
|
||||||
|
|
||||||
// Remote
|
// Remote
|
||||||
dnsServers += QJsonObject{
|
auto remoteDnsObj = BuildDnsObject(dataStore->routing->remote_dns, dataStore->spmode_vpn);
|
||||||
{"tag", "dns-remote"},
|
remoteDnsObj["tag"] = "dns-remote";
|
||||||
{"address_resolver", "dns-local"},
|
remoteDnsObj["domain_resolver"] = "dns-local";
|
||||||
{"strategy", dataStore->routing->remote_dns_strategy},
|
remoteDnsObj["detour"] = tagProxy;
|
||||||
{"address", dataStore->routing->remote_dns},
|
dnsServers += remoteDnsObj;
|
||||||
{"detour", tagProxy},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Direct
|
// Direct
|
||||||
auto directDNSAddress = dataStore->routing->direct_dns;
|
auto directDNSAddress = dataStore->routing->direct_dns;
|
||||||
if (directDNSAddress == "localhost") directDNSAddress = BOX_UNDERLYING_DNS_EXPORT;
|
auto directDnsObj = BuildDnsObject(directDNSAddress, dataStore->spmode_vpn);
|
||||||
#ifdef Q_OS_LINUX
|
directDnsObj["tag"] = "dns-direct";
|
||||||
auto usingSystemdResolved = ReadFileText("/etc/resolv.conf").contains("systemd-resolved");
|
directDnsObj["domain_resolver"] = "dns-local";
|
||||||
if (dataStore->spmode_vpn && (directDNSAddress.startsWith("local") || directDNSAddress.startsWith("underlying")) && usingSystemdResolved)
|
|
||||||
{
|
// default dns server
|
||||||
MW_show_log("[Warning] Using local dns resolver with systemd-resolved enabled causes a dns loophole, using dhcp://auto as direct dns.");
|
|
||||||
directDNSAddress = "dhcp://auto";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
QJsonObject directObj{
|
|
||||||
{"tag", "dns-direct"},
|
|
||||||
{"address_resolver", "dns-local"},
|
|
||||||
{"strategy", dataStore->routing->direct_dns_strategy},
|
|
||||||
{"address", directDNSAddress},
|
|
||||||
{"detour", "direct"},
|
|
||||||
};
|
|
||||||
if (dataStore->routing->dns_final_out == "direct") {
|
if (dataStore->routing->dns_final_out == "direct") {
|
||||||
dnsServers.prepend(directObj);
|
dnsServers.prepend(directDnsObj);
|
||||||
} else {
|
} else {
|
||||||
dnsServers.append(directObj);
|
dnsServers.append(directDnsObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// block
|
// Handle localhost
|
||||||
dnsServers += QJsonObject{
|
dnsRules += QJsonObject{
|
||||||
{"tag", "dns-block"},
|
{"domain", "localhost"},
|
||||||
{"address", "rcode://success"},
|
{"action", "predefined"},
|
||||||
|
{"query_type", "A"},
|
||||||
|
{"rcode", "NOERROR"},
|
||||||
|
{"answer", "localhost. IN A 127.0.0.1"},
|
||||||
|
};
|
||||||
|
|
||||||
|
dnsRules += QJsonObject{
|
||||||
|
{"domain", "localhost"},
|
||||||
|
{"action", "predefined"},
|
||||||
|
{"query_type", "AAAA"},
|
||||||
|
{"rcode", "NOERROR"},
|
||||||
|
{"answer", "localhost. IN AAAA ::1"},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hijack
|
// Hijack
|
||||||
if (dataStore->enable_dns_server && !status->forTest) {
|
if (dataStore->enable_dns_server && !status->forTest) {
|
||||||
dnsServers += QJsonObject {
|
dnsRules += QJsonObject{
|
||||||
{"tag", "dns-hijack"},
|
{"rule_set", hijackGeoAssets},
|
||||||
{"address", "hijack://10.10.10.10"},
|
{"domain", hijackDomains},
|
||||||
{"inet4_response", dataStore->dns_v4_resp},
|
{"domain_suffix", hijackDomainSuffix},
|
||||||
{"inet6_response", dataStore->dns_v6_resp},
|
{"domain_regex", hijackDomainRegex},
|
||||||
|
{"query_type", "A"},
|
||||||
|
{"action", "predefined"},
|
||||||
|
{"rcode", "NOERROR"},
|
||||||
|
{"answer", QString("* IN A %1").arg(dataStore->dns_v4_resp)},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!dataStore->dns_v6_resp.isEmpty())
|
||||||
|
{
|
||||||
|
dnsRules += QJsonObject{
|
||||||
|
{"rule_set", hijackGeoAssets},
|
||||||
|
{"domain", hijackDomains},
|
||||||
|
{"domain_suffix", hijackDomainSuffix},
|
||||||
|
{"domain_regex", hijackDomainRegex},
|
||||||
|
{"query_type", "AAAA"},
|
||||||
|
{"action", "predefined"},
|
||||||
|
{"rcode", "NOERROR"},
|
||||||
|
{"answer", QString("* IN AAAA %1").arg(dataStore->dns_v6_resp)},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
status->inbounds.prepend(QJsonObject{
|
status->inbounds.prepend(QJsonObject{
|
||||||
{"tag", "dns-in"},
|
{"tag", "dns-in"},
|
||||||
{"type", "direct"},
|
{"type", "direct"},
|
||||||
@ -775,22 +866,16 @@ namespace Configs {
|
|||||||
if (dataStore->fake_dns) {
|
if (dataStore->fake_dns) {
|
||||||
dnsServers += QJsonObject{
|
dnsServers += QJsonObject{
|
||||||
{"tag", "dns-fake"},
|
{"tag", "dns-fake"},
|
||||||
{"address", "fakeip"},
|
{"type", "fakeip"},
|
||||||
};
|
|
||||||
dns["fakeip"] = QJsonObject{
|
|
||||||
{"enabled", true},
|
|
||||||
{"inet4_range", "198.18.0.0/15"},
|
{"inet4_range", "198.18.0.0/15"},
|
||||||
{"inet6_range", "fc00::/18"},
|
{"inet6_range", "fc00::/18"},
|
||||||
};
|
};
|
||||||
dnsRules += QJsonObject{
|
|
||||||
{"outbound", "any"},
|
|
||||||
{"server", "dns-local"},
|
|
||||||
};
|
|
||||||
dnsRules += QJsonObject{
|
dnsRules += QJsonObject{
|
||||||
{"query_type", QJsonArray{
|
{"query_type", QJsonArray{
|
||||||
"A",
|
"A",
|
||||||
"AAAA"
|
"AAAA"
|
||||||
}},
|
}},
|
||||||
|
{"action", "route"},
|
||||||
{"server", "dns-fake"}
|
{"server", "dns-fake"}
|
||||||
};
|
};
|
||||||
dns["independent_cache"] = true;
|
dns["independent_cache"] = true;
|
||||||
@ -806,34 +891,17 @@ namespace Configs {
|
|||||||
{"action", "route"},
|
{"action", "route"},
|
||||||
{"server", "dns-direct"},
|
{"server", "dns-direct"},
|
||||||
};
|
};
|
||||||
}
|
routeObj["default_domain_resolver"] = QJsonObject{
|
||||||
|
{"server", "dns-direct"},
|
||||||
// dns hijack rules
|
{"strategy", dataStore->routing->outbound_domain_strategy},
|
||||||
if (needHijackRules) {
|
|
||||||
dnsRules += QJsonObject{
|
|
||||||
{"rule_set", hijackGeoAssets},
|
|
||||||
{"domain", hijackDomains},
|
|
||||||
{"domain_suffix", hijackDomainSuffix},
|
|
||||||
{"domain_regex", hijackDomainRegex},
|
|
||||||
{"action", "route"},
|
|
||||||
{"server", "dns-hijack"},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Underlying 100% Working DNS
|
// Underlying 100% Working DNS
|
||||||
auto dnsLocalAddress = BOX_UNDERLYING_DNS_EXPORT;
|
auto dnsLocalAddress = dataStore->core_box_underlying_dns.isEmpty() ? "local" : dataStore->core_box_underlying_dns;
|
||||||
#ifdef Q_OS_LINUX
|
auto dnsLocalObj = BuildDnsObject(dnsLocalAddress, dataStore->spmode_vpn);
|
||||||
if (dataStore->spmode_vpn && (dnsLocalAddress.startsWith("local") || dnsLocalAddress.startsWith("underlying")) && usingSystemdResolved)
|
dnsLocalObj["tag"] = "dns-local";
|
||||||
{
|
dnsServers += dnsLocalObj;
|
||||||
MW_show_log("[Warning] Using local dns resolver with systemd-resolved enabled causes a dns loophole, using dhcp://auto as local dns.");
|
|
||||||
dnsLocalAddress = "dhcp://auto";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
dnsServers += QJsonObject{
|
|
||||||
{"tag", "dns-local"},
|
|
||||||
{"address", dnsLocalAddress},
|
|
||||||
{"detour", "direct"},
|
|
||||||
};
|
|
||||||
|
|
||||||
dns["servers"] = dnsServers;
|
dns["servers"] = dnsServers;
|
||||||
dns["rules"] = dnsRules;
|
dns["rules"] = dnsRules;
|
||||||
@ -852,7 +920,7 @@ namespace Configs {
|
|||||||
{
|
{
|
||||||
if (dataStore->core_box_clash_api > 0){
|
if (dataStore->core_box_clash_api > 0){
|
||||||
clash_api = {
|
clash_api = {
|
||||||
{"external_controller", Configs::dataStore->core_box_clash_listen_addr + ":" + Int2String(dataStore->core_box_clash_api)},
|
{"external_controller", dataStore->core_box_clash_listen_addr + ":" + Int2String(dataStore->core_box_clash_api)},
|
||||||
{"secret", dataStore->core_box_clash_api_secret},
|
{"secret", dataStore->core_box_clash_api_secret},
|
||||||
{"external_ui", "dashboard"},
|
{"external_ui", "dashboard"},
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user