Skip to content

Commit

Permalink
ResolveEndpoint has always taken the first entry from the AddressList…
Browse files Browse the repository at this point in the history
…. If, for example, IPv6 has been completely deactivated on your system, AddressList still always contains the entry "::1" in the first place, which leads to problems in certain constellations.

If, for example, virtual network adapters (e.g. Hyper-V Network Switch) are also used on the system, the first entry does not return the correct outgoing IP address.

Numerous tests have confirmed that the last address in the list is always the correct and desired address. By setting onlyUseIPv4 = true you can force an IPv4 address to be returned, even if the list contains "::1", for example. As a rule, the AddressList contains IPv6 addresses first and then IPv4 addresses. However, there are situations where additional IPv6 addresses appear in the list after the IPv4 addresses, and these are the correct addresses that you actually want.

My changes cover all cases and you have full control over what the end result is. Otherwise, for example, an IP address from a Hyper-V switch is incorrectly used for a hostname. Connection problems arise, especially in conjunction with SSL and an SSL certificate that is then issued for this hostname or IP address.
  • Loading branch information
Sascha Lange committed Nov 25, 2024
1 parent bd9de43 commit 2e29d1e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
17 changes: 15 additions & 2 deletions extensions/Sisk.SslProxy/DnsUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Sisk.Ssl;

static class DnsUtil
{
public static IPEndPoint ResolveEndpoint(ListeningPort port)
public static IPEndPoint ResolveEndpoint(ListeningPort port, bool onlyUseIPv4 = false)
{
var hostEntry = Dns.GetHostEntry(port.Hostname);
if (hostEntry.AddressList.Length == 0)
Expand All @@ -23,7 +23,20 @@ public static IPEndPoint ResolveEndpoint(ListeningPort port)
}
else
{
return new IPEndPoint(hostEntry.AddressList[0], port.Port);
if (onlyUseIPv4)
{
return new IPEndPoint(hostEntry.AddressList.Where(a => a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Last(), port.Port);
}
else
{
var ipv6AddressList = hostEntry.AddressList.Where(a => a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6);
if (ipv6AddressList.Any())
{
return new IPEndPoint(ipv6AddressList.Last(), port.Port);
}
else
return new IPEndPoint(hostEntry.AddressList.Last(), port.Port);
}
}
}
}
6 changes: 4 additions & 2 deletions extensions/Sisk.SslProxy/SslProxyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,22 @@ public static class SslProxyExtensions
/// <param name="clientCertificateRequired">Optional. Specifies whether a client certificate is required for authentication. Defaults to <c>false</c>.</param>
/// <param name="proxyAuthorization">Optional. Specifies the Proxy-Authorization header value for creating an trusted gateway between
/// the application and the proxy.</param>
/// <param name="onlyUseIPv4">Optional. Specifies whether DNS Resolve may also use IPv6 addresses or should only use IPv4 addresses</param>
/// <returns>The configured <see cref="HttpServerHostContextBuilder"/> instance.</returns>
public static HttpServerHostContextBuilder UseSsl(
this HttpServerHostContextBuilder builder,
short sslListeningPort,
X509Certificate? certificate = null,
SslProtocols allowedProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
bool clientCertificateRequired = false,
object? proxyAuthorization = null)
object? proxyAuthorization = null,
bool onlyUseIPv4 = false)
{
var primaryHost = builder.ServerConfiguration.ListeningHosts[0];
var primaryPort = primaryHost.Ports[0];
var usableHosts = primaryHost.Ports.Select(p => p.Hostname);

var endpoint = DnsUtil.ResolveEndpoint(primaryPort);
var endpoint = DnsUtil.ResolveEndpoint(primaryPort, onlyUseIPv4);
if (certificate is null)
{
certificate = CertificateUtil.CreateTrustedDevelopmentCertificate(["localhost", .. usableHosts]);
Expand Down

0 comments on commit 2e29d1e

Please sign in to comment.