公众号关注 「奇妙的 Linux 世界」

设为「星标」,每天带你玩转 Linux !

如何确定公网IP地址是一个让很多家用宽带朋友们经常遇到的问题,毕竟固定IP地址总是价格不菲因而不适用于家庭宽带,而我们的电信宽带运营商(ISP)往往给我们分配的是动态IP地址,之所以称作为动态IP地址,是因为每次拨号得到的IP地址可能会不一样,还有更骚的操作就是有的运营商每天或不定期在某个时间刷新IP地址池,这样已经获得的IP地址将会被强制释放并分配新的IP地址。

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

对于 DDNS 如何使用 API 更新不在本文叙述范围内,但调用 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 fallbackshosts=("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]+$ ]]; thenecho "Unable to get your public IP address by OpenDNS service, try to another way."count=${#hosts[@]}while [ -z "$check" ] && [[ $count -ne 0 ]]; doselectedhost=${hosts[ $RANDOM % ${#hosts[@]} ]}check=$($CURL -4s https://$selectedhost | grep '[^[:blank:]]') && {if [ -n "$check" ] && [[ $check =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; thenbreakelsecheck=""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
fiif [ -z "$check" ]; thenecho "Unable to get your public IP address. Please check your internet connection."exit 1
fiecho "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。

本文转载自:「 王晔的博客 」,原文:https://tinyurl.com/2p95wpue ,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。

最近,我们建立了一个技术交流微信群。目前群里已加入了不少行业内的大神,有兴趣的同学可以加入和我们一起交流技术,在 「奇妙的 Linux 世界」 公众号直接回复 「加群」 邀请你入群。

你可能还喜欢

点击下方图片即可阅读

Kubernetes 故障排除三板斧:理解、管理和预防

点击上方图片,『美团|饿了么』大额外卖红包天天免费领

更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!

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

  1. 快速获取本机IP地址AWK功能

    有些时候,我们在应用中可能要用到通过linux命令来获取本机IP地址,方法有很多种,例如最常见的就是ifconfig 如果我想尽尽只获取IP地址,方法也有很多种 例如:获取eth0的IP信息,利用cu ...

  2. 通过命令行方式批量设置保留IP地址的代码

    前段时间看到一个提问关于如何批量设置DHCP保留地址的贴子,后来经作实验测试,现将解决方法分享给大家,供互相学习讨论 前段时间看到一个提问关于如何批量设置DHCP保留地址的贴子,后来经作实验测试,现将 ...

  3. [命令行] curl查询公网出口IP

    一般 curl ipinfo.iocurl https://ip.cncurl cip.cccurl myip.ipip.netcurl ifconfig.mecurl http://members. ...

  4. 获取本地的IP地址(内网)

    方法一 public static String getLocalIpAddress() {try {for (Enumeration<NetworkInterface> en = Net ...

  5. 【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 命令行中获取要调试的应用进程的 PID | 进程注入调试进程内存的 so 库 )

    文章目录 一.Android 命令行中获取要调试的应用进程的 PID 二.进程注入调试进程内存的 so 库 一.Android 命令行中获取要调试的应用进程的 PID 前置博客 [Android 逆向 ...

  6. linux快速切换目录命令,Linux在命令行快速切换目录 - 米扑博客

    今天在微博上看到一个用命令行快速切换目录的文章,比之前自己的解决方案好了非常多,必须记录下来分享下. 每天在命令行下,一大部分的工作都是一遍又一遍的输入 cd ~/some/very/deep/oft ...

  7. linux 权限提示信息,命令行快速提示:权限进阶 | Linux 中国

    原标题:命令行快速提示:权限进阶 | Linux 中国 本部分介绍使用权限管理文件访问和共享的其他方法. -- Paul W. Frields 前一篇文章.本部分介绍使用权限管理文件访问和共享的其他方 ...

  8. matlab bdir 排序,命令行 - 如何获取按文件夹名称排序的子文件夹及其文件列表

    命令行 - 如何获取按文件夹名称排序的子文件夹及其文件列表 我可以使用dir命令行来获取子文件夹及其文件的列表,按文件夹名称排序,而不仅仅是文件名? 运用 dir / s / b / o:gn> ...

  9. 命令行快速删除当前行_在命令行中快速有效地工作

    命令行快速删除当前行 There are a lot of command line tips and trics in the internet. Most of them discribe the ...

最新文章

  1. ELK教程3:logstash的部署、SpringBoot整合ELK+Filebeat
  2. oracle更改控制文件位置
  3. 怎样轻松做到SD卡照片数据恢复
  4. 开启大数据时代谷歌三篇论文-Mapreduce
  5. 基于 Spring Boot 和 Spring Cloud 实现微服务架构
  6. SCL定时 1500_iPhone12开售当天黄牛加价1500,哪里买最划算?
  7. Mac使用Homebrew安装Kafka
  8. python爬虫获取中国天气网天气数据 requests BeautifulSoup re
  9. RNN调试错误:lstm_cell = tf.contrib.rnn.core_rnn_cell.BasicLSTMCell(lstm_size) 方法已失效
  10. document.execCommand() 解析
  11. ext2文件系统学习(一)
  12. 好程序员分享js实现简单的板球游
  13. 水晶报表中的主从表结构
  14. echarts--(1)--基本使用
  15. matlab sprintf函数的用法
  16. 无需Root实现Android手机屏幕流畅投影到电脑进行演示(附软件下载)
  17. 常用收藏(自己用的)
  18. 看完《一九四二》的感受--也写给正在找工作时迷茫的你
  19. 杨幂晒七月孕肚揭怀孕只胖baby不胖身材的女星
  20. 人工智能在集装箱识别中应用

热门文章

  1. 微信mars学习笔记
  2. antd踩坑记录之upload上传
  3. 实现内嵌tomcat
  4. TensorFlow常用激活函数及其特点用法(6种)详解
  5. EXCEL(Power BI)获取天天基金网每日历史净值数据,我去,这也太简单了吧!
  6. 网络安全kali渗透学习 web渗透入门 ARL资产侦察灯塔系统搭建及使用
  7. C语言:while后接分号“;”与不接分号“;”的区别
  8. CSDN自动展开全文的插件
  9. list 根据某个字段分组
  10. 最近爆火的电子血氧仪是什么原理?测的准吗?