通过命令行的方式查找公网动态 IP 地址

公网IP是运行商给你的IP,是互联网上的一个“门牌号”。内网IP一般是你的局域网IP,比如你家有路由器,就必须有一个内网IP,是内网的一个“门牌号”。“门牌号”是“唯一”的,使别人能“找”到你。当然,没有路由也有内网IP,是因为你的本地链接里设置了一个固定IP了。

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
1.2.3.4.5.6.7.

cURL 方式

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

使用 dig 命令

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

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

这个是由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
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.

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

3. 总结

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

原创文章,作者:晴川运维,如若转载,请注明出处:https://baike.qcidc.com/10338.html

(0)
晴川运维晴川运维
上一篇 2025年6月24日
下一篇 2025年6月24日

相关推荐

  • Python3 re模块match与search

    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的…

    Linux系统 2025年7月10日
  • Linux su命令:用户间切换(包含su和su -的区别)

    su 是最简单的用户切换命令,通过该命令可以实现任何身份的切换,包括从普通用户切换为 root 用户、从 root 用户切换为普通用户以及普通用户之间的切换。 普通用户之间切换以及…

    Linux系统 2025年6月8日
  • 详解Linux输入子系统

    Linux 的输入子系统又叫 input 子系统,其构建非常灵活,不仅支持鼠标、键盘等常规输入设备,而且还支持蜂鸣器、触摸屏等设备。下面为大家详细讲解一下 Linux输入子系统。 …

    Linux系统 2025年6月20日
  • 在 Linux 上使用 systemd 设置定时器

    学习使用 systemd 创建启动你的游戏服务器的定时器。 之前,我们看到了如何手动的、在开机与关机时、在启用某个设备时、在文件系统发生改变时 启用与禁用 systemd 服务。 …

    Linux系统 2025年6月8日
  • Kubernetes共享Ceph存储具体方法

    Kubernetes pod 结合Ceph rbd块设备的使用,让Docker 数据存储在Ceph,重启Docker或k8s RC重新调度pod 不会引起数据来回迁移。 工作原理无…

    Linux系统 2025年10月19日
  • 使用C++解决牛吃草问题

    问题如下: 有一个牧场,牧场上的牧草每天都在匀速生长,这片牧场可供15头牛吃20天,或供20头牛吃10天,那么,这片牧场每天新生的草量可供几头牛吃一天? 数学解题思路如下: 假设一…

    Linux系统 2025年6月30日
  • 如何在 Apache 中重定向 URL 到另外一台服务器

    如我们前面两篇文章(使用 mod_rewrite 执行内部重定向和基于浏览器来显示自定义内容)中提到的,在本文中,我们将解释如何在 Apache 中使用 mod_rewrite 模…

    Linux系统 2025年10月8日
  • 详解Linux下端口映射

    端口映射器可实现端口映射功能,一个主要用途就是可以在局域网的网关上运行本程序,将网关服务器的某个端口映射为局域网中某台机器的某个端口,这样,局域网外部访问网关服务器的8081端口就…

    Linux系统 2025年6月21日
  • Fedora Linux 中使用 Homebrew 包管理器

    Homebrew是一款Mac OS平台下的软件包管理工具,拥有安装、卸载、更新、查看、搜索等很多实用的功能。简单的一条指令,就可以实现包管理,而不用你关心各种依赖和文件路径的情况,…

    Linux系统 2025年7月4日
  • Linux memcache安装和配置(自启动)过程详解

    memcache 是一个高性能的分布式的内存对象缓存系统,通过在内存中维护一张统一的、巨大的 Hash 表,它能够用来存储各种格式的数据,包括图像、视频、文件及数据库检索的结果等。…

    Linux系统 2025年6月18日

发表回复

登录后才能评论