DnsWebService.cs 122 KB

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