时间:2023-02-19 23:44:01 | 来源:建站知识
时间:2023-02-19 23:44:01 来源:建站知识
检测外网IP变化,动态更新阿里云域名解析:置办宽带后,运营商一般会给猫(路由器)的WAN网口分配一个外网IP。再通过端口映射(port forwarding)功能,就能远程ssh访问家里的设备(PC/树莓派)或者将其作为服务器使用。为了方便,我将我的域名@.aaron-xin.tech
解析到了该外网IP。使用一段时间后,突然有一天,突然所有服务都无法访问了,但是IP还是能够ping通。排查后发现,外网IP也是通过DHCP的方式获取的,意味着每次lease更新的时候,有比较大的概率IP会发生变化。所以,我通过家中的树莓派实时(每小时)监控外网IP的变化,并根据新的外网IP调用阿里云API更新域名解析。ping
命令,再从ping
的输出中解析出想要的IP地址。ping
不通的情况。所以最自然最保险的办法应该是去做DNS Lookup,对应的Linux Command就是dig <domain name>
:192.168.0.1#53
查询。也可以指定8.8.8.8#53
(Google的DNS server)。Golang
代码为:func getResolver() *net.Resolver { return &net.Resolver{ PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) { d := net.Dialer{ Timeout: time.Millisecond * time.Duration(10000), } return d.DialContext(ctx, "udp", "8.8.8.8:53") }, }}// DNS lookupips, _ := resolver.LookupHost(context.Background(), "aaron-xin.tech")dnsIP = ips[0]
ifconfig.me
:Golang
代码为:var realIP string// Get real IPresp, err := http.Get("http://ifconfig.me") // the ip discover service, choose a nearby oneif err == nil { defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) realIP = string(body)} else { log.Println("Fail to get ip from ifconfig.me")}
UpdateDomainRecord
和DescribeDomainRecords
。通过DescribeDomainRecord获取对应域名解析记录的Record ID,使用Record ID作为参数调用UpdateDomainRecord
修改对应解析记录。func descRecords(domain string) (string, error)func updateDomainRecord(ipAddr string, recordID string) errorif dnsIP != realIP { log.Println("IPs do not match, requesting DNS change...") recordID, err := descRecords(domain) if err != nil { log.Fatal(err) } err = updateDomainRecord(realIP, recordID) if err != nil { log.Fatal(err) }}
完整代码可参考 dynamicDNS.go/etc/rc.local
脚本的方式。/etc/rc.local
是一个.sh
脚本,会在系统启动后以root
身份执行命令。如果没有这个文件,可以通过sudo touch /etc/rc.local
创建或者sudo vim /etc/rc.local
创建并编辑。#!/bin/sh -e## rc.local## This script is executed at the end of each multiuser runlevel.# Make sure that the script will "exit 0" on success or any other# value on error.## In order to enable or disable this script just change the execution# bits.## By default this script does nothing.# Logexec 2> /tmp/rc.local.log # send stderr from rc.local to a log fileexec 1>&2 # send stdout to the same log fileset -x # tell sh to display commands before execution# Run the dynamic dns update servicerunuser -u ubuntu -- /usr/bin/tmux new-session -s dns -d /usr/local/go/bin/go run /home/ubuntu/go/src/github.com/Airine/dynamic-dns/main.go# Endexit 0
关于后台运行,我使用了tmux
这个工具(一款优秀的终端复用软件)。由于/etc/rc.local
会使用root
身份执行,而我的tmux
和go
都属于ubuntu
。这里使用了runuser -u <username> -- <command>
命令,可以以任意user
身份执行--
后的命令。关键词:更新,动态,变化