PostgreSQL DNS 解析功能 - get ip, get host name

简介: 标签PostgreSQL , dns , python , gethostname , gethost背景在数据库中,根据主机名获得IP,根据IP解析主机名。这个功能没有什么花哨,可以通过C函数或者PYTHON函数得到。

标签

PostgreSQL , dns , python , gethostname , gethost


背景

在数据库中,根据主机名获得IP,根据IP解析主机名。

这个功能没有什么花哨,可以通过C函数或者PYTHON函数得到。

src/common/ip.c

/*  
 *      pg_getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets  
 *  
 * The API of this routine differs from the standard getnameinfo() definition  
 * in two ways: first, the addr parameter is declared as sockaddr_storage  
 * rather than struct sockaddr, and second, the node and service fields are  
 * guaranteed to be filled with something even on failure return.  
 */  
int  
pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen,  
                                   char *node, int nodelen,  
                                   char *service, int servicelen,  
                                   int flags)  
{  
        int                     rc;  
  
#ifdef HAVE_UNIX_SOCKETS  
        if (addr && addr->ss_family == AF_UNIX)  
                rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,  
                                                          node, nodelen,  
                                                          service, servicelen,  
                                                          flags);  
        else  
#endif  
                rc = getnameinfo((const struct sockaddr *) addr, salen,  
                                                 node, nodelen,  
                                                 service, servicelen,  
                                                 flags);  
  
        if (rc != 0)  
        {  
                if (node)  
                        strlcpy(node, "???", nodelen);  
                if (service)  
                        strlcpy(service, "???", servicelen);  
        }  
  
        return rc;  
}  

pgdnsres

有个python的插件,可以直接使用。

https://www.postgresql.org/ftp/projects/pgFoundry/pgdnsres/pgdnsres/1.1/

/*   
  
IPv4 DNS Resolution Functions for PostgreSQL  
============================================  
  
Author: Christian J. Dietrich <dietrich@internet-sicherheit.de>  
Version: 1.1  
License: BSD license  
  
pg-dns-resolve contains PL/Python functions for DNS resolution at the SQL   
prompt. Ever wanted to issue SELECT hostbyname('www.google.com') in   
order to get its IP address(es) from the pgsql command line? Then   
pg-dns-resolve is the right thing for you. See below for more examples.  
  
  
INSTALLATION  
============  
 * Make sure, you have ip4r installed. Get it from: http://pgfoundry.org/projects/ip4r/  
 * Make sure, you have PL/Pythonu installed and are allowed to add new functions  
 * PL/Pythonu must be built against Python >= 2.4  
 * psql [YOUR OPTIONS] < plpython_dns-functions.sql  
  
  
EXAMPLES  
========  
  
NOTE: If you run any of the functions below on a massive   
      data set, your DNS resolver might misinterpret this as a   
      DoS attack and get somewhat angry. Thus, it is a good idea   
      to run your own local resolver.  
  
  
For all of the functions there is a variant ending in "_n" which means   
that on error, NULL is to be returned instead of an error string describing   
the cause of the error. Some functions have a _s version which means they   
return the result as a set, i.e. multiple rows.  
  
Resolve the hostname for a given IP address:  
  
db=# select dst, hostbyaddr(dst) from dns_per_ip limit 2;  
      dst      |        hostbyaddr  
---------------+-----------------------------  
 192.168.1.1   | (1, 'Unbekannter Rechner')  
 193.232.128.6 | ns5.msk-ix.net  
(2 rows)  
  
  
Forward resolve www.google.de to (one of) its IP address:  
  
db=# select hostbyname('www.google.de');  
 hostbyname  
---------------  
 74.125.43.105  
(1 row)  
  
  
Note that on error, NULL is returned by hostbyname_n,   
BUT hostbyname returns an error string instead. So if   
you want to know why the resolution failed, use   
hostbyname, otherwise use hostbyname_n.  
  
db=# select hostbyname_n('deafd'), hostbyname('deafd');  
  hostbyname_n |                  hostbyname  
---------------+----------------------------------------------------  
               | (-2, 'Der Name oder der Dienst ist nicht bekannt')  
(1 row)  
  
  
db=# select hostbyname_n('nonexistinghost') is NULL;  
 ?column?  
----------  
 true  
(1 row)  
  
  
If you need all IP addresses of a hostname, use addrsbyname.   
DNS usually returns a different order of multiple IP addresses due   
to round-robin. Note that, the list of IP addresses of   
addrsbyname is sorted, thus two executions with the same   
argument return the same list. This is very useful for comparisons.  
  
db=# select addrsbyname('www.google.de');  
 addrsbyname  
-------------------  
 74.125.43.103  
 74.125.43.104  
 74.125.43.105  
 74.125.43.106  
 74.125.43.147  
 74.125.43.99  
(1 row)  
  
If you want e.g. a comma-separated list instead of newline-separated list,   
use your own separator string as the second argument to addrsbyname:  
  
db=# select addrsbyname('www.google.de', ', ');  
                                    addrsbyname  
-----------------------------------------------------------------------------------------  
 74.125.43.103, 74.125.43.104, 74.125.43.105, 74.125.43.106, 74.125.43.147, 74.125.43.99  
(1 row)   
  
  
hostsbyname works similar to addrsbyname. hostsbyname returns a list of   
all hostnames associated with a given hostname, including aliases. As with  
addrsbyname there are 2 variants, one using the default newline delimiter  
to separate elements and one where you can specify the delimiter yourself.  
The list of resulting hostnames is sorted.  
  
db=# select hostsbyname('www.google.de', ', ');  
                  hostsbyname  
-------------------------------------------------  
 www.google.com, www.google.de, www.l.google.com  
(1 row)  
  
  
When working with sets, there are 4 interesting functions: addrsbyname_s and   
addrsbyname_ns as well as hostsbyname_s and hostsbyname_ns.   
Those return a set, i.e. multiple rows, instead of an aggregated   
string and they are useful when working with statements such as   
  
  SELECT ...   
  FROM ...  
  WHERE xxx IN ( SELECT addrsbyname_ns('www.google.com') )  
  
  
db=# SELECT addrsbyname_s('www.google.com');  
 addrsbyname_s  
---------------  
 74.125.43.103  
 74.125.43.104  
 74.125.43.105  
 74.125.43.106  
 74.125.43.147  
 74.125.43.99  
(6 rows)  
  
Note the subtle difference: 6 rows instead of 1 row when comparing the output   
of addrsbyname_s to that of addrsbyname.  
  
  
db=# SELECT '74.125.43.103'::ip4 IN ( SELECT addrsbyname_s('www.google.com') );  
 ?column?  
----------  
 t  
(1 row)  
  
db=# SELECT hostsbyname_ns('www.google.com');  
  hostsbyname_ns  
------------------  
 www.google.com  
 www.l.google.com  
(2 rows)  
  
Querying a non existing hostname will result in an empty set:  
  
db=# SELECT hostsbyname_ns('nonexistinghost');  
 hostsbyname_ns  
----------------  
(0 rows)  
  
A special case is forward-confirmed reverse DNS resolution (http://en.wikipedia.org/wiki/Forward-confirmed_reverse_DNS):  
  
db=# SELECT fcrdns('192.203.230.10');  
 fcrdns  
--------  
 f  
(1 row)  
  
db=# SELECT fcrdns('74.125.43.104');  
 fcrdns  
--------  
 t  
(1 row)  
  
*/  
  
  
/* **********   reverse resolution    ********** */  
  
-- returns the hostname for a given IP address  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostbyaddr (addr ip4)  
    RETURNS text  
AS $$  
    import socket  
	  
    if addr is None: return None  
    try:  
        hostname = socket.gethostbyaddr(addr)[0]  
    except Exception, e:   
        hostname = str(e)  
    return hostname  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostbyaddr (ip4) IS 'Returns the hostname for a given IP address. Returns an error string on resolution errors. Returns NULL on NULL input.';  
  
-- returns the hostname for a given IP address  
-- returns NULL for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostbyaddr_n (addr ip4)  
    RETURNS text  
AS $$  
    import socket  
	  
    if addr is None: return None  
    try:  
        hostname = socket.gethostbyaddr(addr)[0]  
    except Exception, e:   
        hostname = None  
    return hostname  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostbyaddr_n (ip4) IS 'Returns the hostname for a given IP address, NULL on error. Returns NULL on NULL input.';  
  
-- returns true, if the given IP address passes forward-confirmed reverse DNS, false otherwise (also on error)  
-- see http://en.wikipedia.org/wiki/Forward-confirmed_reverse_DNS  
CREATE OR REPLACE FUNCTION fcrdns (addr ip4)  
    RETURNS boolean  
AS $$  
    import socket  
	  
    if addr is None: return None  
    try:  
        # reverse resolution of the given IP address returns all rhostnames  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyaddr(addr)  
        for rhostname in [hostname]+aliaslist:  
            (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(rhostname)  
            # if the given ip addr is at least once in ipaddrlist, we pass the test  
            if addr in ipaddrlist:  
                return True  
        # if the ip addr has not been in any of the ipaddrlists, we fail  
        return False  
    except Exception, e:   
        pass  
    return False  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION fcrdns (ip4) IS 'Returns true, if the given IP address passes forward-confirmed reverse DNS, false otherwise. see http://en.wikipedia.org/wiki/Forward-confirmed_reverse_DNS';  
  
  
  
  
/* **********   forward resolution    ********** */  
  
-- returns an IP address for the given hostname  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostbyname (name text)  
    RETURNS text  
AS $$  
    import socket  
	  
    if name is None: return None  
    try:  
        addr = socket.gethostbyname(name)  
    except Exception, e:   
        addr = str(e)  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostbyname (text) IS 'Returns an IP address for the given hostname. Returns an error string on resolution errors. Returns NULL on NULL input.';  
  
-- returns an IP address for the given hostname  
-- returns NULL for non-resolvable hostnames  
CREATE OR REPLACE FUNCTION hostbyname_n (name text)  
    RETURNS ip4  
AS $$  
    import socket  
	  
    if name is None: return None  
    try:  
        addr = socket.gethostbyname(name)  
    except Exception, e:   
        addr = None  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostbyname_n (text) IS 'Returns an IP address for the given hostname, NULL on error. Returns NULL on NULL input.';  
  
  
-- returns all IP addresses for the given hostname  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION addrsbyname (name text)  
    RETURNS text  
AS $$  
    import socket, string  
	  
    if name is None: return None  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = string.join(sorted(ipaddrlist), '\n')  
    except Exception, e:   
        addr = str(e)  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION addrsbyname (text) IS 'Returns all IP addresses for the given hostname. Returns an error string on resolution errors. Returns NULL on NULL input.';  
  
-- returns all IP addresses for the given hostname as a set (multiple rows)  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION addrsbyname_s (name text)  
    RETURNS SETOF ip4  
AS $$  
    import socket, string  
	  
    if name is None: return []  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = sorted(ipaddrlist)  
    except Exception, e:   
        addr = [str(e)]  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION addrsbyname_s (text) IS 'Returns all IP addresses for the given hostname as multiple rows. Returns an error string on resolution errors. Returns empty set on NULL input.';  
  
  
-- returns all IP addresses for the given hostname as a string where the elements are separated by sep  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION addrsbyname (name text, sep text)  
    RETURNS text  
AS $$  
    import socket, string  
	  
    if name is None or sep is None: return None  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = string.join(sorted(ipaddrlist), sep)  
    except Exception, e:   
        addr = str(e)  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION addrsbyname (text, text) IS 'Returns all IP addresses for the given hostname with custom delimiter. Returns an error string on resolution errors. Returns NULL on NULL input.';  
  
-- returns all IP addresses for the given hostname  
-- returns NULL for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION addrsbyname_n (name text)  
    RETURNS text  
AS $$  
    import socket, string  
	  
    if name is None: return None  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = string.join(sorted(ipaddrlist), '\n')  
    except Exception, e:   
        addr = None  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION addrsbyname_n (text) IS 'Returns all IP addresses for the given hostname, NULL on error. Returns NULL on NULL input.';  
  
-- returns all IP addresses for the given hostname as a set (multiple rows)  
-- returns an empty set for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION addrsbyname_ns (name text)  
    RETURNS SETOF ip4  
AS $$  
    import socket, string  
	  
    if name is None: return []  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = sorted(ipaddrlist)  
    except Exception, e:   
        addr = ()  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION addrsbyname_ns (text) IS 'Returns all IP addresses for the given hostname as a set (multiple rows), empty set on error or NULL input.';  
  
-- returns all IP addresses for the given hostname as a string where the elements are separated by sep  
-- returns NULL for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION addrsbyname_n (name text, sep text)  
    RETURNS text  
AS $$  
    import socket, string  
	  
    if name is None or sep is None: return None  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = string.join(sorted(ipaddrlist), sep)  
    except Exception, e:   
        addr = None  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION addrsbyname_n (text, text) IS 'Returns all IP addresses for the given hostname with custom delimiter, NULL on error or NULL input.';  
  
  
  
  
/* **********   hostname alias resolution    ********** */  
  
-- returns all hostnames for the given hostname  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostsbyname (name text)  
    RETURNS text  
AS $$  
    import socket, string  
	  
    if name is None: return None  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = string.join(sorted([hostname] + aliaslist), '\n')  
    except Exception, e:   
        addr = str(e)  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostsbyname (text) IS 'Returns all hostnames for the given hostname. Returns an error string on resolution errors. Returns NULL on NULL input.';  
  
-- returns all hostnames for the given hostname as a string where the elements are separated by sep  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostsbyname (name text, sep text)  
    RETURNS text  
AS $$  
    import socket, string  
	  
    if name is None or sep is None: return None  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = string.join(sorted([hostname] + aliaslist), sep)  
    except Exception, e:   
        addr = str(e)  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostsbyname (text, text) IS 'Returns all hostnames for the given hostname with custom delimiter. Returns an error string on resolution errors. Returns NULL on NULL input.';  
  
-- returns all hostnames for the given hostname as a set  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostsbyname_s (name text)  
    RETURNS SETOF text  
AS $$  
    import socket, string  
	  
    if name is None: return []  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = sorted([hostname] + aliaslist)  
    except Exception, e:   
        addr = [str(e)]  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostsbyname_s (text) IS 'Returns all hostnames for the given hostname as a set. Returns an error string on resolution errors. Returns empty set on NULL input.';  
  
  
  
-- returns all hostnames for the given hostname  
-- returns NULL for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostsbyname_n (name text)  
    RETURNS text  
AS $$  
    import socket, string  
	  
    if name is None: return None  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = string.join(sorted([hostname] + aliaslist), '\n')  
    except Exception, e:   
        addr = None  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostsbyname_n (text) IS 'Returns all hostnames for the given hostname, NULL on error. Returns NULL on NULL input.';  
  
-- returns all hostnames for the given hostname as a string where the elements are separated by sep  
-- returns NULL for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostsbyname_n (name text, sep text)  
    RETURNS text  
AS $$  
    import socket, string  
	  
    if name is None or sep is None: return None  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = string.join(sorted([hostname] + aliaslist), sep)  
    except Exception, e:   
        addr = None  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostsbyname_n (text, text) IS 'Returns all hostnames for the given hostname with custom delimiter, NULL on error. Returns NULL on NULL input.';  
  
-- returns all hostnames for the given hostname as a set  
-- returns an error string for non-resolvable hostnames or resolution errors  
CREATE OR REPLACE FUNCTION hostsbyname_ns (name text)  
    RETURNS SETOF text  
AS $$  
    import socket, string  
	  
    if name is None: return []  
    try:  
        (hostname, aliaslist, ipaddrlist) = socket.gethostbyname_ex(name)  
        addr = sorted([hostname] + aliaslist)  
    except Exception, e:   
        addr = ()  
    return addr  
$$ LANGUAGE plpythonu;  
COMMENT ON FUNCTION hostsbyname_ns (text) IS 'Returns all hostnames for the given hostname as a set, on error or on NULL input returns empty set.';  
  
/* end of file */  
目录
相关文章
|
域名解析 存储 网络协议
域名解析的终极指南:从基础到进阶,彻底搞懂 DNS 记录
域名解析是网站运行的基础,正确配置DNS记录至关重要。本文从基础到进阶全面解析DNS知识,涵盖A、AAAA、CNAME、MX、TXT、CAA等常见记录类型及其应用场景。通过学习,你将了解DNS的工作原理,掌握如何优化域名配置,确保网站与邮件服务高效运行。无论搭建个人博客还是企业官网,本文都能助你轻松搞定域名解析!
3310 0
|
10月前
|
监控
新功能上线:云解析DNS-重点域名监控功能发布
新功能上线:云解析DNS-重点域名监控功能发布
|
弹性计算 运维 安全
优化管理与服务:操作系统控制平台的订阅功能解析
本文介绍了如何通过操作系统控制平台提升系统效率,优化资源利用。首先,通过阿里云官方平台开通服务并安装SysOM组件,体验操作系统控制平台的功能。接着,详细讲解了订阅管理功能,包括创建订阅、查看和管理ECS实例的私有YUM仓库权限。订阅私有YUM仓库能够集中管理软件包版本、提升安全性,并提供灵活的配置选项。最后总结指出,使用阿里云的订阅和私有YUM仓库功能,可以提高系统可靠性和运维效率,确保业务顺畅运行。
|
存储 前端开发 JavaScript
调用DeepSeek API增强版纯前端实现方案,支持文件上传和内容解析功能
本方案基于DeepSeek API增强版,提供纯前端实现的文件上传与内容解析功能。通过HTML和JavaScript,用户可选择文件并调用API完成上传及解析操作。方案支持多种文件格式(如PDF、TXT、DOCX),具备简化架构、提高响应速度和增强安全性等优势。示例代码展示了文件上传、内容解析及结果展示的完整流程,适合快速构建高效Web应用。开发者可根据需求扩展功能,满足多样化场景要求。
4367 64
|
域名解析 网络协议 网络安全
SSL证书验证全攻略:DNS/HTTP/手动解析怎么选?
SSL证书在网络安全中至关重要,1Panel提供三种验证方式:DNS验证、HTTP验证和手动解析。DNS验证便捷,适合CDN网站;HTTP验证快速,需服务器在线;手动解析灵活,但操作复杂。根据需求选择合适确认方式,定期检查证书状态。
1434 2
|
域名解析 存储 缓存
深入学习 DNS 域名解析
在平时工作中相信大家都离不开 DNS 解析,因为 DNS 解析是互联网访问的第一步,无论是使用笔记本浏览器访问网络还是打开手机APP的时候,访问网络资源的第一步必然要经过DNS解析流程。
1620 31
|
供应链 监控 搜索推荐
反向海淘代购独立站:功能解析与搭建指南
“反向海淘”指海外消费者购买中国商品的现象,体现了中国制造的创新与强大。国产商品凭借高性价比和丰富功能,在全球市场备受欢迎。跨境电商平台的兴起为“反向海淘”提供了桥梁,而独立站因其自主权和品牌溢价能力逐渐成为趋势。一个成功的反向海淘代购独立站需具备多语言支持、多币种支付、物流跟踪、商品展示、购物车管理等功能,并通过SEO优化、社交媒体营销等手段提升运营效果。这不仅助力中国企业开拓海外市场,还推动了品牌全球化进程。
480 19
|
SQL 运维 监控
高效定位 Go 应用问题:Go 可观测性功能深度解析
为进一步赋能用户在复杂场景下快速定位与解决问题,我们结合近期发布的一系列全新功能,精心梳理了一套从接入到问题发现、再到问题排查与精准定位的最佳实践指南。
|
算法 前端开发 定位技术
地铁站内导航系统解决方案:技术架构与核心功能设计解析
本文旨在分享一套地铁站内导航系统技术方案,通过蓝牙Beacon技术与AI算法的结合,解决传统导航定位不准确、路径规划不合理等问题,提升乘客出行体验,同时为地铁运营商提供数据支持与增值服务。 如需获取校地铁站内智能导航系统方案文档可前往文章最下方获取,如有项目合作及技术交流欢迎私信我们哦~
1374 1

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多