How to Migrate Existing GeoIP Data to Supported Formats Using loyalsoldier/geoip
To migrate existing GeoIP data to supported formats, create a JSON configuration file specifying your input sources and desired outputs, then run the geoip convert command to execute the transformation pipeline.
The loyalsoldier/geoip project provides a powerful conversion pipeline that enables you to migrate existing GeoIP data between multiple formats including MaxMind CSV, V2Ray DAT, MMDB, and plain-text lists. This Go-based tool uses a plugin-driven architecture to read data from any supported input format and write it to any supported output format through a simple JSON configuration. Whether you need to convert commercial GeoIP databases into open-source proxy formats or merge multiple sources into a single dataset, this guide walks you through the complete migration process using the project's source code.
Understanding the Migration Architecture
Core Orchestration Components
The migration engine centers around three primary components defined in the lib/ directory. The Instance struct in lib/instance.go orchestrates the entire conversion lifecycle, managing configuration loading and coordinating between input and output phases. Configuration parsing occurs in lib/config.go, which registers available converters and validates the JSON schema. Finally, lib/converter.go maintains the registry that maps type strings (like maxmindGeoLite2CountryCSV) to concrete implementations.
The Container and Entry Model
All GeoIP data flows through an in-memory abstraction defined in lib/lib.go. During migration, InputConverters populate a Container with Entry objects representing CIDR ranges grouped by country codes or categories. This intermediate representation allows the tool to merge multiple sources, apply filters, and perform set operations before OutputConverters serialize the data to the target format.
Step-by-Step Migration Process
1. Prepare the Configuration File
Create a JSON configuration file (e.g., config.json) that defines your migration pipeline. The configuration requires two top-level arrays: input and output. Each array entry is an object containing:
type: The converter identifier (e.g.,maxmindGeoLite2CountryCSV,v2rayGeoIPDat)action: Eitheraddto include CIDRs orremoveto exclude themargs: Converter-specific parameters such as file paths, wanted lists, and IP type filters
Example configuration converting MaxMind CSV to V2Ray DAT while filtering for IPv4 only:
{
"input": [
{
"type": "maxmindGeoLite2CountryCSV",
"action": "add",
"args": {
"country": "./geolite2/GeoLite2-Country-Locations-en.csv",
"ipv4": "./geolite2/GeoLite2-Country-Blocks-IPv4.csv",
"ipv6": "",
"wantedList": ["CN"],
"onlyIPType": "ipv4"
}
}
],
"output": [
{
"type": "v2rayGeoIPDat",
"action": "add",
"args": {
"outputFile": "./geoip.dat",
"pretty": false
}
}
]
}
2. Execute the Conversion Command
Run the migration using the CLI entry point defined in convert.go. The command initializes the Instance, loads your configuration, and processes the pipeline:
go run ./ convert -c ./config.json
This executes Instance.InitConfig which unmarshals the JSON (supporting comments via hujson), creates input configurations through createInputConfig, and prepares output converters.
3. Validate the Generated Data
Verify your migration results using the built-in lookup utility before deploying to production:
go run ./ lookup -f ./geoip.dat 8.8.8.8
Alternatively, load the generated file into your target application (V2Ray, Clash, or other proxy tools) to confirm that categories and IP ranges appear correctly.
How the Conversion Pipeline Works
Input Processing and Plugin Registration
When Instance.InitConfig calls createInputConfig, it queries the inputConfigCreatorCache registry populated by each plugin's init() function. For example, plugin/maxmind/maxmind_country_csv_in.go registers the maxmindGeoLite2CountryCSV type. The concrete InputConverter opens source files, builds mapping tables (such as GeoIP ID to country code), and produces Entry objects stored in the shared Container.
Output Generation
After all inputs are merged into the Container, each OutputConverter receives the dataset. In plugin/v2ray/dat_out.go, the v2rayGeoIPDat converter writes binary format using internal WriteGeoIPDat logic, while plugin/maxmind/maxmind_country_mmdb_out.go handles MMDB generation. You can specify multiple output blocks in your configuration to generate several formats in a single run.
Supported Migration Formats
The project supports extensive format interoperability through its plugin system. Key converters include:
Input Formats:
maxmindGeoLite2CountryCSV: Reads MaxMind GeoLite2 country CSV files (implementation inplugin/maxmind/maxmind_country_csv_in.go)maxmindGeoLite2ASNCSV: Processes MaxMind ASN databasesv2rayGeoIPDat: Ingests existing V2Ray binary databases (plugin/v2ray/dat_in.go)text: Parses plain-text IP/CIDR lists from files or stdin (plugin/plaintext/text_in.go)clashRuleSet/clashRuleSetClassical: Reads Clash proxy rule sets
Output Formats:
v2rayGeoIPDat: Writes V2Ray binary format (plugin/v2ray/dat_out.go)maxmindMMDB: Generates MaxMind MMDB databases (plugin/maxmind/maxmind_country_mmdb_out.go)text: Exports plain-text CIDR lists (plugin/plaintext/text_out.go)
Inspect all available converters by running go run ./ list (defined in list.go).
Advanced Migration Techniques
Merging Multiple Sources
Add multiple input blocks to merge several GeoIP databases into a single output. The Container aggregates all entries, allowing you to combine commercial MaxMind data with custom IP lists or private ranges using the private input type.
Applying Set Operations
Use the action: remove directive to prune unwanted CIDRs after merging. This works with cutter plugins to exclude specific IP ranges or countries from the final output, enabling you to create filtered datasets like "all countries except X".
Summary
- loyalsoldier/geoip migrates data between formats using a JSON-driven configuration pipeline orchestrated by
lib/instance.go. - The migration process requires creating a configuration file with
inputandoutputarrays specifying converter types, actions, and arguments. - Input converters in the
plugin/directory (such asmaxmind_country_csv_in.goanddat_in.go) read source data into a sharedContainerofEntryobjects. - Output converters (such as
dat_out.goandmaxmind_country_mmdb_out.go) serialize the Container contents to target formats. - Execute migrations with
geoip convert -c config.jsonand validate results usinggeoip lookup.
Frequently Asked Questions
What file formats can I migrate from and to?
The project supports migration between MaxMind CSV/MMDB, V2Ray DAT, plain-text lists, and Clash rule sets. You can convert any supported input format to any supported output format by specifying the appropriate type identifiers in your configuration file, such as maxmindGeoLite2CountryCSV for input and v2rayGeoIPDat for output.
How do I filter specific countries or IP types during migration?
Use the wantedList argument in your input configuration to specify an array of country codes (e.g., ["CN", "US"]), and set onlyIPType to ipv4 or ipv6 to restrict the address family. These filters are applied during the InputConverter phase before data reaches the Container.
Can I convert one input file into multiple output formats simultaneously?
Yes. Add multiple entries to the output array in your configuration file, each with a different type (e.g., v2rayGeoIPDat, maxmindMMDB, and text). The Instance will execute all output converters against the same Container data in a single run.
Does the configuration file support comments?
Yes. The parser in lib/config.go uses hujson to allow C-style and JavaScript-style comments within your JSON configuration files, making it easier to document complex migration pipelines with multiple input sources and transformations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →