Geoip MaxMind DB 生成指南

目前MaxMind對MMDB的讀寫支持如下
Writer:
perl
Reader:
C
C#
Java
Perl
PHP
Python

所以本文着重介紹如何快速使用perl生成mmdb文件,以及查詢mmdb基本原理


工作環境:Centos 6.5

一、安裝perl環境

忽略解壓、cd等基礎操作

二、生成庫文件

  • 編寫perl代碼,下面爲樣例,將讀local.db文件,生成dt.mmdb文件
use MaxMind::DB::Writer::Tree;
use Net::Works::Network;

use strict;
use warnings;
use Path::Class;
use autodie;

my %types = (
    product => 'utf8_string',
    rack => 'utf8_string',
    administrator => 'utf8_string',
    room => 'utf8_string',
);

my $tree = MaxMind::DB::Writer::Tree->new(
    ip_version            => 4,
    record_size           => 24,
    database_type         => 'kevin_test',
    languages             => [ 'en' ],
    description           => { en => 'Used in MarkDown display' },
    map_key_type_callback => sub { $types{ $_[0] } },
);

sub tree_insert_network{
    my $network = Net::Works::Network->new_from_string( string => $_[1] );
    $_[0]->insert_network(
        $network,
        {
        product => $_[2],
        rack => $_[3],
        administrator => $_[4],
        room => $_[5]
        },
    );
}

sub build_tree{
    my $dir = dir(".");
    my $file = $dir->file($_[0]);
    my $content = $file->slurp();
    my $file_handle = $file->openr();
    binmode($file_handle, ":utf8");
    while( my $line = $file_handle->getline() ) {
        $line =~ s/^\s+|\s+$//g;
        if ($line eq "") {
            next;
        }
        my @values = split('\|', $line);
        for (my $i= 1;$i <= 4;$i++){
            if (!defined $values[$i]) {
                $values[$i] = ""
            }
        }
        my @networks = split(',', $values[0]);
        foreach my $net (@networks) {
            tree_insert_network($tree, $net, $values[1], $values[2], $values[3], $values[4]);
        }
    }
}
build_tree('local.db', $tree);
open my $fh, '>:bytes', 'dt.mmdb';
$tree->write_tree($fh);
  • 編輯local.db文件

    1.1.1.1/32|Alipapa.Portal.COM.發佈系統|西單.4-2號機房.01-21|kevin|西單

    分別表示 IP/掩碼|產品線|機架|管理員|機房 (純屬虛構)

  • perl test.pl


MMDB查詢原理

一.簡單介紹下ipv4地址格式

我們所常見的ipv4地址如1.1.1.1均是點分十進制描述,以便用戶來書寫記憶,操作系統需要對該地址進行轉義生成32位2進制地址,如上面的地址1.1.1.1將轉換爲00000001 00000001 00000001 00000001

二.mmdb文件三部分

MMDB文件內容爲二進制格式,其內容分爲三大塊:搜索樹、數據段和元數據
爲了便於讀者理解,我在此先介紹元數據
1.元數據區
(本文僅介紹對文件結構有影響的元數據,其他描述性質的元數據不在此討論,有需要的讀者請參考文尾的官方文檔)

元數據區記錄了該mmdb文件的有關描述信息,以及對搜索數據有關的必要字段,元數據區位於文件尾部,以\xab\xcd\xefMaxMind.com字串分割元數據區與數據段,具體的存儲結構與數據段類似。

  • node_count 節點數量
    記錄搜索樹中有多少節點
  • record_size 記錄位大小
    每個搜索樹節點有兩個record
  • ip_version ip地址版本
    IPV4 或 IPV6

2.搜索樹

搜索樹用來通過ip來索引數據,由node_count 個node節點組成,每個節點有2個record,以24位size大小爲例:
| <— node —>|
| 23 .. 0 | 23 .. 0 |
record的值爲node號
搜索樹位於文件首部

3.數據段

數據段的值爲某ip所對應的具體內容,如城市、座標(當然也可在生成時自定義);數據段位於文件中部,與前邊的搜索樹以16個8位的null分割。

  • 字段類型:常見類型 UTF-8 string、pointer、double、map
    (其他類型請參考官網,如首3位爲0的擴展字段)
    • pointer:指針類型,類型值爲1
    • UTF-8 string: UTF字串類型,類型值爲2
    • double:雙精度數字,類型值爲3
    • map:映射類型,類型值爲7
  • 類型字段結構:
    • 8位表示,前三位爲字段類型,後五位爲有效載荷
    • 有效載荷:通常爲該字段在當前類型下,實際存儲的數量;指針和映射類型除外,指針的載荷爲數據區域指針偏移地址,映射的載荷爲有多少k-v對
    • 例如:
      • 映射類型 4個k-v對 –>11100100
      • UTF8類型 13個字符 –>01001101
  • 存儲結構:
    • 首位爲映射字段,表示該數據塊有N個k-v
    • N個字段塊,每個塊首部指出該字段類型,其後爲具體的值

簡介mmdb文件查詢算法

我們以1.1.1.1這個ip地址爲例:

  • 1.將該地址轉置成二進制形式00000001 00000001 00000001 00000001
  • 2.取大端第一位,在搜索樹查看起始node的recore,因爲值爲0故選擇大端的recore,判斷該值,有如下三種情況
    • 該值大小小於node_count 則表明該值指向搜索樹中的另外一個節點,則按照下一位的值重複此搜索
    • 若值等於node_count則表明該ip在此mmdb文件中不存在
    • 若值大於node_count則表明該指針指向了數據段
  • 3.若該值指向了數據段,則判斷該值所表示在數據段的偏移量
    offset=valuenodecount16
    16爲數據段和搜索樹中的16個8位null
  • 4.取到在數據段的偏移量後,找到該偏移量指向的區域,首位爲map類型指示了該段有多少個kv對,每個字段依次先指明字段類型然後緊隨值類型。

附:
MaxMind官方文檔:http://maxmind.github.io/MaxMind-DB/


若想支持查詢內網IP需要修改MMDB生成腳本的pm文件
./MaxMind-DB-Writer-perl/lib/MaxMind/DB/Writer/Tree.pm
刪除307行左右關於內網保留IP的內容


下文爲一個二進制索引的例子:
查詢1.1.1.1加粗字體爲路徑

0000000: 00000000 00000000 00000001 00000000 00000000 00101111 …../
0000006: 00000000 00000000 00000010 00000000 00000000 00100011 …..#
000000c: 00000000 00000000 00000011 00000000 00000000 10011111 ……
0000012: 00000000 00000000 00000100 00000000 00000000 10011111 ……
0000018: 00000000 00000000 00000101 00000000 00000000 00100000 …..
000001e: 00000000 00000000 00000110 00000000 00000000 10011111 ……
0000024: 00000000 00000000 00000111 00000000 00000000 10011111 ……
000002a: 00000000 00000000 10011111 00000000 00000000 00001000 ……
0000030: 00000000 00000000 00001001 00000000 00000000 10011111 ……
0000036: 00000000 00000000 00001010 00000000 00000000 10011111 ……
000003c: 00000000 00000000 00001011 00000000 00000000 10011111 ……
0000042: 00000000 00000000 00001100 00000000 00000000 10011111 ……
0000048: 00000000 00000000 00001101 00000000 00000000 10011111 ……
000004e: 00000000 00000000 00001110 00000000 00000000 10011111 ……
0000054: 00000000 00000000 00001111 00000000 00000000 10011111 ……
000005a: 00000000 00000000 10011111 00000000 00000000 00010000 ……
0000060: 00000000 00000000 00010001 00000000 00000000 10011111 ……
0000066: 00000000 00000000 00010010 00000000 00000000 10011111 ……
000006c: 00000000 00000000 00010011 00000000 00000000 10011111 ……
0000072: 00000000 00000000 00010100 00000000 00000000 10011111 ……
0000078: 00000000 00000000 00010101 00000000 00000000 10011111 ……
000007e: 00000000 00000000 00010110 00000000 00000000 10011111 ……
0000084: 00000000 00000000 00010111 00000000 00000000 10011111 ……
000008a: 00000000 00000000 10011111 00000000 00000000 00011000 ……
0000090: 00000000 00000000 00011001 00000000 00000000 10011111 ……
0000096: 00000000 00000000 00011010 00000000 00000000 10011111 ……
000009c: 00000000 00000000 00011011 00000000 00000000 10011111 ……
00000a2: 00000000 00000000 00011100 00000000 00000000 10011111 ……
00000a8: 00000000 00000000 00011101 00000000 00000000 10011111 ……
00000ae: 00000000 00000000 00011110 00000000 00000000 10011111 ……
00000b4: 00000000 00000000 00011111 00000000 00000000 10011111 ……
00000ba: 00000000 00000000 10011111 00000000 00000000 10101111 ……
00000c0: 00000000 00000000 00100001 00000000 00000000 10011111 ..!…
00000c6: 00000000 00000000 10011111 00000000 00000000 00100010 …..”
00000cc: 00000000 00000000 10011111 00000000 00000000 10011111 ……
00000d2: 00000000 00000000 10011111 00000000 00000000 00100100 …..$
00000d8: 00000000 00000000 00100101 00000000 00000000 00101011 ..%..+
00000de: 00000000 00000000 00100110 00000000 00000000 10011111 ..&…
00000e4: 00000000 00000000 10011111 00000000 00000000 00100111 …..’
00000ea: 00000000 00000000 00101000 00000000 00000000 10011111 ..(…
00000f0: 00000000 00000000 00101001 00000000 00000000 10011111 ..)…
00000f6: 00000000 00000000 00101010 00000000 00000000 10011111 ..*…
00000fc: 00000000 00000000 10011111 00000000 00000000 10011111 ……
0000102: 00000000 00000000 10011111 00000000 00000000 00101100 …..,
0000108: 00000000 00000000 10011111 00000000 00000000 00101101 …..-
000010e: 00000000 00000000 10011111 00000000 00000000 00101110 ……
0000114: 00000000 00000000 10011111 00000000 00000000 10011111 ……
000011a: 00000000 00000000 00110000 00000000 00000000 01000100 ..0..D
0000120: 00000000 00000000 10011111 00000000 00000000 00110001 …..1
0000126: 00000000 00000000 00110010 00000000 00000000 10011111 ..2…
000012c: 00000000 00000000 10011111 00000000 00000000 00110011 …..3
0000132: 00000000 00000000 00110100 00000000 00000000 00111110 ..4..>
0000138: 00000000 00000000 00110101 00000000 00000000 10011111 ..5…
000013e: 00000000 00000000 10011111 00000000 00000000 00110110 …..6
0000144: 00000000 00000000 10011111 00000000 00000000 00110111 …..7
000014a: 00000000 00000000 10011111 00000000 00000000 00111000 …..8
0000150: 00000000 00000000 10011111 00000000 00000000 00111001 …..9
0000156: 00000000 00000000 10011111 00000000 00000000 00111010 …..:
000015c: 00000000 00000000 10011111 00000000 00000000 00111011 …..;
0000162: 00000000 00000000 10011111 00000000 00000000 00111100 …..<
0000168: 00000000 00000000 10011111 00000000 00000000 00111101 …..=
000016e: 00000000 00000000 10011111 00000000 00000000 10011111 ……
0000174: 00000000 00000000 00111111 00000000 00000000 10011111 ..?…
000017a: 00000000 00000000 01000000 00000000 00000000 10011111 ..@…
0000180: 00000000 00000000 01000001 00000000 00000000 10011111 ..A…
0000186: 00000000 00000000 01000010 00000000 00000000 10011111 ..B…
000018c: 00000000 00000000 01000011 00000000 00000000 10011111 ..C…
0000192: 00000000 00000000 10011111 00000000 00000000 10011111 ……
0000198: 00000000 00000000 01000101 00000000 00000000 10011110 ..E…
000019e: 00000000 00000000 01000110 00000000 00000000 10011111 ..F…
00001a4: 00000000 00000000 01000111 00000000 00000000 10001011 ..G…
00001aa: 00000000 00000000 01001000 00000000 00000000 01110101 ..H..u
00001b0: 00000000 00000000 01001001 00000000 00000000 10011111 ..I…
00001b6: 00000000 00000000 01001010 00000000 00000000 10011111 ..J…
00001bc: 00000000 00000000 01001011 00000000 00000000 01101110 ..K..n
00001c2: 00000000 00000000 01001100 00000000 00000000 01100000 ..L..`
00001c8: 00000000 00000000 01001101 00000000 00000000 10011111 ..M…
00001ce: 00000000 00000000 01001110 00000000 00000000 10011111 ..N…
00001d4: 00000000 00000000 01001111 00000000 00000000 10011111 ..O…
00001da: 00000000 00000000 01010000 00000000 00000000 10011111 ..P…
00001e0: 00000000 00000000 01010001 00000000 00000000 10011111 ..Q…
00001e6: 00000000 00000000 01010010 00000000 00000000 10011111 ..R…
00001ec: 00000000 00000000 01010011 00000000 00000000 10011111 ..S…
00001f2: 00000000 00000000 01010100 00000000 00000000 10011111 ..T…
00001f8: 00000000 00000000 01010101 00000000 00000000 10011111 ..U…
00001fe: 00000000 00000000 01010110 00000000 00000000 10011111 ..V…
0000204: 00000000 00000000 01010111 00000000 00000000 10011111 ..W…
000020a: 00000000 00000000 01011000 00000000 00000000 10011111 ..X…
0000210: 00000000 00000000 01011001 00000000 00000000 01011111 ..Y.._
0000216: 00000000 00000000 01011010 00000000 00000000 10011111 ..Z…
000021c: 00000000 00000000 01011011 00000000 00000000 10011111 ..[…
0000222: 00000000 00000000 01011100 00000000 00000000 10011111 …..
0000228: 00000000 00000000 01011101 00000000 00000000 10011111 ..]…
000022e: 00000000 00000000 01011110 00000000 00000000 10011111 ..^…
0000234: 00000000 00000000 10011111 00000000 00000000 10011111 ……
000023a: 00000000 00000000 10011111 00000000 00000000 10011111 ……
0000240: 00000000 00000000 01100001 00000000 00000000 10011111 ..a…
0000246: 00000000 00000000 10011111 00000000 00000000 01100010 …..b
000024c: 00000000 00000000 10011111 00000000 00000000 01100011 …..c
0000252: 00000000 00000000 01100100 00000000 00000000 10011111 ..d…
0000258: 00000000 00000000 01100101 00000000 00000000 10011111 ..e…
000025e: 00000000 00000000 01100110 00000000 00000000 10011111 ..f…
0000264: 00000000 00000000 01100111 00000000 00000000 10011111 ..g…
000026a: 00000000 00000000 10011111 00000000 00000000 01101000 …..h
0000270: 00000000 00000000 10011111 00000000 00000000 01101001 …..i
0000276: 00000000 00000000 01101010 00000000 00000000 10011111 ..j…
000027c: 00000000 00000000 01101011 00000000 00000000 10011111 ..k…
0000282: 00000000 00000000 01101100 00000000 00000000 10011111 ..l…
0000288: 00000000 00000000 10011111 00000000 00000000 01101101 …..m
000028e: 00000000 00000000 10011111 00000000 00000000 10011111 ……
0000294: 00000000 00000000 01101111 00000000 00000000 10011111 ..o…
000029a: 00000000 00000000 10011111 00000000 00000000 01110000 …..p
00002a0: 00000000 00000000 01110001 00000000 00000000 10011111 ..q…
00002a6: 00000000 00000000 10011111 00000000 00000000 01110010 …..r
00002ac: 00000000 00000000 01110011 00000000 00000000 10011111 ..s…
00002b2: 00000000 00000000 01110100 00000000 00000000 10011111 ..t…
00002b8: 00000000 00000000 10011111 00000000 00000000 10011111 ……
00002be: 00000000 00000000 10011111 00000000 00000000 01110110 …..v
00002c4: 00000000 00000000 01110111 00000000 00000000 10011111 ..w…
00002ca: 00000000 00000000 01111000 00000000 00000000 10011111 ..x…
00002d0: 00000000 00000000 01111001 00000000 00000000 10011111 ..y…
00002d6: 00000000 00000000 01111010 00000000 00000000 01111110 ..z..~
00002dc: 00000000 00000000 10011111 00000000 00000000 01111011 …..{
00002e2: 00000000 00000000 01111100 00000000 00000000 10011111 ..|…
00002e8: 00000000 00000000 01111101 00000000 00000000 10011111 ..}…
00002ee: 00000000 00000000 10011111 00000000 00000000 10011111 ……
00002f4: 00000000 00000000 10011111 00000000 00000000 01111111 ……
00002fa: 00000000 00000000 10000000 00000000 00000000 10011111 ……
0000300: 00000000 00000000 10000001 00000000 00000000 10011111 ……
0000306: 00000000 00000000 10011111 00000000 00000000 10000010 ……
000030c: 00000000 00000000 10011111 00000000 00000000 10000011 ……
0000312: 00000000 00000000 10000100 00000000 00000000 10011111 ……
0000318: 00000000 00000000 10011111 00000000 00000000 10000101 ……
000031e: 00000000 00000000 10011111 00000000 00000000 10000110 ……
0000324: 00000000 00000000 10000111 00000000 00000000 10011111 ……
000032a: 00000000 00000000 10001000 00000000 00000000 10011111 ……
0000330: 00000000 00000000 10011111 00000000 00000000 10001001 ……
0000336: 00000000 00000000 10001010 00000000 00000000 10011111 ……
000033c: 00000000 00000000 10011111 00000000 00000000 10011111 ……
0000342: 00000000 00000000 10001100 00000000 00000000 10011111 ……
0000348: 00000000 00000000 10011111 00000000 00000000 10001101 ……
000034e: 00000000 00000000 10011111 00000000 00000000 10001110 ……
0000354: 00000000 00000000 10001111 00000000 00000000 10011111 ……
000035a: 00000000 00000000 10010000 00000000 00000000 10011111 ……
0000360: 00000000 00000000 10010001 00000000 00000000 10011111 ……
0000366: 00000000 00000000 10010010 00000000 00000000 10011111 ……
000036c: 00000000 00000000 10010011 00000000 00000000 10011111 ……
0000372: 00000000 00000000 10010100 00000000 00000000 10011111 ……
0000378: 00000000 00000000 10010101 00000000 00000000 10011111 ……
000037e: 00000000 00000000 10010110 00000000 00000000 10011111 ……
0000384: 00000000 00000000 10010111 00000000 00000000 10011111 ……
000038a: 00000000 00000000 10011111 00000000 00000000 10011000 ……
0000390: 00000000 00000000 10011111 00000000 00000000 10011001 ……
0000396: 00000000 00000000 10011111 00000000 00000000 10011010 ……
000039c: 00000000 00000000 10011011 00000000 00000000 10011111 ……
00003a2: 00000000 00000000 10011100 00000000 00000000 10011111 ……
00003a8: 00000000 00000000 10011101 00000000 00000000 10011111 ……
00003ae: 00000000 00000000 10011111 00000000 00000000 10011111 ……
00003b4: 00000000 00000000 10011111 00000000 00000000 10011111 ……
00003ba: 00000000 00000000 00000000 00000000 00000000 00000000 ……
00003c0: 00000000 00000000 00000000 00000000 00000000 00000000 ……
00003c6: 00000000 00000000 00000000 00000000 11100100 01001101 …..M
00003cc: 01100001 01100100 01101101 01101001 01101110 01101001 admini
00003d2: 01110011 01110100 01110010 01100001 01110100 01101111 strato
00003d8: 01110010 01000101 01101011 01100101 01110110 01101001 rEkevi
00003de: 01101110 01000111 01110000 01110010 01101111 01100100 nGprod
00003e4: 01110101 01100011 01110100 01011101 00000010 01000001 uct].A
00003ea: 01101100 01101001 01110000 01100001 01110000 01100001 lipapa
00003f0: 00101110 01010000 01101111 01110010 01110100 01100001 .Porta
00003f6: 01101100 00101110 01000011 01001111 01001101 00101110 l.COM.
00003fc: 11100101 10001111 10010001 11100101 10111000 10000011 ……
0000402: 11100111 10110011 10111011 11100111 10111011 10011111 ……
0000408: 01000100 01110010 01100001 01100011 01101011 01011001 DrackY
000040e: 11101000 10100101 10111111 11100101 10001101 10010101 ……
0000414: 00101110 00110100 00101101 00110010 11100101 10001111 .4-2..
000041a: 10110111 11100110 10011100 10111010 11100110 10001000 ……
0000420: 10111111 00101110 00110000 00110001 00101101 00110010 ..01-2
0000426: 00110001 01000100 01110010 01101111 01101111 01101101 1Droom
000042c: 01000110 11101000 10100101 10111111 11100101 10001101 F…..
0000432: 10010101 10101011 11001101 11101111 01001101 01100001 ….Ma
0000438: 01111000 01001101 01101001 01101110 01100100 00101110 xMind.
000043e: 01100011 01101111 01101101 11101001 01011011 01100010 com.[b
0000444: 01101001 01101110 01100001 01110010 01111001 01011111 inary_
000044a: 01100110 01101111 01110010 01101101 01100001 01110100 format
0000450: 01011111 01101101 01100001 01101010 01101111 01110010 _major
0000456: 01011111 01110110 01100101 01110010 01110011 01101001 _versi
000045c: 01101111 01101110 10100001 00000010 01011011 01100010 on..[b
0000462: 01101001 01101110 01100001 01110010 01111001 01011111 inary_
0000468: 01100110 01101111 01110010 01101101 01100001 01110100 format
000046e: 01011111 01101101 01101001 01101110 01101111 01110010 _minor
0000474: 01011111 01110110 01100101 01110010 01110011 01101001 _versi
000047a: 01101111 01101110 10100000 01001011 01100010 01110101 on.Kbu
0000480: 01101001 01101100 01100100 01011111 01100101 01110000 ild_ep
0000486: 01101111 01100011 01101000 00000100 00000010 01011000 och..X
000048c: 01000110 10001011 10100000 01001101 01100100 01100001 F..Mda
0000492: 01110100 01100001 01100010 01100001 01110011 01100101 tabase
0000498: 01011111 01110100 01111001 01110000 01100101 01001010 _typeJ
000049e: 01101011 01100101 01110110 01101001 01101110 01011111 kevin_
00004a4: 01110100 01100101 01110011 01110100 01001011 01100100 testKd
00004aa: 01100101 01110011 01100011 01110010 01101001 01110000 escrip
00004b0: 01110100 01101001 01101111 01101110 11100001 01000010 tion.B
00004b6: 01100101 01101110 01011000 01010101 01110011 01100101 enXUse
00004bc: 01100100 00100000 01101001 01101110 00100000 01001101 d in M
00004c2: 01100001 01110010 01101011 01000100 01101111 01110111 arkDow
00004c8: 01101110 00100000 01100100 01101001 01110011 01110000 n disp
00004ce: 01101100 01100001 01111001 01001010 01101001 01110000 layJip
00004d4: 01011111 01110110 01100101 01110010 01110011 01101001 _versi
00004da: 01101111 01101110 10100001 00000100 01001001 01101100 on..Il
00004e0: 01100001 01101110 01100111 01110101 01100001 01100111 anguag
00004e6: 01100101 01110011 00000001 00000100 01000010 01100101 es..Be
00004ec: 01101110 01001010 01101110 01101111 01100100 01100101 nJnode
00004f2: 01011111 01100011 01101111 01110101 01101110 01110100 _count
00004f8: 11000001 10011111 01001011 01110010 01100101 01100011 ..Krec
00004fe: 01101111 01110010 01100100 01011111 01110011 01101001 ord_si
0000504: 01111010 01100101 10100001 00011000 ze..

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章