mirror of
https://github.com/taigrr/godns
synced 2025-01-18 04:03:25 -08:00
commit
6a164f8b0b
30
README.md
30
README.md
@ -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
1
go.mod
@ -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
2
go.sum
@ -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=
|
||||
|
129
handler/dreamhost/dreamhost_handler.go
Normal file
129
handler/dreamhost/dreamhost_handler.go
Normal 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))
|
||||
}
|
||||
}
|
||||
}
|
@ -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:
|
||||
|
13
utils.go
13
utils.go
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user