mysql external shell命令从IP地址

时间:2018-01-02 19:01:27

标签: mysql shell command-line external geoip

我在Centos 7上安装了geoiplookup,我想从mysql表中选择一个IP,然后从命令行获取IP地址的位置。

例如,我可以输入! geoiplookup'123.45.36.35在mysql中获取城市,国家等

我可以从MaxMind下载数据,然后将其上传到mysql并按照site或此site提及运行查询,但我不想维护和更新另一个每月一次。这是最好的解决方案吗?

这个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;

非常感谢!

1 个答案:

答案 0 :(得分:1)

如您所述,如果您想使用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输出。

但我必须提醒您:此 DOES 每个 IP地址查询发出3个HTTP请求。如果它是一个大型表,那么对表中的每一行执行3个HTTP curl请求将是一个相当大的性能影响。

如果您需要多次访问此IP数据,您应该考虑在原始表中创建country,region和city列以及IP地址,然后运行UPDATE语句以仅更新这些列为空的行,并填写他们使用你的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)