mysql 外部 shell 命令从 IP 地址获取 GeoIP 信息

mysql external shell command to get GeoIP Information from an IP address

我在 Centos 7 上安装了 geoiplookup,我想 select 来自 mysql table 的 IP,然后从命令行获取 IP 地址的位置.

例如,我可以打字! geoiplookup' 123.45.36.35 in mysql 并获取城市、国家等

我可以从 MaxMind and then upload it to mysql and run a query as mentioned on this site or this site 下载数据,但我不想每月维护和更新另一个 table。这是最好的解决方案吗?

这个 link 显示了我在 fail2ban 日志中使用的几个 python 示例。

我喜欢做这样的事情:

SELECT udf_geoip_lookup(ip) AS 'City',  
     udf_geoip_lookup(ip) AS 'State'
     udf_geoip_lookup(ip) AS 'Region
FROM table-name
 ;

3 个函数调用太多了。

CREATE FUNCTION `udf_geoip_lookup` (ip varchar(15))
RETURNS varchar(100)
BEGIN

      SET @sql = CONCAT('\! geoiplookup', @ip);
      -- I need to parse the city, region, country etc, somehow.
      PREPARE stmt FROM @sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;   

RETURN @sql;
END;

非常感谢!

如您所述,如果您想使用 geoiplookup 实用程序并保持最新的 IP 信息,您需要定期(每月)从 MaxMind[= 下载和维护 IP 更新43=](有一个 cron 作业)。

您可能想要做的是调用 curl 实用程序,并从超酷的 ipinfo.io 网站检索数据:

$ curl ipinfo.io/47.144.148.253
{
  "ip": "47.144.148.253",
  "city": "Hermosa Beach",
  "region": "California",
  "country": "US",
  "loc": "33.8622,-118.3990",
  "org": "AS5650 Frontier Communications of America, Inc.",
  "postal": "90254"
}

然后您需要解析 JSON 输出。但是您也可以传递一个带有 ip 地址的 GET 参数,并准确获取您想要检索的内容。

例如,我 运行 curl 使用这些参数:

$ curl ipinfo.io/47.144.148.253/country
US
$ curl ipinfo.io/47.144.148.253/region
California
$ curl ipinfo.io/47.144.148.253/city
Hermosa Beach

所以你的 SQL 函数应该是这样的:

CREATE FUNCTION `curl_lookup_country` (ip varchar(15))
RETURNS varchar(100)
BEGIN
      SET @sql = CONCAT('\! curl', 'ipinfo.io/',@ip,'/country');
      PREPARE stmt FROM @sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;   // country
RETURN @sql;
END;

CREATE FUNCTION `curl_lookup_region` (ip varchar(15))
RETURNS varchar(100)
BEGIN
      SET @sql = CONCAT('\! curl', 'ipinfo.io/',@ip,'/region');
      PREPARE stmt FROM @sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;   // region or state
RETURN @sql;
END;

CREATE FUNCTION `curl_lookup_city` (ip varchar(15))
RETURNS varchar(100)
BEGIN
      SET @sql = CONCAT('\! curl', 'ipinfo.io/',@ip,'/city');
      PREPARE stmt FROM @sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;   // city
RETURN @sql;
END;

您的 SQL 查询将是:

SELECT curl_lookup_country(ip) AS 'Country',  
     curl_lookup_region(ip) AS 'State'
     curl_lookup_city(ip) AS 'City
FROM table-name

这样您就不必解析 JSON 输出。

但我必须警告你:这个确实每个 IP发出3个HTTP请求地址查询。如果它很大 table,那么对 table.

中的每一行执行 3 个 HTTP curl 请求会对性能造成相当大的影响。

如果您需要多次访问此 IP 数据,您应该考虑在原始 table 中创建国家、地区和城市列以及 IP 地址,然后 运行 更新语句仅更新这些列为空的行,并用您的 groovy 新 curl_lookup_xxx 函数填充它们。

像这样:

UPDATE table_name
SET country = curl_lookup_country(ip),
    region = curl_lookup_region(ip),
    city = curl_lookup_city(ip)
WHERE ip IS NOT NULL AND
  (country IS NULL OR
   region IS NULL OR
   city IS NULL)

如果您希望以高效的方式在数据库级别执行此操作,请随时阅读我们最新的博客。

我们基本上将 IP 范围数据集转换为每八位字节 3 个键值数据集(没有第 4 个),并且它在多个仓库中通过 SQL 在超过 10MM 的记录上运行良好。

我们发现我们的客户主要询问国家或美国各州,因此我们仅根据这些特定需求设计数据集。

您可以在这里阅读更多相关信息: https://cloudinary.com/blog/identifying_countries_by_ip_address_in_columnar_databases_through_sql

免责声明:我是这篇文章的作者。