11 Commits
master ... v2.7

Author SHA1 Message Date
Quentin McGaw
f4e1cca222 docs(readme): update v2.7 links to point to v2.7.1 2024-09-17 07:58:22 +00:00
Quentin McGaw
79efca2bf4 fix(publicip/http): remove google provider which no longer works 2024-09-17 07:52:19 +00:00
dependabot[bot]
f17be83112 chore(deps): bump github.com/breml/rootcerts from 0.2.17 to 0.2.18 (#814) 2024-09-17 07:51:39 +00:00
Quentin McGaw
2a9e41c646 fix(ci): ignore duckdns.org for links check 2024-09-17 07:51:06 +00:00
Quentin McGaw
8664aa0e5c fix(config): upgrade qdm12/gosettings from v0.4.1 to v0.4.4-rc1 2024-09-17 07:50:34 +00:00
Quentin McGaw
4c840f4bb6 fix(dondominio): remove unneeded name field 2024-09-17 07:50:17 +00:00
Benjamin Temple
7230fea962 fix(porkbun): fix wildcard behavior (#773) 2024-09-17 07:49:01 +00:00
Benjamin Temple
8aa6aba8b7 fix(porkbun): remove trailing '.' from alias delete request (#775) 2024-09-17 07:48:06 +00:00
Quentin McGaw
1d8690fb14 fix(noip): force useProviderIP to false for IPv6 2024-09-17 07:47:02 +00:00
Quentin McGaw
2922d441d2 docs(readme): add readme and docs/ versioned links 2024-09-17 07:45:46 +00:00
Quentin McGaw
607ca8f0b8 docs(goip): fix documentation for the host field 2024-09-17 07:42:44 +00:00
19 changed files with 67 additions and 46 deletions

View File

@@ -26,6 +26,9 @@
},
{
"pattern": "https://github.com/qdm12/ddns-updater/pkgs/container/ddns-updater"
},
{
"pattern": "^https://www.duckdns.org/$"
}
],
"timeout": "20s",

View File

@@ -30,6 +30,17 @@ Program to keep DNS A and/or AAAA records updated for multiple DNS providers
[![MIT](https://img.shields.io/github/license/qdm12/ddns-updater)](LICENSE)
![Visitors count](https://visitor-badge.laobi.icu/badge?page_id=ddns-updater.readme)
## Versioned documentation
This readme and the [docs/](docs/) directory are **versioned** to match the program version:
| Version | Readme link | Docs link |
| --- | --- | --- |
| Latest | [README](https://github.com/qdm12/ddns-updater/blob/master/README.md) | [docs/](https://github.com/qdm12/ddns-updater/tree/master/docs) |
| `v2.7` | [README](https://github.com/qdm12/ddns-updater/blob/v2.7.1/README.md) | [docs/](https://github.com/qdm12/ddns-updater/blob/v2.7.1/docs) |
| `v2.6` | [README](https://github.com/qdm12/ddns-updater/blob/v2.6.1/README.md) | [docs/](https://github.com/qdm12/ddns-updater/blob/v2.6.1/docs) |
| `v2.5` | [README](https://github.com/qdm12/ddns-updater/blob/v2.5/README.md) | [docs/](https://github.com/qdm12/ddns-updater/blob/v2.5/docs) |
## Features
- Available as a Docker image [`qmcgaw/ddns-updater`](https://hub.docker.com/r/qmcgaw/ddns-updater) and [`ghcr.io/qdm12/ddns-updater`]((https://github.com/qdm12/ddns-updater/pkgs/container/ddns-updater))
@@ -294,7 +305,6 @@ You can otherwise customize it with the following:
- `ipify` using [https://api64.ipify.org](https://api64.ipify.org)
- `ifconfig` using [https://ifconfig.io/ip](https://ifconfig.io/ip)
- `ipinfo` using [https://ipinfo.io/ip](https://ipinfo.io/ip)
- `google` using [https://domains.google.com/checkip](https://domains.google.com/checkip)
- `spdyn` using [https://checkip.spdyn.de](https://checkip.spdyn.de/)
- `ipleak` using [https://ipleak.net/json](https://ipleak.net/json)
- `icanhazip` using [https://icanhazip.com](https://icanhazip.com)

View File

@@ -262,7 +262,7 @@ func _main(ctx context.Context, reader *reader.Reader, args []string, logger log
}
func printSplash(buildInfo models.BuildInformation) {
announcementExp, err := time.Parse(time.RFC3339, "2023-07-15T00:00:00Z")
announcementExp, err := time.Parse(time.RFC3339, "2024-10-15T00:00:00Z")
if err != nil {
panic(err)
}
@@ -273,7 +273,7 @@ func printSplash(buildInfo models.BuildInformation) {
Version: buildInfo.Version,
Commit: buildInfo.Commit,
BuildDate: buildInfo.Date,
Announcement: "Public IP dns provider GOOGLE, see https://github.com/qdm12/ddns-updater/issues/492",
Announcement: "Public IP http provider GOOGLE is no longer working",
AnnounceExp: announcementExp,
// Sponsor information
PaypalUser: "qmcgaw",

View File

@@ -11,7 +11,6 @@
"provider": "dondominio",
"domain": "domain.com",
"host": "@",
"name": "something",
"username": "username",
"key": "key",
"ip_version": "ipv4",
@@ -25,7 +24,6 @@
- `"domain"`
- `"host"` is the subdomain to update which can be `@`, `*` or a subdomain
- `"name"` is the name of the service/hosting
- `"username"`
- `"password"`

View File

@@ -24,7 +24,7 @@
### Compulsory parameters
- `"host"` is the full FQDN of your ddns address. sample.goip.de or something.goip.it
- `"host"` is the host of your domain, for example `"example"` for `example.goip.de`.
- `"username"` is your goip.de username listed under "Routers"
- `"password"` is your router account password

4
go.mod
View File

@@ -3,14 +3,14 @@ module github.com/qdm12/ddns-updater
go 1.22
require (
github.com/breml/rootcerts v0.2.17
github.com/breml/rootcerts v0.2.18
github.com/chmike/domain v1.0.1
github.com/containrrr/shoutrrr v0.8.0
github.com/go-chi/chi/v5 v5.0.12
github.com/golang/mock v1.6.0
github.com/miekg/dns v1.1.61
github.com/qdm12/goservices v0.1.0
github.com/qdm12/gosettings v0.4.1
github.com/qdm12/gosettings v0.4.4-rc1
github.com/qdm12/gosplash v0.1.0
github.com/qdm12/gotree v0.2.0
github.com/qdm12/log v0.1.0

8
go.sum
View File

@@ -1,7 +1,7 @@
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
github.com/breml/rootcerts v0.2.17 h1:0/M2BE2Apw0qEJCXDOkaiu7d5Sx5ObNfe1BkImJ4u1I=
github.com/breml/rootcerts v0.2.17/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
github.com/breml/rootcerts v0.2.18 h1:KjZaNT7AX/akUjzpStuwTMQs42YHlPyc6NmdwShVba0=
github.com/breml/rootcerts v0.2.18/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
github.com/chmike/domain v1.0.1 h1:ug6h3a7LLAfAecBAysbCXWxP1Jo8iBKWNVDxcs1BNzA=
github.com/chmike/domain v1.0.1/go.mod h1:h558M2qGKpYRUxHHNyey6puvXkZBjvjmseOla/d1VGQ=
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=
@@ -42,8 +42,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/qdm12/goservices v0.1.0 h1:9sODefm/yuIGS7ynCkEnNlMTAYn9GzPhtcK4F69JWvc=
github.com/qdm12/goservices v0.1.0/go.mod h1:/JOFsAnHFiSjyoXxa5FlfX903h20K5u/3rLzCjYVMck=
github.com/qdm12/gosettings v0.4.1 h1:c7+14jO1Y2kFXBCUfS2+QE2NgwTKfzcdJzGEFRItCI8=
github.com/qdm12/gosettings v0.4.1/go.mod h1:uItKwGXibJp2pQ0am6MBKilpjfvYTGiH+zXHd10jFj8=
github.com/qdm12/gosettings v0.4.4-rc1 h1:VT+6O6ww3Cn5v5/LgY2zlXoiCkZzbaLDWaA8ufQoOLY=
github.com/qdm12/gosettings v0.4.4-rc1/go.mod h1:CPrt2YC4UsURTrslmhxocVhMCW03lIrqdH2hzIf5prg=
github.com/qdm12/gosplash v0.1.0 h1:Sfl+zIjFZFP7b0iqf2l5UkmEY97XBnaKkH3FNY6Gf7g=
github.com/qdm12/gosplash v0.1.0/go.mod h1:+A3fWW4/rUeDXhY3ieBzwghKdnIPFJgD8K3qQkenJlw=
github.com/qdm12/gotree v0.2.0 h1:+58ltxkNLUyHtATFereAcOjBVfY6ETqRex8XK90Fb/c=

View File

@@ -263,7 +263,12 @@ func (p *PubIP) read(r *reader.Reader, warner Warner) (err error) {
copy(httpIPProvidersTemp, p.HTTPIPProviders)
p.HTTPIPProviders = make([]string, 0, len(p.HTTPIPProviders))
for _, provider := range httpIPProvidersTemp {
if provider != "opendns" {
switch provider {
case "opendns": // no longer available, for a long time
case "google": // found no longer working on 2024.09.17
warner.Warnf("http provider google will be ignored " +
"since it is no longer supported by Google")
default:
p.HTTPIPProviders = append(p.HTTPIPProviders, provider)
}
}

View File

@@ -25,7 +25,6 @@ var (
ErrIPv6KeyNotSet = errors.New("IPv6 key is not set")
ErrKeyNotSet = errors.New("key is not set")
ErrKeyNotValid = errors.New("key is not valid")
ErrNameNotSet = errors.New("name is not set")
ErrPasswordNotSet = errors.New("password is not set")
ErrPasswordNotValid = errors.New("password is not valid")
ErrSecretKeyNotSet = errors.New("secret key is not set")

View File

@@ -24,7 +24,6 @@ type Provider struct {
ipv6Suffix netip.Prefix
username string
key string
name string
}
func New(data json.RawMessage, domain, host string,
@@ -34,7 +33,6 @@ func New(data json.RawMessage, domain, host string,
Username string `json:"username"`
Password string `json:"password"` // retro-compatibility
Key string `json:"key"`
Name string `json:"name"`
}{}
err = json.Unmarshal(data, &extraSettings)
if err != nil {
@@ -54,7 +52,6 @@ func New(data json.RawMessage, domain, host string,
ipv6Suffix: ipv6Suffix,
username: extraSettings.Username,
key: extraSettings.Key,
name: extraSettings.Name,
}
err = p.isValid()
if err != nil {
@@ -69,8 +66,6 @@ func (p *Provider) isValid() error {
return fmt.Errorf("%w", errors.ErrUsernameNotSet)
case p.key == "":
return fmt.Errorf("%w", errors.ErrKeyNotSet)
case p.name == "":
return fmt.Errorf("%w", errors.ErrNameNotSet)
}
return nil
}

View File

@@ -41,6 +41,13 @@ func New(data json.RawMessage, domain, host string,
if err != nil {
return nil, err
}
if ipVersion == ipversion.IP6 {
// Thanks to @NightFurySL2001
// See https://github.com/qdm12/ddns-updater/discussions/750
extraSettings.UseProviderIP = false
}
p = &Provider{
domain: domain,
host: host,

View File

@@ -20,9 +20,6 @@ func (p *Provider) getRecordIDs(ctx context.Context, client *http.Client, record
Host: "porkbun.com",
Path: "/api/json/v3/dns/retrieveByNameType/" + p.domain + "/" + recordType + "/",
}
if p.host != "@" && p.host != "*" {
u.Path += p.host
}
postRecordsParams := struct {
SecretAPIKey string `json:"secretapikey"`
@@ -38,7 +35,14 @@ func (p *Provider) getRecordIDs(ctx context.Context, client *http.Client, record
return nil, fmt.Errorf("json encoding request data: %w", err)
}
request, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), buffer)
encodedRequestURL := u.String()
if p.host != "@" {
// add host after string-ing the URL to avoid encoding the '*' character,
// since Porkbun requires we send the unencoded '*' character.
encodedRequestURL += p.host
}
request, err := http.NewRequestWithContext(ctx, http.MethodPost, encodedRequestURL, buffer)
if err != nil {
return nil, fmt.Errorf("creating http request: %w", err)
}
@@ -173,14 +177,11 @@ func (p *Provider) updateRecord(ctx context.Context, client *http.Client,
// See https://porkbun.com/api/json/v3/documentation#DNS%20Delete%20Records%20by%20Domain,%20Subdomain%20and%20Type
func (p *Provider) deleteAliasRecord(ctx context.Context, client *http.Client) (err error) {
var subdomain string
if p.host != "@" {
subdomain = p.host + "."
}
u := url.URL{
Scheme: "https",
Host: "porkbun.com",
Path: "/api/json/v3/dns/deleteByNameType/" + p.domain + "/ALIAS/" + subdomain,
// host is added below after string-ing the URL
Path: "/api/json/v3/dns/deleteByNameType/" + p.domain + "/ALIAS/",
}
postRecordsParams := struct {
SecretAPIKey string `json:"secretapikey"`
@@ -196,7 +197,14 @@ func (p *Provider) deleteAliasRecord(ctx context.Context, client *http.Client) (
return fmt.Errorf("json encoding request data: %w", err)
}
request, err := http.NewRequestWithContext(ctx, http.MethodPost, u.String(), buffer)
encodedRequestURL := u.String()
if p.host != "@" {
// add host after string-ing the URL to avoid encoding the '*' character,
// since Porkbun requires we send the unencoded '*' character.
encodedRequestURL += p.host
}
request, err := http.NewRequestWithContext(ctx, http.MethodPost, encodedRequestURL, buffer)
if err != nil {
return fmt.Errorf("creating http request: %w", err)
}

View File

@@ -27,7 +27,7 @@ func Test_SetProviders(t *testing.T) {
expectedSettings settings
err error
}{
"Google": {
"OpenDNS": {
initialSettings: settings{
providers: []Provider{Cloudflare},
},

View File

@@ -25,7 +25,7 @@ func Test_New(t *testing.T) {
timeout: 5 * time.Second,
ip4or6: &urlsRing{
banned: map[int]string{},
urls: []string{"https://domains.google.com/checkip"},
urls: []string{"https://api64.ipify.org"},
},
ip4: &urlsRing{
banned: map[int]string{},
@@ -39,7 +39,7 @@ func Test_New(t *testing.T) {
},
"with options": {
options: []Option{
SetProvidersIP(Google),
SetProvidersIP(Ifconfig),
SetProvidersIP4(Ipify),
SetProvidersIP6(Ipify),
SetTimeout(time.Second),
@@ -49,7 +49,7 @@ func Test_New(t *testing.T) {
timeout: time.Second,
ip4or6: &urlsRing{
banned: map[int]string{},
urls: []string{"https://domains.google.com/checkip"},
urls: []string{"https://ifconfig.io/ip"},
},
ip4: &urlsRing{
banned: map[int]string{},

View File

@@ -17,7 +17,7 @@ func Test_integration(t *testing.T) {
client := &http.Client{}
fetcher, err := New(client, SetProvidersIP(Google))
fetcher, err := New(client, SetProvidersIP(Ipify))
require.NoError(t, err)
ctx := context.Background()

View File

@@ -16,7 +16,7 @@ type settings struct {
func newDefaultSettings() settings {
const defaultTimeout = 5 * time.Second
return settings{
providersIP: []Provider{Google},
providersIP: []Provider{Ipify},
providersIP4: []Provider{Ipify},
providersIP6: []Provider{Ipify},
timeout: defaultTimeout,

View File

@@ -29,13 +29,13 @@ func Test_SetProvidersIP(t *testing.T) {
expectedSettings settings
err error
}{
"Google": {
"Ipify": {
initialSettings: settings{
providersIP: []Provider{Ifconfig},
},
providers: []Provider{Google},
providers: []Provider{Ipify},
expectedSettings: settings{
providersIP: []Provider{Google},
providersIP: []Provider{Ipify},
},
},
}

View File

@@ -12,7 +12,6 @@ import (
type Provider string
const (
Google Provider = "google"
Ifconfig Provider = "ifconfig"
Ipify Provider = "ipify"
Ipinfo Provider = "ipinfo"
@@ -28,7 +27,6 @@ const (
func ListProviders() []Provider {
return []Provider{
Google,
Ifconfig,
Ipify,
Ipinfo,
@@ -118,8 +116,6 @@ func (provider Provider) url(version ipversion.IPVersion) (url string, ok bool)
switch provider {
case Ipify:
url = "https://api64.ipify.org"
case Google:
url = "https://domains.google.com/checkip"
case Ifconfig:
url = "https://ifconfig.io/ip"
case Ipinfo:

View File

@@ -19,7 +19,7 @@ func Test_ListProvidersForVersion(t *testing.T) {
}{
"ip4or6": {
version: ipversion.IP4or6,
providers: []Provider{Google, Ifconfig, Ipify, Ipinfo, Spdyn, Ipleak,
providers: []Provider{Ifconfig, Ipify, Ipinfo, Spdyn, Ipleak,
Icanhazip, Ident, Nnev, Wtfismyip, Seeip, Changeip},
},
"ip4": {
@@ -51,7 +51,7 @@ func Test_ValidateProvider(t *testing.T) {
err error
}{
"valid": {
provider: Google,
provider: Ifconfig,
version: ipversion.IP4or6,
},
"custom url": {
@@ -59,9 +59,9 @@ func Test_ValidateProvider(t *testing.T) {
version: ipversion.IP4or6,
},
"invalid for ip version": {
provider: Google,
provider: Ifconfig,
version: ipversion.IP4,
err: errors.New(`provider does not support IP version: "google" for version ipv4`),
err: errors.New(`provider does not support IP version: "ifconfig" for version ipv4`),
},
"unknown": {
provider: Provider("unknown"),