diff --git a/providers/dns/bunny/bunny.go b/providers/dns/bunny/bunny.go index 4d61adc7de..69645c46fb 100644 --- a/providers/dns/bunny/bunny.go +++ b/providers/dns/bunny/bunny.go @@ -9,6 +9,7 @@ import ( "github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/platform/config/env" + "github.com/miekg/dns" "github.com/nrdcg/bunny-go" ) @@ -190,7 +191,28 @@ func getZone(fqdn string) (string, error) { return "", err } - return dns01.UnFqdn(authZone), nil + zone, _, err := splitDomain(dns01.UnFqdn(authZone)) + if err != nil { + return "", err + } + + return zone, nil +} + +func splitDomain(full string) (string, string, error) { + split := dns.Split(full) + if len(split) < 2 { + return "", "", fmt.Errorf("unsupported domain: %s", full) + } + + if len(split) == 2 { + return full, "", nil + } + + domain := full[split[len(split)-2]:] + subDomain := full[:split[len(split)-2]-1] + + return domain, subDomain, nil } func pointer[T string | int | int32 | int64](v T) *T { return &v } diff --git a/providers/dns/bunny/bunny_test.go b/providers/dns/bunny/bunny_test.go index e5724bcd23..744febef3b 100644 --- a/providers/dns/bunny/bunny_test.go +++ b/providers/dns/bunny/bunny_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/go-acme/lego/v4/platform/tester" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -123,3 +124,83 @@ func TestLiveCleanUp(t *testing.T) { err = provider.CleanUp(envTest.GetDomain(), "", "123d==") require.NoError(t, err) } + +func Test_splitDomain(t *testing.T) { + type expected struct { + root string + sub string + requireErr require.ErrorAssertionFunc + } + + testCases := []struct { + desc string + domain string + expected expected + }{ + { + desc: "empty", + domain: "", + expected: expected{ + requireErr: require.Error, + }, + }, + { + desc: "2 levels", + domain: "example.com", + expected: expected{ + root: "example.com", + sub: "", + requireErr: require.NoError, + }, + }, + { + desc: "3 levels", + domain: "_acme-challenge.example.com", + expected: expected{ + root: "example.com", + sub: "_acme-challenge", + requireErr: require.NoError, + }, + }, + { + desc: "4 levels", + domain: "_acme-challenge.sub.example.com", + expected: expected{ + root: "example.com", + sub: "_acme-challenge.sub", + requireErr: require.NoError, + }, + }, + { + desc: "5 levels", + domain: "_acme-challenge.my.sub.example.com", + expected: expected{ + root: "example.com", + sub: "_acme-challenge.my.sub", + requireErr: require.NoError, + }, + }, + { + desc: "6 levels", + domain: "_acme-challenge.my.sub.sub.example.com", + expected: expected{ + root: "example.com", + sub: "_acme-challenge.my.sub.sub", + requireErr: require.NoError, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + root, sub, err := splitDomain(test.domain) + test.expected.requireErr(t, err) + + assert.Equal(t, test.expected.root, root) + assert.Equal(t, test.expected.sub, sub) + }) + } +}