时间: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身份执行--后的命令。关键词:更新,动态,变化