GeoIP 处理器

编辑

geoip 处理器添加有关 IPv4 或 IPv6 地址的地理位置信息。

默认情况下,该处理器使用来自 MaxMind 的 GeoLite2 City、GeoLite2 Country 和 GeoLite2 ASN IP 地理位置数据库,这些数据库在 CC BY-SA 4.0 许可下共享。如果您的节点可以连接到 storage.googleapis.com 域,并且满足以下任一条件,它会自动下载这些数据库:

  • ingest.geoip.downloader.eager.download 设置为 true
  • 您的集群至少有一个包含 geoipip_location 处理器的管道

Elasticsearch 会自动从 Elastic GeoIP 端点下载这些数据库的更新:https://geoip.elastic.co/v1/database。要获取这些更新的下载统计信息,请使用 GeoIP 统计 API

如果您的集群无法连接到 Elastic GeoIP 端点,或者您想管理自己的更新,请参阅 管理您自己的 IP 地理位置数据库更新

如果您希望 Elasticsearch 使用您自己提供的许可证密钥直接从 Maxmind 下载数据库文件,请参阅 创建或更新 IP 地理位置数据库配置

如果 Elasticsearch 无法连接到端点 30 天,则所有更新的数据库都将失效。Elasticsearch 将停止使用 IP 地理位置数据丰富文档,而是添加 tags: ["_geoip_expired_database"] 字段。

在管道中使用 geoip 处理器

编辑

表 22. geoip 选项

名称 必需 默认值 描述

field

-

从中获取 IP 地址以进行地理位置查找的字段。

target_field

geoip

将保存从数据库中查找的地理信息的字段。

database_file

GeoLite2-City.mmdb

数据库文件名,指代自动下载的 GeoLite2 数据库之一(GeoLite2-City.mmdb、GeoLite2-Country.mmdb 或 GeoLite2-ASN.mmdb),或 ingest-geoip 配置目录中支持的数据库文件的名称,或 配置的数据库的名称(附加 .mmdb 后缀)。

properties

[continent_name, country_iso_code, country_name, region_iso_code, region_name, city_name, location] *

控制根据 IP 地理位置查找添加到 target_field 的属性。

ignore_missing

false

如果为 truefield 不存在,则处理器静默退出而不修改文档

first_only

true

如果为 true,则只返回第一个找到的 IP 地理位置数据,即使 field 包含数组

download_database_on_pipeline_creation

true

如果为 true(并且如果 ingest.geoip.downloader.eager.downloadfalse),则在创建管道时下载缺少的数据库。否则,当管道用作索引中的 default_pipelinefinal_pipeline 时,会触发下载。

*取决于 database_file 中可用的内容

  • 如果使用 GeoLite2 City 或 GeoIP2 City 数据库,则可以在 target_field 下添加以下字段:ipcountry_iso_codecountry_namecountry_in_european_unionregistered_country_iso_coderegistered_country_nameregistered_country_in_european_unioncontinent_codecontinent_nameregion_iso_coderegion_namecity_namepostal_codetimezonelocationaccuracy_radius。实际添加的字段取决于找到的内容以及在 properties 中配置的属性。
  • 如果使用 GeoLite2 Country 或 GeoIP2 Country 数据库,则可以在 target_field 下添加以下字段:ipcountry_iso_codecountry_namecountry_in_european_unionregistered_country_iso_coderegistered_country_nameregistered_country_in_european_unioncontinent_codecontinent_name。实际添加的字段取决于找到的内容以及在 properties 中配置的属性。
  • 如果使用 GeoLite2 ASN 数据库,则可以在 target_field 下添加以下字段:ipasnorganization_namenetwork。实际添加的字段取决于找到的内容以及在 properties 中配置的属性。
  • 如果使用 GeoIP2 Anonymous IP 数据库,则可以在 target_field 下添加以下字段:iphosting_providertor_exit_nodeanonymous_vpnanonymouspublic_proxyresidential_proxy。实际添加的字段取决于找到的内容以及在 properties 中配置的属性。
  • 如果使用 GeoIP2 Connection Type 数据库,则可以在 target_field 下添加以下字段:ipconnection_type。实际添加的字段取决于找到的内容以及在 properties 中配置的属性。
  • 如果使用 GeoIP2 Domain 数据库,则可以在 target_field 下添加以下字段:ipdomain。实际添加的字段取决于找到的内容以及在 properties 中配置的属性。
  • 如果使用 GeoIP2 ISP 数据库,则可以在 target_field 下添加以下字段:ipasnorganization_namenetworkispisp_organization_namemobile_country_codemobile_network_code。实际添加的字段取决于找到的内容以及在 properties 中配置的属性。
  • 如果使用 GeoIP2 Enterprise 数据库,则可以在 target_field 下添加以下字段:ipcountry_iso_codecountry_namecountry_in_european_unionregistered_country_iso_coderegistered_country_nameregistered_country_in_european_unioncontinent_codecontinent_nameregion_iso_coderegion_namecity_namepostal_codetimezonelocationaccuracy_radiuscountry_confidencecity_confidencepostal_confidenceasnorganization_namenetworkhosting_providertor_exit_nodeanonymous_vpnanonymouspublic_proxyresidential_proxydomainispisp_organization_namemobile_country_codemobile_network_codeuser_typeconnection_type。实际添加的字段取决于找到的内容以及在 properties 中配置的属性。

这是一个示例,它使用默认的城市数据库,并根据 ip 字段将地理信息添加到 geoip 字段中

resp = client.ingest.put_pipeline(
    id="geoip",
    description="Add ip geolocation info",
    processors=[
        {
            "geoip": {
                "field": "ip"
            }
        }
    ],
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="my_id",
    pipeline="geoip",
    document={
        "ip": "89.160.20.128"
    },
)
print(resp1)

resp2 = client.get(
    index="my-index-000001",
    id="my_id",
)
print(resp2)
const response = await client.ingest.putPipeline({
  id: "geoip",
  description: "Add ip geolocation info",
  processors: [
    {
      geoip: {
        field: "ip",
      },
    },
  ],
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: "my_id",
  pipeline: "geoip",
  document: {
    ip: "89.160.20.128",
  },
});
console.log(response1);

const response2 = await client.get({
  index: "my-index-000001",
  id: "my_id",
});
console.log(response2);
PUT _ingest/pipeline/geoip
{
  "description" : "Add ip geolocation info",
  "processors" : [
    {
      "geoip" : {
        "field" : "ip"
      }
    }
  ]
}
PUT my-index-000001/_doc/my_id?pipeline=geoip
{
  "ip": "89.160.20.128"
}
GET my-index-000001/_doc/my_id

这将返回

{
  "found": true,
  "_index": "my-index-000001",
  "_id": "my_id",
  "_version": 1,
  "_seq_no": 55,
  "_primary_term": 1,
  "_source": {
    "ip": "89.160.20.128",
    "geoip": {
      "continent_name": "Europe",
      "country_name": "Sweden",
      "country_iso_code": "SE",
      "city_name" : "Linköping",
      "region_iso_code" : "SE-E",
      "region_name" : "Östergötland County",
      "location": { "lat": 58.4167, "lon": 15.6167 }
    }
  }
}

这是一个示例,它使用默认的国家数据库,并根据 ip 字段将地理信息添加到 geo 字段中。请注意,此数据库会自动下载。所以这个

resp = client.ingest.put_pipeline(
    id="geoip",
    description="Add ip geolocation info",
    processors=[
        {
            "geoip": {
                "field": "ip",
                "target_field": "geo",
                "database_file": "GeoLite2-Country.mmdb"
            }
        }
    ],
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="my_id",
    pipeline="geoip",
    document={
        "ip": "89.160.20.128"
    },
)
print(resp1)

resp2 = client.get(
    index="my-index-000001",
    id="my_id",
)
print(resp2)
const response = await client.ingest.putPipeline({
  id: "geoip",
  description: "Add ip geolocation info",
  processors: [
    {
      geoip: {
        field: "ip",
        target_field: "geo",
        database_file: "GeoLite2-Country.mmdb",
      },
    },
  ],
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: "my_id",
  pipeline: "geoip",
  document: {
    ip: "89.160.20.128",
  },
});
console.log(response1);

const response2 = await client.get({
  index: "my-index-000001",
  id: "my_id",
});
console.log(response2);
PUT _ingest/pipeline/geoip
{
  "description" : "Add ip geolocation info",
  "processors" : [
    {
      "geoip" : {
        "field" : "ip",
        "target_field" : "geo",
        "database_file" : "GeoLite2-Country.mmdb"
      }
    }
  ]
}
PUT my-index-000001/_doc/my_id?pipeline=geoip
{
  "ip": "89.160.20.128"
}
GET my-index-000001/_doc/my_id

返回这个

{
  "found": true,
  "_index": "my-index-000001",
  "_id": "my_id",
  "_version": 1,
  "_seq_no": 65,
  "_primary_term": 1,
  "_source": {
    "ip": "89.160.20.128",
    "geo": {
      "continent_name": "Europe",
      "country_name": "Sweden",
      "country_iso_code": "SE"
    }
  }
}

并非所有 IP 地址都能从数据库中找到地理信息。发生这种情况时,不会将 target_field 插入到文档中。

这是一个示例,说明当找不到“80.231.5.0”的信息时,文档将如何被索引

resp = client.ingest.put_pipeline(
    id="geoip",
    description="Add ip geolocation info",
    processors=[
        {
            "geoip": {
                "field": "ip"
            }
        }
    ],
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="my_id",
    pipeline="geoip",
    document={
        "ip": "80.231.5.0"
    },
)
print(resp1)

resp2 = client.get(
    index="my-index-000001",
    id="my_id",
)
print(resp2)
const response = await client.ingest.putPipeline({
  id: "geoip",
  description: "Add ip geolocation info",
  processors: [
    {
      geoip: {
        field: "ip",
      },
    },
  ],
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: "my_id",
  pipeline: "geoip",
  document: {
    ip: "80.231.5.0",
  },
});
console.log(response1);

const response2 = await client.get({
  index: "my-index-000001",
  id: "my_id",
});
console.log(response2);
PUT _ingest/pipeline/geoip
{
  "description" : "Add ip geolocation info",
  "processors" : [
    {
      "geoip" : {
        "field" : "ip"
      }
    }
  ]
}

PUT my-index-000001/_doc/my_id?pipeline=geoip
{
  "ip": "80.231.5.0"
}

GET my-index-000001/_doc/my_id

这将返回

{
  "_index" : "my-index-000001",
  "_id" : "my_id",
  "_version" : 1,
  "_seq_no" : 71,
  "_primary_term": 1,
  "found" : true,
  "_source" : {
    "ip" : "80.231.5.0"
  }
}

将位置识别为地理点

编辑

尽管此处理器使用包含 IP 地址的估计纬度和经度的 location 字段丰富您的文档,但如果没有在映射中明确将其定义为 geo_point 类型,则该字段将不会在 Elasticsearch 中被索引为 geo_point 类型。

您可以对上面的示例索引使用以下映射

resp = client.indices.create(
    index="my_ip_locations",
    mappings={
        "properties": {
            "geoip": {
                "properties": {
                    "location": {
                        "type": "geo_point"
                    }
                }
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my_ip_locations',
  body: {
    mappings: {
      properties: {
        geoip: {
          properties: {
            location: {
              type: 'geo_point'
            }
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my_ip_locations",
  mappings: {
    properties: {
      geoip: {
        properties: {
          location: {
            type: "geo_point",
          },
        },
      },
    },
  },
});
console.log(response);
PUT my_ip_locations
{
  "mappings": {
    "properties": {
      "geoip": {
        "properties": {
          "location": { "type": "geo_point" }
        }
      }
    }
  }
}

管理您自己的 IP 地理位置数据库更新

编辑

如果您无法从 Elastic 端点 自动更新 您的 IP 地理位置数据库,您还有其他几个选项

使用代理端点

如果您无法直接连接到 Elastic GeoIP 端点,请考虑设置一个安全代理。然后,您可以在每个节点的 elasticsearch.yml 文件的 ingest.geoip.downloader.endpoint 设置中指定代理端点 URL。

在严格的设置中,可能需要将以下域添加到允许的域列表中

  • geoip.elastic.co
  • storage.googleapis.com

使用自定义端点

您可以创建一个模拟 Elastic GeoIP 端点的服务。然后,您可以从此服务获取自动更新。

  1. MaxMind 站点下载您的 .mmdb 数据库文件。
  2. 将您的数据库文件复制到单个目录。
  3. 从您的 Elasticsearch 目录中,运行

    ./bin/elasticsearch-geoip -s my/source/dir [-t target/directory]
  4. 从您的目录提供静态数据库文件。例如,您可以使用 Docker 从 nginx 服务器提供文件

    docker run -v my/source/dir:/usr/share/nginx/html:ro nginx
  5. 在每个节点的 elasticsearch.yml 文件的 ingest.geoip.downloader.endpoint 设置中指定服务的端点 URL。

    默认情况下,Elasticsearch 每三天检查一次端点更新。要使用其他轮询间隔,请使用 集群更新设置 API 来设置 ingest.geoip.downloader.poll.interval

手动更新您的 IP 地理位置数据库

  1. 使用集群更新设置 APIingest.geoip.downloader.enabled 设置为 false。这将禁用可能覆盖您数据库更改的自动更新。这还会删除所有已下载的数据库。
  2. MaxMind 站点下载您的 .mmdb 数据库文件。

    您还可以使用自定义的城市、国家和 ASN .mmdb 文件。这些文件必须是未压缩的。类型(城市、国家或 ASN)将从文件元数据中提取,因此文件名无关紧要。

  3. 在 Elasticsearch Service 部署中,使用自定义捆绑包上传数据库。
  4. 在自托管的部署中,将数据库文件复制到 $ES_CONFIG/ingest-geoip
  5. 在您的 geoip 处理器中,配置 database_file 参数以使用自定义数据库文件。

节点设置

编辑

geoip 处理器支持以下设置:

ingest.geoip.cache_size
应缓存的最大结果数。默认为 1000

请注意,这些设置是节点设置,适用于所有 geoipip_location 处理器,即所有此类处理器都使用单个缓存。

集群设置

编辑
ingest.geoip.downloader.enabled
(动态,布尔值) 如果为 true,Elasticsearch 会自动从 ingest.geoip.downloader.endpoint 下载并管理 IP 地理位置数据库的更新。如果为 false,Elasticsearch 将不下载更新并删除所有已下载的数据库。默认为 true
ingest.geoip.downloader.eager.download
(动态,布尔值) 如果为 true,Elasticsearch 会立即下载 IP 地理位置数据库,无论是否存在带有 geoip 处理器的管道。如果为 false,则仅当存在带有 geoip 处理器的管道或添加了该管道时,Elasticsearch 才会开始下载数据库。默认为 false
ingest.geoip.downloader.endpoint
(静态,字符串) 用于下载 IP 地理位置数据库更新的端点 URL。例如,https://myDomain.com/overview.json。默认为 https://geoip.elastic.co/v1/database。Elasticsearch 将下载的数据库文件存储在每个节点的临时目录中的 $ES_TMPDIR/geoip-databases/<node_id> 下。请注意,Elasticsearch 将向 ${ingest.geoip.downloader.endpoint}?elastic_geoip_service_tos=agree 发出 GET 请求,期望获得通常在 overview.json 中找到的关于数据库的元数据列表。

下载器使用 JDK 的内置 cacerts。如果您使用的是自定义端点,请将自定义 https 端点 cacert 添加到 JDK 的信任库。

ingest.geoip.downloader.poll.interval
(动态时间值) Elasticsearch 在 ingest.geoip.downloader.endpoint 检查 IP 地理位置数据库更新的频率。必须大于 1d(一天)。默认为 3d(三天)。