DnsWebService.cs 116 KB

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