mysql external shell命令从ip地址获取geoip信息

uurity8g  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(375)

我在centos7上安装了geoiplookup,我想从mysql表中选择一个ip,然后从命令行获取ip地址的位置。
例如,我会打字!在mysql中geoiplookup'123.45.36.35并获取城市、国家等信息。
我可以从maxmind下载数据,然后上传到mysql并运行一个查询,就像这个站点或这个站点上提到的那样,但是我不想每月维护和更新另一个表。这是最好的解决办法吗?
这个链接展示了我在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;

非常感谢!

4ioopgfo

4ioopgfo1#

正如您所提到的,如果您想使用geoiplookup实用程序并保持最新的ip信息,您需要定期(每月)从maxmind下载并维护ip更新(使用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请求。如果它是一个大表,那么为表中的每一行执行3个httpcurl请求会对性能造成很大的影响。
如果您需要多次访问这个ip数据,您应该考虑在原始表中创建country、region和city列以及ip地址,然后运行update语句只更新这些列为空的行,并用groovy新的curl\u lookup\u 函数填充它们。
像这样:

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)

相关问题