agent: allow only public addresses as single-agent targets unless allowed_target_cidrs says otherwise
This commit is contained in:
1 parent
8efc16f341
commit
32547032d8
3 files changed
+60
-16
No files matched your search
@@ -107,8 +107,8 @@ public sealed class BudgetGuard
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 目标在静态上可不可以接受:IP 字面量按 <c>allowed_target_cidrs</c> 检查;域名(包括 URL 里的)要解析之后才知道,
|
||||
/// 这里只要求配置过白名单,运行时每次解析出的地址再用 <see cref="AddressAllowed"/> 检查。
|
||||
/// 目标在静态上可不可以接受:IP 字面量直接用 <see cref="AddressAllowed"/> 判断;域名(包括 URL 里的)要解析之后才知道,
|
||||
/// 这里先接受,运行时每次解析出的地址再逐个检查。
|
||||
/// </summary>
|
||||
public bool TargetAllowed(string? target)
|
||||
{
|
||||
@@ -117,9 +117,13 @@ public sealed class BudgetGuard
|
||||
return false;
|
||||
}
|
||||
|
||||
return IPAddress.TryParse(host, out IPAddress? address) ? AddressAllowed(address) : _cidrs.Count > 0;
|
||||
return !IPAddress.TryParse(host, out IPAddress? address) || AddressAllowed(address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 这个地址能不能作为单个 Agent 任务的目标。<c>allowed_target_cidrs</c> 没配置时只允许公网地址(内网、回环、链路本地、组播等一律拒绝),
|
||||
/// 防止被攻破的 Backend 借 Agent 探测它所在的内网;配置了就只允许列出的网段(包括内网段,由节点所有者显式决定)。
|
||||
/// </summary>
|
||||
public bool AddressAllowed(IPAddress address)
|
||||
{
|
||||
if (address.IsIPv4MappedToIPv6)
|
||||
@@ -127,6 +131,11 @@ public sealed class BudgetGuard
|
||||
address = address.MapToIPv4();
|
||||
}
|
||||
|
||||
if (_limits.AllowedTargetCidrs.Count == 0)
|
||||
{
|
||||
return IsPublic(address);
|
||||
}
|
||||
|
||||
foreach ((IPAddress network, int prefix) in _cidrs)
|
||||
{
|
||||
if (InCidr(address, network, prefix))
|
||||
@@ -138,6 +147,28 @@ public sealed class BudgetGuard
|
||||
return false;
|
||||
}
|
||||
|
||||
private static readonly (IPAddress Network, int Prefix)[] s_nonPublic =
|
||||
[
|
||||
(IPAddress.Parse("0.0.0.0"), 8), (IPAddress.Parse("10.0.0.0"), 8), (IPAddress.Parse("100.64.0.0"), 10), (IPAddress.Parse("127.0.0.0"), 8),
|
||||
(IPAddress.Parse("169.254.0.0"), 16), (IPAddress.Parse("172.16.0.0"), 12), (IPAddress.Parse("192.0.0.0"), 24), (IPAddress.Parse("192.168.0.0"), 16),
|
||||
(IPAddress.Parse("198.18.0.0"), 15), (IPAddress.Parse("224.0.0.0"), 3),
|
||||
(IPAddress.Parse("::"), 128), (IPAddress.Parse("::1"), 128), (IPAddress.Parse("fc00::"), 7), (IPAddress.Parse("fe80::"), 10), (IPAddress.Parse("ff00::"), 8),
|
||||
];
|
||||
|
||||
/// <summary>不是公网:私有、回环、链路本地、运营商级 NAT、组播、保留地址。</summary>
|
||||
private static bool IsPublic(IPAddress address)
|
||||
{
|
||||
foreach ((IPAddress network, int prefix) in s_nonPublic)
|
||||
{
|
||||
if (InCidr(address, network, prefix))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool PortAllowed(KindSpec kind, ParamValues values)
|
||||
{
|
||||
if (!kind.Params.Any(p => p.Name == "port"))
|
||||
|
||||
Reference in new issue
Block a user