Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 96 additions & 2 deletions DnsServerCore/Dns/DnsServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ enum ServiceState
int _dnsOverTlsPort = 853;
int _dnsOverHttpsPort = 443;
int _dnsOverQuicPort = 853;
string _dnsOverHttpUnixSocket;
string _dnsOverHttpsUnixSocket;
string _dnsTlsCertificatePath;
string _dnsTlsCertificatePassword;
string _dnsOverHttpRealIpHeader = "X-Real-IP";
Expand Down Expand Up @@ -632,7 +634,7 @@ private void ReadConfigFrom(Stream s, bool isConfigTransfer)
throw new InvalidDataException("DNS Server config file format is invalid.");

int version = bR.ReadByte();
if ((version < 1) || (version > 2))
if ((version < 1) || (version > 3))
throw new InvalidDataException("DNS Server config version not supported.");

//general
Expand Down Expand Up @@ -1078,14 +1080,31 @@ private void ReadConfigFrom(Stream s, bool isConfigTransfer)
int maxStatFileDays = bR.ReadInt32();
if (!isConfigTransfer)
_statsManager.MaxStatFileDays = maxStatFileDays;

if (version >= 3)
{
if (bR.ReadByte() > 0)
{
string socket = bR.ReadShortString();
if (!isConfigTransfer)
_dnsOverHttpUnixSocket = socket;
}

if (bR.ReadByte() > 0)
{
string socket = bR.ReadShortString();
if (!isConfigTransfer)
_dnsOverHttpsUnixSocket = socket;
}
}
}

private void WriteConfigTo(Stream s)
{
BinaryWriter bW = new BinaryWriter(s);

bW.Write(Encoding.ASCII.GetBytes("DC")); //format
bW.Write((byte)2); //version
bW.Write((byte)3); //version

//general
bW.WriteShortString(_serverDomain);
Expand Down Expand Up @@ -1359,6 +1378,26 @@ private void WriteConfigTo(Stream s)
bW.Write(_queryLog is not null); //log all queries
bW.Write(_statsManager.EnableInMemoryStats);
bW.Write(_statsManager.MaxStatFileDays);

if (string.IsNullOrWhiteSpace(_dnsOverHttpUnixSocket))
{
bW.Write((byte)0);
}
else
{
bW.Write((byte)1);
bW.WriteShortString(_dnsOverHttpUnixSocket);
}

if (string.IsNullOrWhiteSpace(_dnsOverHttpsUnixSocket))
{
bW.Write((byte)0);
}
else
{
bW.Write((byte)1);
bW.WriteShortString(_dnsOverHttpsUnixSocket);
}
}

#endregion
Expand Down Expand Up @@ -5998,6 +6037,9 @@ private async Task StartDoHAsync(bool throwIfBindFails)
{
foreach (IPAddress localAddress in localAddresses)
serverOptions.Listen(localAddress, _dnsOverHttpPort);

if (!string.IsNullOrWhiteSpace(_dnsOverHttpUnixSocket))
serverOptions.ListenUnixSocket(_dnsOverHttpUnixSocket);
}

//bind to https port
Expand All @@ -6020,6 +6062,22 @@ private async Task StartDoHAsync(bool throwIfBindFails)
}, null);
});
}

if (!string.IsNullOrWhiteSpace(_dnsOverHttpsUnixSocket))
{
serverOptions.ListenUnixSocket(_dnsOverHttpsUnixSocket, delegate (ListenOptions listenOptions)
{
if (IsHttp2Supported())
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
else
listenOptions.Protocols = HttpProtocols.Http1;

listenOptions.UseHttps(delegate (SslStream stream, SslClientHelloInfo clientHelloInfo, object state, CancellationToken cancellationToken)
{
return ValueTask.FromResult(_dohSslServerAuthenticationOptions);
}, null);
});
}
}

serverOptions.AddServerHeader = false;
Expand Down Expand Up @@ -6061,6 +6119,18 @@ private async Task StartDoHAsync(bool throwIfBindFails)
if (_enableDnsOverHttps && (_dohSslServerAuthenticationOptions is not null))
_log.Write(new IPEndPoint(localAddress, _dnsOverHttpsPort), "Https", "DNS Server was bound successfully.");
}

if (_enableDnsOverHttp)
{
if (!string.IsNullOrWhiteSpace(_dnsOverHttpUnixSocket))
_log.Write(new IPEndPoint(IPAddress.None, 0), "Http", $"DNS Server was bound successfully on unix socket: {_dnsOverHttpUnixSocket}");
}

if (_enableDnsOverHttps && (_dohSslServerAuthenticationOptions is not null))
{
if (!string.IsNullOrWhiteSpace(_dnsOverHttpsUnixSocket))
_log.Write(new IPEndPoint(IPAddress.None, 0), "Https", $"DNS Server was bound successfully on unix socket: {_dnsOverHttpsUnixSocket}");
}
}
catch (Exception ex)
{
Expand All @@ -6075,6 +6145,18 @@ private async Task StartDoHAsync(bool throwIfBindFails)
_log.Write(new IPEndPoint(localAddress, _dnsOverHttpsPort), "Https", "DNS Server failed to bind.");
}

if (_enableDnsOverHttp)
{
if (!string.IsNullOrWhiteSpace(_dnsOverHttpUnixSocket))
_log.Write(new IPEndPoint(IPAddress.None, 0), "Http", $"DNS Server failed to bind on unix socket: {_dnsOverHttpUnixSocket}");
}

if (_enableDnsOverHttps && (_dohSslServerAuthenticationOptions is not null))
{
if (!string.IsNullOrWhiteSpace(_dnsOverHttpsUnixSocket))
_log.Write(new IPEndPoint(IPAddress.None, 0), "Https", $"DNS Server failed to bind on unix socket: {_dnsOverHttpsUnixSocket}");
}

_log.Write(ex);

if (throwIfBindFails)
Expand Down Expand Up @@ -7212,6 +7294,18 @@ public int DnsOverQuicPort
}
}

public string DnsOverHttpUnixSocket
{
get { return _dnsOverHttpUnixSocket; }
set { _dnsOverHttpUnixSocket = value; }
}

public string DnsOverHttpsUnixSocket
{
get { return _dnsOverHttpsUnixSocket; }
set { _dnsOverHttpsUnixSocket = value; }
}

public string DnsTlsCertificatePath
{ get { return _dnsTlsCertificatePath; } }

Expand Down
76 changes: 74 additions & 2 deletions DnsServerCore/DnsWebService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ public sealed partial class DnsWebService : IAsyncDisposable, IDisposable

//web service
IReadOnlyList<IPAddress> _webServiceLocalAddresses = [IPAddress.Any, IPAddress.IPv6Any];
string _webServiceHttpUnixSocket;
string _webServiceTlsUnixSocket;
int _webServiceHttpPort = 5380;
int _webServiceTlsPort = 53443;
bool _webServiceEnableTls;
Expand Down Expand Up @@ -438,7 +440,7 @@ private void ReadConfigFrom(Stream s)
throw new InvalidDataException("Web Service config file format is invalid.");

int version = bR.ReadByte();
if (version > 1)
if (version > 2)
throw new InvalidDataException("Web Service config version not supported.");

_webServiceHttpPort = bR.ReadInt32();
Expand Down Expand Up @@ -499,14 +501,27 @@ private void ReadConfigFrom(Stream s)
CheckAndLoadSelfSignedCertificate(false, false);

_webServiceRealIpHeader = bR.ReadShortString();

if (version >= 2)
{
if (bR.ReadByte() > 0)
{
_webServiceHttpUnixSocket = bR.ReadShortString();
}

if (bR.ReadByte() > 0)
{
_webServiceTlsUnixSocket = bR.ReadShortString();
}
}
}

private void WriteConfigTo(Stream s)
{
BinaryWriter bW = new BinaryWriter(s);

bW.Write(Encoding.ASCII.GetBytes("WC")); //format
bW.Write((byte)1); //version
bW.Write((byte)2); //version

bW.Write(_webServiceHttpPort);
bW.Write(_webServiceTlsPort);
Expand Down Expand Up @@ -534,6 +549,26 @@ private void WriteConfigTo(Stream s)
bW.WriteShortString(_webServiceTlsCertificatePassword);

bW.WriteShortString(_webServiceRealIpHeader);

if (string.IsNullOrWhiteSpace(_webServiceHttpUnixSocket))
{
bW.Write((byte)0);
}
else
{
bW.Write((byte)1);
bW.WriteShortString(_webServiceHttpUnixSocket);
}

if (string.IsNullOrWhiteSpace(_webServiceTlsUnixSocket))
{
bW.Write((byte)0);
}
else
{
bW.Write((byte)1);
bW.WriteShortString(_webServiceTlsUnixSocket);
}
}

#endregion
Expand Down Expand Up @@ -1547,6 +1582,9 @@ private async Task StartWebServiceAsync(bool httpOnlyMode)
foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
serverOptions.Listen(webServiceLocalAddress, _webServiceHttpPort);

if (!string.IsNullOrWhiteSpace(_webServiceHttpUnixSocket))
serverOptions.ListenUnixSocket(_webServiceHttpUnixSocket);

//https
if (!httpOnlyMode && _webServiceEnableTls && (_webServiceSslServerAuthenticationOptions is not null))
{
Expand All @@ -1567,6 +1605,22 @@ private async Task StartWebServiceAsync(bool httpOnlyMode)
}, null);
});
}

if (!string.IsNullOrWhiteSpace(_webServiceTlsUnixSocket))
{
serverOptions.ListenUnixSocket(_webServiceTlsUnixSocket, delegate (ListenOptions listenOptions)
{
if (IsHttp2Supported())
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
else
listenOptions.Protocols = HttpProtocols.Http1;

listenOptions.UseHttps(delegate (SslStream stream, SslClientHelloInfo clientHelloInfo, object state, CancellationToken cancellationToken)
{
return ValueTask.FromResult(_webServiceSslServerAuthenticationOptions);
}, null);
});
}
}

serverOptions.AddServerHeader = false;
Expand Down Expand Up @@ -1611,6 +1665,15 @@ private async Task StartWebServiceAsync(bool httpOnlyMode)
if (!httpOnlyMode && _webServiceEnableTls && (_webServiceSslServerAuthenticationOptions is not null))
_log.Write(new IPEndPoint(webServiceLocalAddress, _webServiceTlsPort), "Https", "Web Service was bound successfully.");
}

if (!string.IsNullOrWhiteSpace(_webServiceHttpUnixSocket))
_log.Write(new IPEndPoint(IPAddress.None, 0), "Http", $"Web Service was bound successfully on unix socket: {_webServiceHttpUnixSocket}");

if (!httpOnlyMode && _webServiceEnableTls && (_webServiceSslServerAuthenticationOptions is not null))
{
if (!string.IsNullOrWhiteSpace(_webServiceTlsUnixSocket))
_log.Write(new IPEndPoint(IPAddress.None, 0), "Https", $"Web Service was bound successfully on unix socket: {_webServiceTlsUnixSocket}");
}
}
catch
{
Expand All @@ -1624,6 +1687,15 @@ private async Task StartWebServiceAsync(bool httpOnlyMode)
_log.Write(new IPEndPoint(webServiceLocalAddress, _webServiceTlsPort), "Https", "Web Service failed to bind.");
}

if (!string.IsNullOrWhiteSpace(_webServiceHttpUnixSocket))
_log.Write(new IPEndPoint(IPAddress.None, 0), "Http", $"Web Service failed to bind on unix socket: {_webServiceHttpUnixSocket}");

if (!httpOnlyMode && _webServiceEnableTls && (_webServiceSslServerAuthenticationOptions is not null))
{
if (!string.IsNullOrWhiteSpace(_webServiceTlsUnixSocket))
_log.Write(new IPEndPoint(IPAddress.None, 0), "Https", $"Web Service failed to bind on unix socket: {_webServiceTlsUnixSocket}");
}

throw;
}
}
Expand Down
1 change: 1 addition & 0 deletions DnsServerCore/WebServiceAuthApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ private void WriteCurrentSessionDetails(Utf8JsonWriter jsonWriter, UserSession c
jsonWriter.WriteStartObject("info");

jsonWriter.WriteString("version", _dnsWebService.GetServerVersion());
jsonWriter.WriteBoolean("supportsUnixSockets", Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX);
jsonWriter.WriteString("uptimestamp", _dnsWebService._uptimestamp);
jsonWriter.WriteString("dnsServerDomain", _dnsWebService._dnsServer.ServerDomain);
jsonWriter.WriteNumber("defaultRecordTtl", _dnsWebService._dnsServer.AuthZoneManager.DefaultRecordTtl);
Expand Down
42 changes: 42 additions & 0 deletions DnsServerCore/WebServiceSettingsApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ private void WriteDnsSettings(Utf8JsonWriter jsonWriter)

jsonWriter.WriteEndArray();

jsonWriter.WriteString("webServiceHttpUnixSocket", _dnsWebService._webServiceHttpUnixSocket);
jsonWriter.WriteString("webServiceTlsUnixSocket", _dnsWebService._webServiceTlsUnixSocket);

jsonWriter.WriteNumber("webServiceHttpPort", _dnsWebService._webServiceHttpPort);
jsonWriter.WriteBoolean("webServiceEnableTls", _dnsWebService._webServiceEnableTls);
jsonWriter.WriteBoolean("webServiceEnableHttp3", _dnsWebService._webServiceEnableHttp3);
Expand All @@ -267,6 +270,9 @@ private void WriteDnsSettings(Utf8JsonWriter jsonWriter)
jsonWriter.WriteNumber("dnsOverHttpsPort", _dnsWebService._dnsServer.DnsOverHttpsPort);
jsonWriter.WriteNumber("dnsOverQuicPort", _dnsWebService._dnsServer.DnsOverQuicPort);

jsonWriter.WriteString("dnsOverHttpUnixSocket", _dnsWebService._dnsServer.DnsOverHttpUnixSocket);
jsonWriter.WriteString("dnsOverHttpsUnixSocket", _dnsWebService._dnsServer.DnsOverHttpsUnixSocket);

jsonWriter.WritePropertyName("reverseProxyNetworkACL");
{
jsonWriter.WriteStartArray();
Expand Down Expand Up @@ -901,6 +907,24 @@ public async Task SetDnsSettingsAsync(HttpContext context)
_dnsWebService._webServiceLocalAddresses = WebUtilities.GetValidKestrelLocalAddresses(webServiceLocalAddresses);
}

if (request.TryGetQueryOrForm("webServiceHttpUnixSocket", out string webServiceHttpUnixSocket))
{
if (_dnsWebService._webServiceHttpUnixSocket != webServiceHttpUnixSocket)
{
restartWebService = true;
}
_dnsWebService._webServiceHttpUnixSocket = webServiceHttpUnixSocket;
}

if (request.TryGetQueryOrForm("webServiceTlsUnixSocket", out string webServiceTlsUnixSocket))
{
if (_dnsWebService._webServiceTlsUnixSocket != webServiceTlsUnixSocket)
{
restartWebService = true;
}
_dnsWebService._webServiceTlsUnixSocket = webServiceTlsUnixSocket;
}

if (request.TryGetQueryOrForm("webServiceHttpPort", int.Parse, out int webServiceHttpPort))
{
if (_dnsWebService._webServiceHttpPort != webServiceHttpPort)
Expand Down Expand Up @@ -1117,6 +1141,24 @@ public async Task SetDnsSettingsAsync(HttpContext context)
}
}

if (request.TryGetQueryOrForm("dnsOverHttpUnixSocket", out string dnsOverHttpUnixSocket))
{
if (_dnsWebService._dnsServer.DnsOverHttpUnixSocket != dnsOverHttpUnixSocket)
{
restartDnsService = true;
}
_dnsWebService._dnsServer.DnsOverHttpUnixSocket = dnsOverHttpUnixSocket;
}

if (request.TryGetQueryOrForm("dnsOverHttpsUnixSocket", out string dnsOverHttpsUnixSocket))
{
if (_dnsWebService._dnsServer.DnsOverHttpsUnixSocket != dnsOverHttpsUnixSocket)
{
restartDnsService = true;
}
_dnsWebService._dnsServer.DnsOverHttpsUnixSocket = dnsOverHttpsUnixSocket;
}

if (request.TryGetQueryOrFormArray("reverseProxyNetworkACL", NetworkAccessControl.Parse, out NetworkAccessControl[] reverseProxyNetworkACL))
_dnsWebService._dnsServer.ReverseProxyNetworkACL = reverseProxyNetworkACL;

Expand Down
Loading