如何用 Powershell 查 IPv6
年更 again (今年其他事情比较多,blog 没太多干货分享啦
发现电信下发的 IPv6 连续连接十几天后会失效 (光猫路由 SLAAC 下发的,不知道是哪的问题),重新连接就好了.
NAS 需要 IPv6 才能连接 Zerotier (没有要公网 IPv4,马上双栈公网就莫得了[1]),最简单的办法是,每天查下 IPv6, 没有就重启.
1. 获取 IPv6 的方式
第一时间大部分人都能想到,curl
一下 ifconfig.io
或者 ip.sb
这样.
1 | PS C:\Users\xiaopc> curl ip.sb |
那如果不走 HTTP 呢?通过 EDNS Client Subnet (ECS)[2],在 DNS 查询中递归解析器将客户端 IP 给到权威服务器,来实现地域化精细解析.
一个例子就是用 DNS 查 IP:
1 | PS C:\Users\xiaopc> nslookup -type=TXT o-o.myaddr.l.google.com ns1.google.com |
2. 但是怎么把地址抽出来呢
nslookup
不像 dig
,没有 +short
,那怎么把地址抽出来呢?
Powershell 名字里的 Power,它 Power 在哪呢?
比如说它的 builtin function:
1 | PS C:\Users\xiaopc> Resolve-DnsName -Name o-o.myaddr.l.google.com -Server ns1.google.com -Type TXT |
其实这个函数的输出是个对象 (毕竟是微软,肯定是 .NET 了),当然,Powershell 是强类型的.
(它是个 HashTable)
可以用管道符传给 Get-Member
看看有什么成员:
1 | PS C:\Users\xiaopc> (Resolve-DnsName -Name o-o.myaddr.l.google.com -Server ns1.google.com -Type TXT) | Get-Member |
那么就很简单了:
1 | PS C:\Users\xiaopc> (Resolve-DnsName -Name o-o.myaddr.l.google.com -Server ns1.google.com -Type TXT)[0].Strings[0] |
加上重启的判断:
1 | if (-not (Resolve-DnsName -Name o-o.myaddr.l.google.com -Server ns1.google.com -Type TXT)[0].Strings[0].StartsWith("240e")) { |
注:5:20
是关机原因—网络连接丢失(计划外)
3. 定时启动
但是弹黑框不好看,不妨借鉴一下一些红方用的持久化方法[3].
1 | PS C:\Users\xiaopc> powershell /? |
那么最终的命令就是:
1 | powershell.exe -NonI -c "if (-not (Resolve-DnsName -Name o-o.myaddr.l.google.com -Server ns1.google.com -Type TXT)[0].Strings[0].StartsWith(\"240e\")) { shutdown /r /t 120 /d 5:20 }" |
把它加到任务计划就行了.
注:在既没有 IPv4 又没有 IPv6 时(aka 断网)脚本会报错退出,这样正好满足需求.
[1] https://www.ithome.com/0/716/097.htm
[2] https://developers.google.com/speed/public-dns/docs/ecs
[3] https://www.freebuf.com/articles/system/229209.html