良许Linux教程网 干货合集 如何在命令行快速获取公网动态 IP 地址

如何在命令行快速获取公网动态 IP 地址

如何确定公网 IP 地址是一个让很多家用宽带用户经常遇到的问题。毕竟,固定 IP 地址的价格通常很高,不适用于家庭宽带。而我们的电信宽带运营商(ISP)通常会给我们分配动态 IP 地址。之所以称为动态 IP 地址,是因为每次拨号获得的 IP 地址可能会不同。有些运营商甚至会每天或不定期刷新 IP 地址池,在某个时间强制释放已经获得的 IP 地址并分配新的 IP 地址。

这对我们在家用宽带下运行的服务产生了影响——需要重新设置服务端 IP 地址,例如监控、网络存储等。这时,DDNS 就发挥了作用。现在大部分路由器都内置了 DDNS 客户端,例如花生壳等服务客户端。但这些客户端存在收费、不稳定和刷新间隔小等问题。对于拥有自己域名的朋友,可以使用 DNS 服务商的 API 自行实现 IP 更新操作,例如阿里云(Aliyun)和 Cloudflare 都可以实现。

本文不涉及如何使用 API 更新 DDNS 的内容,但调用 API 时有一个关键参数——公网 IP 地址。那么,如何获取当前运营商分配的公网 IP 地址呢?除了询问路由器(打开路由器管理界面查看 WAN 口信息)外,我们还可以通过一些网络服务进行检测。

1使用 Shell 命令获取公网 IP 地址

浏览器方式

如果我们使用浏览器打开这个地址checkip.amazonaws.com你就会发现你的公网IP地址赫然在目,互联网上的服务器总是能够知道是什么 IP地址的客户端发起了连接,当然就可以通过这种方式获取公网 IP,同样功能的网站有很多,这里列举部分我收集到的:

https://checkip.amazonaws.com
https://api.ipify.org
https://ifconfig.me/ip
https://icanhazip.com
https://ipinfo.io/ip
https://ipecho.net/plain
https://checkipv4.dedyn.io

cURL 方式

在命令行下我们当然不能为这点小事随便启动浏览器,我们可以请出另外一个功能强大的工具,那就是curl,cURL 是一个利用URL语法在命令行下工作的文件传输工具,关于cURL的快速用法可以参考阮一峰的网络日志《curl 的用法指南》,这里不再详述,最简单的用法就是curl 你要请求的网址,比如curl checkip.amazonaws.com

使用 dig 命令

首次在别人脚本中看到这个方式获取公网IP觉得比较新奇,命令如下:

dig +short myip.opendns.com @resolver1.opendns.com

这个是由OpenDNS提供的服务,如果你的主机上没有安装dig命令,对于Debian系列系统可以通过apt-get install dnsutils安装,这个命令的原理是指定resolver1.opendns.com为域名myip.opendns.com的解析服务器,为什么要指定,主要是避免 DNS 下游服务器缓存,另外这个指定的解析服务器被 OpenDNS 进行了特殊配置,其始终将域名myip.opendns.com解析为发起 DNS 请求的客户端 IP 地址,这样也就实现了查找公网 IP的功能。

这个和 cURL 方式比有什么优势呢?当然是数据量更小传输更快,毕竟使用 cURL 发起 HTTP 请求必然会导致协议头等无关信息的交换,如果启用了 HTTPS/TLS 那么还要进行加密协商,效率会比较低,当然这种方式的缺点就是 DNS 查询容易被运营商审计和过滤,稳定性略差,不过我测试下来除了偶尔查询失败外其余情况是完全 OK 的。

2使用 Shell 脚本获取公网 IP 地址

至此我有个新的主意,那就是首先采用 dig 命令快速检索公网 IP 地址,如果失败则切换到 cURL 的方式,为了避免 cURL 单一服务器失败,采用轮询或者随机的方式,尽可能提高成功率。

使用 Bash Shell 脚本 do it,比如获取公网 IPv4 的脚本如下:

#!/bin/bash

# This script try to ensure gets the current IP address (as assigned by the ISP) from
# OpenDNS and other online services as fallbacks

hosts=("checkip.amazonaws.com" "api.ipify.org" "ifconfig.me/ip" "icanhazip.com" "ipinfo.io/ip" "ipecho.net/plain" "checkipv4.dedyn.io")

CURL=`which curl`
DIG=`which dig`

check=$($DIG +short myip.opendns.com @resolver1.opendns.com A) 

if [ ! $? -eq 0 ] || [ -z "$check" ] || [[ ! $check =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    echo "Unable to get your public IP address by OpenDNS service, try to another way."
    count=${#hosts[@]}

    while [ -z "$check" ] && [[ $count -ne 0 ]]; do
        selectedhost=${hosts[ $RANDOM % ${#hosts[@]} ]}
        check=$($CURL -4s https://$selectedhost | grep '[^[:blank:]]') && {
            if [ -n "$check" ] && [[ $check =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
                break
            else
                check=""
                count=$(expr $count - 1)
                echo "The host $selectedhost returned an invalid IP address."
            fi
        } || {
            check=""
            count=$(expr $count - 1)
            echo "The host $selectedhost did not respond."
        }
    done
fi

if [ -z "$check" ]; then
    echo "Unable to get your public IP address. Please check your internet connection."
    exit 1
fi

echo "Your public IP address is $check"

exit 0

上述脚本可以看出首先我使用 dig 方式查询 OpenDNS,如果查询失败或者返回为空或者不是 IP 地址,那么进入cURL模式,这里将可用服务器添加到 hosts 列表,并且随机抽取一个进行cURL,这里使用了curl -4s参数-4s分别表示仅使用 IPv4 方式连接(确保获取 IPv4 地址)和抑制进度条和错误信息,如果抽取的服务发生错误,那么进入循环再抽取一个,直到循环满最大 hosts 数停止。

3总结

大部分脚本甚至一些程序仅使用了一种方式获取公网 IP,但是互联网上这些服务往往是不可靠的,如果你所选用的服务出现故障,那么将会影响到你后续业务的开展,所以本文的核心思想还是多个备份,另外对于 cURL 方式采用随机确保所谓的“负载平衡”,避免 fallback 时过度请求某个服务导致 IP 被 Ban。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部