Giter Club home page Giter Club logo

Comments (20)

ShreyasZare avatar ShreyasZare commented on June 1, 2024 1

Thanks for the request. Will get the environment variable added in the upcoming update.

from dnsserver.

ShreyasZare avatar ShreyasZare commented on June 1, 2024 1

How is your release schedule? I'd like to know when I should check back.

The next update is planned for upcoming weekend but it may get a bit delayed too. I will post here when its available so that you are notified.

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Doing a code search for how this text field is handled...

Element ID: txtWebServiceLocalAddresses

That element gets sanitized for saving here:

//web service
var webServiceLocalAddresses = cleanTextList($("#txtWebServiceLocalAddresses").val());
if ((webServiceLocalAddresses.length === 0) || (webServiceLocalAddresses === ","))
webServiceLocalAddresses = "0.0.0.0,[::]";
else
$("#txtWebServiceLocalAddresses").val(webServiceLocalAddresses.replace(/,/g, "\n"));

relevant HTTP request:

HTTPRequest({
url: "/api/settings/set",
method: "POST",
data: "token=" + sessionData.token + "&dnsServerDomain=" + dnsServerDomain + "&dnsServerLocalEndPoints=" + encodeURIComponent(dnsServerLocalEndPoints) + "&dnsServerIPv4SourceAddresses=" + encodeURIComponent(dnsServerIPv4SourceAddresses) + "&dnsServerIPv6SourceAddresses=" + encodeURIComponent(dnsServerIPv6SourceAddresses)
+ "&defaultRecordTtl=" + defaultRecordTtl + "&useSoaSerialDateScheme=" + useSoaSerialDateScheme + "&zoneTransferAllowedNetworks=" + encodeURIComponent(zoneTransferAllowedNetworks) + "&notifyAllowedNetworks=" + encodeURIComponent(notifyAllowedNetworks) + "&dnsAppsEnableAutomaticUpdate=" + dnsAppsEnableAutomaticUpdate + "&preferIPv6=" + preferIPv6 + "&udpPayloadSize=" + udpPayloadSize + "&dnssecValidation=" + dnssecValidation
+ "&eDnsClientSubnet=" + eDnsClientSubnet + "&eDnsClientSubnetIPv4PrefixLength=" + eDnsClientSubnetIPv4PrefixLength + "&eDnsClientSubnetIPv6PrefixLength=" + eDnsClientSubnetIPv6PrefixLength
+ "&qpmLimitRequests=" + qpmLimitRequests + "&qpmLimitErrors=" + qpmLimitErrors + "&qpmLimitSampleMinutes=" + qpmLimitSampleMinutes + "&qpmLimitIPv4PrefixLength=" + qpmLimitIPv4PrefixLength + "&qpmLimitIPv6PrefixLength=" + qpmLimitIPv6PrefixLength + "&qpmLimitBypassList=" + encodeURIComponent(qpmLimitBypassList)
+ "&clientTimeout=" + clientTimeout + "&tcpSendTimeout=" + tcpSendTimeout + "&tcpReceiveTimeout=" + tcpReceiveTimeout + "&quicIdleTimeout=" + quicIdleTimeout + "&quicMaxInboundStreams=" + quicMaxInboundStreams + "&listenBacklog=" + listenBacklog
+ "&webServiceLocalAddresses=" + encodeURIComponent(webServiceLocalAddresses) + "&webServiceHttpPort=" + webServiceHttpPort + "&webServiceEnableTls=" + webServiceEnableTls + "&webServiceEnableHttp3=" + webServiceEnableHttp3 + "&webServiceHttpToTlsRedirect=" + webServiceHttpToTlsRedirect + "&webServiceUseSelfSignedTlsCertificate=" + webServiceUseSelfSignedTlsCertificate + "&webServiceTlsPort=" + webServiceTlsPort + "&webServiceTlsCertificatePath=" + encodeURIComponent(webServiceTlsCertificatePath) + "&webServiceTlsCertificatePassword=" + encodeURIComponent(webServiceTlsCertificatePassword)
+ "&enableDnsOverUdpProxy=" + enableDnsOverUdpProxy + "&enableDnsOverTcpProxy=" + enableDnsOverTcpProxy + "&enableDnsOverHttp=" + enableDnsOverHttp + "&enableDnsOverTls=" + enableDnsOverTls + "&enableDnsOverHttps=" + enableDnsOverHttps + "&enableDnsOverQuic=" + enableDnsOverQuic + "&dnsOverUdpProxyPort=" + dnsOverUdpProxyPort + "&dnsOverTcpProxyPort=" + dnsOverTcpProxyPort + "&dnsOverHttpPort=" + dnsOverHttpPort + "&dnsOverTlsPort=" + dnsOverTlsPort + "&dnsOverHttpsPort=" + dnsOverHttpsPort + "&dnsOverQuicPort=" + dnsOverQuicPort + "&dnsTlsCertificatePath=" + encodeURIComponent(dnsTlsCertificatePath) + "&dnsTlsCertificatePassword=" + encodeURIComponent(dnsTlsCertificatePassword)
+ "&tsigKeys=" + encodeURIComponent(tsigKeys)
+ "&recursion=" + recursion + "&recursionDeniedNetworks=" + encodeURIComponent(recursionDeniedNetworks) + "&recursionAllowedNetworks=" + encodeURIComponent(recursionAllowedNetworks) + "&randomizeName=" + randomizeName + "&qnameMinimization=" + qnameMinimization + "&nsRevalidation=" + nsRevalidation + "&resolverRetries=" + resolverRetries + "&resolverTimeout=" + resolverTimeout + "&resolverMaxStackCount=" + resolverMaxStackCount
+ "&saveCache=" + saveCache + "&serveStale=" + serveStale + "&serveStaleTtl=" + serveStaleTtl + "&cacheMaximumEntries=" + cacheMaximumEntries + "&cacheMinimumRecordTtl=" + cacheMinimumRecordTtl + "&cacheMaximumRecordTtl=" + cacheMaximumRecordTtl + "&cacheNegativeRecordTtl=" + cacheNegativeRecordTtl + "&cacheFailureRecordTtl=" + cacheFailureRecordTtl + "&cachePrefetchEligibility=" + cachePrefetchEligibility + "&cachePrefetchTrigger=" + cachePrefetchTrigger + "&cachePrefetchSampleIntervalInMinutes=" + cachePrefetchSampleIntervalInMinutes + "&cachePrefetchSampleEligibilityHitsPerHour=" + cachePrefetchSampleEligibilityHitsPerHour
+ "&enableBlocking=" + enableBlocking + "&allowTxtBlockingReport=" + allowTxtBlockingReport + "&blockingBypassList=" + encodeURIComponent(blockingBypassList) + "&blockingType=" + blockingType + "&customBlockingAddresses=" + encodeURIComponent(customBlockingAddresses) + "&blockListUrls=" + encodeURIComponent(blockListUrls) + "&blockListUpdateIntervalHours=" + blockListUpdateIntervalHours
+ proxy + "&forwarders=" + encodeURIComponent(forwarders) + "&forwarderProtocol=" + forwarderProtocol + "&forwarderRetries=" + forwarderRetries + "&forwarderTimeout=" + forwarderTimeout + "&forwarderConcurrency=" + forwarderConcurrency
+ "&enableLogging=" + enableLogging + "&ignoreResolverLogs=" + ignoreResolverLogs + "&logQueries=" + logQueries + "&useLocalTime=" + useLocalTime + "&logFolder=" + encodeURIComponent(logFolder) + "&maxLogFileDays=" + maxLogFileDays + "&enableInMemoryStats=" + enableInMemoryStats + "&maxStatFileDays=" + maxStatFileDays,
processData: false,
showInnerError: true,
success: function (responseJSON) {
loadDnsSettings(responseJSON);

and it is retrieved here:

var dnsServerLocalEndPoints = responseJSON.response.dnsServerLocalEndPoints;
if (dnsServerLocalEndPoints == null)
$("#txtDnsServerLocalEndPoints").val("");
else
$("#txtDnsServerLocalEndPoints").val(getArrayAsString(dnsServerLocalEndPoints));

relevant HTTP request:

HTTPRequest({
url: "/api/settings/get?token=" + sessionData.token,
success: function (responseJSON) {
loadDnsSettings(responseJSON);
checkForReverseProxy(responseJSON);
divDnsSettingsLoader.hide();
divDnsSettings.show();
},
invalidToken: function () {
showPageLogin();
},
objLoaderPlaceholder: divDnsSettingsLoader
});

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Settings API source code:

https://github.com/TechnitiumSoftware/DnsServer/blob/master/DnsServerCore/WebServiceSettingsApi.cs

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Relevant lines for setting the web addresss:

IReadOnlyList<IPAddress> oldWebServiceLocalAddresses = _dnsWebService._webServiceLocalAddresses;

string webServiceLocalAddresses = request.QueryOrForm("webServiceLocalAddresses");
if (webServiceLocalAddresses is not null)
{
if (webServiceLocalAddresses.Length == 0)
webServiceLocalAddresses = "0.0.0.0,[::]";
IPAddress[] localAddresses = webServiceLocalAddresses.Split(IPAddress.Parse, ',');
if (localAddresses.Length > 0)
{
if (_dnsWebService._webServiceLocalAddresses.Count != localAddresses.Length)
{
restartWebService = true;
}
else
{
foreach (IPAddress currentlocalAddress in _dnsWebService._webServiceLocalAddresses)
{
if (!localAddresses.Contains(currentlocalAddress))
{
restartWebService = true;
break;
}
}
}
_dnsWebService._webServiceLocalAddresses = DnsServer.GetValidKestralLocalAddresses(localAddresses);
}
}

Note this line from the above blob:

restartWebService = true;

The restart of the server (and the application of the new listening address), starts here:

https://github.com/TechnitiumSoftware/DnsServer/blob/master/DnsServerCore/WebServiceSettingsApi.cs#L1344

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

It is appears that while running, the webserver uses _dnsWebService._webServiceLocalAddresses for storing the listening address

The class for this is defined here:

https://github.com/TechnitiumSoftware/DnsServer/blob/master/DnsServerCore/DnsWebService.cs

Here is the property:

internal IReadOnlyList<IPAddress> _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any, IPAddress.IPv6Any };

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

This appears to be where the config is read from:

private void ReadConfigFrom(BinaryReader bR, int version)

{
int count = bR.ReadByte();
if (count > 0)
{
IPAddress[] localAddresses = new IPAddress[count];
for (int i = 0; i < count; i++)
localAddresses[i] = IPAddressExtensions.ReadFrom(bR);
_webServiceLocalAddresses = localAddresses;
}
else
{
_webServiceLocalAddresses = new IPAddress[] { IPAddress.Any, IPAddress.IPv6Any };
}
}

Which is wrapped by this method:

private int ReadConfigFrom(BinaryReader bR)
{
if (Encoding.ASCII.GetString(bR.ReadBytes(2)) != "DS") //format
throw new InvalidDataException("DNS Server config file format is invalid.");
int version = bR.ReadByte();
if ((version >= 28) && (version <= 34))
{
ReadConfigFrom(bR, version);
}
else if ((version >= 2) && (version <= 27))
{
ReadOldConfigFrom(bR, version);
//new default settings
DnsClientConnection.IPv4SourceAddresses = null;
DnsClientConnection.IPv6SourceAddresses = null;
_webServiceEnableHttp3 = _webServiceEnableTls && IsQuicSupported();
_dnsServer.AuthZoneManager.UseSoaSerialDateScheme = false;
_dnsServer.ZoneTransferAllowedNetworks = null;
_dnsServer.NotifyAllowedNetworks = null;
_dnsServer.QpmLimitBypassList = null;
_dnsServer.BlockingBypassList = null;
_dnsServer.ResolverLogManager = _log;
_appsApi.EnableAutomaticUpdate = true;
_dnsServer.StatsManager.EnableInMemoryStats = false;
}
else
{
throw new InvalidDataException("DNS Server config version not supported.");
}
return version;
}

Which is called by this method:

internal void LoadConfigFile()

Which loads the config file with this snippet:

string configFile = Path.Combine(_configFolder, "dns.config");
try
{
int version;
using (FileStream fS = new FileStream(configFile, FileMode.Open, FileAccess.Read))
{
version = ReadConfigFrom(new BinaryReader(fS));
}
_log.Write("DNS Server config file was loaded: " + configFile);
if (version <= 27)
SaveConfigFile(); //save as new config version to avoid loading old version next time
}

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Config file (for the DnsWebService class) appears to be defined here on Linux:

service = new DnsWebService(configFolder, updateCheckUri, new Uri("https://go.technitium.com/?id=44"));

Which is pulled from the arguments passed to the executable:

if (args.Length == 1)
configFolder = args[0];

Which for docker, is defined in the service file:

ExecStart=/usr/bin/dotnet /opt/technitium/dns/DnsServerApp.dll /etc/dns

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Next thing I need to do is to determine if I can even interact with that binary file (dns.config). When I try to cat it on ubuntu, I got a bunch of garbage in the output, so it does not appear to be plain text

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Looks like it should be easy to set it with the LoadConfigFile() method:

string strWebServiceHttpPort = Environment.GetEnvironmentVariable("DNS_SERVER_WEB_SERVICE_HTTP_PORT");
if (!string.IsNullOrEmpty(strWebServiceHttpPort))
_webServiceHttpPort = int.Parse(strWebServiceHttpPort);
string webServiceTlsPort = Environment.GetEnvironmentVariable("DNS_SERVER_WEB_SERVICE_HTTPS_PORT");
if (!string.IsNullOrEmpty(webServiceTlsPort))
_webServiceTlsPort = int.Parse(webServiceTlsPort);
string webServiceEnableTls = Environment.GetEnvironmentVariable("DNS_SERVER_WEB_SERVICE_ENABLE_HTTPS");
if (!string.IsNullOrEmpty(webServiceEnableTls))
_webServiceEnableTls = bool.Parse(webServiceEnableTls);
string webServiceUseSelfSignedTlsCertificate = Environment.GetEnvironmentVariable("DNS_SERVER_WEB_SERVICE_USE_SELF_SIGNED_CERT");
if (!string.IsNullOrEmpty(webServiceUseSelfSignedTlsCertificate))
_webServiceUseSelfSignedTlsCertificate = bool.Parse(webServiceUseSelfSignedTlsCertificate);

You would just have to transpile the sanitization scripts and place them in the above blob

frontend:

//web service
var webServiceLocalAddresses = cleanTextList($("#txtWebServiceLocalAddresses").val());
if ((webServiceLocalAddresses.length === 0) || (webServiceLocalAddresses === ","))
webServiceLocalAddresses = "0.0.0.0,[::]";
else
$("#txtWebServiceLocalAddresses").val(webServiceLocalAddresses.replace(/,/g, "\n"));

backend:

string webServiceLocalAddresses = request.QueryOrForm("webServiceLocalAddresses");
if (webServiceLocalAddresses is not null)
{
if (webServiceLocalAddresses.Length == 0)
webServiceLocalAddresses = "0.0.0.0,[::]";
IPAddress[] localAddresses = webServiceLocalAddresses.Split(IPAddress.Parse, ',');
if (localAddresses.Length > 0)
{
if (_dnsWebService._webServiceLocalAddresses.Count != localAddresses.Length)
{
restartWebService = true;
}
else
{
foreach (IPAddress currentlocalAddress in _dnsWebService._webServiceLocalAddresses)
{
if (!localAddresses.Contains(currentlocalAddress))
{
restartWebService = true;
break;
}
}
}
_dnsWebService._webServiceLocalAddresses = DnsServer.GetValidKestralLocalAddresses(localAddresses);
}
}

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

It looks like it might not even need to be that complicated, since cleanTextList just replaces newlines and removes additional commas

// Replace newlines with commas
string webServiceLocalAddresses = input.Replace("\n", ",")

// Replace duplicate commas with single commas
webServiceLocalAddresses = Regex.Replace(webServiceLocalAddresses, ",{2,}", ",");

// Trim the string of starting/trailing whitespace and commas
webServiceLocalAddresses = Regex.Replace(webServiceLocalAddresses, "(?:^[, ]+)|(?:[, ]+$)", ",");

// insert above snippet from DnsServerCore/WebServiceSettingsApi.cs (lines L703-L730)
// ...

I currently lack an environment to build and test on right now, but if someone thinks they can get a fork/PR spun up faster than me, please go for it. If not, I might have my lab back up and running by end of this week or next week.

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

How is your release schedule? I'd like to know when I should check back.

from dnsserver.

ShreyasZare avatar ShreyasZare commented on June 1, 2024

Technitium DNS Server v12.1 is now available that adds the environment variable. Do update and let me know your feedback.

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Will do. Have inspections this weekend, so this will likely get implemented later this week

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

New environment variable (DNS_SERVER_WEB_SERVICE_LOCAL_ADDRESSES) will need to be added to the docker compose file.

Testing out the change now. Give me a bit

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Works for singular listening address.

DNS_SERVER_WEB_SERVICE_LOCAL_ADDRESSES="172.18.0.1" # Single Docker bridge address

Rebuilding it for 2 addresses

DNS_SERVER_WEB_SERVICE_LOCAL_ADDRESSES="172.18.0.1, 172.17.0.1" # Multiple Docker bridge addresses, comma-delimited

I'm not entirely sure if the environment variables can handle line returns, but I don't see why anyone would use line returns over the comma-delimiter for this. So I won't test that.

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

It did not like the comma-delimited address

EDIT: also tried newlines with compose.yaml:

- DNS_SERVER_WEB_SERVICE_LOCAL_ADDRESSES=|
          172.18.0.1
          127.0.0.1 # also changed this just in case it didn't like the docker bridge adapter

Did not work, but newlines seem like a strange way to do this from yaml, so I would worry about the prior, but not the latter.

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Here are the logs:

dns-dhcp-test  | System.FormatException: An invalid IP address was specified.
dns-dhcp-test  |  ---> System.Net.Sockets.SocketException (22): Invalid argument
dns-dhcp-test  |    --- End of inner exception stack trace ---
dns-dhcp-test  |    at System.Net.IPAddressParser.Parse(ReadOnlySpan`1 ipSpan, Boolean tryParse)
dns-dhcp-test  |    at TechnitiumLibrary.StringExtensions.Split[T](String value, Func`2 parse, Char[] separator) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary\StringExtensions.cs:line 34
dns-dhcp-test  |    at DnsServerCore.DnsWebService.LoadConfigFile() in Z:\Technitium\Projects\DnsServer\DnsServerCore\DnsWebService.cs:line 898
dns-dhcp-test  |    at DnsServerCore.DnsWebService.StartAsync() in Z:\Technitium\Projects\DnsServer\DnsServerCore\DnsWebService.cs:line 2540
dns-dhcp-test  |    at TechnitiumLibrary.TaskExtensions.Sync(Task task) in Z:\Technitium\Projects\TechnitiumLibrary\TechnitiumLibrary\TaskExtensions.cs:line 56
dns-dhcp-test  |    at DnsServerCore.DnsWebService.Start() in Z:\Technitium\Projects\DnsServer\DnsServerCore\DnsWebService.cs:line 2668
dns-dhcp-test  |    at DnsServerApp.Program.Main(String[] args) in Z:\Technitium\Projects\DnsServer\DnsServerApp\Program.cs:line 55
dns-dhcp-test  | 
dns-dhcp-test  | Technitium DNS Server is stopping...
dns-dhcp-test  | Technitium DNS Server was stopped successfully.
dns-dhcp-test exited with code 0

from dnsserver.

anonhostpi avatar anonhostpi commented on June 1, 2024

Got it. The compose file did not like the quotes, so in YAML you can use:

- DNS_SERVER_WEB_SERVICE_LOCAL_ADDRESSES=172.18.0.1,127.0.0.1

image

Will be submitting a PR for the docker compose file

from dnsserver.

ShreyasZare avatar ShreyasZare commented on June 1, 2024

Thanks for the feedback and for the PR. Had missed updating the docker compose file to add it.

from dnsserver.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.