mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 07:38:19 +00:00

When not using data stores, these scripts were intended to suppress sending duplicate events to proxies by looking up the key in the local cache.
166 lines
4.5 KiB
Text
166 lines
4.5 KiB
Text
##! This script logs hosts that Bro determines have performed complete TCP
|
|
##! handshakes and logs the address once per day (by default). The log that
|
|
##! is output provides an easy way to determine a count of the IP addresses in
|
|
##! use on a network per day.
|
|
|
|
@load base/utils/directions-and-hosts
|
|
@load base/frameworks/cluster
|
|
|
|
module Known;
|
|
|
|
export {
|
|
## The known-hosts logging stream identifier.
|
|
redef enum Log::ID += { HOSTS_LOG };
|
|
|
|
## The record type which contains the column fields of the known-hosts log.
|
|
type HostsInfo: record {
|
|
## The timestamp at which the host was detected.
|
|
ts: time &log;
|
|
## The address that was detected originating or responding to a
|
|
## TCP connection.
|
|
host: addr &log;
|
|
};
|
|
|
|
## Toggles between different implementations of this script.
|
|
## When true, use a Broker data store, else use a regular Bro set
|
|
## with keys uniformly distributed over proxy nodes in cluster
|
|
## operation.
|
|
const use_host_store = T &redef;
|
|
|
|
## The hosts whose existence should be logged and tracked.
|
|
## See :bro:type:`Host` for possible choices.
|
|
const host_tracking = LOCAL_HOSTS &redef;
|
|
|
|
## Holds the set of all known hosts. Keys in the store are addresses
|
|
## and their associated value will always be the "true" boolean.
|
|
global host_store: Cluster::StoreInfo;
|
|
|
|
## The Broker topic name to use for :bro:see:`Known::host_store`.
|
|
const host_store_name = "bro/known/hosts" &redef;
|
|
|
|
## The expiry interval of new entries in :bro:see:`Known::host_store`.
|
|
## This also changes the interval at which hosts get logged.
|
|
const host_store_expiry = 1day &redef;
|
|
|
|
## The timeout interval to use for operations against
|
|
## :bro:see:`Known::host_store`.
|
|
const host_store_timeout = 15sec &redef;
|
|
|
|
## The set of all known addresses to store for preventing duplicate
|
|
## logging of addresses. It can also be used from other scripts to
|
|
## inspect if an address has been seen in use.
|
|
## Maintain the list of known hosts for 24 hours so that the existence
|
|
## of each individual address is logged each day.
|
|
##
|
|
## In cluster operation, this set is distributed uniformly across
|
|
## proxy nodes.
|
|
global hosts: set[addr] &create_expire=1day &redef;
|
|
|
|
## An event that can be handled to access the :bro:type:`Known::HostsInfo`
|
|
## record as it is sent on to the logging framework.
|
|
global log_known_hosts: event(rec: HostsInfo);
|
|
}
|
|
|
|
event bro_init()
|
|
{
|
|
if ( ! Known::use_host_store )
|
|
return;
|
|
|
|
Known::host_store = Cluster::create_store(Known::host_store_name);
|
|
}
|
|
|
|
event Known::host_found(info: HostsInfo)
|
|
{
|
|
if ( ! Known::use_host_store )
|
|
return;
|
|
|
|
when ( local r = Broker::put_unique(Known::host_store$store, info$host,
|
|
T, Known::host_store_expiry) )
|
|
{
|
|
if ( r$status == Broker::SUCCESS )
|
|
{
|
|
if ( r$result as bool )
|
|
Log::write(Known::HOSTS_LOG, info);
|
|
}
|
|
else
|
|
Reporter::error(fmt("%s: data store put_unique failure",
|
|
Known::host_store_name));
|
|
}
|
|
timeout Known::host_store_timeout
|
|
{
|
|
# Can't really tell if master store ended up inserting a key.
|
|
Log::write(Known::HOSTS_LOG, info);
|
|
}
|
|
}
|
|
|
|
event known_host_add(info: HostsInfo)
|
|
{
|
|
if ( use_host_store )
|
|
return;
|
|
|
|
if ( info$host in Known::hosts )
|
|
return;
|
|
|
|
add Known::hosts[info$host];
|
|
|
|
@if ( ! Cluster::is_enabled() ||
|
|
Cluster::local_node_type() == Cluster::PROXY )
|
|
Log::write(Known::HOSTS_LOG, info);
|
|
@endif
|
|
}
|
|
|
|
event Cluster::node_up(name: string, id: string)
|
|
{
|
|
if ( use_host_store )
|
|
return;
|
|
|
|
if ( Cluster::local_node_type() != Cluster::WORKER )
|
|
return;
|
|
|
|
# Drop local suppression cache on workers to force HRW key repartitioning.
|
|
Known::hosts = set();
|
|
}
|
|
|
|
event Cluster::node_down(name: string, id: string)
|
|
{
|
|
if ( use_host_store )
|
|
return;
|
|
|
|
if ( Cluster::local_node_type() != Cluster::WORKER )
|
|
return;
|
|
|
|
# Drop local suppression cache on workers to force HRW key repartitioning.
|
|
Known::hosts = set();
|
|
}
|
|
|
|
event Known::host_found(info: HostsInfo)
|
|
{
|
|
if ( use_host_store )
|
|
return;
|
|
|
|
if ( info$host in Known::hosts )
|
|
return;
|
|
|
|
Cluster::publish_hrw(Cluster::proxy_pool, info$host, known_host_add, info);
|
|
event known_host_add(info);
|
|
}
|
|
|
|
event bro_init()
|
|
{
|
|
Log::create_stream(Known::HOSTS_LOG, [$columns=HostsInfo, $ev=log_known_hosts, $path="known_hosts"]);
|
|
}
|
|
|
|
event connection_established(c: connection) &priority=5
|
|
{
|
|
if ( c$orig$state != TCP_ESTABLISHED )
|
|
return;
|
|
|
|
if ( c$resp$state != TCP_ESTABLISHED )
|
|
return;
|
|
|
|
local id = c$id;
|
|
|
|
for ( host in set(id$orig_h, id$resp_h) )
|
|
if ( addr_matches_host(host, host_tracking) )
|
|
event Known::host_found([$ts = network_time(), $host = host]);
|
|
}
|