DnsWebService.cs 96 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2023 Shreyas Zare (shreyas@technitium.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using DnsServerCore.Auth;
  16. using DnsServerCore.Dhcp;
  17. using DnsServerCore.Dns;
  18. using DnsServerCore.Dns.ZoneManagers;
  19. using DnsServerCore.Dns.Zones;
  20. using Microsoft.AspNetCore.Builder;
  21. using Microsoft.AspNetCore.Connections;
  22. using Microsoft.AspNetCore.Diagnostics;
  23. using Microsoft.AspNetCore.Hosting;
  24. using Microsoft.AspNetCore.Http;
  25. using Microsoft.AspNetCore.Server.Kestrel.Core;
  26. using Microsoft.AspNetCore.Server.Kestrel.Https;
  27. using Microsoft.AspNetCore.StaticFiles;
  28. using Microsoft.Extensions.FileProviders;
  29. using Microsoft.Extensions.Logging;
  30. using System;
  31. using System.Collections.Generic;
  32. using System.IO;
  33. using System.Net;
  34. using System.Net.Quic;
  35. using System.Net.Sockets;
  36. using System.Reflection;
  37. using System.Security.Cryptography;
  38. using System.Security.Cryptography.X509Certificates;
  39. using System.Text;
  40. using System.Text.Json;
  41. using System.Threading;
  42. using System.Threading.Tasks;
  43. using TechnitiumLibrary;
  44. using TechnitiumLibrary.IO;
  45. using TechnitiumLibrary.Net;
  46. using TechnitiumLibrary.Net.Dns;
  47. using TechnitiumLibrary.Net.Dns.ResourceRecords;
  48. using TechnitiumLibrary.Net.Proxy;
  49. namespace DnsServerCore
  50. {
  51. public sealed class DnsWebService : IAsyncDisposable, IDisposable
  52. {
  53. #region variables
  54. internal readonly Version _currentVersion;
  55. readonly string _appFolder;
  56. internal readonly string _configFolder;
  57. internal readonly LogManager _log;
  58. internal readonly AuthManager _authManager;
  59. readonly WebServiceApi _api;
  60. readonly WebServiceDashboardApi _dashboardApi;
  61. internal readonly WebServiceZonesApi _zonesApi;
  62. readonly WebServiceOtherZonesApi _otherZonesApi;
  63. internal readonly WebServiceAppsApi _appsApi;
  64. readonly WebServiceSettingsApi _settingsApi;
  65. readonly WebServiceDhcpApi _dhcpApi;
  66. readonly WebServiceAuthApi _authApi;
  67. readonly WebServiceLogsApi _logsApi;
  68. WebApplication _webService;
  69. X509Certificate2 _webServiceTlsCertificate;
  70. DnsServer _dnsServer;
  71. DhcpServer _dhcpServer;
  72. //web service
  73. internal IReadOnlyList<IPAddress> _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any, IPAddress.IPv6Any };
  74. internal int _webServiceHttpPort = 5380;
  75. internal int _webServiceTlsPort = 53443;
  76. internal bool _webServiceEnableTls;
  77. internal bool _webServiceHttpToTlsRedirect;
  78. internal bool _webServiceUseSelfSignedTlsCertificate;
  79. internal string _webServiceTlsCertificatePath;
  80. internal string _webServiceTlsCertificatePassword;
  81. DateTime _webServiceTlsCertificateLastModifiedOn;
  82. //optional protocols
  83. internal string _dnsTlsCertificatePath;
  84. internal string _dnsTlsCertificatePassword;
  85. DateTime _dnsTlsCertificateLastModifiedOn;
  86. //cache
  87. internal bool _saveCache = true;
  88. Timer _tlsCertificateUpdateTimer;
  89. const int TLS_CERTIFICATE_UPDATE_TIMER_INITIAL_INTERVAL = 60000;
  90. const int TLS_CERTIFICATE_UPDATE_TIMER_INTERVAL = 60000;
  91. List<string> _configDisabledZones;
  92. #endregion
  93. #region constructor
  94. public DnsWebService(string configFolder = null, Uri updateCheckUri = null, Uri appStoreUri = null)
  95. {
  96. Assembly assembly = Assembly.GetExecutingAssembly();
  97. _currentVersion = assembly.GetName().Version;
  98. _appFolder = Path.GetDirectoryName(assembly.Location);
  99. if (configFolder is null)
  100. _configFolder = Path.Combine(_appFolder, "config");
  101. else
  102. _configFolder = configFolder;
  103. Directory.CreateDirectory(_configFolder);
  104. Directory.CreateDirectory(Path.Combine(_configFolder, "blocklists"));
  105. _log = new LogManager(_configFolder);
  106. _authManager = new AuthManager(_configFolder, _log);
  107. _api = new WebServiceApi(this, updateCheckUri);
  108. _dashboardApi = new WebServiceDashboardApi(this);
  109. _zonesApi = new WebServiceZonesApi(this);
  110. _otherZonesApi = new WebServiceOtherZonesApi(this);
  111. _appsApi = new WebServiceAppsApi(this, appStoreUri);
  112. _settingsApi = new WebServiceSettingsApi(this);
  113. _dhcpApi = new WebServiceDhcpApi(this);
  114. _authApi = new WebServiceAuthApi(this);
  115. _logsApi = new WebServiceLogsApi(this);
  116. }
  117. #endregion
  118. #region IDisposable
  119. bool _disposed;
  120. public async ValueTask DisposeAsync()
  121. {
  122. if (_disposed)
  123. return;
  124. await StopAsync();
  125. if (_appsApi is not null)
  126. _appsApi.Dispose();
  127. if (_settingsApi is not null)
  128. _settingsApi.Dispose();
  129. if (_authManager is not null)
  130. _authManager.Dispose();
  131. if (_log is not null)
  132. _log.Dispose();
  133. _disposed = true;
  134. }
  135. public void Dispose()
  136. {
  137. DisposeAsync().Sync();
  138. }
  139. #endregion
  140. #region server version
  141. internal string GetServerVersion()
  142. {
  143. return GetCleanVersion(_currentVersion);
  144. }
  145. internal static string GetCleanVersion(Version version)
  146. {
  147. string strVersion = version.Major + "." + version.Minor;
  148. if (version.Build > 0)
  149. strVersion += "." + version.Build;
  150. if (version.Revision > 0)
  151. strVersion += "." + version.Revision;
  152. return strVersion;
  153. }
  154. #endregion
  155. #region web service
  156. internal async Task TryStartWebServiceAsync()
  157. {
  158. try
  159. {
  160. _webServiceLocalAddresses = DnsServer.GetValidKestralLocalAddresses(_webServiceLocalAddresses);
  161. await StartWebServiceAsync(false);
  162. }
  163. catch (Exception ex)
  164. {
  165. _log.Write("Web Service failed to start: " + ex.ToString());
  166. _log.Write("Attempting to start Web Service on ANY (0.0.0.0) fallback address...");
  167. try
  168. {
  169. _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any };
  170. await StartWebServiceAsync(false);
  171. }
  172. catch (Exception ex2)
  173. {
  174. _log.Write("Web Service failed to start: " + ex2.ToString());
  175. _log.Write("Attempting to start Web Service on loopback (127.0.0.1) fallback address...");
  176. _webServiceLocalAddresses = new IPAddress[] { IPAddress.Loopback };
  177. await StartWebServiceAsync(true);
  178. }
  179. }
  180. }
  181. private async Task StartWebServiceAsync(bool safeMode)
  182. {
  183. WebApplicationBuilder builder = WebApplication.CreateBuilder();
  184. builder.Environment.ContentRootFileProvider = new PhysicalFileProvider(_appFolder)
  185. {
  186. UseActivePolling = true,
  187. UsePollingFileWatcher = true
  188. };
  189. builder.Environment.WebRootFileProvider = new PhysicalFileProvider(Path.Combine(_appFolder, "www"))
  190. {
  191. UseActivePolling = true,
  192. UsePollingFileWatcher = true
  193. };
  194. builder.WebHost.ConfigureKestrel(delegate (WebHostBuilderContext context, KestrelServerOptions serverOptions)
  195. {
  196. //http
  197. foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
  198. serverOptions.Listen(webServiceLocalAddress, _webServiceHttpPort);
  199. //https
  200. if (!safeMode && _webServiceEnableTls && (_webServiceTlsCertificate is not null))
  201. {
  202. serverOptions.ConfigureHttpsDefaults(delegate (HttpsConnectionAdapterOptions configureOptions)
  203. {
  204. configureOptions.ServerCertificateSelector = delegate (ConnectionContext context, string dnsName)
  205. {
  206. return _webServiceTlsCertificate;
  207. };
  208. });
  209. foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
  210. {
  211. serverOptions.Listen(webServiceLocalAddress, _webServiceTlsPort, delegate (ListenOptions listenOptions)
  212. {
  213. listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
  214. listenOptions.UseHttps();
  215. });
  216. }
  217. }
  218. serverOptions.AddServerHeader = false;
  219. serverOptions.Limits.MaxRequestBodySize = null;
  220. });
  221. builder.Logging.ClearProviders();
  222. _webService = builder.Build();
  223. if (_webServiceHttpToTlsRedirect && !safeMode && _webServiceEnableTls && (_webServiceTlsCertificate is not null))
  224. _webService.UseHttpsRedirection();
  225. _webService.UseDefaultFiles();
  226. _webService.UseStaticFiles(new StaticFileOptions()
  227. {
  228. OnPrepareResponse = delegate (StaticFileResponseContext ctx)
  229. {
  230. ctx.Context.Response.Headers.Add("X-Robots-Tag", "noindex, nofollow");
  231. ctx.Context.Response.Headers.Add("Cache-Control", "private, max-age=300");
  232. },
  233. ServeUnknownFileTypes = true
  234. });
  235. ConfigureWebServiceRoutes();
  236. try
  237. {
  238. await _webService.StartAsync();
  239. foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
  240. {
  241. _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Http", "Web Service was bound successfully.");
  242. if (!safeMode && _webServiceEnableTls && (_webServiceTlsCertificate is not null))
  243. _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Https", "Web Service was bound successfully.");
  244. }
  245. }
  246. catch
  247. {
  248. await StopWebServiceAsync();
  249. foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
  250. {
  251. _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Http", "Web Service failed to bind.");
  252. if (!safeMode && _webServiceEnableTls && (_webServiceTlsCertificate is not null))
  253. _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Https", "Web Service failed to bind.");
  254. }
  255. throw;
  256. }
  257. }
  258. internal async Task StopWebServiceAsync()
  259. {
  260. if (_webService is not null)
  261. {
  262. await _webService.DisposeAsync();
  263. _webService = null;
  264. }
  265. }
  266. private void ConfigureWebServiceRoutes()
  267. {
  268. _webService.UseExceptionHandler(WebServiceExceptionHandler);
  269. _webService.Use(WebServiceApiMiddleware);
  270. _webService.UseRouting();
  271. //user auth
  272. _webService.MapGetAndPost("/api/user/login", delegate (HttpContext context) { return _authApi.LoginAsync(context, UserSessionType.Standard); });
  273. _webService.MapGetAndPost("/api/user/createToken", delegate (HttpContext context) { return _authApi.LoginAsync(context, UserSessionType.ApiToken); });
  274. _webService.MapGetAndPost("/api/user/logout", _authApi.Logout);
  275. //user
  276. _webService.MapGetAndPost("/api/user/session/get", _authApi.GetCurrentSessionDetails);
  277. _webService.MapGetAndPost("/api/user/session/delete", delegate (HttpContext context) { _authApi.DeleteSession(context, false); });
  278. _webService.MapGetAndPost("/api/user/changePassword", _authApi.ChangePassword);
  279. _webService.MapGetAndPost("/api/user/profile/get", _authApi.GetProfile);
  280. _webService.MapGetAndPost("/api/user/profile/set", _authApi.SetProfile);
  281. _webService.MapGetAndPost("/api/user/checkForUpdate", _api.CheckForUpdateAsync);
  282. //dashboard
  283. _webService.MapGetAndPost("/api/dashboard/stats/get", _dashboardApi.GetStats);
  284. _webService.MapGetAndPost("/api/dashboard/stats/getTop", _dashboardApi.GetTopStats);
  285. _webService.MapGetAndPost("/api/dashboard/stats/deleteAll", _logsApi.DeleteAllStats);
  286. //zones
  287. _webService.MapGetAndPost("/api/zones/list", _zonesApi.ListZones);
  288. _webService.MapGetAndPost("/api/zones/create", _zonesApi.CreateZoneAsync);
  289. _webService.MapGetAndPost("/api/zones/convert", _zonesApi.ConvertZone);
  290. _webService.MapGetAndPost("/api/zones/enable", _zonesApi.EnableZone);
  291. _webService.MapGetAndPost("/api/zones/disable", _zonesApi.DisableZone);
  292. _webService.MapGetAndPost("/api/zones/delete", _zonesApi.DeleteZone);
  293. _webService.MapGetAndPost("/api/zones/resync", _zonesApi.ResyncZone);
  294. _webService.MapGetAndPost("/api/zones/options/get", _zonesApi.GetZoneOptions);
  295. _webService.MapGetAndPost("/api/zones/options/set", _zonesApi.SetZoneOptions);
  296. _webService.MapGetAndPost("/api/zones/permissions/get", delegate (HttpContext context) { _authApi.GetPermissionDetails(context, PermissionSection.Zones); });
  297. _webService.MapGetAndPost("/api/zones/permissions/set", delegate (HttpContext context) { _authApi.SetPermissionsDetails(context, PermissionSection.Zones); });
  298. _webService.MapGetAndPost("/api/zones/dnssec/sign", _zonesApi.SignPrimaryZone);
  299. _webService.MapGetAndPost("/api/zones/dnssec/unsign", _zonesApi.UnsignPrimaryZone);
  300. _webService.MapGetAndPost("/api/zones/dnssec/properties/get", _zonesApi.GetPrimaryZoneDnssecProperties);
  301. _webService.MapGetAndPost("/api/zones/dnssec/properties/convertToNSEC", _zonesApi.ConvertPrimaryZoneToNSEC);
  302. _webService.MapGetAndPost("/api/zones/dnssec/properties/convertToNSEC3", _zonesApi.ConvertPrimaryZoneToNSEC3);
  303. _webService.MapGetAndPost("/api/zones/dnssec/properties/updateNSEC3Params", _zonesApi.UpdatePrimaryZoneNSEC3Parameters);
  304. _webService.MapGetAndPost("/api/zones/dnssec/properties/updateDnsKeyTtl", _zonesApi.UpdatePrimaryZoneDnssecDnsKeyTtl);
  305. _webService.MapGetAndPost("/api/zones/dnssec/properties/generatePrivateKey", _zonesApi.GenerateAndAddPrimaryZoneDnssecPrivateKey);
  306. _webService.MapGetAndPost("/api/zones/dnssec/properties/updatePrivateKey", _zonesApi.UpdatePrimaryZoneDnssecPrivateKey);
  307. _webService.MapGetAndPost("/api/zones/dnssec/properties/deletePrivateKey", _zonesApi.DeletePrimaryZoneDnssecPrivateKey);
  308. _webService.MapGetAndPost("/api/zones/dnssec/properties/publishAllPrivateKeys", _zonesApi.PublishAllGeneratedPrimaryZoneDnssecPrivateKeys);
  309. _webService.MapGetAndPost("/api/zones/dnssec/properties/rolloverDnsKey", _zonesApi.RolloverPrimaryZoneDnsKey);
  310. _webService.MapGetAndPost("/api/zones/dnssec/properties/retireDnsKey", _zonesApi.RetirePrimaryZoneDnsKey);
  311. _webService.MapGetAndPost("/api/zones/records/add", _zonesApi.AddRecord);
  312. _webService.MapGetAndPost("/api/zones/records/get", _zonesApi.GetRecords);
  313. _webService.MapGetAndPost("/api/zones/records/update", _zonesApi.UpdateRecord);
  314. _webService.MapGetAndPost("/api/zones/records/delete", _zonesApi.DeleteRecord);
  315. //cache
  316. _webService.MapGetAndPost("/api/cache/list", _otherZonesApi.ListCachedZones);
  317. _webService.MapGetAndPost("/api/cache/delete", _otherZonesApi.DeleteCachedZone);
  318. _webService.MapGetAndPost("/api/cache/flush", _otherZonesApi.FlushCache);
  319. //allowed
  320. _webService.MapGetAndPost("/api/allowed/list", _otherZonesApi.ListAllowedZones);
  321. _webService.MapGetAndPost("/api/allowed/add", _otherZonesApi.AllowZone);
  322. _webService.MapGetAndPost("/api/allowed/delete", _otherZonesApi.DeleteAllowedZone);
  323. _webService.MapGetAndPost("/api/allowed/flush", _otherZonesApi.FlushAllowedZone);
  324. _webService.MapGetAndPost("/api/allowed/import", _otherZonesApi.ImportAllowedZones);
  325. _webService.MapGetAndPost("/api/allowed/export", _otherZonesApi.ExportAllowedZonesAsync);
  326. //blocked
  327. _webService.MapGetAndPost("/api/blocked/list", _otherZonesApi.ListBlockedZones);
  328. _webService.MapGetAndPost("/api/blocked/add", _otherZonesApi.BlockZone);
  329. _webService.MapGetAndPost("/api/blocked/delete", _otherZonesApi.DeleteBlockedZone);
  330. _webService.MapGetAndPost("/api/blocked/flush", _otherZonesApi.FlushBlockedZone);
  331. _webService.MapGetAndPost("/api/blocked/import", _otherZonesApi.ImportBlockedZones);
  332. _webService.MapGetAndPost("/api/blocked/export", _otherZonesApi.ExportBlockedZonesAsync);
  333. //apps
  334. _webService.MapGetAndPost("/api/apps/list", _appsApi.ListInstalledAppsAsync);
  335. _webService.MapGetAndPost("/api/apps/listStoreApps", _appsApi.ListStoreApps);
  336. _webService.MapGetAndPost("/api/apps/downloadAndInstall", _appsApi.DownloadAndInstallAppAsync);
  337. _webService.MapGetAndPost("/api/apps/downloadAndUpdate", _appsApi.DownloadAndUpdateAppAsync);
  338. _webService.MapPost("/api/apps/install", _appsApi.InstallAppAsync);
  339. _webService.MapPost("/api/apps/update", _appsApi.UpdateAppAsync);
  340. _webService.MapGetAndPost("/api/apps/uninstall", _appsApi.UninstallApp);
  341. _webService.MapGetAndPost("/api/apps/config/get", _appsApi.GetAppConfigAsync);
  342. _webService.MapGetAndPost("/api/apps/config/set", _appsApi.SetAppConfigAsync);
  343. //dns client
  344. _webService.MapGetAndPost("/api/dnsClient/resolve", _api.ResolveQueryAsync);
  345. //settings
  346. _webService.MapGetAndPost("/api/settings/get", _settingsApi.GetDnsSettings);
  347. _webService.MapGetAndPost("/api/settings/set", _settingsApi.SetDnsSettings);
  348. _webService.MapGetAndPost("/api/settings/getTsigKeyNames", _settingsApi.GetTsigKeyNames);
  349. _webService.MapGetAndPost("/api/settings/forceUpdateBlockLists", _settingsApi.ForceUpdateBlockLists);
  350. _webService.MapGetAndPost("/api/settings/temporaryDisableBlocking", _settingsApi.TemporaryDisableBlocking);
  351. _webService.MapGetAndPost("/api/settings/backup", _settingsApi.BackupSettingsAsync);
  352. _webService.MapPost("/api/settings/restore", _settingsApi.RestoreSettingsAsync);
  353. //dhcp
  354. _webService.MapGetAndPost("/api/dhcp/leases/list", _dhcpApi.ListDhcpLeases);
  355. _webService.MapGetAndPost("/api/dhcp/leases/remove", _dhcpApi.RemoveDhcpLease);
  356. _webService.MapGetAndPost("/api/dhcp/leases/convertToReserved", _dhcpApi.ConvertToReservedLease);
  357. _webService.MapGetAndPost("/api/dhcp/leases/convertToDynamic", _dhcpApi.ConvertToDynamicLease);
  358. _webService.MapGetAndPost("/api/dhcp/scopes/list", _dhcpApi.ListDhcpScopes);
  359. _webService.MapGetAndPost("/api/dhcp/scopes/get", _dhcpApi.GetDhcpScope);
  360. _webService.MapGetAndPost("/api/dhcp/scopes/set", _dhcpApi.SetDhcpScopeAsync);
  361. _webService.MapGetAndPost("/api/dhcp/scopes/addReservedLease", _dhcpApi.AddReservedLease);
  362. _webService.MapGetAndPost("/api/dhcp/scopes/removeReservedLease", _dhcpApi.RemoveReservedLease);
  363. _webService.MapGetAndPost("/api/dhcp/scopes/enable", _dhcpApi.EnableDhcpScopeAsync);
  364. _webService.MapGetAndPost("/api/dhcp/scopes/disable", _dhcpApi.DisableDhcpScope);
  365. _webService.MapGetAndPost("/api/dhcp/scopes/delete", _dhcpApi.DeleteDhcpScope);
  366. //administration
  367. _webService.MapGetAndPost("/api/admin/sessions/list", _authApi.ListSessions);
  368. _webService.MapGetAndPost("/api/admin/sessions/createToken", _authApi.CreateApiToken);
  369. _webService.MapGetAndPost("/api/admin/sessions/delete", delegate (HttpContext context) { _authApi.DeleteSession(context, true); });
  370. _webService.MapGetAndPost("/api/admin/users/list", _authApi.ListUsers);
  371. _webService.MapGetAndPost("/api/admin/users/create", _authApi.CreateUser);
  372. _webService.MapGetAndPost("/api/admin/users/get", _authApi.GetUserDetails);
  373. _webService.MapGetAndPost("/api/admin/users/set", _authApi.SetUserDetails);
  374. _webService.MapGetAndPost("/api/admin/users/delete", _authApi.DeleteUser);
  375. _webService.MapGetAndPost("/api/admin/groups/list", _authApi.ListGroups);
  376. _webService.MapGetAndPost("/api/admin/groups/create", _authApi.CreateGroup);
  377. _webService.MapGetAndPost("/api/admin/groups/get", _authApi.GetGroupDetails);
  378. _webService.MapGetAndPost("/api/admin/groups/set", _authApi.SetGroupDetails);
  379. _webService.MapGetAndPost("/api/admin/groups/delete", _authApi.DeleteGroup);
  380. _webService.MapGetAndPost("/api/admin/permissions/list", _authApi.ListPermissions);
  381. _webService.MapGetAndPost("/api/admin/permissions/get", delegate (HttpContext context) { _authApi.GetPermissionDetails(context, PermissionSection.Unknown); });
  382. _webService.MapGetAndPost("/api/admin/permissions/set", delegate (HttpContext context) { _authApi.SetPermissionsDetails(context, PermissionSection.Unknown); });
  383. //logs
  384. _webService.MapGetAndPost("/api/logs/list", _logsApi.ListLogs);
  385. _webService.MapGetAndPost("/api/logs/download", _logsApi.DownloadLogAsync);
  386. _webService.MapGetAndPost("/api/logs/delete", _logsApi.DeleteLog);
  387. _webService.MapGetAndPost("/api/logs/deleteAll", _logsApi.DeleteAllLogs);
  388. _webService.MapGetAndPost("/api/logs/query", _logsApi.QueryLogsAsync);
  389. }
  390. private async Task WebServiceApiMiddleware(HttpContext context, RequestDelegate next)
  391. {
  392. bool needsJsonResponseObject;
  393. switch (context.Request.Path)
  394. {
  395. case "/api/user/login":
  396. case "/api/user/createToken":
  397. case "/api/user/logout":
  398. needsJsonResponseObject = false;
  399. break;
  400. case "/api/user/session/get":
  401. {
  402. if (!TryGetSession(context, out UserSession session))
  403. throw new InvalidTokenWebServiceException("Invalid token or session expired.");
  404. context.Items["session"] = session;
  405. needsJsonResponseObject = false;
  406. }
  407. break;
  408. case "/api/allowed/export":
  409. case "/api/blocked/export":
  410. case "/api/settings/backup":
  411. case "/api/logs/download":
  412. {
  413. if (!TryGetSession(context, out UserSession session))
  414. throw new InvalidTokenWebServiceException("Invalid token or session expired.");
  415. context.Items["session"] = session;
  416. await next(context);
  417. }
  418. return;
  419. default:
  420. {
  421. if (!TryGetSession(context, out UserSession session))
  422. throw new InvalidTokenWebServiceException("Invalid token or session expired.");
  423. context.Items["session"] = session;
  424. needsJsonResponseObject = true;
  425. }
  426. break;
  427. }
  428. using (MemoryStream mS = new MemoryStream())
  429. {
  430. Utf8JsonWriter jsonWriter = new Utf8JsonWriter(mS);
  431. context.Items["jsonWriter"] = jsonWriter;
  432. jsonWriter.WriteStartObject();
  433. if (needsJsonResponseObject)
  434. {
  435. jsonWriter.WritePropertyName("response");
  436. jsonWriter.WriteStartObject();
  437. await next(context);
  438. jsonWriter.WriteEndObject();
  439. }
  440. else
  441. {
  442. await next(context);
  443. }
  444. jsonWriter.WriteString("status", "ok");
  445. jsonWriter.WriteEndObject();
  446. jsonWriter.Flush();
  447. mS.Position = 0;
  448. HttpResponse response = context.Response;
  449. response.StatusCode = StatusCodes.Status200OK;
  450. response.ContentType = "application/json; charset=utf-8";
  451. response.ContentLength = mS.Length;
  452. await mS.CopyToAsync(response.Body);
  453. }
  454. }
  455. private static void WebServiceExceptionHandler(IApplicationBuilder exceptionHandlerApp)
  456. {
  457. exceptionHandlerApp.Run(async delegate (HttpContext context)
  458. {
  459. IExceptionHandlerPathFeature exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
  460. if (exceptionHandlerPathFeature.Path.StartsWith("/api/"))
  461. {
  462. Exception ex = exceptionHandlerPathFeature.Error;
  463. context.Response.StatusCode = StatusCodes.Status200OK;
  464. context.Response.ContentType = "application/json; charset=utf-8";
  465. await using (Utf8JsonWriter jsonWriter = new Utf8JsonWriter(context.Response.Body))
  466. {
  467. jsonWriter.WriteStartObject();
  468. if (ex is InvalidTokenWebServiceException)
  469. {
  470. jsonWriter.WriteString("status", "invalid-token");
  471. jsonWriter.WriteString("errorMessage", ex.Message);
  472. }
  473. else
  474. {
  475. jsonWriter.WriteString("status", "error");
  476. jsonWriter.WriteString("errorMessage", ex.Message);
  477. jsonWriter.WriteString("stackTrace", ex.StackTrace);
  478. if (ex.InnerException is not null)
  479. jsonWriter.WriteString("innerErrorMessage", ex.InnerException.Message);
  480. }
  481. jsonWriter.WriteEndObject();
  482. }
  483. }
  484. });
  485. }
  486. private bool TryGetSession(HttpContext context, out UserSession session)
  487. {
  488. string token = context.Request.GetQueryOrForm("token");
  489. session = _authManager.GetSession(token);
  490. if ((session is null) || session.User.Disabled)
  491. return false;
  492. if (session.HasExpired())
  493. {
  494. _authManager.DeleteSession(session.Token);
  495. _authManager.SaveConfigFile();
  496. return false;
  497. }
  498. IPEndPoint remoteEP = context.GetRemoteEndPoint();
  499. session.UpdateLastSeen(remoteEP.Address, context.Request.Headers.UserAgent);
  500. return true;
  501. }
  502. #endregion
  503. #region tls
  504. internal void StartTlsCertificateUpdateTimer()
  505. {
  506. if (_tlsCertificateUpdateTimer is null)
  507. {
  508. _tlsCertificateUpdateTimer = new Timer(delegate (object state)
  509. {
  510. if (!string.IsNullOrEmpty(_webServiceTlsCertificatePath))
  511. {
  512. try
  513. {
  514. FileInfo fileInfo = new FileInfo(_webServiceTlsCertificatePath);
  515. if (fileInfo.Exists && (fileInfo.LastWriteTimeUtc != _webServiceTlsCertificateLastModifiedOn))
  516. LoadWebServiceTlsCertificate(_webServiceTlsCertificatePath, _webServiceTlsCertificatePassword);
  517. }
  518. catch (Exception ex)
  519. {
  520. _log.Write("DNS Server encountered an error while updating Web Service TLS Certificate: " + _webServiceTlsCertificatePath + "\r\n" + ex.ToString());
  521. }
  522. }
  523. if (!string.IsNullOrEmpty(_dnsTlsCertificatePath))
  524. {
  525. try
  526. {
  527. FileInfo fileInfo = new FileInfo(_dnsTlsCertificatePath);
  528. if (fileInfo.Exists && (fileInfo.LastWriteTimeUtc != _dnsTlsCertificateLastModifiedOn))
  529. LoadDnsTlsCertificate(_dnsTlsCertificatePath, _dnsTlsCertificatePassword);
  530. }
  531. catch (Exception ex)
  532. {
  533. _log.Write("DNS Server encountered an error while updating DNS Server TLS Certificate: " + _dnsTlsCertificatePath + "\r\n" + ex.ToString());
  534. }
  535. }
  536. }, null, TLS_CERTIFICATE_UPDATE_TIMER_INITIAL_INTERVAL, TLS_CERTIFICATE_UPDATE_TIMER_INTERVAL);
  537. }
  538. }
  539. internal void StopTlsCertificateUpdateTimer()
  540. {
  541. if (_tlsCertificateUpdateTimer is not null)
  542. {
  543. _tlsCertificateUpdateTimer.Dispose();
  544. _tlsCertificateUpdateTimer = null;
  545. }
  546. }
  547. internal void LoadWebServiceTlsCertificate(string tlsCertificatePath, string tlsCertificatePassword)
  548. {
  549. FileInfo fileInfo = new FileInfo(tlsCertificatePath);
  550. if (!fileInfo.Exists)
  551. throw new ArgumentException("Web Service TLS certificate file does not exists: " + tlsCertificatePath);
  552. if (Path.GetExtension(tlsCertificatePath) != ".pfx")
  553. throw new ArgumentException("Web Service TLS certificate file must be PKCS #12 formatted with .pfx extension: " + tlsCertificatePath);
  554. _webServiceTlsCertificate = new X509Certificate2(tlsCertificatePath, tlsCertificatePassword);
  555. _webServiceTlsCertificateLastModifiedOn = fileInfo.LastWriteTimeUtc;
  556. _log.Write("Web Service TLS certificate was loaded: " + tlsCertificatePath);
  557. }
  558. internal void LoadDnsTlsCertificate(string tlsCertificatePath, string tlsCertificatePassword)
  559. {
  560. FileInfo fileInfo = new FileInfo(tlsCertificatePath);
  561. if (!fileInfo.Exists)
  562. throw new ArgumentException("DNS Server TLS certificate file does not exists: " + tlsCertificatePath);
  563. if (Path.GetExtension(tlsCertificatePath) != ".pfx")
  564. throw new ArgumentException("DNS Server TLS certificate file must be PKCS #12 formatted with .pfx extension: " + tlsCertificatePath);
  565. _dnsServer.Certificate = new X509Certificate2(tlsCertificatePath, tlsCertificatePassword);
  566. _dnsTlsCertificateLastModifiedOn = fileInfo.LastWriteTimeUtc;
  567. _log.Write("DNS Server TLS certificate was loaded: " + tlsCertificatePath);
  568. }
  569. internal void SelfSignedCertCheck(bool generateNew, bool throwException)
  570. {
  571. string selfSignedCertificateFilePath = Path.Combine(_configFolder, "cert.pfx");
  572. if (_webServiceUseSelfSignedTlsCertificate)
  573. {
  574. if (generateNew || !File.Exists(selfSignedCertificateFilePath))
  575. {
  576. RSA rsa = RSA.Create(2048);
  577. CertificateRequest req = new CertificateRequest("cn=" + _dnsServer.ServerDomain, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
  578. X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(5));
  579. File.WriteAllBytes(selfSignedCertificateFilePath, cert.Export(X509ContentType.Pkcs12, null as string));
  580. }
  581. if (_webServiceEnableTls && string.IsNullOrEmpty(_webServiceTlsCertificatePath))
  582. {
  583. try
  584. {
  585. LoadWebServiceTlsCertificate(selfSignedCertificateFilePath, null);
  586. }
  587. catch (Exception ex)
  588. {
  589. _log.Write("DNS Server encountered an error while loading self signed Web Service TLS certificate: " + selfSignedCertificateFilePath + "\r\n" + ex.ToString());
  590. if (throwException)
  591. throw;
  592. }
  593. }
  594. }
  595. else
  596. {
  597. File.Delete(selfSignedCertificateFilePath);
  598. }
  599. }
  600. #endregion
  601. #region quic
  602. internal static void ValidateQuicSupport()
  603. {
  604. #pragma warning disable CA2252 // This API requires opting into preview features
  605. #pragma warning disable CA1416 // Validate platform compatibility
  606. if (!QuicConnection.IsSupported)
  607. throw new DnsWebServiceException("DNS-over-QUIC is supported only on Windows 11, Windows Server 2022, and Linux. On Linux, you must install 'libmsquic' and OpenSSL v1.1.1 manually.");
  608. #pragma warning restore CA1416 // Validate platform compatibility
  609. #pragma warning restore CA2252 // This API requires opting into preview features
  610. }
  611. #endregion
  612. #region config
  613. internal void LoadConfigFile()
  614. {
  615. string configFile = Path.Combine(_configFolder, "dns.config");
  616. try
  617. {
  618. int version;
  619. using (FileStream fS = new FileStream(configFile, FileMode.Open, FileAccess.Read))
  620. {
  621. version = ReadConfigFrom(new BinaryReader(fS));
  622. }
  623. _log.Write("DNS Server config file was loaded: " + configFile);
  624. if (version <= 27)
  625. SaveConfigFile(); //save as new config version to avoid loading old version next time
  626. }
  627. catch (FileNotFoundException)
  628. {
  629. _log.Write("DNS Server config file was not found: " + configFile);
  630. _log.Write("DNS Server is restoring default config file.");
  631. //general
  632. string serverDomain = Environment.GetEnvironmentVariable("DNS_SERVER_DOMAIN");
  633. if (!string.IsNullOrEmpty(serverDomain))
  634. _dnsServer.ServerDomain = serverDomain;
  635. _appsApi.EnableAutomaticUpdate = true;
  636. string strPreferIPv6 = Environment.GetEnvironmentVariable("DNS_SERVER_PREFER_IPV6");
  637. if (!string.IsNullOrEmpty(strPreferIPv6))
  638. _dnsServer.PreferIPv6 = bool.Parse(strPreferIPv6);
  639. _dnsServer.DnssecValidation = true;
  640. CreateForwarderZoneToDisableDnssecForNTP();
  641. //web service
  642. string strWebServiceHttpPort = Environment.GetEnvironmentVariable("DNS_SERVER_WEB_SERVICE_HTTP_PORT");
  643. if (!string.IsNullOrEmpty(strWebServiceHttpPort))
  644. _webServiceHttpPort = int.Parse(strWebServiceHttpPort);
  645. string webServiceTlsPort = Environment.GetEnvironmentVariable("DNS_SERVER_WEB_SERVICE_HTTPS_PORT");
  646. if (!string.IsNullOrEmpty(webServiceTlsPort))
  647. _webServiceTlsPort = int.Parse(webServiceTlsPort);
  648. string webServiceEnableTls = Environment.GetEnvironmentVariable("DNS_SERVER_WEB_SERVICE_ENABLE_HTTPS");
  649. if (!string.IsNullOrEmpty(webServiceEnableTls))
  650. _webServiceEnableTls = bool.Parse(webServiceEnableTls);
  651. string webServiceUseSelfSignedTlsCertificate = Environment.GetEnvironmentVariable("DNS_SERVER_WEB_SERVICE_USE_SELF_SIGNED_CERT");
  652. if (!string.IsNullOrEmpty(webServiceUseSelfSignedTlsCertificate))
  653. _webServiceUseSelfSignedTlsCertificate = bool.Parse(webServiceUseSelfSignedTlsCertificate);
  654. //optional protocols
  655. string strDnsOverHttp = Environment.GetEnvironmentVariable("DNS_SERVER_OPTIONAL_PROTOCOL_DNS_OVER_HTTP");
  656. if (!string.IsNullOrEmpty(strDnsOverHttp))
  657. _dnsServer.EnableDnsOverHttp = bool.Parse(strDnsOverHttp);
  658. //recursion
  659. string strRecursion = Environment.GetEnvironmentVariable("DNS_SERVER_RECURSION");
  660. if (!string.IsNullOrEmpty(strRecursion))
  661. _dnsServer.Recursion = Enum.Parse<DnsServerRecursion>(strRecursion, true);
  662. else
  663. _dnsServer.Recursion = DnsServerRecursion.AllowOnlyForPrivateNetworks; //default for security reasons
  664. string strRecursionDeniedNetworks = Environment.GetEnvironmentVariable("DNS_SERVER_RECURSION_DENIED_NETWORKS");
  665. if (!string.IsNullOrEmpty(strRecursionDeniedNetworks))
  666. _dnsServer.RecursionDeniedNetworks = strRecursionDeniedNetworks.Split(NetworkAddress.Parse, ',');
  667. string strRecursionAllowedNetworks = Environment.GetEnvironmentVariable("DNS_SERVER_RECURSION_ALLOWED_NETWORKS");
  668. if (!string.IsNullOrEmpty(strRecursionAllowedNetworks))
  669. _dnsServer.RecursionAllowedNetworks = strRecursionAllowedNetworks.Split(NetworkAddress.Parse, ',');
  670. _dnsServer.RandomizeName = true; //default true to enable security feature
  671. _dnsServer.QnameMinimization = true; //default true to enable privacy feature
  672. _dnsServer.NsRevalidation = true; //default true for security reasons
  673. //cache
  674. _dnsServer.CacheZoneManager.MaximumEntries = 10000;
  675. //blocking
  676. string strEnableBlocking = Environment.GetEnvironmentVariable("DNS_SERVER_ENABLE_BLOCKING");
  677. if (!string.IsNullOrEmpty(strEnableBlocking))
  678. _dnsServer.EnableBlocking = bool.Parse(strEnableBlocking);
  679. string strAllowTxtBlockingReport = Environment.GetEnvironmentVariable("DNS_SERVER_ALLOW_TXT_BLOCKING_REPORT");
  680. if (!string.IsNullOrEmpty(strAllowTxtBlockingReport))
  681. _dnsServer.AllowTxtBlockingReport = bool.Parse(strAllowTxtBlockingReport);
  682. string strBlockListUrls = Environment.GetEnvironmentVariable("DNS_SERVER_BLOCK_LIST_URLS");
  683. if (!string.IsNullOrEmpty(strBlockListUrls))
  684. {
  685. string[] strBlockListUrlList = strBlockListUrls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  686. foreach (string strBlockListUrl in strBlockListUrlList)
  687. {
  688. if (strBlockListUrl.StartsWith('!'))
  689. {
  690. Uri allowListUrl = new Uri(strBlockListUrl.Substring(1));
  691. if (!_dnsServer.BlockListZoneManager.AllowListUrls.Contains(allowListUrl))
  692. _dnsServer.BlockListZoneManager.AllowListUrls.Add(allowListUrl);
  693. }
  694. else
  695. {
  696. Uri blockListUrl = new Uri(strBlockListUrl);
  697. if (!_dnsServer.BlockListZoneManager.BlockListUrls.Contains(blockListUrl))
  698. _dnsServer.BlockListZoneManager.BlockListUrls.Add(blockListUrl);
  699. }
  700. }
  701. }
  702. //proxy & forwarders
  703. string strForwarders = Environment.GetEnvironmentVariable("DNS_SERVER_FORWARDERS");
  704. if (!string.IsNullOrEmpty(strForwarders))
  705. {
  706. DnsTransportProtocol forwarderProtocol;
  707. string strForwarderProtocol = Environment.GetEnvironmentVariable("DNS_SERVER_FORWARDER_PROTOCOL");
  708. if (string.IsNullOrEmpty(strForwarderProtocol))
  709. {
  710. forwarderProtocol = DnsTransportProtocol.Udp;
  711. }
  712. else
  713. {
  714. forwarderProtocol = Enum.Parse<DnsTransportProtocol>(strForwarderProtocol, true);
  715. if (forwarderProtocol == DnsTransportProtocol.HttpsJson)
  716. forwarderProtocol = DnsTransportProtocol.Https;
  717. }
  718. _dnsServer.Forwarders = strForwarders.Split(delegate (string value)
  719. {
  720. NameServerAddress forwarder = NameServerAddress.Parse(value);
  721. if (forwarder.Protocol != forwarderProtocol)
  722. forwarder = forwarder.ChangeProtocol(forwarderProtocol);
  723. return forwarder;
  724. }, ',');
  725. }
  726. //logging
  727. string strUseLocalTime = Environment.GetEnvironmentVariable("DNS_SERVER_LOG_USING_LOCAL_TIME");
  728. if (!string.IsNullOrEmpty(strUseLocalTime))
  729. _log.UseLocalTime = bool.Parse(strUseLocalTime);
  730. SaveConfigFile();
  731. }
  732. catch (Exception ex)
  733. {
  734. _log.Write("DNS Server encountered an error while loading config file: " + configFile + "\r\n" + ex.ToString());
  735. _log.Write("Note: You may try deleting the config file to fix this issue. However, you will lose DNS settings but, zone data wont be affected.");
  736. throw;
  737. }
  738. }
  739. private void CreateForwarderZoneToDisableDnssecForNTP()
  740. {
  741. if (Environment.OSVersion.Platform == PlatformID.Unix)
  742. {
  743. //adding a conditional forwarder zone for disabling DNSSEC validation for ntp.org so that systems with no real-time clock can sync time
  744. string ntpDomain = "ntp.org";
  745. string fwdRecordComments = "This forwarder zone was automatically created to disable DNSSEC validation for ntp.org to allow systems with no real-time clock (e.g. Raspberry Pi) to sync time via NTP when booting.";
  746. if (_dnsServer.AuthZoneManager.CreateForwarderZone(ntpDomain, DnsTransportProtocol.Udp, "this-server", false, NetProxyType.None, null, 0, null, null, fwdRecordComments) is not null)
  747. {
  748. //set permissions
  749. _authManager.SetPermission(PermissionSection.Zones, ntpDomain, _authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
  750. _authManager.SetPermission(PermissionSection.Zones, ntpDomain, _authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
  751. _authManager.SaveConfigFile();
  752. Directory.CreateDirectory(Path.Combine(_dnsServer.ConfigFolder, "zones"));
  753. _dnsServer.AuthZoneManager.SaveZoneFile(ntpDomain);
  754. }
  755. }
  756. }
  757. internal void SaveConfigFile()
  758. {
  759. string configFile = Path.Combine(_configFolder, "dns.config");
  760. using (MemoryStream mS = new MemoryStream())
  761. {
  762. //serialize config
  763. WriteConfigTo(new BinaryWriter(mS));
  764. //write config
  765. mS.Position = 0;
  766. using (FileStream fS = new FileStream(configFile, FileMode.Create, FileAccess.Write))
  767. {
  768. mS.CopyTo(fS);
  769. }
  770. }
  771. _log.Write("DNS Server config file was saved: " + configFile);
  772. }
  773. internal void InspectAndFixZonePermissions()
  774. {
  775. Permission permission = _authManager.GetPermission(PermissionSection.Zones);
  776. IReadOnlyDictionary<string, Permission> subItemPermissions = permission.SubItemPermissions;
  777. //remove ghost permissions
  778. foreach (KeyValuePair<string, Permission> subItemPermission in subItemPermissions)
  779. {
  780. string zoneName = subItemPermission.Key;
  781. if (_dnsServer.AuthZoneManager.GetAuthZoneInfo(zoneName) is null)
  782. permission.RemoveAllSubItemPermissions(zoneName); //no such zone exists; remove permissions
  783. }
  784. //add missing admin permissions
  785. IReadOnlyList<AuthZoneInfo> zones = _dnsServer.AuthZoneManager.GetAllZones();
  786. Group admins = _authManager.GetGroup(Group.ADMINISTRATORS);
  787. Group dnsAdmins = _authManager.GetGroup(Group.DNS_ADMINISTRATORS);
  788. foreach (AuthZoneInfo zone in zones)
  789. {
  790. if (zone.Internal)
  791. {
  792. _authManager.SetPermission(PermissionSection.Zones, zone.Name, admins, PermissionFlag.View);
  793. _authManager.SetPermission(PermissionSection.Zones, zone.Name, dnsAdmins, PermissionFlag.View);
  794. }
  795. else
  796. {
  797. _authManager.SetPermission(PermissionSection.Zones, zone.Name, admins, PermissionFlag.ViewModifyDelete);
  798. _authManager.SetPermission(PermissionSection.Zones, zone.Name, dnsAdmins, PermissionFlag.ViewModifyDelete);
  799. }
  800. }
  801. _authManager.SaveConfigFile();
  802. }
  803. private int ReadConfigFrom(BinaryReader bR)
  804. {
  805. if (Encoding.ASCII.GetString(bR.ReadBytes(2)) != "DS") //format
  806. throw new InvalidDataException("DNS Server config file format is invalid.");
  807. int version = bR.ReadByte();
  808. if ((version >= 28) && (version <= 31))
  809. {
  810. ReadConfigFrom(bR, version);
  811. }
  812. else if ((version >= 2) && (version <= 27))
  813. {
  814. ReadOldConfigFrom(bR, version);
  815. //new default settings
  816. _appsApi.EnableAutomaticUpdate = true;
  817. }
  818. else
  819. {
  820. throw new InvalidDataException("DNS Server config version not supported.");
  821. }
  822. return version;
  823. }
  824. private void ReadConfigFrom(BinaryReader bR, int version)
  825. {
  826. //web service
  827. {
  828. _webServiceHttpPort = bR.ReadInt32();
  829. _webServiceTlsPort = bR.ReadInt32();
  830. {
  831. int count = bR.ReadByte();
  832. if (count > 0)
  833. {
  834. IPAddress[] localAddresses = new IPAddress[count];
  835. for (int i = 0; i < count; i++)
  836. localAddresses[i] = IPAddressExtensions.ReadFrom(bR);
  837. _webServiceLocalAddresses = localAddresses;
  838. }
  839. }
  840. _webServiceEnableTls = bR.ReadBoolean();
  841. _webServiceHttpToTlsRedirect = bR.ReadBoolean();
  842. _webServiceUseSelfSignedTlsCertificate = bR.ReadBoolean();
  843. _webServiceTlsCertificatePath = bR.ReadShortString();
  844. _webServiceTlsCertificatePassword = bR.ReadShortString();
  845. if (_webServiceTlsCertificatePath.Length == 0)
  846. _webServiceTlsCertificatePath = null;
  847. if (_webServiceTlsCertificatePath != null)
  848. {
  849. try
  850. {
  851. LoadWebServiceTlsCertificate(_webServiceTlsCertificatePath, _webServiceTlsCertificatePassword);
  852. }
  853. catch (Exception ex)
  854. {
  855. _log.Write("DNS Server encountered an error while loading Web Service TLS certificate: " + _webServiceTlsCertificatePath + "\r\n" + ex.ToString());
  856. }
  857. StartTlsCertificateUpdateTimer();
  858. }
  859. SelfSignedCertCheck(false, false);
  860. }
  861. //dns
  862. {
  863. //general
  864. _dnsServer.ServerDomain = bR.ReadShortString();
  865. {
  866. int count = bR.ReadByte();
  867. if (count > 0)
  868. {
  869. IPEndPoint[] localEndPoints = new IPEndPoint[count];
  870. for (int i = 0; i < count; i++)
  871. localEndPoints[i] = (IPEndPoint)EndPointExtensions.ReadFrom(bR);
  872. _dnsServer.LocalEndPoints = localEndPoints;
  873. }
  874. }
  875. _zonesApi.DefaultRecordTtl = bR.ReadUInt32();
  876. _appsApi.EnableAutomaticUpdate = bR.ReadBoolean();
  877. _dnsServer.PreferIPv6 = bR.ReadBoolean();
  878. _dnsServer.UdpPayloadSize = bR.ReadUInt16();
  879. _dnsServer.DnssecValidation = bR.ReadBoolean();
  880. if (version >= 29)
  881. {
  882. _dnsServer.EDnsClientSubnet = bR.ReadBoolean();
  883. _dnsServer.EDnsClientSubnetIPv4PrefixLength = bR.ReadByte();
  884. _dnsServer.EDnsClientSubnetIPv6PrefixLength = bR.ReadByte();
  885. }
  886. else
  887. {
  888. _dnsServer.EDnsClientSubnet = false;
  889. _dnsServer.EDnsClientSubnetIPv4PrefixLength = 24;
  890. _dnsServer.EDnsClientSubnetIPv6PrefixLength = 56;
  891. }
  892. _dnsServer.QpmLimitRequests = bR.ReadInt32();
  893. _dnsServer.QpmLimitErrors = bR.ReadInt32();
  894. _dnsServer.QpmLimitSampleMinutes = bR.ReadInt32();
  895. _dnsServer.QpmLimitIPv4PrefixLength = bR.ReadInt32();
  896. _dnsServer.QpmLimitIPv6PrefixLength = bR.ReadInt32();
  897. _dnsServer.ClientTimeout = bR.ReadInt32();
  898. _dnsServer.TcpSendTimeout = bR.ReadInt32();
  899. _dnsServer.TcpReceiveTimeout = bR.ReadInt32();
  900. if (version >= 30)
  901. {
  902. _dnsServer.QuicIdleTimeout = bR.ReadInt32();
  903. _dnsServer.QuicMaxInboundStreams = bR.ReadInt32();
  904. _dnsServer.ListenBacklog = bR.ReadInt32();
  905. }
  906. else
  907. {
  908. _dnsServer.QuicIdleTimeout = 60000;
  909. _dnsServer.QuicMaxInboundStreams = 100;
  910. _dnsServer.ListenBacklog = 100;
  911. }
  912. //optional protocols
  913. _dnsServer.EnableDnsOverHttp = bR.ReadBoolean();
  914. _dnsServer.EnableDnsOverTls = bR.ReadBoolean();
  915. _dnsServer.EnableDnsOverHttps = bR.ReadBoolean();
  916. if (version >= 31)
  917. {
  918. _dnsServer.EnableDnsOverQuic = bR.ReadBoolean();
  919. _dnsServer.DnsOverHttpPort = bR.ReadInt32();
  920. _dnsServer.DnsOverTlsPort = bR.ReadInt32();
  921. _dnsServer.DnsOverHttpsPort = bR.ReadInt32();
  922. _dnsServer.DnsOverQuicPort = bR.ReadInt32();
  923. }
  924. else if (version >= 30)
  925. {
  926. _ = bR.ReadBoolean(); //removed EnableDnsOverHttpPort80 value
  927. _dnsServer.EnableDnsOverQuic = bR.ReadBoolean();
  928. _dnsServer.DnsOverHttpPort = bR.ReadInt32();
  929. _dnsServer.DnsOverTlsPort = bR.ReadInt32();
  930. _dnsServer.DnsOverHttpsPort = bR.ReadInt32();
  931. _dnsServer.DnsOverQuicPort = bR.ReadInt32();
  932. }
  933. else
  934. {
  935. _dnsServer.EnableDnsOverQuic = false;
  936. if (_dnsServer.EnableDnsOverHttps)
  937. {
  938. _dnsServer.EnableDnsOverHttp = true;
  939. _dnsServer.DnsOverHttpPort = 80;
  940. }
  941. else if (_dnsServer.EnableDnsOverHttp)
  942. {
  943. _dnsServer.DnsOverHttpPort = 8053;
  944. }
  945. else
  946. {
  947. _dnsServer.DnsOverHttpPort = 80;
  948. }
  949. _dnsServer.DnsOverTlsPort = 853;
  950. _dnsServer.DnsOverHttpsPort = 443;
  951. _dnsServer.DnsOverQuicPort = 853;
  952. }
  953. _dnsTlsCertificatePath = bR.ReadShortString();
  954. _dnsTlsCertificatePassword = bR.ReadShortString();
  955. if (_dnsTlsCertificatePath.Length == 0)
  956. _dnsTlsCertificatePath = null;
  957. if (_dnsTlsCertificatePath != null)
  958. {
  959. try
  960. {
  961. LoadDnsTlsCertificate(_dnsTlsCertificatePath, _dnsTlsCertificatePassword);
  962. }
  963. catch (Exception ex)
  964. {
  965. _log.Write("DNS Server encountered an error while loading DNS Server TLS certificate: " + _dnsTlsCertificatePath + "\r\n" + ex.ToString());
  966. }
  967. StartTlsCertificateUpdateTimer();
  968. }
  969. //tsig
  970. {
  971. int count = bR.ReadByte();
  972. Dictionary<string, TsigKey> tsigKeys = new Dictionary<string, TsigKey>(count);
  973. for (int i = 0; i < count; i++)
  974. {
  975. string keyName = bR.ReadShortString();
  976. string sharedSecret = bR.ReadShortString();
  977. TsigAlgorithm algorithm = (TsigAlgorithm)bR.ReadByte();
  978. tsigKeys.Add(keyName, new TsigKey(keyName, sharedSecret, algorithm));
  979. }
  980. _dnsServer.TsigKeys = tsigKeys;
  981. }
  982. //recursion
  983. _dnsServer.Recursion = (DnsServerRecursion)bR.ReadByte();
  984. {
  985. int count = bR.ReadByte();
  986. if (count > 0)
  987. {
  988. NetworkAddress[] networks = new NetworkAddress[count];
  989. for (int i = 0; i < count; i++)
  990. networks[i] = NetworkAddress.ReadFrom(bR);
  991. _dnsServer.RecursionDeniedNetworks = networks;
  992. }
  993. }
  994. {
  995. int count = bR.ReadByte();
  996. if (count > 0)
  997. {
  998. NetworkAddress[] networks = new NetworkAddress[count];
  999. for (int i = 0; i < count; i++)
  1000. networks[i] = NetworkAddress.ReadFrom(bR);
  1001. _dnsServer.RecursionAllowedNetworks = networks;
  1002. }
  1003. }
  1004. _dnsServer.RandomizeName = bR.ReadBoolean();
  1005. _dnsServer.QnameMinimization = bR.ReadBoolean();
  1006. _dnsServer.NsRevalidation = bR.ReadBoolean();
  1007. _dnsServer.ResolverRetries = bR.ReadInt32();
  1008. _dnsServer.ResolverTimeout = bR.ReadInt32();
  1009. _dnsServer.ResolverMaxStackCount = bR.ReadInt32();
  1010. //cache
  1011. if (version >= 30)
  1012. _saveCache = bR.ReadBoolean();
  1013. else
  1014. _saveCache = true;
  1015. _dnsServer.ServeStale = bR.ReadBoolean();
  1016. _dnsServer.CacheZoneManager.ServeStaleTtl = bR.ReadUInt32();
  1017. _dnsServer.CacheZoneManager.MaximumEntries = bR.ReadInt64();
  1018. _dnsServer.CacheZoneManager.MinimumRecordTtl = bR.ReadUInt32();
  1019. _dnsServer.CacheZoneManager.MaximumRecordTtl = bR.ReadUInt32();
  1020. _dnsServer.CacheZoneManager.NegativeRecordTtl = bR.ReadUInt32();
  1021. _dnsServer.CacheZoneManager.FailureRecordTtl = bR.ReadUInt32();
  1022. _dnsServer.CachePrefetchEligibility = bR.ReadInt32();
  1023. _dnsServer.CachePrefetchTrigger = bR.ReadInt32();
  1024. _dnsServer.CachePrefetchSampleIntervalInMinutes = bR.ReadInt32();
  1025. _dnsServer.CachePrefetchSampleEligibilityHitsPerHour = bR.ReadInt32();
  1026. //blocking
  1027. _dnsServer.EnableBlocking = bR.ReadBoolean();
  1028. _dnsServer.AllowTxtBlockingReport = bR.ReadBoolean();
  1029. _dnsServer.BlockingType = (DnsServerBlockingType)bR.ReadByte();
  1030. {
  1031. //read custom blocking addresses
  1032. int count = bR.ReadByte();
  1033. if (count > 0)
  1034. {
  1035. List<DnsARecordData> dnsARecords = new List<DnsARecordData>();
  1036. List<DnsAAAARecordData> dnsAAAARecords = new List<DnsAAAARecordData>();
  1037. for (int i = 0; i < count; i++)
  1038. {
  1039. IPAddress customAddress = IPAddressExtensions.ReadFrom(bR);
  1040. switch (customAddress.AddressFamily)
  1041. {
  1042. case AddressFamily.InterNetwork:
  1043. dnsARecords.Add(new DnsARecordData(customAddress));
  1044. break;
  1045. case AddressFamily.InterNetworkV6:
  1046. dnsAAAARecords.Add(new DnsAAAARecordData(customAddress));
  1047. break;
  1048. }
  1049. }
  1050. _dnsServer.CustomBlockingARecords = dnsARecords;
  1051. _dnsServer.CustomBlockingAAAARecords = dnsAAAARecords;
  1052. }
  1053. }
  1054. {
  1055. //read block list urls
  1056. int count = bR.ReadByte();
  1057. for (int i = 0; i < count; i++)
  1058. {
  1059. string listUrl = bR.ReadShortString();
  1060. if (listUrl.StartsWith('!'))
  1061. _dnsServer.BlockListZoneManager.AllowListUrls.Add(new Uri(listUrl.Substring(1)));
  1062. else
  1063. _dnsServer.BlockListZoneManager.BlockListUrls.Add(new Uri(listUrl));
  1064. }
  1065. _settingsApi.BlockListUpdateIntervalHours = bR.ReadInt32();
  1066. _settingsApi.BlockListLastUpdatedOn = bR.ReadDateTime();
  1067. }
  1068. //proxy & forwarders
  1069. NetProxyType proxyType = (NetProxyType)bR.ReadByte();
  1070. if (proxyType != NetProxyType.None)
  1071. {
  1072. string address = bR.ReadShortString();
  1073. int port = bR.ReadInt32();
  1074. NetworkCredential credential = null;
  1075. if (bR.ReadBoolean()) //credential set
  1076. credential = new NetworkCredential(bR.ReadShortString(), bR.ReadShortString());
  1077. _dnsServer.Proxy = NetProxy.CreateProxy(proxyType, address, port, credential);
  1078. int count = bR.ReadByte();
  1079. List<NetProxyBypassItem> bypassList = new List<NetProxyBypassItem>(count);
  1080. for (int i = 0; i < count; i++)
  1081. bypassList.Add(new NetProxyBypassItem(bR.ReadShortString()));
  1082. _dnsServer.Proxy.BypassList = bypassList;
  1083. }
  1084. else
  1085. {
  1086. _dnsServer.Proxy = null;
  1087. }
  1088. {
  1089. int count = bR.ReadByte();
  1090. if (count > 0)
  1091. {
  1092. NameServerAddress[] forwarders = new NameServerAddress[count];
  1093. for (int i = 0; i < count; i++)
  1094. {
  1095. forwarders[i] = new NameServerAddress(bR);
  1096. if (forwarders[i].Protocol == DnsTransportProtocol.HttpsJson)
  1097. forwarders[i] = forwarders[i].ChangeProtocol(DnsTransportProtocol.Https);
  1098. }
  1099. _dnsServer.Forwarders = forwarders;
  1100. }
  1101. }
  1102. _dnsServer.ForwarderRetries = bR.ReadInt32();
  1103. _dnsServer.ForwarderTimeout = bR.ReadInt32();
  1104. _dnsServer.ForwarderConcurrency = bR.ReadInt32();
  1105. //logging
  1106. if (bR.ReadBoolean()) //log all queries
  1107. _dnsServer.QueryLogManager = _log;
  1108. else
  1109. _dnsServer.QueryLogManager = null;
  1110. _dnsServer.StatsManager.MaxStatFileDays = bR.ReadInt32();
  1111. }
  1112. if ((_webServiceTlsCertificatePath == null) && (_dnsTlsCertificatePath == null))
  1113. StopTlsCertificateUpdateTimer();
  1114. }
  1115. private void ReadOldConfigFrom(BinaryReader bR, int version)
  1116. {
  1117. _dnsServer.ServerDomain = bR.ReadShortString();
  1118. _webServiceHttpPort = bR.ReadInt32();
  1119. if (version >= 13)
  1120. {
  1121. {
  1122. int count = bR.ReadByte();
  1123. if (count > 0)
  1124. {
  1125. IPAddress[] localAddresses = new IPAddress[count];
  1126. for (int i = 0; i < count; i++)
  1127. localAddresses[i] = IPAddressExtensions.ReadFrom(bR);
  1128. _webServiceLocalAddresses = localAddresses;
  1129. }
  1130. }
  1131. _webServiceTlsPort = bR.ReadInt32();
  1132. _webServiceEnableTls = bR.ReadBoolean();
  1133. _webServiceHttpToTlsRedirect = bR.ReadBoolean();
  1134. _webServiceTlsCertificatePath = bR.ReadShortString();
  1135. _webServiceTlsCertificatePassword = bR.ReadShortString();
  1136. if (_webServiceTlsCertificatePath.Length == 0)
  1137. _webServiceTlsCertificatePath = null;
  1138. if (_webServiceTlsCertificatePath != null)
  1139. {
  1140. try
  1141. {
  1142. LoadWebServiceTlsCertificate(_webServiceTlsCertificatePath, _webServiceTlsCertificatePassword);
  1143. }
  1144. catch (Exception ex)
  1145. {
  1146. _log.Write("DNS Server encountered an error while loading Web Service TLS certificate: " + _webServiceTlsCertificatePath + "\r\n" + ex.ToString());
  1147. }
  1148. StartTlsCertificateUpdateTimer();
  1149. }
  1150. }
  1151. else
  1152. {
  1153. _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any, IPAddress.IPv6Any };
  1154. _webServiceTlsPort = 53443;
  1155. _webServiceEnableTls = false;
  1156. _webServiceHttpToTlsRedirect = false;
  1157. _webServiceTlsCertificatePath = string.Empty;
  1158. _webServiceTlsCertificatePassword = string.Empty;
  1159. }
  1160. _dnsServer.PreferIPv6 = bR.ReadBoolean();
  1161. if (bR.ReadBoolean()) //logQueries
  1162. _dnsServer.QueryLogManager = _log;
  1163. if (version >= 14)
  1164. _dnsServer.StatsManager.MaxStatFileDays = bR.ReadInt32();
  1165. else
  1166. _dnsServer.StatsManager.MaxStatFileDays = 0;
  1167. if (version >= 17)
  1168. {
  1169. _dnsServer.Recursion = (DnsServerRecursion)bR.ReadByte();
  1170. {
  1171. int count = bR.ReadByte();
  1172. if (count > 0)
  1173. {
  1174. NetworkAddress[] networks = new NetworkAddress[count];
  1175. for (int i = 0; i < count; i++)
  1176. networks[i] = NetworkAddress.ReadFrom(bR);
  1177. _dnsServer.RecursionDeniedNetworks = networks;
  1178. }
  1179. }
  1180. {
  1181. int count = bR.ReadByte();
  1182. if (count > 0)
  1183. {
  1184. NetworkAddress[] networks = new NetworkAddress[count];
  1185. for (int i = 0; i < count; i++)
  1186. networks[i] = NetworkAddress.ReadFrom(bR);
  1187. _dnsServer.RecursionAllowedNetworks = networks;
  1188. }
  1189. }
  1190. }
  1191. else
  1192. {
  1193. bool allowRecursion = bR.ReadBoolean();
  1194. bool allowRecursionOnlyForPrivateNetworks;
  1195. if (version >= 4)
  1196. allowRecursionOnlyForPrivateNetworks = bR.ReadBoolean();
  1197. else
  1198. allowRecursionOnlyForPrivateNetworks = true; //default true for security reasons
  1199. if (allowRecursion)
  1200. {
  1201. if (allowRecursionOnlyForPrivateNetworks)
  1202. _dnsServer.Recursion = DnsServerRecursion.AllowOnlyForPrivateNetworks;
  1203. else
  1204. _dnsServer.Recursion = DnsServerRecursion.Allow;
  1205. }
  1206. else
  1207. {
  1208. _dnsServer.Recursion = DnsServerRecursion.Deny;
  1209. }
  1210. }
  1211. if (version >= 12)
  1212. _dnsServer.RandomizeName = bR.ReadBoolean();
  1213. else
  1214. _dnsServer.RandomizeName = true; //default true to enable security feature
  1215. if (version >= 15)
  1216. _dnsServer.QnameMinimization = bR.ReadBoolean();
  1217. else
  1218. _dnsServer.QnameMinimization = true; //default true to enable privacy feature
  1219. if (version >= 20)
  1220. {
  1221. _dnsServer.QpmLimitRequests = bR.ReadInt32();
  1222. _dnsServer.QpmLimitErrors = bR.ReadInt32();
  1223. _dnsServer.QpmLimitSampleMinutes = bR.ReadInt32();
  1224. _dnsServer.QpmLimitIPv4PrefixLength = bR.ReadInt32();
  1225. _dnsServer.QpmLimitIPv6PrefixLength = bR.ReadInt32();
  1226. }
  1227. else if (version >= 17)
  1228. {
  1229. _dnsServer.QpmLimitRequests = bR.ReadInt32();
  1230. _dnsServer.QpmLimitSampleMinutes = bR.ReadInt32();
  1231. _ = bR.ReadInt32(); //read obsolete value _dnsServer.QpmLimitSamplingIntervalInMinutes
  1232. }
  1233. else
  1234. {
  1235. _dnsServer.QpmLimitRequests = 0;
  1236. _dnsServer.QpmLimitErrors = 0;
  1237. _dnsServer.QpmLimitSampleMinutes = 1;
  1238. _dnsServer.QpmLimitIPv4PrefixLength = 24;
  1239. _dnsServer.QpmLimitIPv6PrefixLength = 56;
  1240. }
  1241. if (version >= 13)
  1242. {
  1243. _dnsServer.ServeStale = bR.ReadBoolean();
  1244. _dnsServer.CacheZoneManager.ServeStaleTtl = bR.ReadUInt32();
  1245. }
  1246. else
  1247. {
  1248. _dnsServer.ServeStale = true;
  1249. _dnsServer.CacheZoneManager.ServeStaleTtl = CacheZoneManager.SERVE_STALE_TTL;
  1250. }
  1251. if (version >= 9)
  1252. {
  1253. _dnsServer.CachePrefetchEligibility = bR.ReadInt32();
  1254. _dnsServer.CachePrefetchTrigger = bR.ReadInt32();
  1255. _dnsServer.CachePrefetchSampleIntervalInMinutes = bR.ReadInt32();
  1256. _dnsServer.CachePrefetchSampleEligibilityHitsPerHour = bR.ReadInt32();
  1257. }
  1258. else
  1259. {
  1260. _dnsServer.CachePrefetchEligibility = 2;
  1261. _dnsServer.CachePrefetchTrigger = 9;
  1262. _dnsServer.CachePrefetchSampleIntervalInMinutes = 5;
  1263. _dnsServer.CachePrefetchSampleEligibilityHitsPerHour = 30;
  1264. }
  1265. NetProxyType proxyType = (NetProxyType)bR.ReadByte();
  1266. if (proxyType != NetProxyType.None)
  1267. {
  1268. string address = bR.ReadShortString();
  1269. int port = bR.ReadInt32();
  1270. NetworkCredential credential = null;
  1271. if (bR.ReadBoolean()) //credential set
  1272. credential = new NetworkCredential(bR.ReadShortString(), bR.ReadShortString());
  1273. _dnsServer.Proxy = NetProxy.CreateProxy(proxyType, address, port, credential);
  1274. if (version >= 10)
  1275. {
  1276. int count = bR.ReadByte();
  1277. List<NetProxyBypassItem> bypassList = new List<NetProxyBypassItem>(count);
  1278. for (int i = 0; i < count; i++)
  1279. bypassList.Add(new NetProxyBypassItem(bR.ReadShortString()));
  1280. _dnsServer.Proxy.BypassList = bypassList;
  1281. }
  1282. else
  1283. {
  1284. _dnsServer.Proxy.BypassList = null;
  1285. }
  1286. }
  1287. else
  1288. {
  1289. _dnsServer.Proxy = null;
  1290. }
  1291. {
  1292. int count = bR.ReadByte();
  1293. if (count > 0)
  1294. {
  1295. NameServerAddress[] forwarders = new NameServerAddress[count];
  1296. for (int i = 0; i < count; i++)
  1297. {
  1298. forwarders[i] = new NameServerAddress(bR);
  1299. if (forwarders[i].Protocol == DnsTransportProtocol.HttpsJson)
  1300. forwarders[i] = forwarders[i].ChangeProtocol(DnsTransportProtocol.Https);
  1301. }
  1302. _dnsServer.Forwarders = forwarders;
  1303. }
  1304. }
  1305. if (version <= 10)
  1306. {
  1307. DnsTransportProtocol forwarderProtocol = (DnsTransportProtocol)bR.ReadByte();
  1308. if (forwarderProtocol == DnsTransportProtocol.HttpsJson)
  1309. forwarderProtocol = DnsTransportProtocol.Https;
  1310. if (_dnsServer.Forwarders != null)
  1311. {
  1312. List<NameServerAddress> forwarders = new List<NameServerAddress>();
  1313. foreach (NameServerAddress forwarder in _dnsServer.Forwarders)
  1314. {
  1315. if (forwarder.Protocol == forwarderProtocol)
  1316. forwarders.Add(forwarder);
  1317. else
  1318. forwarders.Add(forwarder.ChangeProtocol(forwarderProtocol));
  1319. }
  1320. _dnsServer.Forwarders = forwarders;
  1321. }
  1322. }
  1323. {
  1324. int count = bR.ReadByte();
  1325. if (count > 0)
  1326. {
  1327. if (version > 2)
  1328. {
  1329. for (int i = 0; i < count; i++)
  1330. {
  1331. string username = bR.ReadShortString();
  1332. string passwordHash = bR.ReadShortString();
  1333. if (username.Equals("admin", StringComparison.OrdinalIgnoreCase))
  1334. {
  1335. _authManager.LoadOldConfig(passwordHash, true);
  1336. break;
  1337. }
  1338. }
  1339. }
  1340. else
  1341. {
  1342. for (int i = 0; i < count; i++)
  1343. {
  1344. string username = bR.ReadShortString();
  1345. string password = bR.ReadShortString();
  1346. if (username.Equals("admin", StringComparison.OrdinalIgnoreCase))
  1347. {
  1348. _authManager.LoadOldConfig(password, false);
  1349. break;
  1350. }
  1351. }
  1352. }
  1353. }
  1354. }
  1355. if (version <= 6)
  1356. {
  1357. int count = bR.ReadInt32();
  1358. _configDisabledZones = new List<string>(count);
  1359. for (int i = 0; i < count; i++)
  1360. {
  1361. string domain = bR.ReadShortString();
  1362. _configDisabledZones.Add(domain);
  1363. }
  1364. }
  1365. if (version >= 18)
  1366. _dnsServer.EnableBlocking = bR.ReadBoolean();
  1367. else
  1368. _dnsServer.EnableBlocking = true;
  1369. if (version >= 18)
  1370. _dnsServer.BlockingType = (DnsServerBlockingType)bR.ReadByte();
  1371. else if (version >= 16)
  1372. _dnsServer.BlockingType = bR.ReadBoolean() ? DnsServerBlockingType.NxDomain : DnsServerBlockingType.AnyAddress;
  1373. else
  1374. _dnsServer.BlockingType = DnsServerBlockingType.AnyAddress;
  1375. if (version >= 18)
  1376. {
  1377. //read custom blocking addresses
  1378. int count = bR.ReadByte();
  1379. if (count > 0)
  1380. {
  1381. List<DnsARecordData> dnsARecords = new List<DnsARecordData>();
  1382. List<DnsAAAARecordData> dnsAAAARecords = new List<DnsAAAARecordData>();
  1383. for (int i = 0; i < count; i++)
  1384. {
  1385. IPAddress customAddress = IPAddressExtensions.ReadFrom(bR);
  1386. switch (customAddress.AddressFamily)
  1387. {
  1388. case AddressFamily.InterNetwork:
  1389. dnsARecords.Add(new DnsARecordData(customAddress));
  1390. break;
  1391. case AddressFamily.InterNetworkV6:
  1392. dnsAAAARecords.Add(new DnsAAAARecordData(customAddress));
  1393. break;
  1394. }
  1395. }
  1396. _dnsServer.CustomBlockingARecords = dnsARecords;
  1397. _dnsServer.CustomBlockingAAAARecords = dnsAAAARecords;
  1398. }
  1399. }
  1400. else
  1401. {
  1402. _dnsServer.CustomBlockingARecords = null;
  1403. _dnsServer.CustomBlockingAAAARecords = null;
  1404. }
  1405. if (version > 4)
  1406. {
  1407. //read block list urls
  1408. int count = bR.ReadByte();
  1409. for (int i = 0; i < count; i++)
  1410. {
  1411. string listUrl = bR.ReadShortString();
  1412. if (listUrl.StartsWith('!'))
  1413. _dnsServer.BlockListZoneManager.AllowListUrls.Add(new Uri(listUrl.Substring(1)));
  1414. else
  1415. _dnsServer.BlockListZoneManager.BlockListUrls.Add(new Uri(listUrl));
  1416. }
  1417. _settingsApi.BlockListLastUpdatedOn = bR.ReadDateTime();
  1418. if (version >= 13)
  1419. _settingsApi.BlockListUpdateIntervalHours = bR.ReadInt32();
  1420. }
  1421. else
  1422. {
  1423. _dnsServer.BlockListZoneManager.AllowListUrls.Clear();
  1424. _dnsServer.BlockListZoneManager.BlockListUrls.Clear();
  1425. _settingsApi.BlockListLastUpdatedOn = DateTime.MinValue;
  1426. _settingsApi.BlockListUpdateIntervalHours = 24;
  1427. }
  1428. if (version >= 11)
  1429. {
  1430. int count = bR.ReadByte();
  1431. if (count > 0)
  1432. {
  1433. IPEndPoint[] localEndPoints = new IPEndPoint[count];
  1434. for (int i = 0; i < count; i++)
  1435. localEndPoints[i] = (IPEndPoint)EndPointExtensions.ReadFrom(bR);
  1436. _dnsServer.LocalEndPoints = localEndPoints;
  1437. }
  1438. }
  1439. else if (version >= 6)
  1440. {
  1441. int count = bR.ReadByte();
  1442. if (count > 0)
  1443. {
  1444. IPEndPoint[] localEndPoints = new IPEndPoint[count];
  1445. for (int i = 0; i < count; i++)
  1446. localEndPoints[i] = new IPEndPoint(IPAddressExtensions.ReadFrom(bR), 53);
  1447. _dnsServer.LocalEndPoints = localEndPoints;
  1448. }
  1449. }
  1450. else
  1451. {
  1452. _dnsServer.LocalEndPoints = new IPEndPoint[] { new IPEndPoint(IPAddress.Any, 53), new IPEndPoint(IPAddress.IPv6Any, 53) };
  1453. }
  1454. if (version >= 8)
  1455. {
  1456. _dnsServer.EnableDnsOverHttp = bR.ReadBoolean();
  1457. _dnsServer.EnableDnsOverTls = bR.ReadBoolean();
  1458. _dnsServer.EnableDnsOverHttps = bR.ReadBoolean();
  1459. _dnsTlsCertificatePath = bR.ReadShortString();
  1460. _dnsTlsCertificatePassword = bR.ReadShortString();
  1461. if (_dnsTlsCertificatePath.Length == 0)
  1462. _dnsTlsCertificatePath = null;
  1463. if (_dnsTlsCertificatePath != null)
  1464. {
  1465. try
  1466. {
  1467. LoadDnsTlsCertificate(_dnsTlsCertificatePath, _dnsTlsCertificatePassword);
  1468. }
  1469. catch (Exception ex)
  1470. {
  1471. _log.Write("DNS Server encountered an error while loading DNS Server TLS certificate: " + _dnsTlsCertificatePath + "\r\n" + ex.ToString());
  1472. }
  1473. StartTlsCertificateUpdateTimer();
  1474. }
  1475. }
  1476. else
  1477. {
  1478. _dnsServer.EnableDnsOverHttp = false;
  1479. _dnsServer.EnableDnsOverTls = false;
  1480. _dnsServer.EnableDnsOverHttps = false;
  1481. _dnsTlsCertificatePath = string.Empty;
  1482. _dnsTlsCertificatePassword = string.Empty;
  1483. }
  1484. if (version >= 19)
  1485. {
  1486. _dnsServer.CacheZoneManager.MinimumRecordTtl = bR.ReadUInt32();
  1487. _dnsServer.CacheZoneManager.MaximumRecordTtl = bR.ReadUInt32();
  1488. _dnsServer.CacheZoneManager.NegativeRecordTtl = bR.ReadUInt32();
  1489. _dnsServer.CacheZoneManager.FailureRecordTtl = bR.ReadUInt32();
  1490. }
  1491. else
  1492. {
  1493. _dnsServer.CacheZoneManager.MinimumRecordTtl = CacheZoneManager.MINIMUM_RECORD_TTL;
  1494. _dnsServer.CacheZoneManager.MaximumRecordTtl = CacheZoneManager.MAXIMUM_RECORD_TTL;
  1495. _dnsServer.CacheZoneManager.NegativeRecordTtl = CacheZoneManager.NEGATIVE_RECORD_TTL;
  1496. _dnsServer.CacheZoneManager.FailureRecordTtl = CacheZoneManager.FAILURE_RECORD_TTL;
  1497. }
  1498. if (version >= 21)
  1499. {
  1500. int count = bR.ReadByte();
  1501. Dictionary<string, TsigKey> tsigKeys = new Dictionary<string, TsigKey>(count);
  1502. for (int i = 0; i < count; i++)
  1503. {
  1504. string keyName = bR.ReadShortString();
  1505. string sharedSecret = bR.ReadShortString();
  1506. TsigAlgorithm algorithm = (TsigAlgorithm)bR.ReadByte();
  1507. tsigKeys.Add(keyName, new TsigKey(keyName, sharedSecret, algorithm));
  1508. }
  1509. _dnsServer.TsigKeys = tsigKeys;
  1510. }
  1511. else if (version >= 20)
  1512. {
  1513. int count = bR.ReadByte();
  1514. Dictionary<string, TsigKey> tsigKeys = new Dictionary<string, TsigKey>(count);
  1515. for (int i = 0; i < count; i++)
  1516. {
  1517. string keyName = bR.ReadShortString();
  1518. string sharedSecret = bR.ReadShortString();
  1519. tsigKeys.Add(keyName, new TsigKey(keyName, sharedSecret, TsigAlgorithm.HMAC_SHA256));
  1520. }
  1521. _dnsServer.TsigKeys = tsigKeys;
  1522. }
  1523. else
  1524. {
  1525. _dnsServer.TsigKeys = null;
  1526. }
  1527. if (version >= 22)
  1528. _dnsServer.NsRevalidation = bR.ReadBoolean();
  1529. else
  1530. _dnsServer.NsRevalidation = true; //default true for security reasons
  1531. if (version >= 23)
  1532. {
  1533. _dnsServer.AllowTxtBlockingReport = bR.ReadBoolean();
  1534. _zonesApi.DefaultRecordTtl = bR.ReadUInt32();
  1535. }
  1536. else
  1537. {
  1538. _dnsServer.AllowTxtBlockingReport = true;
  1539. _zonesApi.DefaultRecordTtl = 3600;
  1540. }
  1541. if (version >= 24)
  1542. {
  1543. _webServiceUseSelfSignedTlsCertificate = bR.ReadBoolean();
  1544. SelfSignedCertCheck(false, false);
  1545. }
  1546. else
  1547. {
  1548. _webServiceUseSelfSignedTlsCertificate = false;
  1549. }
  1550. if (version >= 25)
  1551. _dnsServer.UdpPayloadSize = bR.ReadUInt16();
  1552. else
  1553. _dnsServer.UdpPayloadSize = DnsDatagram.EDNS_DEFAULT_UDP_PAYLOAD_SIZE;
  1554. if (version >= 26)
  1555. {
  1556. _dnsServer.DnssecValidation = bR.ReadBoolean();
  1557. _dnsServer.ResolverRetries = bR.ReadInt32();
  1558. _dnsServer.ResolverTimeout = bR.ReadInt32();
  1559. _dnsServer.ResolverMaxStackCount = bR.ReadInt32();
  1560. _dnsServer.ForwarderRetries = bR.ReadInt32();
  1561. _dnsServer.ForwarderTimeout = bR.ReadInt32();
  1562. _dnsServer.ForwarderConcurrency = bR.ReadInt32();
  1563. _dnsServer.ClientTimeout = bR.ReadInt32();
  1564. _dnsServer.TcpSendTimeout = bR.ReadInt32();
  1565. _dnsServer.TcpReceiveTimeout = bR.ReadInt32();
  1566. }
  1567. else
  1568. {
  1569. _dnsServer.DnssecValidation = true;
  1570. CreateForwarderZoneToDisableDnssecForNTP();
  1571. _dnsServer.ResolverRetries = 2;
  1572. _dnsServer.ResolverTimeout = 2000;
  1573. _dnsServer.ResolverMaxStackCount = 16;
  1574. _dnsServer.ForwarderRetries = 3;
  1575. _dnsServer.ForwarderTimeout = 2000;
  1576. _dnsServer.ForwarderConcurrency = 2;
  1577. _dnsServer.ClientTimeout = 4000;
  1578. _dnsServer.TcpSendTimeout = 10000;
  1579. _dnsServer.TcpReceiveTimeout = 10000;
  1580. }
  1581. if (version >= 27)
  1582. _dnsServer.CacheZoneManager.MaximumEntries = bR.ReadInt32();
  1583. else
  1584. _dnsServer.CacheZoneManager.MaximumEntries = 10000;
  1585. }
  1586. private void WriteConfigTo(BinaryWriter bW)
  1587. {
  1588. bW.Write(Encoding.ASCII.GetBytes("DS")); //format
  1589. bW.Write((byte)31); //version
  1590. //web service
  1591. {
  1592. bW.Write(_webServiceHttpPort);
  1593. bW.Write(_webServiceTlsPort);
  1594. {
  1595. bW.Write(Convert.ToByte(_webServiceLocalAddresses.Count));
  1596. foreach (IPAddress localAddress in _webServiceLocalAddresses)
  1597. localAddress.WriteTo(bW);
  1598. }
  1599. bW.Write(_webServiceEnableTls);
  1600. bW.Write(_webServiceHttpToTlsRedirect);
  1601. bW.Write(_webServiceUseSelfSignedTlsCertificate);
  1602. if (_webServiceTlsCertificatePath is null)
  1603. bW.WriteShortString(string.Empty);
  1604. else
  1605. bW.WriteShortString(_webServiceTlsCertificatePath);
  1606. if (_webServiceTlsCertificatePassword is null)
  1607. bW.WriteShortString(string.Empty);
  1608. else
  1609. bW.WriteShortString(_webServiceTlsCertificatePassword);
  1610. }
  1611. //dns
  1612. {
  1613. //general
  1614. bW.WriteShortString(_dnsServer.ServerDomain);
  1615. {
  1616. bW.Write(Convert.ToByte(_dnsServer.LocalEndPoints.Count));
  1617. foreach (IPEndPoint localEP in _dnsServer.LocalEndPoints)
  1618. localEP.WriteTo(bW);
  1619. }
  1620. bW.Write(_zonesApi.DefaultRecordTtl);
  1621. bW.Write(_appsApi.EnableAutomaticUpdate);
  1622. bW.Write(_dnsServer.PreferIPv6);
  1623. bW.Write(_dnsServer.UdpPayloadSize);
  1624. bW.Write(_dnsServer.DnssecValidation);
  1625. bW.Write(_dnsServer.EDnsClientSubnet);
  1626. bW.Write(_dnsServer.EDnsClientSubnetIPv4PrefixLength);
  1627. bW.Write(_dnsServer.EDnsClientSubnetIPv6PrefixLength);
  1628. bW.Write(_dnsServer.QpmLimitRequests);
  1629. bW.Write(_dnsServer.QpmLimitErrors);
  1630. bW.Write(_dnsServer.QpmLimitSampleMinutes);
  1631. bW.Write(_dnsServer.QpmLimitIPv4PrefixLength);
  1632. bW.Write(_dnsServer.QpmLimitIPv6PrefixLength);
  1633. bW.Write(_dnsServer.ClientTimeout);
  1634. bW.Write(_dnsServer.TcpSendTimeout);
  1635. bW.Write(_dnsServer.TcpReceiveTimeout);
  1636. bW.Write(_dnsServer.QuicIdleTimeout);
  1637. bW.Write(_dnsServer.QuicMaxInboundStreams);
  1638. bW.Write(_dnsServer.ListenBacklog);
  1639. //optional protocols
  1640. bW.Write(_dnsServer.EnableDnsOverHttp);
  1641. bW.Write(_dnsServer.EnableDnsOverTls);
  1642. bW.Write(_dnsServer.EnableDnsOverHttps);
  1643. bW.Write(_dnsServer.EnableDnsOverQuic);
  1644. bW.Write(_dnsServer.DnsOverHttpPort);
  1645. bW.Write(_dnsServer.DnsOverTlsPort);
  1646. bW.Write(_dnsServer.DnsOverHttpsPort);
  1647. bW.Write(_dnsServer.DnsOverQuicPort);
  1648. if (_dnsTlsCertificatePath == null)
  1649. bW.WriteShortString(string.Empty);
  1650. else
  1651. bW.WriteShortString(_dnsTlsCertificatePath);
  1652. if (_dnsTlsCertificatePassword == null)
  1653. bW.WriteShortString(string.Empty);
  1654. else
  1655. bW.WriteShortString(_dnsTlsCertificatePassword);
  1656. //tsig
  1657. if (_dnsServer.TsigKeys is null)
  1658. {
  1659. bW.Write((byte)0);
  1660. }
  1661. else
  1662. {
  1663. bW.Write(Convert.ToByte(_dnsServer.TsigKeys.Count));
  1664. foreach (KeyValuePair<string, TsigKey> tsigKey in _dnsServer.TsigKeys)
  1665. {
  1666. bW.WriteShortString(tsigKey.Key);
  1667. bW.WriteShortString(tsigKey.Value.SharedSecret);
  1668. bW.Write((byte)tsigKey.Value.Algorithm);
  1669. }
  1670. }
  1671. //recursion
  1672. bW.Write((byte)_dnsServer.Recursion);
  1673. if (_dnsServer.RecursionDeniedNetworks is null)
  1674. {
  1675. bW.Write((byte)0);
  1676. }
  1677. else
  1678. {
  1679. bW.Write(Convert.ToByte(_dnsServer.RecursionDeniedNetworks.Count));
  1680. foreach (NetworkAddress networkAddress in _dnsServer.RecursionDeniedNetworks)
  1681. networkAddress.WriteTo(bW);
  1682. }
  1683. if (_dnsServer.RecursionAllowedNetworks is null)
  1684. {
  1685. bW.Write((byte)0);
  1686. }
  1687. else
  1688. {
  1689. bW.Write(Convert.ToByte(_dnsServer.RecursionAllowedNetworks.Count));
  1690. foreach (NetworkAddress networkAddress in _dnsServer.RecursionAllowedNetworks)
  1691. networkAddress.WriteTo(bW);
  1692. }
  1693. bW.Write(_dnsServer.RandomizeName);
  1694. bW.Write(_dnsServer.QnameMinimization);
  1695. bW.Write(_dnsServer.NsRevalidation);
  1696. bW.Write(_dnsServer.ResolverRetries);
  1697. bW.Write(_dnsServer.ResolverTimeout);
  1698. bW.Write(_dnsServer.ResolverMaxStackCount);
  1699. //cache
  1700. bW.Write(_saveCache);
  1701. bW.Write(_dnsServer.ServeStale);
  1702. bW.Write(_dnsServer.CacheZoneManager.ServeStaleTtl);
  1703. bW.Write(_dnsServer.CacheZoneManager.MaximumEntries);
  1704. bW.Write(_dnsServer.CacheZoneManager.MinimumRecordTtl);
  1705. bW.Write(_dnsServer.CacheZoneManager.MaximumRecordTtl);
  1706. bW.Write(_dnsServer.CacheZoneManager.NegativeRecordTtl);
  1707. bW.Write(_dnsServer.CacheZoneManager.FailureRecordTtl);
  1708. bW.Write(_dnsServer.CachePrefetchEligibility);
  1709. bW.Write(_dnsServer.CachePrefetchTrigger);
  1710. bW.Write(_dnsServer.CachePrefetchSampleIntervalInMinutes);
  1711. bW.Write(_dnsServer.CachePrefetchSampleEligibilityHitsPerHour);
  1712. //blocking
  1713. bW.Write(_dnsServer.EnableBlocking);
  1714. bW.Write(_dnsServer.AllowTxtBlockingReport);
  1715. bW.Write((byte)_dnsServer.BlockingType);
  1716. {
  1717. bW.Write(Convert.ToByte(_dnsServer.CustomBlockingARecords.Count + _dnsServer.CustomBlockingAAAARecords.Count));
  1718. foreach (DnsARecordData record in _dnsServer.CustomBlockingARecords)
  1719. record.Address.WriteTo(bW);
  1720. foreach (DnsAAAARecordData record in _dnsServer.CustomBlockingAAAARecords)
  1721. record.Address.WriteTo(bW);
  1722. }
  1723. {
  1724. bW.Write(Convert.ToByte(_dnsServer.BlockListZoneManager.AllowListUrls.Count + _dnsServer.BlockListZoneManager.BlockListUrls.Count));
  1725. foreach (Uri allowListUrl in _dnsServer.BlockListZoneManager.AllowListUrls)
  1726. bW.WriteShortString("!" + allowListUrl.AbsoluteUri);
  1727. foreach (Uri blockListUrl in _dnsServer.BlockListZoneManager.BlockListUrls)
  1728. bW.WriteShortString(blockListUrl.AbsoluteUri);
  1729. bW.Write(_settingsApi.BlockListUpdateIntervalHours);
  1730. bW.Write(_settingsApi.BlockListLastUpdatedOn);
  1731. }
  1732. //proxy & forwarders
  1733. if (_dnsServer.Proxy == null)
  1734. {
  1735. bW.Write((byte)NetProxyType.None);
  1736. }
  1737. else
  1738. {
  1739. bW.Write((byte)_dnsServer.Proxy.Type);
  1740. bW.WriteShortString(_dnsServer.Proxy.Address);
  1741. bW.Write(_dnsServer.Proxy.Port);
  1742. NetworkCredential credential = _dnsServer.Proxy.Credential;
  1743. if (credential == null)
  1744. {
  1745. bW.Write(false);
  1746. }
  1747. else
  1748. {
  1749. bW.Write(true);
  1750. bW.WriteShortString(credential.UserName);
  1751. bW.WriteShortString(credential.Password);
  1752. }
  1753. //bypass list
  1754. {
  1755. bW.Write(Convert.ToByte(_dnsServer.Proxy.BypassList.Count));
  1756. foreach (NetProxyBypassItem item in _dnsServer.Proxy.BypassList)
  1757. bW.WriteShortString(item.Value);
  1758. }
  1759. }
  1760. if (_dnsServer.Forwarders == null)
  1761. {
  1762. bW.Write((byte)0);
  1763. }
  1764. else
  1765. {
  1766. bW.Write(Convert.ToByte(_dnsServer.Forwarders.Count));
  1767. foreach (NameServerAddress forwarder in _dnsServer.Forwarders)
  1768. forwarder.WriteTo(bW);
  1769. }
  1770. bW.Write(_dnsServer.ForwarderRetries);
  1771. bW.Write(_dnsServer.ForwarderTimeout);
  1772. bW.Write(_dnsServer.ForwarderConcurrency);
  1773. //logging
  1774. bW.Write(_dnsServer.QueryLogManager is not null); //log all queries
  1775. bW.Write(_dnsServer.StatsManager.MaxStatFileDays);
  1776. }
  1777. }
  1778. #endregion
  1779. #region public
  1780. public async Task StartAsync()
  1781. {
  1782. if (_disposed)
  1783. throw new ObjectDisposedException(nameof(DnsWebService));
  1784. try
  1785. {
  1786. //get initial server domain
  1787. string dnsServerDomain = Environment.MachineName.ToLower();
  1788. if (!DnsClient.IsDomainNameValid(dnsServerDomain))
  1789. dnsServerDomain = "dns-server-1"; //use this name instead since machine name is not a valid domain name
  1790. //init dns server
  1791. _dnsServer = new DnsServer(dnsServerDomain, _configFolder, Path.Combine(_appFolder, "dohwww"), _log);
  1792. //init dhcp server
  1793. _dhcpServer = new DhcpServer(Path.Combine(_configFolder, "scopes"), _log);
  1794. _dhcpServer.DnsServer = _dnsServer;
  1795. _dhcpServer.AuthManager = _authManager;
  1796. //load auth config
  1797. _authManager.LoadConfigFile();
  1798. //load config
  1799. LoadConfigFile();
  1800. //load all dns applications
  1801. _dnsServer.DnsApplicationManager.LoadAllApplications();
  1802. //load all zones files
  1803. _dnsServer.AuthZoneManager.LoadAllZoneFiles();
  1804. InspectAndFixZonePermissions();
  1805. //disable zones from old config format
  1806. if (_configDisabledZones != null)
  1807. {
  1808. foreach (string domain in _configDisabledZones)
  1809. {
  1810. AuthZoneInfo zoneInfo = _dnsServer.AuthZoneManager.GetAuthZoneInfo(domain);
  1811. if (zoneInfo is not null)
  1812. {
  1813. zoneInfo.Disabled = true;
  1814. _dnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
  1815. }
  1816. }
  1817. }
  1818. //load allowed zone and blocked zone
  1819. _dnsServer.AllowedZoneManager.LoadAllowedZoneFile();
  1820. _dnsServer.BlockedZoneManager.LoadBlockedZoneFile();
  1821. //load block list zone async
  1822. if (_dnsServer.BlockListZoneManager.BlockListUrls.Count > 0)
  1823. {
  1824. ThreadPool.QueueUserWorkItem(delegate (object state)
  1825. {
  1826. try
  1827. {
  1828. _dnsServer.BlockListZoneManager.LoadBlockLists();
  1829. }
  1830. catch (Exception ex)
  1831. {
  1832. _log.Write(ex);
  1833. }
  1834. });
  1835. }
  1836. if (_settingsApi.BlockListUpdateIntervalHours > 0)
  1837. _settingsApi.StartBlockListUpdateTimer();
  1838. //load dns cache async
  1839. if (_saveCache)
  1840. {
  1841. ThreadPool.QueueUserWorkItem(delegate (object state)
  1842. {
  1843. try
  1844. {
  1845. _dnsServer.CacheZoneManager.LoadCacheZoneFile();
  1846. }
  1847. catch (Exception ex)
  1848. {
  1849. _log.Write(ex);
  1850. }
  1851. });
  1852. }
  1853. //start web service
  1854. await TryStartWebServiceAsync();
  1855. //start dns and dhcp
  1856. await _dnsServer.StartAsync();
  1857. _dhcpServer.Start();
  1858. _log.Write("DNS Server (v" + _currentVersion.ToString() + ") was started successfully.");
  1859. }
  1860. catch (Exception ex)
  1861. {
  1862. _log.Write("Failed to start DNS Server (v" + _currentVersion.ToString() + ")\r\n" + ex.ToString());
  1863. throw;
  1864. }
  1865. }
  1866. public async Task StopAsync()
  1867. {
  1868. if (_disposed || (_dnsServer is null))
  1869. return;
  1870. try
  1871. {
  1872. //stop dns
  1873. if (_dnsServer is not null)
  1874. await _dnsServer.DisposeAsync();
  1875. //stop dhcp
  1876. if (_dhcpServer is not null)
  1877. _dhcpServer.Dispose();
  1878. //stop web service
  1879. if (_settingsApi is not null)
  1880. {
  1881. _settingsApi.StopBlockListUpdateTimer();
  1882. _settingsApi.StopTemporaryDisableBlockingTimer();
  1883. }
  1884. StopTlsCertificateUpdateTimer();
  1885. await StopWebServiceAsync();
  1886. if (_saveCache)
  1887. {
  1888. try
  1889. {
  1890. _dnsServer.CacheZoneManager.SaveCacheZoneFile();
  1891. }
  1892. catch (Exception ex)
  1893. {
  1894. _log.Write(ex);
  1895. }
  1896. }
  1897. _log?.Write("DNS Server (v" + _currentVersion.ToString() + ") was stopped successfully.");
  1898. _dnsServer = null;
  1899. }
  1900. catch (Exception ex)
  1901. {
  1902. _log?.Write("Failed to stop DNS Server (v" + _currentVersion.ToString() + ")\r\n" + ex.ToString());
  1903. throw;
  1904. }
  1905. }
  1906. public void Start()
  1907. {
  1908. StartAsync().Sync();
  1909. }
  1910. public void Stop()
  1911. {
  1912. StopAsync().Sync();
  1913. }
  1914. #endregion
  1915. #region properties
  1916. internal DnsServer DnsServer
  1917. { get { return _dnsServer; } }
  1918. internal DhcpServer DhcpServer
  1919. { get { return _dhcpServer; } }
  1920. public string ConfigFolder
  1921. { get { return _configFolder; } }
  1922. public int WebServiceHttpPort
  1923. { get { return _webServiceHttpPort; } }
  1924. public int WebServiceTlsPort
  1925. { get { return _webServiceTlsPort; } }
  1926. #endregion
  1927. }
  1928. }