mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Fixes for GeoIP support (addresses #538).
- Missing GeoIP databases now generate warnings/errors that go through the reporter framework instead of hitting GeoIP's internal use of stderr - lookup_location now just queries for country code if the city database was not loaded, which gets rid of invalid database type errors. - lookup_location now leaves missing fields uninitialized in the returned geo_location record value. Updated existing scripts to check for initialized fields in geo_location records before use. - Fixed support for GeoIP's IPv6 API and databases
This commit is contained in:
parent
005b1505b8
commit
13a09aa488
5 changed files with 99 additions and 43 deletions
|
@ -16,6 +16,8 @@
|
|||
# LIBGEOIP_FOUND System has GeoIP libraries and headers
|
||||
# LibGeoIP_LIBRARY The GeoIP library
|
||||
# LibGeoIP_INCLUDE_DIR The location of GeoIP headers
|
||||
# HAVE_GEOIP_COUNTRY_EDITION_V6 Whether the API support IPv6 country edition
|
||||
# HAVE_GEOIP_CITY_EDITION_REV0_V6 Whether the API supports IPv6 city edition
|
||||
|
||||
find_path(LibGeoIP_ROOT_DIR
|
||||
NAMES include/GeoIPCity.h
|
||||
|
@ -45,6 +47,20 @@ find_package_handle_standard_args(LibGeoIP DEFAULT_MSG
|
|||
LibGeoIP_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if (LIBGEOIP_FOUND)
|
||||
include(CheckCXXSourceCompiles)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${LibGeoIP_INCLUDE_DIR})
|
||||
check_cxx_source_compiles("
|
||||
#include <GeoIPCity.h>
|
||||
int main() { GEOIP_COUNTRY_EDITION_V6; return 0; }
|
||||
" HAVE_GEOIP_COUNTRY_EDITION_V6)
|
||||
check_cxx_source_compiles("
|
||||
#include <GeoIPCity.h>
|
||||
int main() { GEOIP_CITY_EDITION_REV0_V6; return 0; }
|
||||
" HAVE_GEOIP_CITY_EDITION_REV0_V6)
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(
|
||||
LibGeoIP_ROOT_DIR
|
||||
LibGeoIP_LIBRARY
|
||||
|
|
|
@ -114,6 +114,12 @@
|
|||
/* GeoIP geographic lookup functionality */
|
||||
#cmakedefine USE_GEOIP
|
||||
|
||||
/* Whether the found GeoIP API supports IPv6 Country Edition */
|
||||
#cmakedefine HAVE_GEOIP_COUNTRY_EDITION_V6
|
||||
|
||||
/* Whether the found GeoIP API supports IPv6 City Edition */
|
||||
#cmakedefine HAVE_GEOIP_CITY_EDITION_REV0_V6
|
||||
|
||||
/* Use Google's perftools */
|
||||
#cmakedefine USE_PERFTOOLS
|
||||
|
||||
|
|
|
@ -25,11 +25,13 @@ event log_smtp(rec: Info)
|
|||
ip = rec$x_originating_ip;
|
||||
loc = lookup_location(ip);
|
||||
|
||||
if ( loc$country_code in suspicious_origination_countries ||
|
||||
if ( (loc?$country_code &&
|
||||
loc$country_code in suspicious_origination_countries) ||
|
||||
ip in suspicious_origination_networks )
|
||||
{
|
||||
NOTICE([$note=Suspicious_Origination,
|
||||
$msg=fmt("An email originated from %s (%s).", loc$country_code, ip),
|
||||
$msg=fmt("An email originated from %s (%s).",
|
||||
loc?$country_code ? loc$country_code : "", ip),
|
||||
$id=rec$id]);
|
||||
}
|
||||
}
|
||||
|
@ -38,11 +40,12 @@ event log_smtp(rec: Info)
|
|||
ip = rec$path[|rec$path|-1];
|
||||
loc = lookup_location(ip);
|
||||
|
||||
if ( loc$country_code in suspicious_origination_countries ||
|
||||
if ( (loc?$country_code &&
|
||||
loc$country_code in suspicious_origination_countries) ||
|
||||
ip in suspicious_origination_networks )
|
||||
{
|
||||
NOTICE([$note=Suspicious_Origination,
|
||||
$msg=fmt("Based up Received headers, email originated from %s (%s).", loc$country_code, ip),
|
||||
$msg=fmt("Based up Received headers, email originated from %s (%s).", loc?$country_code ? loc$country_code : "", ip),
|
||||
$id=rec$id]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ event SSH::heuristic_successful_login(c: connection) &priority=5
|
|||
# Add the location data to the SSH record.
|
||||
c$ssh$remote_location = location;
|
||||
|
||||
if ( location$country_code in watched_countries )
|
||||
if ( location?$country_code && location$country_code in watched_countries )
|
||||
{
|
||||
NOTICE([$note=Login_From_Watched_Country,
|
||||
$conn=c,
|
||||
|
|
95
src/bro.bif
95
src/bro.bif
|
@ -3019,6 +3019,18 @@ function syslog%(s: string%): any
|
|||
extern "C" {
|
||||
#include <GeoIPCity.h>
|
||||
}
|
||||
|
||||
static GeoIP* open_geoip_db(GeoIPDBTypes type)
|
||||
{
|
||||
GeoIP* geoip = 0;
|
||||
if ( GeoIP_db_avail(type) )
|
||||
geoip = GeoIP_open_type(type, GEOIP_MEMORY_CACHE);
|
||||
if ( ! geoip )
|
||||
reporter->Warning("Failed to open GeoIP database: %s",
|
||||
GeoIPDBFileName[type]);
|
||||
return geoip;
|
||||
}
|
||||
|
||||
#endif
|
||||
%%}
|
||||
|
||||
|
@ -3031,82 +3043,103 @@ function lookup_location%(a: addr%) : geo_location
|
|||
static GeoIP* geoip = 0;
|
||||
static GeoIP* geoip_v6 = 0;
|
||||
static bool geoip_initialized = false;
|
||||
static bool have_city_db = false;
|
||||
static bool have_cityv6_db = false;
|
||||
GeoIPRecord* gir = 0;
|
||||
const char* cc = 0;
|
||||
|
||||
if ( ! geoip_initialized )
|
||||
{
|
||||
geoip_initialized = true;
|
||||
geoip = GeoIP_open_type(GEOIP_CITY_EDITION_REV0,
|
||||
GEOIP_MEMORY_CACHE);
|
||||
|
||||
geoip = open_geoip_db(GEOIP_CITY_EDITION_REV0);
|
||||
|
||||
if ( ! geoip )
|
||||
{
|
||||
builtin_error("can't initialize GeoIP City database.. trying Country version");
|
||||
geoip = GeoIP_open_type(GEOIP_COUNTRY_EDITION,
|
||||
GEOIP_MEMORY_CACHE);
|
||||
geoip = open_geoip_db(GEOIP_COUNTRY_EDITION);
|
||||
if ( ! geoip )
|
||||
builtin_error("can't initialize GeoIP Country database");
|
||||
builtin_error("Can't initialize GeoIP City/Country database");
|
||||
else
|
||||
reporter->Warning("Fell back to GeoIP Country database");
|
||||
}
|
||||
else
|
||||
have_city_db = true;
|
||||
|
||||
#ifdef BROv6
|
||||
#ifdef GEOIP_COUNTRY_EDITION_V6
|
||||
geoip_v6 = GeoIP_open_type(GEOIP_COUNTRY_EDITION_V6,
|
||||
GEOIP_MEMORY_CACHE);
|
||||
#ifdef HAVE_GEOIP_CITY_EDITION_REV0_V6
|
||||
geoip_v6 = open_geoip_db(GEOIP_CITY_EDITION_REV0_V6);
|
||||
if ( geoip_v6 ) have_cityv6_db = true;
|
||||
#endif
|
||||
#ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
|
||||
if ( ! geoip_v6 )
|
||||
builtin_error("can't initialize the GeoIPv6 Country database");
|
||||
geoip_v6 = open_geoip_db(GEOIP_COUNTRY_EDITION_V6);
|
||||
#endif
|
||||
if ( ! geoip_v6 )
|
||||
builtin_error("Can't initialize GeoIPv6 City/Country database");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BROv6
|
||||
#ifdef GEOIP_COUNTRY_EDITION_V6
|
||||
#ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
|
||||
if ( geoip_v6 && ! is_v4_addr(a) )
|
||||
gir = GeoIP_record_by_ipnum_v6(geoip_v6, geoipv6_t(a));
|
||||
{
|
||||
geoipv6_t ga;
|
||||
memcpy(&ga, a, 16);
|
||||
if ( have_cityv6_db )
|
||||
gir = GeoIP_record_by_ipnum_v6(geoip_v6, ga);
|
||||
else
|
||||
cc = GeoIP_country_code_by_ipnum_v6(geoip_v6, ga);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ( geoip && is_v4_addr(a) )
|
||||
{
|
||||
uint32 addr = to_v4_addr(a);
|
||||
if ( have_city_db )
|
||||
gir = GeoIP_record_by_ipnum(geoip, ntohl(addr));
|
||||
else
|
||||
cc = GeoIP_country_code_by_ipnum(geoip, ntohl(addr));
|
||||
}
|
||||
#else
|
||||
if ( geoip )
|
||||
{
|
||||
if ( have_city_db )
|
||||
gir = GeoIP_record_by_ipnum(geoip, ntohl(a));
|
||||
else
|
||||
cc = GeoIP_country_code_by_ipnum(geoip, ntohl(a));
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( gir )
|
||||
{
|
||||
if ( gir->country_code )
|
||||
location->Assign(0, new StringVal(gir->country_code));
|
||||
else
|
||||
location->Assign(0, new StringVal(""));
|
||||
|
||||
if ( gir->region )
|
||||
location->Assign(1, new StringVal(gir->region));
|
||||
else
|
||||
location->Assign(1, new StringVal(""));
|
||||
|
||||
if ( gir->city )
|
||||
location->Assign(2, new StringVal(gir->city));
|
||||
else
|
||||
location->Assign(2, new StringVal(""));
|
||||
|
||||
if ( gir->latitude )
|
||||
location->Assign(3, new Val(gir->latitude,
|
||||
TYPE_DOUBLE));
|
||||
else
|
||||
location->Assign(3, new Val(0.0, TYPE_DOUBLE));
|
||||
|
||||
if ( gir->longitude )
|
||||
location->Assign(4, new Val(gir->longitude,
|
||||
TYPE_DOUBLE));
|
||||
else
|
||||
location->Assign(4, new Val(0.0, TYPE_DOUBLE));
|
||||
|
||||
GeoIPRecord_delete(gir);
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
else if (cc)
|
||||
{
|
||||
location->Assign(0, new StringVal(cc));
|
||||
return location;
|
||||
}
|
||||
|
||||
#else
|
||||
static int missing_geoip_reported = 0;
|
||||
|
||||
|
@ -3120,11 +3153,6 @@ function lookup_location%(a: addr%) : geo_location
|
|||
// We can get here even if we have GeoIP support if we weren't
|
||||
// able to initialize it or it didn't return any information for
|
||||
// the address.
|
||||
location->Assign(0, new StringVal(""));
|
||||
location->Assign(1, new StringVal(""));
|
||||
location->Assign(2, new StringVal(""));
|
||||
location->Assign(3, new Val(0.0, TYPE_DOUBLE));
|
||||
location->Assign(4, new Val(0.0, TYPE_DOUBLE));
|
||||
|
||||
return location;
|
||||
%}
|
||||
|
@ -3139,10 +3167,9 @@ function lookup_asn%(a: addr%) : count
|
|||
if ( ! geoip_asn_initialized )
|
||||
{
|
||||
geoip_asn_initialized = true;
|
||||
geoip_asn = GeoIP_open_type(GEOIP_ASNUM_EDITION,
|
||||
GEOIP_MEMORY_CACHE);
|
||||
geoip_asn = open_geoip_db(GEOIP_ASNUM_EDITION);
|
||||
if ( ! geoip_asn )
|
||||
builtin_error("can't initialize GeoIP ASNUM database");
|
||||
builtin_error("Can't initialize GeoIP ASNUM database");
|
||||
}
|
||||
|
||||
if ( geoip_asn )
|
||||
|
@ -3150,9 +3177,13 @@ function lookup_asn%(a: addr%) : count
|
|||
#ifdef BROv6
|
||||
|
||||
// IPv6 support showed up in 1.4.5.
|
||||
#ifdef GEOIP_COUNTRY_EDITION_V6
|
||||
#ifdef HAVE_GEOIP_COUNTRY_EDITION_V6
|
||||
if ( ! is_v4_addr(a) )
|
||||
gir = GeoIP_name_by_ipnum_v6(geoip_asn, geoipv6_t(a));
|
||||
{
|
||||
geoipv6_t ga;
|
||||
memcpy(&ga, a, 16);
|
||||
gir = GeoIP_name_by_ipnum_v6(geoip_asn, ga);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ( is_v4_addr(a) )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue