diff --git a/APIDOCS.md b/APIDOCS.md index 575542f2..e5958e5f 100644 --- a/APIDOCS.md +++ b/APIDOCS.md @@ -494,8 +494,12 @@ RESPONSE: "totalCached": 228, "totalBlocked": 111, "totalClients": 831, + "zones": 5, + "cachedEntries": 28, "allowedZones": 6, - "blockedZones": 1136182 + "blockedZones": 10, + "allowListZones": 0, + "blockListZones": 1136182 }, "mainChartData": { "labelFormat": "HH:mm", diff --git a/Apps/AdvancedBlockingApp/AdvancedBlockingApp.csproj b/Apps/AdvancedBlockingApp/AdvancedBlockingApp.csproj index 6cd8b4ab..8b246742 100644 --- a/Apps/AdvancedBlockingApp/AdvancedBlockingApp.csproj +++ b/Apps/AdvancedBlockingApp/AdvancedBlockingApp.csproj @@ -3,7 +3,7 @@ net7.0 false - 5.0 + 5.0.1 Technitium Technitium DNS Server Shreyas Zare diff --git a/Apps/AdvancedBlockingApp/App.cs b/Apps/AdvancedBlockingApp/App.cs index a15781cb..28a9228a 100644 --- a/Apps/AdvancedBlockingApp/App.cs +++ b/Apps/AdvancedBlockingApp/App.cs @@ -1110,7 +1110,7 @@ namespace AdvancedBlocking if (line.Length == 0) continue; //skip empty line - if (line.StartsWith("#")) + if (line.StartsWith('#')) continue; //skip comment line firstWord = PopWord(ref line); @@ -1123,7 +1123,7 @@ namespace AdvancedBlocking { secondWord = PopWord(ref line); - if (secondWord.Length == 0) + if ((secondWord.Length == 0) || secondWord.StartsWith('#')) hostname = firstWord; else hostname = secondWord; @@ -1239,7 +1239,7 @@ namespace AdvancedBlocking if (line.Length == 0) continue; //skip empty line - if (line.StartsWith("#")) + if (line.StartsWith('#')) continue; //skip comment line regices.Enqueue(line); @@ -1338,7 +1338,7 @@ namespace AdvancedBlocking if (line.Length == 0) continue; //skip empty line - if (line.StartsWith("!")) + if (line.StartsWith('!')) continue; //skip comment line if (line.StartsWith("||")) @@ -1349,7 +1349,7 @@ namespace AdvancedBlocking string domain = line.Substring(2, i - 2); string options = line.Substring(i + 1); - if (((options.Length == 0) || (options.StartsWith("$") && (options.Contains("doc") || options.Contains("all")))) && DnsClient.IsDomainNameValid(domain)) + if (((options.Length == 0) || (options.StartsWith('$') && (options.Contains("doc") || options.Contains("all")))) && DnsClient.IsDomainNameValid(domain)) blockedDomains.Enqueue(domain); } else @@ -1368,7 +1368,7 @@ namespace AdvancedBlocking string domain = line.Substring(4, i - 4); string options = line.Substring(i + 1); - if (((options.Length == 0) || (options.StartsWith("$") && (options.Contains("doc") || options.Contains("all")))) && DnsClient.IsDomainNameValid(domain)) + if (((options.Length == 0) || (options.StartsWith('$') && (options.Contains("doc") || options.Contains("all")))) && DnsClient.IsDomainNameValid(domain)) allowedDomains.Enqueue(domain); } else diff --git a/Apps/AdvancedForwardingApp/AdvancedForwardingApp.csproj b/Apps/AdvancedForwardingApp/AdvancedForwardingApp.csproj index c923bc47..ffae889c 100644 --- a/Apps/AdvancedForwardingApp/AdvancedForwardingApp.csproj +++ b/Apps/AdvancedForwardingApp/AdvancedForwardingApp.csproj @@ -3,7 +3,7 @@ net7.0 false - 1.0 + 1.0.1 Technitium Technitium DNS Server Shreyas Zare diff --git a/Apps/AdvancedForwardingApp/App.cs b/Apps/AdvancedForwardingApp/App.cs index 267fc0e4..bbed2e56 100644 --- a/Apps/AdvancedForwardingApp/App.cs +++ b/Apps/AdvancedForwardingApp/App.cs @@ -444,6 +444,28 @@ namespace AdvancedForwarding return false; } + public static bool IsForwarderDomain(string domain, IReadOnlyList forwardings) + { + foreach (Forwarding forwarding in forwardings) + { + if (IsForwarderDomain(domain, forwarding._forwarderRecords)) + return true; + } + + return false; + } + + public static bool IsForwarderDomain(string domain, IReadOnlyList forwarderRecords) + { + foreach (DnsForwarderRecordData forwarderRecord in forwarderRecords) + { + if (domain.Equals(forwarderRecord.NameServer.Host, StringComparison.OrdinalIgnoreCase)) + return true; + } + + return false; + } + #endregion #region private @@ -554,7 +576,12 @@ namespace AdvancedForwarding { DateTime configFileLastModified = File.GetLastWriteTimeUtc(_configFile); if (configFileLastModified > _configFileLastModified) + { ReloadUpstreamsFile(); + + //force GC collection to remove old cache data from memory quickly + GC.Collect(); + } } catch (Exception ex) { @@ -611,10 +638,10 @@ namespace AdvancedForwarding if (line.Length == 0) continue; //skip empty line - if (line.StartsWith("#")) + if (line.StartsWith('#')) continue; //skip comment line - if (line.StartsWith("[")) + if (line.StartsWith('[')) { int i = line.LastIndexOf(']'); if (i < 0) @@ -689,11 +716,26 @@ namespace AdvancedForwarding public bool TryGetForwarderRecords(string domain, out IReadOnlyList forwarderRecords) { - if ((_forwardings.Count > 0) && Forwarding.TryGetForwarderRecords(domain, _forwardings, out forwarderRecords)) - return true; - - if (_defaultForwarderRecords.Count > 0) + if ((_forwardings is not null) && (_forwardings.Count > 0)) { + if (Forwarding.IsForwarderDomain(domain, _forwardings)) + { + forwarderRecords = null; + return false; + } + + if (Forwarding.TryGetForwarderRecords(domain, _forwardings, out forwarderRecords)) + return true; + } + + if ((_defaultForwarderRecords is not null) && (_defaultForwarderRecords.Count > 0)) + { + if (Forwarding.IsForwarderDomain(domain, _defaultForwarderRecords)) + { + forwarderRecords = null; + return false; + } + forwarderRecords = _defaultForwarderRecords; return true; } diff --git a/Apps/NxDomainApp/dnsApp.config b/Apps/NxDomainApp/dnsApp.config index 1cbf6609..aaaacc26 100644 --- a/Apps/NxDomainApp/dnsApp.config +++ b/Apps/NxDomainApp/dnsApp.config @@ -2,6 +2,8 @@ "enableBlocking": true, "allowTxtBlockingReport": true, "blocked": [ - "use-application-dns.net" + "use-application-dns.net", + "mask.icloud.com", + "mask-h2.icloud.com" ] } diff --git a/Apps/QueryLogsSqliteApp/dnsApp.config b/Apps/QueryLogsSqliteApp/dnsApp.config index 73323d35..743c53f7 100644 --- a/Apps/QueryLogsSqliteApp/dnsApp.config +++ b/Apps/QueryLogsSqliteApp/dnsApp.config @@ -1,6 +1,6 @@ { "enableLogging": true, - "maxLogDays": 0, + "maxLogDays": 7, "sqliteDbPath": "querylogs.db", "connectionString": "Data Source='{sqliteDbPath}'; Cache=Shared;" } diff --git a/CHANGELOG.md b/CHANGELOG.md index cff8c749..10826b25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Technitium DNS Server Change Log +## Version 11.0.1 +Release Date: 25 February 2023 + +- Changed allow list implementation to handle them separately and show allow list count on Dashboard. +- Fixed bug in conditional forwarder zone for root zone that caused the DNS server to return RCODE=ServerFailure. +- Fixed issues with DNS server's App request query handling sequence to fix issues with Advanced Forwarding app. +- Fixed issues with block list parser to detect in-line comments. +- Fixed issue of "URI too long" in save DHCP scope action. +- Updated Linux install script to use new install path in `/opt` and new config path `/etc/dns` for new installations. +- Updated Docker container to use new volume path `/etc/dns` for config. +- Updated Docker container to correctly handle container stop event to gracefully shutdown the DNS server. +- Updated Docker container to include `libmsquic` to allow QUIC support. +- Multiple other minor bug fixes and improvements. + ## Version 11.0 Release Date: 18 February 2023 diff --git a/DnsServerApp/DnsServerApp.csproj b/DnsServerApp/DnsServerApp.csproj index 827cb031..13079d49 100644 --- a/DnsServerApp/DnsServerApp.csproj +++ b/DnsServerApp/DnsServerApp.csproj @@ -6,7 +6,7 @@ Exe net7.0 logo2.ico - 11.0 + 11.0.1 Technitium Technitium DNS Server Shreyas Zare diff --git a/DnsServerApp/install.sh b/DnsServerApp/install.sh index 5b7a1885..131120c7 100644 --- a/DnsServerApp/install.sh +++ b/DnsServerApp/install.sh @@ -1,8 +1,15 @@ #!/bin/sh dotnetDir="/opt/dotnet" -dnsDir="/etc/dns" -dnsTar="/etc/dns/DnsServerPortable.tar.gz" + +if [ -d "/etc/dns/config" ] +then + dnsDir="/etc/dns" +else + dnsDir="/opt/technitium/dns" +fi + +dnsTar="$dnsDir/DnsServerPortable.tar.gz" dnsUrl="https://download.technitium.com/dns/DnsServerPortable.tar.gz" mkdir -p $dnsDir diff --git a/DnsServerApp/systemd.service b/DnsServerApp/systemd.service index b445223c..ee68d091 100644 --- a/DnsServerApp/systemd.service +++ b/DnsServerApp/systemd.service @@ -2,8 +2,8 @@ Description=Technitium DNS Server [Service] -WorkingDirectory=/etc/dns -ExecStart=/usr/bin/dotnet /etc/dns/DnsServerApp.dll +WorkingDirectory=/opt/technitium/dns +ExecStart=/usr/bin/dotnet /opt/technitium/dns/DnsServerApp.dll /etc/dns Restart=always # Restart service after 10 seconds if the dotnet service crashes: RestartSec=10 diff --git a/DnsServerApp/uninstall.sh b/DnsServerApp/uninstall.sh index 02414c42..bbeebcac 100644 --- a/DnsServerApp/uninstall.sh +++ b/DnsServerApp/uninstall.sh @@ -1,7 +1,13 @@ #!/bin/sh dotnetDir="/opt/dotnet" -dnsDir="/etc/dns" + +if [ -d "/etc/dns/config" ] +then + dnsDir="/etc/dns" +else + dnsDir="/opt/technitium/dns" +fi echo "" echo "=================================" diff --git a/DnsServerCore/Dns/DnsServer.cs b/DnsServerCore/Dns/DnsServer.cs index d71f67f9..a0423ea5 100644 --- a/DnsServerCore/Dns/DnsServer.cs +++ b/DnsServerCore/Dns/DnsServer.cs @@ -619,6 +619,10 @@ namespace DnsServerCore.Dns _queryLog?.Write(remoteEP, protocol, request, response); _stats.QueueUpdate(request, remoteEP, protocol, response); } + catch (ObjectDisposedException) + { + //ignore + } catch (IOException) { //ignore IO exceptions @@ -1839,38 +1843,9 @@ namespace DnsServerCore.Dns private async Task ProcessAuthoritativeQueryAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed, bool skipDnsAppAuthoritativeRequestHandlers) { - DnsDatagram response = null; - - if (!skipDnsAppAuthoritativeRequestHandlers) - { - foreach (IDnsAuthoritativeRequestHandler requestHandler in _dnsApplicationManager.DnsAuthoritativeRequestHandlers) - { - try - { - response = await requestHandler.ProcessRequestAsync(request, remoteEP, protocol, isRecursionAllowed); - if (response is not null) - { - if (response.Tag is null) - response.Tag = DnsServerResponseType.Authoritative; - - break; - } - } - catch (Exception ex) - { - _log?.Write(remoteEP, protocol, ex); - } - } - } - + DnsDatagram response = await AuthoritativeQueryAsync(request, remoteEP, protocol, isRecursionAllowed, skipDnsAppAuthoritativeRequestHandlers); if (response is null) - { - response = _authZoneManager.Query(request); - if (response is null) - return null; - - response.Tag = DnsServerResponseType.Authoritative; - } + return null; bool reprocessResponse; do @@ -1911,16 +1886,8 @@ namespace DnsServerCore.Dns break; case DnsResourceRecordType.FWD: - if ((response.Authority.Count == 1) && (firstAuthority.RDATA is DnsForwarderRecordData fwd) && fwd.Forwarder.Equals("this-server", StringComparison.OrdinalIgnoreCase)) - { - //do conditional forwarding via "this-server" - return await ProcessRecursiveQueryAsync(request, remoteEP, protocol, null, fwd.DnssecValidation, false, skipDnsAppAuthoritativeRequestHandlers); - } - else - { - //do conditional forwarding - return await ProcessRecursiveQueryAsync(request, remoteEP, protocol, response.Authority, _dnssecValidation, false, skipDnsAppAuthoritativeRequestHandlers); - } + //do conditional forwarding + return await ProcessRecursiveQueryAsync(request, remoteEP, protocol, response.Authority, _dnssecValidation, false, skipDnsAppAuthoritativeRequestHandlers); case DnsResourceRecordType.APP: response = await ProcessAPPAsync(request, remoteEP, response, isRecursionAllowed, protocol); @@ -1935,6 +1902,41 @@ namespace DnsServerCore.Dns return response; } + private async Task AuthoritativeQueryAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed, bool skipDnsAppAuthoritativeRequestHandlers) + { + if (!skipDnsAppAuthoritativeRequestHandlers) + { + foreach (IDnsAuthoritativeRequestHandler requestHandler in _dnsApplicationManager.DnsAuthoritativeRequestHandlers) + { + try + { + DnsDatagram appResponse = await requestHandler.ProcessRequestAsync(request, remoteEP, protocol, isRecursionAllowed); + if (appResponse is not null) + { + if (appResponse.Tag is null) + appResponse.Tag = DnsServerResponseType.Authoritative; + + return appResponse; + } + } + catch (Exception ex) + { + _log?.Write(remoteEP, protocol, ex); + } + } + } + + DnsDatagram response = _authZoneManager.Query(request); + if (response is not null) + { + response.Tag = DnsServerResponseType.Authoritative; + + return response; + } + + return null; + } + private async Task ProcessAPPAsync(DnsDatagram request, IPEndPoint remoteEP, DnsDatagram response, bool isRecursionAllowed, DnsTransportProtocol protocol) { DnsResourceRecord appResourceRecord = response.Authority[0]; @@ -2059,7 +2061,7 @@ namespace DnsServerCore.Dns DnsDatagram newRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(cnameDomain, request.Question[0].Type, request.Question[0].Class) }, null, null, null, _udpPayloadSize, request.DnssecOk ? EDnsHeaderFlags.DNSSEC_OK : EDnsHeaderFlags.None, eDnsClientSubnetOption); //query authoritative zone first - newResponse = _authZoneManager.Query(newRequest); + newResponse = await AuthoritativeQueryAsync(newRequest, remoteEP, protocol, isRecursionAllowed, skipDnsAppAuthoritativeRequestHandlers); if (newResponse is null) { //not found in auth zone @@ -2096,19 +2098,9 @@ namespace DnsServerCore.Dns break; case DnsResourceRecordType.FWD: - if ((newResponse.Authority.Count == 1) && (firstAuthority.RDATA is DnsForwarderRecordData fwd) && fwd.Forwarder.Equals("this-server", StringComparison.OrdinalIgnoreCase)) - { - //do conditional forwarding via "this-server" - newResponse = await RecursiveResolveAsync(newRequest, remoteEP, null, fwd.DnssecValidation, false, false, skipDnsAppAuthoritativeRequestHandlers); - isAuthoritativeAnswer = false; - } - else - { - //do conditional forwarding - newResponse = await RecursiveResolveAsync(newRequest, remoteEP, newResponse.Authority, _dnssecValidation, false, false, skipDnsAppAuthoritativeRequestHandlers); - isAuthoritativeAnswer = false; - } - + //do conditional forwarding + newResponse = await RecursiveResolveAsync(newRequest, remoteEP, newResponse.Authority, _dnssecValidation, false, false, skipDnsAppAuthoritativeRequestHandlers); + isAuthoritativeAnswer = false; break; case DnsResourceRecordType.APP: @@ -2216,7 +2208,7 @@ namespace DnsServerCore.Dns DnsDatagram newRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(lastDomain, request.Question[0].Type, request.Question[0].Class) }, null, null, null, _udpPayloadSize, request.DnssecOk ? EDnsHeaderFlags.DNSSEC_OK : EDnsHeaderFlags.None, eDnsClientSubnetOption); //query authoritative zone first - DnsDatagram newResponse = _authZoneManager.Query(newRequest); + DnsDatagram newResponse = await AuthoritativeQueryAsync(newRequest, remoteEP, protocol, isRecursionAllowed, skipDnsAppAuthoritativeRequestHandlers); if (newResponse is null) { //not found in auth zone; do recursion @@ -2234,17 +2226,8 @@ namespace DnsServerCore.Dns break; case DnsResourceRecordType.FWD: - if ((newResponse.Authority.Count == 1) && (firstAuthority.RDATA is DnsForwarderRecordData fwd) && fwd.Forwarder.Equals("this-server", StringComparison.OrdinalIgnoreCase)) - { - //do conditional forwarding via "this-server" - newResponse = await RecursiveResolveAsync(newRequest, remoteEP, null, fwd.DnssecValidation, false, false, skipDnsAppAuthoritativeRequestHandlers); - } - else - { - //do conditional forwarding - newResponse = await RecursiveResolveAsync(newRequest, remoteEP, newResponse.Authority, _dnssecValidation, false, false, skipDnsAppAuthoritativeRequestHandlers); - } - + //do conditional forwarding + newResponse = await RecursiveResolveAsync(newRequest, remoteEP, newResponse.Authority, _dnssecValidation, false, false, skipDnsAppAuthoritativeRequestHandlers); break; case DnsResourceRecordType.APP: @@ -2366,27 +2349,17 @@ namespace DnsServerCore.Dns private DnsDatagram ProcessBlockedQuery(DnsDatagram request) { - DnsDatagram response = null; - - if (_blockedZoneManager.TotalZonesBlocked > 0) - response = _blockedZoneManager.Query(request); - + DnsDatagram response = _blockedZoneManager.Query(request); if (response is null) { //domain not blocked in blocked zone - if (_blockListZoneManager.TotalZonesBlocked > 0) - { - response = _blockListZoneManager.Query(request); //check in block list zone - if (response is not null) - { - //domain is blocked in block list zone - response.Tag = DnsServerResponseType.Blocked; - return response; - } - } + response = _blockListZoneManager.Query(request); //check in block list zone + if (response is null) + return null; //domain not blocked in block list zone - //domain not blocked in block list zone - return null; + //domain is blocked in block list zone + response.Tag = DnsServerResponseType.Blocked; + return response; } else { @@ -2505,7 +2478,7 @@ namespace DnsServerCore.Dns } else { - inAllowedZone = (_allowedZoneManager.TotalZonesAllowed > 0) && (_allowedZoneManager.Query(request) is not null); + inAllowedZone = _allowedZoneManager.IsAllowed(request) || _blockListZoneManager.IsAllowed(request); if (!inAllowedZone) { //check in blocked zone and block list zone @@ -2538,7 +2511,7 @@ namespace DnsServerCore.Dns DnsDatagram newRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, true, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord((record.RDATA as DnsCNAMERecordData).Domain, request.Question[0].Type, request.Question[0].Class) }); //check allowed zone - inAllowedZone = (_allowedZoneManager.TotalZonesAllowed > 0) && (_allowedZoneManager.Query(newRequest) is not null); + inAllowedZone = _allowedZoneManager.IsAllowed(newRequest) || _blockListZoneManager.IsAllowed(newRequest); if (inAllowedZone) break; //CNAME is in allowed zone @@ -2743,6 +2716,14 @@ namespace DnsServerCore.Dns else dnsCache = _dnsCache; + //check for this-server + if ((conditionalForwarders is not null) && (conditionalForwarders.Count == 1) && (conditionalForwarders[0].RDATA is DnsForwarderRecordData fwd) && fwd.Forwarder.Equals("this-server", StringComparison.OrdinalIgnoreCase)) + { + //resolve directly with DNSSEC validation preference + conditionalForwarders = null; + dnssecValidation = fwd.DnssecValidation; + } + DnsDatagram response; if ((conditionalForwarders is not null) && (conditionalForwarders.Count > 0)) @@ -3414,7 +3395,7 @@ namespace DnsServerCore.Dns return false; //no need to refresh for this query } - private void CachePrefetchSamplingTimerCallback(object state) + private async void CachePrefetchSamplingTimerCallback(object state) { try { @@ -3439,7 +3420,8 @@ namespace DnsServerCore.Dns { reQueryAuthZone = false; - DnsDatagram response = _authZoneManager.Query(new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { eligibleQuerySample })); + DnsDatagram request = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { eligibleQuerySample }); + DnsDatagram response = await AuthoritativeQueryAsync(request, IPENDPOINT_ANY_0, DnsTransportProtocol.Tcp, true, false); if (response is null) { //zone not hosted; do refresh @@ -3469,16 +3451,7 @@ namespace DnsServerCore.Dns case DnsResourceRecordType.FWD: //zone is conditional forwarder refreshQuery = GetCacheRefreshNeededQuery(eligibleQuerySample, cacheRefreshTrigger); - - if ((response.Authority.Count == 1) && (firstAuthority.RDATA as DnsForwarderRecordData).Forwarder.Equals("this-server", StringComparison.OrdinalIgnoreCase)) - { - //do conditional forwarding via "this-server" - } - else - { - //do conditional forwarding - conditionalForwarders = response.Authority; - } + conditionalForwarders = response.Authority; //do conditional forwarding break; } } @@ -3951,8 +3924,8 @@ namespace DnsServerCore.Dns #endregion - udpListener.ReceiveBufferSize = 64 * 1024; - udpListener.SendBufferSize = 64 * 1024; + udpListener.ReceiveBufferSize = 512 * 1024; + udpListener.SendBufferSize = 512 * 1024; udpListener.Bind(localEP); diff --git a/DnsServerCore/Dns/ZoneManagers/AllowedZoneManager.cs b/DnsServerCore/Dns/ZoneManagers/AllowedZoneManager.cs index 34eff79d..7b94a70d 100644 --- a/DnsServerCore/Dns/ZoneManagers/AllowedZoneManager.cs +++ b/DnsServerCore/Dns/ZoneManagers/AllowedZoneManager.cs @@ -176,9 +176,12 @@ namespace DnsServerCore.Dns.ZoneManagers log.Write("DNS Server allowed zone file was saved: " + allowedZoneFile); } - public DnsDatagram Query(DnsDatagram request) + public bool IsAllowed(DnsDatagram request) { - return _zoneManager.Query(request); + if (_zoneManager.TotalZones < 1) + return false; + + return _zoneManager.Query(request) is not null; } #endregion diff --git a/DnsServerCore/Dns/ZoneManagers/BlockListZoneManager.cs b/DnsServerCore/Dns/ZoneManagers/BlockListZoneManager.cs index 0dc0bcfb..9862cca2 100644 --- a/DnsServerCore/Dns/ZoneManagers/BlockListZoneManager.cs +++ b/DnsServerCore/Dns/ZoneManagers/BlockListZoneManager.cs @@ -43,6 +43,8 @@ namespace DnsServerCore.Dns.ZoneManagers readonly List _allowListUrls = new List(); readonly List _blockListUrls = new List(); + + IReadOnlyDictionary _allowListZone = new Dictionary(); IReadOnlyDictionary> _blockListZone = new Dictionary>(); DnsSOARecordData _soaRecord; @@ -109,9 +111,10 @@ namespace DnsServerCore.Dns.ZoneManagers return word; } - private Queue ReadListFile(Uri listUrl, bool isAllowList, Dictionary allowedDomains) + private Queue ReadListFile(Uri listUrl, bool isAllowList, out Queue exceptionDomains) { Queue domains = new Queue(); + exceptionDomains = new Queue(); try { @@ -141,7 +144,7 @@ namespace DnsServerCore.Dns.ZoneManagers if (line.Length == 0) continue; //skip empty line - if (line.StartsWith("#") || line.StartsWith("!")) + if (line.StartsWith('#') || line.StartsWith("!")) continue; //skip comment line if (line.StartsWith("||")) @@ -153,38 +156,35 @@ namespace DnsServerCore.Dns.ZoneManagers domain = line.Substring(2, i - 2); options = line.Substring(i + 1); - if (((options.Length == 0) || (options.StartsWith("$") && (options.Contains("doc") || options.Contains("all")))) && DnsClient.IsDomainNameValid(domain)) - domains.Enqueue(domain); + if (((options.Length == 0) || (options.StartsWith('$') && (options.Contains("doc") || options.Contains("all")))) && DnsClient.IsDomainNameValid(domain)) + domains.Enqueue(domain.ToLower()); } else { domain = line.Substring(2); if (DnsClient.IsDomainNameValid(domain)) - domains.Enqueue(domain); + domains.Enqueue(domain.ToLower()); } } else if (line.StartsWith("@@||")) { - //adblock format - if (!isAllowList) + //adblock format - exception syntax + i = line.IndexOf('^'); + if (i > -1) { - i = line.IndexOf('^'); - if (i > -1) - { - domain = line.Substring(4, i - 4); - options = line.Substring(i + 1); + domain = line.Substring(4, i - 4); + options = line.Substring(i + 1); - if (((options.Length == 0) || (options.StartsWith("$") && (options.Contains("doc") || options.Contains("all")))) && DnsClient.IsDomainNameValid(domain)) - allowedDomains.TryAdd(domain, null); - } - else - { - domain = line.Substring(4); + if (((options.Length == 0) || (options.StartsWith('$') && (options.Contains("doc") || options.Contains("all")))) && DnsClient.IsDomainNameValid(domain)) + exceptionDomains.Enqueue(domain.ToLower()); + } + else + { + domain = line.Substring(4); - if (DnsClient.IsDomainNameValid(domain)) - allowedDomains.TryAdd(domain, null); - } + if (DnsClient.IsDomainNameValid(domain)) + exceptionDomains.Enqueue(domain.ToLower()); } } else @@ -200,7 +200,7 @@ namespace DnsServerCore.Dns.ZoneManagers { secondWord = PopWord(ref line); - if (secondWord.Length == 0) + if ((secondWord.Length == 0) || secondWord.StartsWith('#')) hostname = firstWord; else hostname = secondWord; @@ -267,11 +267,13 @@ namespace DnsServerCore.Dns.ZoneManagers return null; } - private static bool IsZoneAllowed(Dictionary allowedDomains, string domain) + private bool IsZoneAllowed(string domain) { + domain = domain.ToLower(); + do { - if (allowedDomains.TryGetValue(domain, out _)) + if (_allowListZone.TryGetValue(domain, out _)) return true; domain = AuthZoneManager.GetParentZone(domain); @@ -287,37 +289,57 @@ namespace DnsServerCore.Dns.ZoneManagers public void LoadBlockLists() { - //read all allowed domains in dictionary - Dictionary allowedDomains = new Dictionary(); + Dictionary> allowListQueues = new Dictionary>(_allowListUrls.Count); + Dictionary> blockListQueues = new Dictionary>(_blockListUrls.Count); + int totalAllowedDomains = 0; + int totalBlockedDomains = 0; + //read all allow lists in a queue foreach (Uri allowListUrl in _allowListUrls) { - Queue queue = ReadListFile(allowListUrl, true, null); + if (!allowListQueues.ContainsKey(allowListUrl)) + { + Queue allowListQueue = ReadListFile(allowListUrl, true, out Queue blockListQueue); + + totalAllowedDomains += allowListQueue.Count; + allowListQueues.Add(allowListUrl, allowListQueue); + + totalBlockedDomains += blockListQueue.Count; + blockListQueues.Add(allowListUrl, blockListQueue); + } + } + + //read all block lists in a queue + foreach (Uri blockListUrl in _blockListUrls) + { + if (!blockListQueues.ContainsKey(blockListUrl)) + { + Queue blockListQueue = ReadListFile(blockListUrl, false, out Queue allowListQueue); + + totalBlockedDomains += blockListQueue.Count; + blockListQueues.Add(blockListUrl, blockListQueue); + + totalAllowedDomains += allowListQueue.Count; + allowListQueues.Add(blockListUrl, allowListQueue); + } + } + + //load block list zone + Dictionary allowListZone = new Dictionary(totalAllowedDomains); + + foreach (KeyValuePair> allowListQueue in allowListQueues) + { + Queue queue = allowListQueue.Value; while (queue.Count > 0) { string domain = queue.Dequeue(); - allowedDomains.TryAdd(domain, null); + allowListZone.TryAdd(domain, null); } } - //read all block lists in a queue - Dictionary> blockListQueues = new Dictionary>(_blockListUrls.Count); - int totalDomains = 0; - - foreach (Uri blockListUrl in _blockListUrls) - { - if (!blockListQueues.ContainsKey(blockListUrl)) - { - Queue blockListQueue = ReadListFile(blockListUrl, false, allowedDomains); - totalDomains += blockListQueue.Count; - blockListQueues.Add(blockListUrl, blockListQueue); - } - } - - //load block list zone - Dictionary> blockListZone = new Dictionary>(totalDomains); + Dictionary> blockListZone = new Dictionary>(totalBlockedDomains); foreach (KeyValuePair> blockListQueue in blockListQueues) { @@ -327,9 +349,6 @@ namespace DnsServerCore.Dns.ZoneManagers { string domain = queue.Dequeue(); - if (IsZoneAllowed(allowedDomains, domain)) - continue; //domain is in allowed list so skip adding it to block list zone - if (!blockListZone.TryGetValue(domain, out List blockLists)) { blockLists = new List(2); @@ -340,16 +359,16 @@ namespace DnsServerCore.Dns.ZoneManagers } } - //set new blocked zone + //set new allowed and blocked zones + _allowListZone = allowListZone; _blockListZone = blockListZone; - LogManager log = _dnsServer.LogManager; - if (log != null) - log.Write("DNS Server block list zone was loaded successfully."); + _dnsServer.LogManager?.Write("DNS Server block list zone was loaded successfully."); } public void Flush() { + _allowListZone = new Dictionary(); _blockListZone = new Dictionary>(); } @@ -451,8 +470,19 @@ namespace DnsServerCore.Dns.ZoneManagers return downloaded || notModified; } + public bool IsAllowed(DnsDatagram request) + { + if (_allowListZone.Count < 1) + return false; + + return IsZoneAllowed(request.Question[0].Name); + } + public DnsDatagram Query(DnsDatagram request) { + if (_blockListZone.Count < 1) + return null; + DnsQuestionRecord question = request.Question[0]; List blockLists = IsZoneBlocked(question.Name, out string blockedDomain); @@ -572,6 +602,9 @@ namespace DnsServerCore.Dns.ZoneManagers public List BlockListUrls { get { return _blockListUrls; } } + public int TotalZonesAllowed + { get { return _allowListZone.Count; } } + public int TotalZonesBlocked { get { return _blockListZone.Count; } } diff --git a/DnsServerCore/Dns/ZoneManagers/BlockedZoneManager.cs b/DnsServerCore/Dns/ZoneManagers/BlockedZoneManager.cs index 3f6f4695..cfe11d88 100644 --- a/DnsServerCore/Dns/ZoneManagers/BlockedZoneManager.cs +++ b/DnsServerCore/Dns/ZoneManagers/BlockedZoneManager.cs @@ -196,6 +196,9 @@ namespace DnsServerCore.Dns.ZoneManagers public DnsDatagram Query(DnsDatagram request) { + if (_zoneManager.TotalZones < 1) + return null; + return _zoneManager.Query(request); } diff --git a/DnsServerCore/DnsServerCore.csproj b/DnsServerCore/DnsServerCore.csproj index 6e8ebc08..b0c7fe05 100644 --- a/DnsServerCore/DnsServerCore.csproj +++ b/DnsServerCore/DnsServerCore.csproj @@ -12,7 +12,7 @@ DnsServer - 11.0 + 11.0.1 diff --git a/DnsServerCore/DnsWebService.cs b/DnsServerCore/DnsWebService.cs index 98079fef..f1389005 100644 --- a/DnsServerCore/DnsWebService.cs +++ b/DnsServerCore/DnsWebService.cs @@ -203,7 +203,7 @@ namespace DnsServerCore try { _webServiceLocalAddresses = DnsServer.GetValidKestralLocalAddresses(_webServiceLocalAddresses); - await StartWebServiceAsync(); + await StartWebServiceAsync(false); } catch (Exception ex) { @@ -213,7 +213,7 @@ namespace DnsServerCore try { _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any }; - await StartWebServiceAsync(); + await StartWebServiceAsync(false); } catch (Exception ex2) { @@ -221,12 +221,12 @@ namespace DnsServerCore _log.Write("Attempting to start Web Service on loopback (127.0.0.1) fallback address..."); _webServiceLocalAddresses = new IPAddress[] { IPAddress.Loopback }; - await StartWebServiceAsync(); + await StartWebServiceAsync(true); } } } - private async Task StartWebServiceAsync() + private async Task StartWebServiceAsync(bool safeMode) { WebApplicationBuilder builder = WebApplication.CreateBuilder(); @@ -249,7 +249,7 @@ namespace DnsServerCore serverOptions.Listen(webServiceLocalAddress, _webServiceHttpPort); //https - if (_webServiceEnableTls && (_webServiceTlsCertificate is not null)) + if (!safeMode && _webServiceEnableTls && (_webServiceTlsCertificate is not null)) { serverOptions.ConfigureHttpsDefaults(delegate (HttpsConnectionAdapterOptions configureOptions) { @@ -277,7 +277,7 @@ namespace DnsServerCore _webService = builder.Build(); - if (_webServiceHttpToTlsRedirect) + if (_webServiceHttpToTlsRedirect && !safeMode && _webServiceEnableTls && (_webServiceTlsCertificate is not null)) _webService.UseHttpsRedirection(); _webService.UseDefaultFiles(); @@ -300,7 +300,7 @@ namespace DnsServerCore { _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Http", "Web Service was bound successfully."); - if (_webServiceEnableTls && (_webServiceTlsCertificate is not null)) + if (!safeMode && _webServiceEnableTls && (_webServiceTlsCertificate is not null)) _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Https", "Web Service was bound successfully."); } } @@ -312,7 +312,7 @@ namespace DnsServerCore { _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Http", "Web Service failed to bind."); - if (_webServiceEnableTls && (_webServiceTlsCertificate is not null)) + if (!safeMode && _webServiceEnableTls && (_webServiceTlsCertificate is not null)) _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Https", "Web Service failed to bind."); } @@ -832,7 +832,7 @@ namespace DnsServerCore foreach (string strBlockListUrl in strBlockListUrlList) { - if (strBlockListUrl.StartsWith("!")) + if (strBlockListUrl.StartsWith('!')) { Uri allowListUrl = new Uri(strBlockListUrl.Substring(1)); @@ -1288,7 +1288,7 @@ namespace DnsServerCore { string listUrl = bR.ReadShortString(); - if (listUrl.StartsWith("!")) + if (listUrl.StartsWith('!')) _dnsServer.BlockListZoneManager.AllowListUrls.Add(new Uri(listUrl.Substring(1))); else _dnsServer.BlockListZoneManager.BlockListUrls.Add(new Uri(listUrl)); @@ -1710,7 +1710,7 @@ namespace DnsServerCore { string listUrl = bR.ReadShortString(); - if (listUrl.StartsWith("!")) + if (listUrl.StartsWith('!')) _dnsServer.BlockListZoneManager.AllowListUrls.Add(new Uri(listUrl.Substring(1))); else _dnsServer.BlockListZoneManager.BlockListUrls.Add(new Uri(listUrl)); diff --git a/DnsServerCore/WebServiceDashboardApi.cs b/DnsServerCore/WebServiceDashboardApi.cs index f15ab21d..4c9c22ee 100644 --- a/DnsServerCore/WebServiceDashboardApi.cs +++ b/DnsServerCore/WebServiceDashboardApi.cs @@ -237,6 +237,7 @@ namespace DnsServerCore jsonWriter.WriteNumber("cachedEntries", _dnsWebService.DnsServer.CacheZoneManager.TotalEntries); jsonWriter.WriteNumber("allowedZones", _dnsWebService.DnsServer.AllowedZoneManager.TotalZonesAllowed); jsonWriter.WriteNumber("blockedZones", _dnsWebService.DnsServer.BlockedZoneManager.TotalZonesBlocked); + jsonWriter.WriteNumber("allowListZones", _dnsWebService.DnsServer.BlockListZoneManager.TotalZonesAllowed); jsonWriter.WriteNumber("blockListZones", _dnsWebService.DnsServer.BlockListZoneManager.TotalZonesBlocked); jsonWriter.WriteEndObject(); diff --git a/DnsServerCore/WebServiceSettingsApi.cs b/DnsServerCore/WebServiceSettingsApi.cs index 22ff70fb..cebbc06c 100644 --- a/DnsServerCore/WebServiceSettingsApi.cs +++ b/DnsServerCore/WebServiceSettingsApi.cs @@ -1033,7 +1033,7 @@ namespace DnsServerCore { foreach (string strBlockListUrl in blockListUrlList) { - if (strBlockListUrl.StartsWith("!")) + if (strBlockListUrl.StartsWith('!')) { string strAllowListUrl = strBlockListUrl.Substring(1); @@ -1062,7 +1062,7 @@ namespace DnsServerCore foreach (string strBlockListUrl in blockListUrlList) { - if (strBlockListUrl.StartsWith("!")) + if (strBlockListUrl.StartsWith('!')) { Uri allowListUrl = new Uri(strBlockListUrl.Substring(1)); diff --git a/DnsServerCore/www/css/main.css b/DnsServerCore/www/css/main.css index ddcfc970..14451dcd 100644 --- a/DnsServerCore/www/css/main.css +++ b/DnsServerCore/www/css/main.css @@ -289,16 +289,16 @@ th a { } .zone-stats-panel .stats-item { - width: 19.25%; + width: 16%; float: left; padding: 6px 4px; - margin-right: 0.75%; + margin-right: 0.65%; background-color: rgba(51, 122, 183, 0.7); color: #ffffff; } .zone-stats-panel .stats-item .number { - font-size: 15px; + font-size: 14px; font-weight: bold; padding: 6px 0; } diff --git a/DnsServerCore/www/index.html b/DnsServerCore/www/index.html index 596c5c0d..e7ad3453 100644 --- a/DnsServerCore/www/index.html +++ b/DnsServerCore/www/index.html @@ -223,27 +223,32 @@
10
-
Hosted Zones
+
Zones
10
-
Cached Entries
+
Cache
10
-
Allowed Zones
+
Allowed
10
-
Blocked Zones
+
Blocked
+
+ +
+
10
+
Allow List
10
-
Block List Zones
+
Block List
@@ -935,7 +940,7 @@
DNS Server will validate all responses from name servers or forwarders when this option is enabled.
@@ -1167,6 +1172,8 @@

Use the following openssl command to convert your TLS certificate that is in PEM format to PKCS #12 certificate (.pfx) format:

openssl pkcs12 -export -out "example.com.pfx" -inkey "privkey.pem" -in "cert.pem" -certfile "chain.pem"
+ +
Help: Configuring DNS-over-QUIC and HTTPS/3 For Technitium DNS Server
@@ -1260,7 +1267,7 @@

Note! These optional DNS server protocol changes will be automatically applied and so you do not need to manually restart the main service. The DNS-over-TLS, DNS-over-QUIC, and DNS-over-HTTPS protocols will be enabled only when a TLS certificate is configured.

These optional DNS server protocols are used to host these as a service. You do not need to enable these optional protocols to use them with Forwarders or Conditional Forwarder Zones.

-

For DNS-over-HTTP, use http://localhost:8053/dns-query with a TLS terminating reverse proxy like nginx. For DNS-over-TLS, use tls-certificate-domain:853, for DNS-over-QUIC, use tls-certificate-domain:853, and for DNS-over-HTTPS use https://tls-certificate-domain/dns-query to configure supported DNS clients.

+

For DNS-over-HTTP, use http://localhost:8053/dns-query with a TLS terminating reverse proxy like nginx. For DNS-over-TLS, use tls-certificate-domain:853, for DNS-over-QUIC, use tls-certificate-domain:853, and for DNS-over-HTTPS use https://tls-certificate-domain/dns-query to configure supported DNS clients.

When using a reverse proxy with the DNS-over-HTTP service, you need to add X-Real-IP header to the proxy request with the IP address of the client to allow the DNS server to know the real IP address of the client originating the request. For example, if you are using nginx as the reverse proxy, you can add proxy_set_header X-Real-IP $remote_addr; to make it work.

DNS-over-QUIC protocol support is not available on all platforms. On Windows, it is available only on Windows 11 (build 22000 or later) and Windows Server 2022. On Linux, it requires libmsquic and openssl v1.1.1 to be installed.

Use the following openssl command to convert your TLS certificate that is in PEM format to PKCS #12 certificate (.pfx) format:

@@ -1268,6 +1275,7 @@
Help: How To Host Your Own DNS-over-HTTPS And DNS-over-TLS Services
+
Help: Configuring DNS-over-QUIC and HTTPS/3 For Technitium DNS Server
@@ -1446,7 +1454,7 @@ (default 10000; set 0 to disable) -
The maximum number of entries that the cache can store. A relevant value should be configured by monitoring the Cached Entries value on Dashboard and the server's memory usage to limit the amount of RAM used by the DNS server. A cache entry is a complete Resource Record Set (RR Set) which is a group of records with the same type for a given domain name. When a value is configured, the DNS server will trigger a clean up operation every few minutes and remove least recently used entries to maintain the maximum allowed entries in cache.
+
The maximum number of entries that the cache can store. A relevant value should be configured by monitoring the Cache entries value on Dashboard and the server's memory usage to limit the amount of RAM used by the DNS server. A cache entry is a complete Resource Record Set (RR Set) which is a group of records with the same type for a given domain name. When a value is configured, the DNS server will trigger a clean up operation every few minutes and remove least recently used entries to maintain the maximum allowed entries in cache.
@@ -1630,7 +1638,7 @@

Enter block list URL one below another in the above text field or use the Quick Add list to add known block list URLs.

-

Add ! character at the start of an URL to make it an allow list URL. Domain names in such an allow list URL are prevented from being added to the block list zone.

+

Add ! character at the start of an URL to make it an allow list URL. This option must not be used with allow lists that use Adblock plus format.

@@ -1847,6 +1855,7 @@
Forwarders are DNS servers which this DNS Server should use to resolve recursive queries. If no forwarders are configured then this DNS server will use preconfigured ROOT SERVERS to perform recursive resolution.
Help: Configuring DNS Server For Privacy & Security
+
Help: Configuring DNS-over-QUIC and HTTPS/3 For Technitium DNS Server
diff --git a/DnsServerCore/www/js/dhcp.js b/DnsServerCore/www/js/dhcp.js index a7313b45..45046a7c 100644 --- a/DnsServerCore/www/js/dhcp.js +++ b/DnsServerCore/www/js/dhcp.js @@ -1,6 +1,6 @@ /* Technitium DNS Server -Copyright (C) 2022 Shreyas Zare (shreyas@technitium.com) +Copyright (C) 2023 Shreyas Zare (shreyas@technitium.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -516,11 +516,14 @@ function saveDhcpScope() { var btn = $("#btnSaveDhcpScope").button('loading'); HTTPRequest({ - url: "/api/dhcp/scopes/set?token=" + sessionData.token + "&name=" + encodeURIComponent(name) + (newName == null ? "" : "&newName=" + encodeURIComponent(newName)) + "&startingAddress=" + encodeURIComponent(startingAddress) + "&endingAddress=" + encodeURIComponent(endingAddress) + "&subnetMask=" + encodeURIComponent(subnetMask) + + url: "/api/dhcp/scopes/set", + method: "POST", + data: "token=" + sessionData.token + "&name=" + encodeURIComponent(name) + (newName == null ? "" : "&newName=" + encodeURIComponent(newName)) + "&startingAddress=" + encodeURIComponent(startingAddress) + "&endingAddress=" + encodeURIComponent(endingAddress) + "&subnetMask=" + encodeURIComponent(subnetMask) + "&leaseTimeDays=" + leaseTimeDays + "&leaseTimeHours=" + leaseTimeHours + "&leaseTimeMinutes=" + leaseTimeMinutes + "&offerDelayTime=" + offerDelayTime + "&pingCheckEnabled=" + pingCheckEnabled + "&pingCheckTimeout=" + pingCheckTimeout + "&pingCheckRetries=" + pingCheckRetries + "&domainName=" + encodeURIComponent(domainName) + "&domainSearchList=" + encodeURIComponent(domainSearchList) + "&dnsUpdates=" + dnsUpdates + "&dnsTtl=" + dnsTtl + "&serverAddress=" + encodeURIComponent(serverAddress) + "&serverHostName=" + encodeURIComponent(serverHostName) + "&bootFileName=" + encodeURIComponent(bootFileName) + "&routerAddress=" + encodeURIComponent(routerAddress) + "&useThisDnsServer=" + useThisDnsServer + (useThisDnsServer ? "" : "&dnsServers=" + encodeURIComponent(dnsServers)) + "&winsServers=" + encodeURIComponent(winsServers) + "&ntpServers=" + encodeURIComponent(ntpServers) + "&ntpServerDomainNames=" + encodeURIComponent(ntpServerDomainNames) + "&staticRoutes=" + encodeURIComponent(staticRoutes) + "&vendorInfo=" + encodeURIComponent(vendorInfo) + "&capwapAcIpAddresses=" + encodeURIComponent(capwapAcIpAddresses) + "&tftpServerAddresses=" + encodeURIComponent(tftpServerAddresses) + "&genericOptions=" + encodeURIComponent(genericOptions) + "&exclusions=" + encodeURIComponent(exclusions) + "&reservedLeases=" + encodeURIComponent(reservedLeases) + "&allowOnlyReservedLeases=" + allowOnlyReservedLeases + "&blockLocallyAdministeredMacAddresses=" + blockLocallyAdministeredMacAddresses, + processData: false, success: function (responseJSON) { refreshDhcpScopes(); btn.button('reset'); diff --git a/DnsServerCore/www/js/main.js b/DnsServerCore/www/js/main.js index 6523349f..57f31b3f 100644 --- a/DnsServerCore/www/js/main.js +++ b/DnsServerCore/www/js/main.js @@ -942,9 +942,10 @@ function loadDnsSettings() { else $("#txtDnsTlsCertificatePassword").val(responseJSON.response.dnsTlsCertificatePassword); - $("#lblDoHHost").text(window.location.hostname + ":" + responseJSON.response.dnsOverHttpPort); + $("#lblDoHHost").text(window.location.hostname + (responseJSON.response.dnsOverHttpPort == 80 ? "" : ":" + responseJSON.response.dnsOverHttpPort)); $("#lblDoTHost").text("tls-certificate-domain:" + responseJSON.response.dnsOverTlsPort); $("#lblDoQHost").text("tls-certificate-domain:" + responseJSON.response.dnsOverQuicPort); + $("#lblDoHsHost").text("tls-certificate-domain" + (responseJSON.response.dnsOverHttpsPort == 443 ? "" : ":" + responseJSON.response.dnsOverHttpsPort)); //tsig $("#tableTsigKeys").html(""); @@ -1651,9 +1652,10 @@ function saveDnsSettings() { $("#txtWebServiceTlsCertificatePassword").prop("disabled", !responseJSON.response.webServiceEnableTls); //optional protocols - $("#lblDoHHost").text(window.location.hostname + ":" + responseJSON.response.dnsOverHttpPort); + $("#lblDoHHost").text(window.location.hostname + (responseJSON.response.dnsOverHttpPort == 80 ? "" : ":" + responseJSON.response.dnsOverHttpPort)); $("#lblDoTHost").text("tls-certificate-domain:" + responseJSON.response.dnsOverTlsPort); $("#lblDoQHost").text("tls-certificate-domain:" + responseJSON.response.dnsOverQuicPort); + $("#lblDoHsHost").text("tls-certificate-domain" + (responseJSON.response.dnsOverHttpsPort == 443 ? "" : ":" + responseJSON.response.dnsOverHttpsPort)); //reload tsig keys $("#tableTsigKeys").html(""); @@ -1992,6 +1994,7 @@ function refreshDashboard(hideLoader) { $("#divDashboardStatsCachedEntries").text(responseJSON.response.stats.cachedEntries.toLocaleString()); $("#divDashboardStatsAllowedZones").text(responseJSON.response.stats.allowedZones.toLocaleString()); $("#divDashboardStatsBlockedZones").text(responseJSON.response.stats.blockedZones.toLocaleString()); + $("#divDashboardStatsAllowListZones").text(responseJSON.response.stats.allowListZones.toLocaleString()); $("#divDashboardStatsBlockListZones").text(responseJSON.response.stats.blockListZones.toLocaleString()); if (responseJSON.response.stats.totalQueries > 0) { diff --git a/DnsServerWindowsService/DnsServerWindowsService.csproj b/DnsServerWindowsService/DnsServerWindowsService.csproj index c62ea5c5..c894b3f6 100644 --- a/DnsServerWindowsService/DnsServerWindowsService.csproj +++ b/DnsServerWindowsService/DnsServerWindowsService.csproj @@ -8,7 +8,7 @@ DnsServerWindowsService DnsService logo2.ico - 11.0 + 11.0.1 Shreyas Zare Technitium Technitium DNS Server diff --git a/DnsServerWindowsSetup/DnsServerSetup.iss b/DnsServerWindowsSetup/DnsServerSetup.iss index b4115872..aa151a11 100644 --- a/DnsServerWindowsSetup/DnsServerSetup.iss +++ b/DnsServerWindowsSetup/DnsServerSetup.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "Technitium DNS Server" -#define MyAppVersion "11.0" +#define MyAppVersion "11.0.1" #define MyAppPublisher "Technitium" #define MyAppURL "https://technitium.com/dns/" #define MyAppExeName "DnsServerSystemTrayApp.exe" diff --git a/Dockerfile b/Dockerfile index 59d7695c..6f6ba4dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,14 @@ LABEL email="support@technitium.com" LABEL project_url="https://technitium.com/dns/" LABEL github_url="https://github.com/TechnitiumSoftware/DnsServer" -WORKDIR /etc/dns/ +WORKDIR /opt/technitium/dns/ + +RUN apt update; apt install curl -y; \ +curl https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb --output packages-microsoft-prod.deb; \ +dpkg -i packages-microsoft-prod.deb; \ +rm packages-microsoft-prod.deb + +RUN apt update; apt install libmsquic -y; apt clean -y; COPY ./DnsServerApp/bin/Release/publish/ . @@ -21,6 +28,9 @@ EXPOSE 80/tcp EXPOSE 8053/tcp EXPOSE 67/udp -VOLUME ["/etc/dns/config"] +VOLUME ["/etc/dns"] -CMD ["/usr/bin/dotnet", "/etc/dns/DnsServerApp.dll"] +STOPSIGNAL SIGINT + +ENTRYPOINT ["/usr/bin/dotnet", "/opt/technitium/dns/DnsServerApp.dll"] +CMD ["/etc/dns"] diff --git a/docker-compose.yml b/docker-compose.yml index 036cf532..378a488d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,7 +34,7 @@ services: # - DNS_SERVER_FORWARDER_PROTOCOL=Tcp #Forwarder protocol options: Udp, Tcp, Tls, Https, HttpsJson. # - DNS_SERVER_LOG_USING_LOCAL_TIME=true #Enable this option to use local time instead of UTC for logging. volumes: - - config:/etc/dns/config + - config:/etc/dns restart: unless-stopped sysctls: - net.ipv4.ip_local_port_range=1024 65000