mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-18 19:25:00 -04:00
Merge pull request #13493 from gnattu/fix-subnet-check-master
This commit is contained in:
commit
8a6d1402d2
2 changed files with 38 additions and 23 deletions
|
@ -326,4 +326,23 @@ public static partial class NetworkUtils
|
||||||
|
|
||||||
return new IPAddress(BitConverter.GetBytes(broadCastIPAddress));
|
return new IPAddress(BitConverter.GetBytes(broadCastIPAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if a subnet contains an address. This method also handles IPv4 mapped to IPv6 addresses.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="network">The <see cref="IPNetwork"/>.</param>
|
||||||
|
/// <param name="address">The <see cref="IPAddress"/>.</param>
|
||||||
|
/// <returns>Whether the supplied IP is in the supplied network.</returns>
|
||||||
|
public static bool SubnetContainsAddress(IPNetwork network, IPAddress address)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(address);
|
||||||
|
ArgumentNullException.ThrowIfNull(network);
|
||||||
|
|
||||||
|
if (address.IsIPv4MappedToIPv6)
|
||||||
|
{
|
||||||
|
address = address.MapToIPv4();
|
||||||
|
}
|
||||||
|
|
||||||
|
return network.Contains(address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -673,10 +673,10 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
{
|
{
|
||||||
// Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely.
|
// Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely.
|
||||||
// If left blank, all remote addresses will be allowed.
|
// If left blank, all remote addresses will be allowed.
|
||||||
if (_remoteAddressFilter.Any() && !_lanSubnets.Any(x => x.Contains(remoteIP)))
|
if (_remoteAddressFilter.Any() && !IsInLocalNetwork(remoteIP))
|
||||||
{
|
{
|
||||||
// remoteAddressFilter is a whitelist or blacklist.
|
// remoteAddressFilter is a whitelist or blacklist.
|
||||||
var matches = _remoteAddressFilter.Count(remoteNetwork => remoteNetwork.Contains(remoteIP));
|
var matches = _remoteAddressFilter.Count(remoteNetwork => NetworkUtils.SubnetContainsAddress(remoteNetwork, remoteIP));
|
||||||
if ((!config.IsRemoteIPFilterBlacklist && matches > 0)
|
if ((!config.IsRemoteIPFilterBlacklist && matches > 0)
|
||||||
|| (config.IsRemoteIPFilterBlacklist && matches == 0))
|
|| (config.IsRemoteIPFilterBlacklist && matches == 0))
|
||||||
{
|
{
|
||||||
|
@ -793,7 +793,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
_logger.LogWarning("IPv4 is disabled in Jellyfin, but enabled in the OS. This may affect how the interface is selected.");
|
_logger.LogWarning("IPv4 is disabled in Jellyfin, but enabled in the OS. This may affect how the interface is selected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isExternal = !_lanSubnets.Any(network => network.Contains(source));
|
bool isExternal = !IsInLocalNetwork(source);
|
||||||
_logger.LogDebug("Trying to get bind address for source {Source} - External: {IsExternal}", source, isExternal);
|
_logger.LogDebug("Trying to get bind address for source {Source} - External: {IsExternal}", source, isExternal);
|
||||||
|
|
||||||
if (!skipOverrides && MatchesPublishedServerUrl(source, isExternal, out result))
|
if (!skipOverrides && MatchesPublishedServerUrl(source, isExternal, out result))
|
||||||
|
@ -840,7 +840,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
// (For systems with multiple internal network cards, and multiple subnets)
|
// (For systems with multiple internal network cards, and multiple subnets)
|
||||||
foreach (var intf in availableInterfaces)
|
foreach (var intf in availableInterfaces)
|
||||||
{
|
{
|
||||||
if (intf.Subnet.Contains(source))
|
if (NetworkUtils.SubnetContainsAddress(intf.Subnet, source))
|
||||||
{
|
{
|
||||||
result = NetworkUtils.FormatIPString(intf.Address);
|
result = NetworkUtils.FormatIPString(intf.Address);
|
||||||
_logger.LogDebug("{Source}: Found interface with matching subnet, using it as bind address: {Result}", source, result);
|
_logger.LogDebug("{Source}: Found interface with matching subnet, using it as bind address: {Result}", source, result);
|
||||||
|
@ -868,21 +868,11 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
{
|
{
|
||||||
if (NetworkUtils.TryParseToSubnet(address, out var subnet))
|
if (NetworkUtils.TryParseToSubnet(address, out var subnet))
|
||||||
{
|
{
|
||||||
return IPAddress.IsLoopback(subnet.Prefix) || (_lanSubnets.Any(x => x.Contains(subnet.Prefix)) && !_excludedSubnets.Any(x => x.Contains(subnet.Prefix)));
|
return IsInLocalNetwork(subnet.Prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetworkUtils.TryParseHost(address, out var addresses, IsIPv4Enabled, IsIPv6Enabled))
|
return NetworkUtils.TryParseHost(address, out var addresses, IsIPv4Enabled, IsIPv6Enabled)
|
||||||
{
|
&& addresses.Any(IsInLocalNetwork);
|
||||||
foreach (var ept in addresses)
|
|
||||||
{
|
|
||||||
if (IPAddress.IsLoopback(ept) || (_lanSubnets.Any(x => x.Contains(ept)) && !_excludedSubnets.Any(x => x.Contains(ept))))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -917,6 +907,11 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
return CheckIfLanAndNotExcluded(address);
|
return CheckIfLanAndNotExcluded(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the address is in the LAN and not excluded.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The IP address to check. The caller should make sure this is not an IPv4MappedToIPv6 address.</param>
|
||||||
|
/// <returns>Boolean indicates whether the address is in LAN.</returns>
|
||||||
private bool CheckIfLanAndNotExcluded(IPAddress address)
|
private bool CheckIfLanAndNotExcluded(IPAddress address)
|
||||||
{
|
{
|
||||||
foreach (var lanSubnet in _lanSubnets)
|
foreach (var lanSubnet in _lanSubnets)
|
||||||
|
@ -956,7 +951,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
{
|
{
|
||||||
// Only use matching internal subnets
|
// Only use matching internal subnets
|
||||||
// Prefer more specific (bigger subnet prefix) overrides
|
// Prefer more specific (bigger subnet prefix) overrides
|
||||||
validPublishedServerUrls = _publishedServerUrls.Where(x => x.IsInternalOverride && x.Data.Subnet.Contains(source))
|
validPublishedServerUrls = _publishedServerUrls.Where(x => x.IsInternalOverride && NetworkUtils.SubnetContainsAddress(x.Data.Subnet, source))
|
||||||
.OrderByDescending(x => x.Data.Subnet.PrefixLength)
|
.OrderByDescending(x => x.Data.Subnet.PrefixLength)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
@ -964,7 +959,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
{
|
{
|
||||||
// Only use matching external subnets
|
// Only use matching external subnets
|
||||||
// Prefer more specific (bigger subnet prefix) overrides
|
// Prefer more specific (bigger subnet prefix) overrides
|
||||||
validPublishedServerUrls = _publishedServerUrls.Where(x => x.IsExternalOverride && x.Data.Subnet.Contains(source))
|
validPublishedServerUrls = _publishedServerUrls.Where(x => x.IsExternalOverride && NetworkUtils.SubnetContainsAddress(x.Data.Subnet, source))
|
||||||
.OrderByDescending(x => x.Data.Subnet.PrefixLength)
|
.OrderByDescending(x => x.Data.Subnet.PrefixLength)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
@ -972,7 +967,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
foreach (var data in validPublishedServerUrls)
|
foreach (var data in validPublishedServerUrls)
|
||||||
{
|
{
|
||||||
// Get interface matching override subnet
|
// Get interface matching override subnet
|
||||||
var intf = _interfaces.OrderBy(x => x.Index).FirstOrDefault(x => data.Data.Subnet.Contains(x.Address));
|
var intf = _interfaces.OrderBy(x => x.Index).FirstOrDefault(x => NetworkUtils.SubnetContainsAddress(data.Data.Subnet, x.Address));
|
||||||
|
|
||||||
if (intf?.Address is not null
|
if (intf?.Address is not null
|
||||||
|| (data.Data.AddressFamily == AddressFamily.InterNetwork && data.Data.Address.Equals(IPAddress.Any))
|
|| (data.Data.AddressFamily == AddressFamily.InterNetwork && data.Data.Address.Equals(IPAddress.Any))
|
||||||
|
@ -1035,6 +1030,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
if (isInExternalSubnet)
|
if (isInExternalSubnet)
|
||||||
{
|
{
|
||||||
var externalInterfaces = _interfaces.Where(x => !IsInLocalNetwork(x.Address))
|
var externalInterfaces = _interfaces.Where(x => !IsInLocalNetwork(x.Address))
|
||||||
|
.Where(x => !IsLinkLocalAddress(x.Address))
|
||||||
.OrderBy(x => x.Index)
|
.OrderBy(x => x.Index)
|
||||||
.ToList();
|
.ToList();
|
||||||
if (externalInterfaces.Count > 0)
|
if (externalInterfaces.Count > 0)
|
||||||
|
@ -1042,7 +1038,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
// Check to see if any of the external bind interfaces are in the same subnet as the source.
|
// Check to see if any of the external bind interfaces are in the same subnet as the source.
|
||||||
// If none exists, this will select the first external interface if there is one.
|
// If none exists, this will select the first external interface if there is one.
|
||||||
bindAddress = externalInterfaces
|
bindAddress = externalInterfaces
|
||||||
.OrderByDescending(x => x.Subnet.Contains(source))
|
.OrderByDescending(x => NetworkUtils.SubnetContainsAddress(x.Subnet, source))
|
||||||
.ThenByDescending(x => x.Subnet.PrefixLength)
|
.ThenByDescending(x => x.Subnet.PrefixLength)
|
||||||
.ThenBy(x => x.Index)
|
.ThenBy(x => x.Index)
|
||||||
.Select(x => x.Address)
|
.Select(x => x.Address)
|
||||||
|
@ -1060,7 +1056,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
// Check to see if any of the internal bind interfaces are in the same subnet as the source.
|
// Check to see if any of the internal bind interfaces are in the same subnet as the source.
|
||||||
// If none exists, this will select the first internal interface if there is one.
|
// If none exists, this will select the first internal interface if there is one.
|
||||||
bindAddress = _interfaces.Where(x => IsInLocalNetwork(x.Address))
|
bindAddress = _interfaces.Where(x => IsInLocalNetwork(x.Address))
|
||||||
.OrderByDescending(x => x.Subnet.Contains(source))
|
.OrderByDescending(x => NetworkUtils.SubnetContainsAddress(x.Subnet, source))
|
||||||
.ThenByDescending(x => x.Subnet.PrefixLength)
|
.ThenByDescending(x => x.Subnet.PrefixLength)
|
||||||
.ThenBy(x => x.Index)
|
.ThenBy(x => x.Index)
|
||||||
.Select(x => x.Address)
|
.Select(x => x.Address)
|
||||||
|
@ -1104,7 +1100,7 @@ public class NetworkManager : INetworkManager, IDisposable
|
||||||
// (For systems with multiple network cards and/or multiple subnets)
|
// (For systems with multiple network cards and/or multiple subnets)
|
||||||
foreach (var intf in extResult)
|
foreach (var intf in extResult)
|
||||||
{
|
{
|
||||||
if (intf.Subnet.Contains(source))
|
if (NetworkUtils.SubnetContainsAddress(intf.Subnet, source))
|
||||||
{
|
{
|
||||||
result = NetworkUtils.FormatIPString(intf.Address);
|
result = NetworkUtils.FormatIPString(intf.Address);
|
||||||
_logger.LogDebug("{Source}: Found external interface with matching subnet, using it as bind address: {Result}", source, result);
|
_logger.LogDebug("{Source}: Found external interface with matching subnet, using it as bind address: {Result}", source, result);
|
||||||
|
|
Loading…
Add table
Reference in a new issue