DnsWebService.cs 103 KB

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