1
0
mirror of https://github.com/taigrr/godns synced 2025-01-18 04:03:25 -08:00

Merge pull request #62 from ebastos/dreamhost_dns

Dreamhost dns
This commit is contained in:
Timothy 2020-04-29 10:09:41 +08:00 committed by GitHub
commit 6a164f8b0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 173 additions and 5 deletions

View File

@ -32,6 +32,7 @@ Now I rewrite [DynDNS](https://github.com/TimothyYe/DynDNS) by Golang and call i
* HE.net (Hurricane Electric) ([https://dns.he.net/](https://dns.he.net/))
* AliDNS ([https://help.aliyun.com/product/29697.html](https://help.aliyun.com/product/29697.html))
* DuckDNS ([https://www.duckdns.org](https://www.duckdns.org))
* Dreamhost ([https://www.dreamhost.com](https://www.dreamhost.com))
## Supported Platforms
@ -101,7 +102,7 @@ Usage of ./godns:
## Config fields
* provider: The providers that GoDNS supports, available values are: `Cloudflare`, `Google`, `DNSPod`, `AliDNS`, `HE`, `DuckDNS`.
* provider: The providers that GoDNS supports, available values are: `Cloudflare`, `Google`, `DNSPod`, `AliDNS`, `HE`, `DuckDNS`, `Dreamhost`.
* email: Email or account name of your DNS provider.
* password: Password of your account.
* login_token: API token of your account.
@ -116,10 +117,11 @@ Usage of ./godns:
Supported provider(s):
* Cloudflare
* HE.net
* DNSPod
* Dreamhost
* DuckDNS
* Google Domains
* HE.net
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.
@ -210,6 +212,30 @@ For DNSPod, you need to provide your API Token(you can create it [here](https://
}
```
### Config example for Dreamhost
For Dreamhost, you need to provide your API Token(you can create it [here](https://panel.dreamhost.com/?tree=home.api)), and config all the domains & subdomains.
```json
{
"provider": "Dreamhost",
"login_token": "your_api_key",
"domains": [{
"domain_name": "example.com",
"sub_domains": ["www","test"]
},{
"domain_name": "example2.com",
"sub_domains": ["www","test"]
}
],
"ip_url": "https://myip.biturl.top",
"ip_type": "IPV4",
"interval": 300,
"resolver": "ns1.dreamhost.com",
"socks5_proxy": ""
}
```
### Config example for Google Domains
For Google Domains, you need to provide email & password, and config all the domains & subdomains.

1
go.mod
View File

@ -5,6 +5,7 @@ require (
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/bogdanovich/dns_resolver v0.0.0-20170211073258-a8e42bc6a5b6
github.com/fatih/color v1.7.0
github.com/google/uuid v1.1.1
github.com/kr/pretty v0.1.0 // indirect
github.com/mattn/go-colorable v0.0.9 // indirect
github.com/mattn/go-isatty v0.0.4 // indirect

2
go.sum
View File

@ -6,6 +6,8 @@ github.com/bogdanovich/dns_resolver v0.0.0-20170211073258-a8e42bc6a5b6 h1:oV1V+u
github.com/bogdanovich/dns_resolver v0.0.0-20170211073258-a8e42bc6a5b6/go.mod h1:txOV61Nn+21z77KUMkNsp8lTHoOFTtqotltQAFenS9I=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=

View File

@ -0,0 +1,129 @@
package dreamhost
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"runtime/debug"
"strings"
"time"
"github.com/TimothyYe/godns"
"github.com/google/uuid"
)
var (
// DreamhostURL the API address for dreamhost.com
DreamhostURL = "https://api.dreamhost.com"
)
// Handler struct
type Handler struct {
Configuration *godns.Settings
}
// SetConfiguration pass dns settings and store it to handler instance
func (handler *Handler) SetConfiguration(conf *godns.Settings) {
handler.Configuration = conf
}
// DomainLoop the main logic loop
func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.Domain) {
defer func() {
if err := recover(); err != nil {
log.Printf("Recovered in %v: %v\n", err, debug.Stack())
panicChan <- *domain
}
}()
for {
currentIP, err := godns.GetCurrentIP(handler.Configuration)
if err != nil {
log.Println("get_currentIP:", err)
continue
}
log.Println("currentIP is:", currentIP)
for _, subDomain := range domain.SubDomains {
hostname := subDomain + "." + domain.DomainName
lastIP := godns.ResolveDNS(hostname, handler.Configuration.Resolver)
//check against currently known IP, if no change, skip update
if currentIP == lastIP {
log.Printf("IP is the same as cached one. Skip update.\n")
} else {
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
handler.UpdateIP(hostname, currentIP, lastIP)
// Send notification
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
log.Println("Failed to send notification")
}
}
}
// Sleep with interval
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
time.Sleep(time.Second * time.Duration(handler.Configuration.Interval))
}
}
// UpdateIP update subdomain with current IP
func (handler *Handler) UpdateIP(hostname, currentIP, lastIP string) {
handler.updateDNS(lastIP, currentIP, hostname, "remove")
handler.updateDNS(lastIP, currentIP, hostname, "add")
}
// updateDNS can add or remove DNS records.
func (handler *Handler) updateDNS(dns, ip, hostname, action string) {
ipType := "A"
if strings.ToUpper(handler.Configuration.IPType) == godns.IPV6 {
ipType = "AAAA"
}
// Generates UUID
uid, _ := uuid.NewRandom()
values := url.Values{}
values.Add("record", hostname)
values.Add("key", handler.Configuration.LoginToken)
values.Add("type", ipType)
values.Add("unique_id", uid.String())
switch action {
case "remove":
// Build URL query (remove)
values.Add("cmd", "dns-remove_record")
values.Add("value", dns)
case "add":
// Build URL query (add)
values.Add("cmd", "dns-add_record")
values.Add("value", ip)
default:
log.Fatalf("Unknown action %s\n", action)
}
client := godns.GetHttpClient(handler.Configuration)
req, _ := http.NewRequest("POST", DreamhostURL, strings.NewReader(values.Encode()))
req.SetBasicAuth(handler.Configuration.Email, handler.Configuration.Password)
if handler.Configuration.UserAgent != "" {
req.Header.Add("User-Agent", handler.Configuration.UserAgent)
}
resp, err := client.Do(req)
if err != nil {
log.Println("Request error...")
log.Println("Err:", err.Error())
} else {
body, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode == http.StatusOK {
log.Println("Update IP success:", string(body))
} else {
log.Println("Update IP failed:", string(body))
}
}
}

View File

@ -5,6 +5,7 @@ import (
"github.com/TimothyYe/godns/handler/alidns"
"github.com/TimothyYe/godns/handler/cloudflare"
"github.com/TimothyYe/godns/handler/dnspod"
"github.com/TimothyYe/godns/handler/dreamhost"
"github.com/TimothyYe/godns/handler/duck"
"github.com/TimothyYe/godns/handler/google"
"github.com/TimothyYe/godns/handler/he"
@ -25,6 +26,8 @@ func CreateHandler(provider string) IHandler {
handler = IHandler(&cloudflare.Handler{})
case godns.DNSPOD:
handler = IHandler(&dnspod.Handler{})
case godns.DREAMHOST:
handler = IHandler(&dreamhost.Handler{})
case godns.HE:
handler = IHandler(&he.Handler{})
case godns.ALIDNS:

View File

@ -49,6 +49,8 @@ const (
GOOGLE = "Google"
// DUCK for Duck DNS
DUCK = "DuckDNS"
// DREAMHOST for Dreamhost
DREAMHOST = "Dreamhost"
// IPV4 for IPV4 mode
IPV4 = "IPV4"
// IPV6 for IPV6 mode
@ -218,15 +220,20 @@ func CheckSettings(config *Settings) error {
if config.Password == "" {
return errors.New("password cannot be empty")
}
case DREAMHOST:
if config.LoginToken == "" {
return errors.New("login token cannot be empty")
}
default:
return errors.New("please provide supported DNS provider: DNSPod/HE/AliDNS/Cloudflare/GoogleDomain/DuckDNS")
return errors.New("please provide supported DNS provider: DNSPod/HE/AliDNS/Cloudflare/GoogleDomain/DuckDNS/Dreamhost")
}
return nil
}
// SendNotify sends notify if IP is changed
// SendTelegramNotify sends notify if IP is changed
func SendTelegramNotify(configuration *Settings, domain, currentIP string) error {
if !configuration.Notify.Telegram.Enabled {
return nil
@ -287,7 +294,7 @@ func SendTelegramNotify(configuration *Settings, domain, currentIP string) error
return nil
}
// SendNotify sends mail notify if IP is changed
// SendMailNotify sends mail notify if IP is changed
func SendMailNotify(configuration *Settings, domain, currentIP string) error {
if !configuration.Notify.Mail.Enabled {
return nil