diff --git a/README.md b/README.md index fc941a9..55529cf 100644 --- a/README.md +++ b/README.md @@ -106,10 +106,38 @@ Usage of ./godns: * password: Password of your account. * login_token: API token of your account. * domains: Domains list, with your sub domains. -* ip_url: A site helps you to get your public IP address. +* ip_url: A site helps you to get your public IPv4 IP address. +* ipv6_url: A site helps you to get your public IPv6 address. +* ip_type: To configure GoDNS under IPv4 mode or IPv6 mode, available values are: `IPv4`, `IPv6`. * interval: The interval `seconds` that GoDNS check your public IP. * socks5_proxy: Socks5 proxy server. +## IPv6 support + +Supported provider(s): +* Cloudflare + +To enable the `IPv6` mode of GoDNS, you only need two steps: +* Set the `ip_type` as `IPv6`, and make sure the `ipv6_url` is configured. +* Add one `AAAA` record to your provider. + +For example: + +```json +{ + "domains": [ + { + "domain_name": "example.com", + "sub_domains": [ + "ipv6" + ] + } + ], + "ipv6_url": "https://api-ipv6.ip.sb/ip", + "ip_type": "IPv6" +} +``` + ### Config example for Cloudflare For Cloudflare, you need to provide the email & Global API Key as password (or to use the API token) and config all the domains & subdomains. diff --git a/config_sample.json b/config_sample.json index 3d57809..86a2785 100644 --- a/config_sample.json +++ b/config_sample.json @@ -19,6 +19,8 @@ } ], "ip_url": "https://myip.biturl.top", + "ipv6_url": "https://api-ipv6.ip.sb/ip", + "ip_type": "IPv4", "interval": 300, "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36", "ip_interface": "eth0", diff --git a/handler/cloudflare/cloudflare_handler.go b/handler/cloudflare/cloudflare_handler.go index 76bd552..64f96b8 100644 --- a/handler/cloudflare/cloudflare_handler.go +++ b/handler/cloudflare/cloudflare_handler.go @@ -9,6 +9,7 @@ import ( "log" "net/http" "runtime/debug" + "strings" "time" "github.com/TimothyYe/godns" @@ -194,8 +195,16 @@ func (handler *Handler) getDNSRecords(zoneID string) []DNSRecord { var empty []DNSRecord var r DNSRecordResponse + var recordType string - req, client := handler.newRequest("GET", "/zones/"+zoneID+"/dns_records?type=A", nil) + if handler.Configuration.IPType == "" || strings.ToUpper(handler.Configuration.IPType) == godns.IPV4 { + recordType = "A" + } else if strings.ToUpper(handler.Configuration.IPType) == godns.IPV6 { + recordType = "AAAA" + } + + log.Println("Querying records with type:", recordType) + req, client := handler.newRequest("GET", fmt.Sprintf("/zones/"+zoneID+"/dns_records?type=%s", recordType), nil) resp, err := client.Do(req) if err != nil { log.Println("Request error:", err.Error()) diff --git a/settings.go b/settings.go index 1c3411c..0609450 100644 --- a/settings.go +++ b/settings.go @@ -30,14 +30,14 @@ type Settings struct { LoginToken string `json:"login_token"` Domains []Domain `json:"domains"` IPUrl string `json:"ip_url"` + IPV6Url string `json:"ipv6_url"` Interval int `json:"interval"` UserAgent string `json:"user_agent,omitempty"` LogPath string `json:"log_path"` Socks5Proxy string `json:"socks5_proxy"` Notify Notify `json:"notify"` IPInterface string `json:"ip_interface"` - //the code is not ready to update AAAA record - //IPType string `json:"ip_type"` + IPType string `json:"ip_type"` } // LoadSettings -- Load settings from config file diff --git a/utils.go b/utils.go index 9510523..ae80539 100644 --- a/utils.go +++ b/utils.go @@ -46,6 +46,10 @@ const ( GOOGLE = "Google" // DUCK for Duck DNS DUCK = "DuckDNS" + // IPV4 for IPV4 mode + IPV4 = "IPV4" + // IPV6 for IPV6 mode + IPV6 = "IPV6" ) //GetIPFromInterface gets IP address from the specific interface @@ -84,17 +88,16 @@ func GetIPFromInterface(configuration *Settings) (string, error) { continue } - //the code is not ready for updating an AAAA record - /* - if (isIPv4(ip.String())){ - if (configuration.IPType=="IPv6"){ - continue; - } - }else{ - if (configuration.IPType!="IPv6"){ - continue; - } - } */ + if isIPv4(ip.String()) { + if strings.ToUpper(configuration.IPType) == IPV4 { + continue + } + } else { + if configuration.IPType != IPV6 { + continue + } + } + if !isIPv4(ip.String()) { continue } @@ -133,7 +136,7 @@ func GetHttpClient(configuration *Settings) *http.Client { func GetCurrentIP(configuration *Settings) (string, error) { var err error - if configuration.IPUrl != "" { + if configuration.IPUrl != "" || configuration.IPV6Url != "" { ip, err := GetIPOnline(configuration) if err != nil { log.Println("get ip online failed. Fallback to get ip from interface if possible.") @@ -159,7 +162,6 @@ func GetIPOnline(configuration *Settings) (string, error) { client := &http.Client{} if configuration.Socks5Proxy != "" { - log.Println("use socks5 proxy:" + configuration.Socks5Proxy) dialer, err := proxy.SOCKS5("tcp", configuration.Socks5Proxy, nil, proxy.Direct) if err != nil { @@ -172,7 +174,14 @@ func GetIPOnline(configuration *Settings) (string, error) { httpTransport.Dial = dialer.Dial } - response, err := client.Get(configuration.IPUrl) + var response *http.Response + var err error + + if configuration.IPType == "" || configuration.IPType == IPV4 { + response, err = client.Get(configuration.IPUrl) + } else { + response, err = client.Get(configuration.IPV6Url) + } if err != nil { log.Println("Cannot get IP...")