Patrick Kelley 04da5c1250 Inital
2025-05-28 14:31:31 -04:00

112 lines
3.6 KiB
Plaintext

module Site;
export {
# These should be figured out based on how large local_nets is
# if local_nets is a single /24, v4_aggregation_bits can be 32
## When adding a host, truncate it to this many bits and assume the entire
## subnet is in use
const v4_aggregation_bits = 24 &redef;
const v6_aggregation_bits = 64 &redef;
## A set containing subnets from local_nets that are in use
global used_address_space: set[subnet] &redef;
## A set containing subnets from local_nets that are dark
global darknet_address_space: set[subnet] &redef;
## Return true if an address is dark
global is_darknet: function(a: addr): bool;
type DarknetMode: enum {
## Only hosts defined in darknet_address_space are dark
DARKNET,
## Only hosts NOT listed in used_address_space are dark
NOT_ALLOCATED,
## Only hosts defined in darknet_address_space OR NOT listed in used_address_space are dark
## Useful if you reuse part of darknet space for honey net purposes
DARKNET_OR_NOT_ALLOCATED,
## Only hosts both defined in darknet_address_space AND NOT listed in used_address_space are dark
## Useful if your networking group may reallocate your darknet subnets out from under you.
DARKNET_AND_NOT_ALLOCATED,
};
const darknet_mode: DarknetMode=DARKNET &redef;
## Automatically add newly seen hosts to used_address_space after
## truncating to v4_aggregation_bits or v6_aggregation_bits
const auto_manage_allocated: bool=F &redef;
redef enum Notice::Type += {
New_Used_Address_Space
};
global new_used_address_space: event(sn: subnet);
}
function aggregate_address(a: addr): subnet
{
if(is_v4_addr(a)) {
return mask_addr(a, v4_aggregation_bits);
} else {
return mask_addr(a, v6_aggregation_bits);
}
}
######################################
# Cluster mode
@if ( Cluster::is_enabled() )
event zeek_init()
{
Broker::auto_publish(Cluster::manager_topic, Site::new_used_address_space);
Broker::auto_publish(Cluster::proxy_topic, Site::new_used_address_space);
}
event Site::new_used_address_space(sn: subnet)
{
add used_address_space[sn];
}
@endif
######################################
function add_host(a: addr)
{
if (a !in used_address_space) {
local masked = aggregate_address(a);
add used_address_space[masked];
event Site::new_used_address_space(masked);
NOTICE([$note=New_Used_Address_Space,
$identifier=fmt("%s",masked),
$msg=fmt("%s",masked)]);
}
}
function is_darknet(a: addr): bool
{
switch ( darknet_mode) {
case DARKNET:
return (a in darknet_address_space);
case NOT_ALLOCATED:
return (a in local_nets && |used_address_space| != 0 && a !in used_address_space);
case DARKNET_OR_NOT_ALLOCATED:
return (a in darknet_address_space || (|used_address_space| != 0 && a in local_nets && a !in used_address_space));
case DARKNET_AND_NOT_ALLOCATED:
return (a in darknet_address_space && (|used_address_space| != 0 && a in local_nets && a !in used_address_space));
}
Reporter::error(fmt("Invalid darknet_mode %s(%d)", darknet_mode, darknet_mode));
return F;
}
#Similar to how known hosts works, but this will also catch udp only hosts.
event Conn::log_conn(rec: Conn::Info)
{
if (!auto_manage_allocated)
return;
if (|Site::local_nets| == 0)
return;
if (rec$local_orig && rec$orig_pkts > 0)
add_host(rec$id$orig_h);
if (rec$local_resp && rec$resp_pkts > 0)
add_host(rec$id$resp_h);
}