DnsWebService.cs 120 KB

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