<!--startmeta
custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/crates/netflow-plugin/integrations/custom_mmdb_database.md"
meta_yaml: "https://github.com/netdata/netdata/edit/master/src/crates/netflow-plugin/metadata.yaml"
sidebar_label: "Custom MMDB Database"
learn_status: "Published"
learn_rel_path: "Network Performance Monitoring/Network Flows/Enrichment Methods"
keywords: ['mmdb', 'custom database', 'bring your own', 'mmdbwriter', 'internal asn', 'internal ipam', 'ip intelligence']
message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE FLOWS' metadata.yaml FILE"
endmeta-->

<!-- markdownlint-disable-file -->

# Custom MMDB Database


<img src="https://netdata.cloud/img/network-wired.svg" width="150"/>


Plugin: netflow-plugin
Module: custom-mmdb

<img src="https://img.shields.io/badge/maintained%20by-Netdata-%2300ab44" />

## Overview

Enrich network flows with ASN, geographic, or internal network context from
operator-built MMDB databases. Use Custom MMDB Database when you want the netflow
plugin to read a MaxMind-format binary database (`.mmdb`) that your
own tooling produces -- typical use cases are joining the upstream DB-IP /
GeoLite2 data with internal AS labels, or producing a CIDR-tagged custom file
directly from an internal IPAM. The plugin only requires the file to conform to
the [MaxMind DB binary format](https://maxmind.github.io/MaxMind-DB/); whatever
fields it exposes are picked up by the same decoder path used for DB-IP and
MaxMind.

The decoder reads `autonomous_system_number`, `autonomous_system_organization`,
and (optionally) a string `asn` field from the ASN database, and `country.iso_code`,
`subdivisions[].iso_code`, `city.names.en`, `location.latitude`,
`location.longitude`, plus the Netdata-specific `netdata.ip_class` flag from the
geo database. Any other vendor-specific keys are ignored.

Note that `*_GEO_CITY`, `*_GEO_LATITUDE`, and `*_GEO_LONGITUDE` are written to
the raw journal tier only -- the rollup tiers drop these high-cardinality fields.
State and country survive into all four tiers.

For the full IP-intelligence concept (composition rule, ASN provider chain,
auto-detect path order, dual-stack handling, hot reload semantics), see
[IP Intelligence](https://github.com/netdata/netdata/blob/master/docs/npm/network-flows/enrichment.md).


You build (or download) the MMDB file with your own tooling, place it on the
agent host, and point `enrichment.geoip.asn_database` and / or
`enrichment.geoip.geo_database` at it in `netflow.yaml`. The plugin reloads on
file change automatically (mechanism documented on the IP Intelligence page).


This integration is supported on all platforms.

This integration runs as a single instance per Netdata Agent.


### Default Behavior

#### Auto-Detection

Not auto-detected. You must configure paths explicitly.

#### Limits

Coverage, schema quality, and freshness are entirely controlled by the custom MMDB build you provide. Invalid or missing files fail startup unless marked optional.

#### Performance Impact

Lookups are local MMDB reads with no per-flow network call. Memory use depends on the size and number of custom databases you configure.

## Setup


### Prerequisites

#### Build or obtain a standards-compliant MMDB file

The file must conform to the
[MaxMind DB binary format spec](https://maxmind.github.io/MaxMind-DB/) --
a binary search tree over IP prefixes plus a data section of
type-length-value records. Validate with `mmdblookup` from the
`libmaxminddb-tools` package before deploying:

```bash
mmdblookup --file your-custom.mmdb --ip 8.8.8.8
```

Common ways to produce a file:

- **Go**: [`github.com/maxmind/mmdbwriter`](https://github.com/maxmind/mmdbwriter)
  -- MaxMind's official Go writer. Lets you start from an upstream MMDB
  (DB-IP, GeoLite2) and overlay extra records, then write a new file.
  Pairs well with the read-side library
  [`github.com/oschwald/maxminddb-golang`](https://github.com/oschwald/maxminddb-golang).
- **Perl**: [`MaxMind::DB::Writer`](https://metacpan.org/pod/MaxMind::DB::Writer)
  -- the original reference writer.
- **Python**: community ports such as `mmdb_writer` (PyPI) wrap the same
  format.

Whatever fields you encode are read by the plugin only if they match the
standard schema names listed in the metrics description above.



### Configuration

#### Options

Point `enrichment.geoip.asn_database` and / or `enrichment.geoip.geo_database`
at your custom MMDB file paths. Set `optional: true` while you iterate so a
missing or malformed file does not block plugin startup.


<details open><summary>Config options</summary>



| Option | Description | Default | Required |
|:-----|:------------|:--------|:---------:|
| enrichment.geoip.asn_database | List of MMDB paths providing AS data. Multiple files compose -- per field, the last database returning a non-empty value wins. | [] | no |
| enrichment.geoip.geo_database | List of MMDB paths providing geographic data. Same composition rule as the ASN list. | [] | no |
| enrichment.geoip.optional | When true, missing or unreadable files at startup are tolerated (the resolver starts with no databases). Recommended while testing a custom file. | false | no |


</details>



#### via File

The configuration file name for this integration is `netflow.yaml`.


You can edit the configuration file using the [`edit-config`](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#edit-configuration-files) script from the
Netdata [config directory](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#locate-your-config-directory).

```bash
cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
sudo ./edit-config netflow.yaml
```

##### Examples

###### Internal MMDB built with mmdbwriter

A custom build that combines public BGP data with internal CIDR labels, written atomically into the plugin's lookup directory by the operator's own pipeline.

```yaml
enrichment:
  geoip:
    asn_database:
      - /etc/netdata/internal-asn.mmdb
    geo_database:
      - /etc/netdata/internal-geo.mmdb
    optional: false

```
###### Overlay a custom ASN file on top of the bundled DB-IP geo

Keep DB-IP for geographic data and use a custom MMDB only for AS labels (your IPAM-derived prefixes win because they appear last in the list -- the resolver merges per field, last non-empty wins).

<details open><summary>Config</summary>

```yaml
enrichment:
  geoip:
    asn_database:
      - /var/cache/netdata/topology-ip-intel/topology-ip-asn.mmdb
      - /etc/netdata/internal-asn.mmdb
    geo_database:
      - /var/cache/netdata/topology-ip-intel/topology-ip-geo.mmdb
    optional: true

```
</details>

###### Iterating on a new custom MMDB

While you tune the build pipeline, mark the database optional so an absent or malformed file becomes a startup warning instead of a fatal error.

<details open><summary>Config</summary>

```yaml
enrichment:
  geoip:
    asn_database:
      - /etc/netdata/wip-asn.mmdb
    geo_database: []
    optional: true

```
</details>



### Lookups silently return empty

The custom file's schema is non-standard (for example, the ASN is encoded
as a string instead of `autonomous_system_number: uint32`, or the country
is at a non-standard path). The plugin only reads the standard MaxMind
field names listed in the data-collection description. Validate with
`mmdblookup --file your-custom.mmdb --ip <known-public-ip>` and confirm the
standard fields are present at the expected paths.


### Plugin fails to start with optional=false

File missing, unreadable, or not a valid MMDB at the configured path.
Check permissions (the netdata user must be able to read the file) and
re-validate with `mmdblookup`. Set `optional: true` while iterating.


### Custom file refresh did not take effect

The plugin reloads custom databases the same way it reloads stock ones
(signature-driven, in place). If the file was rewritten in place the
plugin will pick it up; if it was edited byte-by-byte (rare with MMDB
builders) verify size or mtime actually changed. The reload mechanism
and its 30-second cadence are documented in
[IP Intelligence](https://github.com/netdata/netdata/blob/master/docs/npm/network-flows/enrichment.md).
Operational practice: have your build pipeline write the new MMDB to a
temp file in the same directory and `rename(2)` it over the live path so
the swap is atomic.
