默认分类

通过阿里云API自动解析域名 解决动态公网IP

申请的公网IP 是动态的,家里光猫重启就失联了
通过阿里云云名解析API ,实时更新解析记录

aliyun.ddns.go

package aliyun

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "time"

    "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
    "github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
)

type RAM struct {
    AccessKeyId     string
    AccessKeySecret string
}

type DDNS struct {
    Ram      RAM
    RegionId string
}

/// AutoSetDomain("lfreedom.com", "demo","1m")
func (dns *DDNS) AutoSetDomain(domain, rr, interval string) error {
    if dura, err := time.ParseDuration(interval); err != nil {
        return err
    } else {
        go func() {
            for {
                dns.SetDomain2Local(domain, rr)
                time.Sleep(dura)
            }
        }()
        return nil
    }
}

/// SetDomain2Local("lfreedom.com", "demo")
func (dns *DDNS) SetDomain2Local(domain, rr string) {
    if ip, err := dns.GetCurrentIP(); err == nil {
        if record, err := dns.GetDomainRecordInfo(domain, rr); err == nil {
            if ip != record.Value {
                record.Value = ip
                if _, err = dns.UpdateDomianRecordInfo(record); err == nil {
                    fmt.Printf("%v DDNS 更新解析ip成功 => %s\n", time.Now().Format("2006-01-02 15:04:05"), ip)
                }
            } else {
                fmt.Printf("%v DDNS ip正常,无需更新 => %s\n", time.Now().Format("2006-01-02 15:04:05"), ip)
            }
        }
    }
}

func (dns *DDNS) GetDomainRecordInfo(domain, rr string) (*alidns.Record, error) {
    client, err := alidns.NewClientWithAccessKey(dns.RegionId, dns.Ram.AccessKeyId, dns.Ram.AccessKeySecret)
    if err != nil {
        return nil, err
    }
    request := alidns.CreateDescribeDomainRecordsRequest()
    request.Scheme = "https"

    request.DomainName = domain
    request.RRKeyWord = rr

    if response, err := client.DescribeDomainRecords(request); err != nil {
        return nil, err
    } else if len(response.DomainRecords.Record) > 0 {
        return &response.DomainRecords.Record[0], nil
    } else {
        return nil, fmt.Errorf("record not found")
    }
}

func (dns *DDNS) UpdateDomianRecordInfo(record *alidns.Record) (*alidns.UpdateDomainRecordResponse, error) {
    client, err := alidns.NewClientWithAccessKey(dns.RegionId, dns.Ram.AccessKeyId, dns.Ram.AccessKeySecret)
    if err != nil {
        return nil, err
    }
    request := alidns.CreateUpdateDomainRecordRequest()
    request.Scheme = "https"

    request.RecordId = record.RecordId
    request.RR = record.RR
    request.Type = record.Type
    request.Value = record.Value
    request.TTL = requests.NewInteger(int(record.TTL))

    return client.UpdateDomainRecord(request)
}

func (dns *DDNS) GetCurrentIP() (string, error) {
    reqest, err := http.NewRequest("GET", "https://httpbin.org/ip", nil)
    if err != nil {
        return "", err
    }

    if response, err := (&http.Client{}).Do(reqest); err != nil {
        return "", err
    } else {

        defer response.Body.Close()
        if body, err := ioutil.ReadAll(response.Body); err != nil {
            return "", err
        } else {
            var res = make(map[string]interface{})
            if err = json.Unmarshal(body, &res); err != nil {
                return "", err
            }
            return res["origin"].(string), nil
        }
    }
}

main.go

package main

import (
    "ddns/aliyun"
    "sync"
)

func main() {

    ddnsCtx := &aliyun.DDNS{
        // home-ddns
        Ram: aliyun.RAM{
            AccessKeyId:     "XXXXXXXXXX",
            AccessKeySecret: "XXXXXXXXXXXXXXXXXXXX",
        },
        RegionId: "cn-hangzhou",
    }

    var wait sync.WaitGroup
    wait.Add(1)
    ddnsCtx.AutoSetDomain("lfreedom.com", "demo", "5m")
    wait.Wait()
}
This is just a placeholder img.