mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-09-20 06:46:19 +08:00
NEW RECORD TYPE: HTTPS & SVCB (#2919)
Thanks so much for this contribution! I have a feeling that a lot of people are going to need these records soon!
This commit is contained in:
parent
eae96860cd
commit
3a9b413175
|
@ -80,12 +80,14 @@ func matrixData() *FeatureMatrix {
|
|||
DomainModifierAlias = "[`ALIAS`](language-reference/domain-modifiers/ALIAS.md)"
|
||||
DomainModifierCaa = "[`CAA`](language-reference/domain-modifiers/CAA.md)"
|
||||
DomainModifierDnssec = "[`AUTODNSSEC`](language-reference/domain-modifiers/AUTODNSSEC_ON.md)"
|
||||
DomainModifierHttps = "[`HTTPS`](language-reference/domain-modifiers/HTTPS.md)"
|
||||
DomainModifierLoc = "[`LOC`](language-reference/domain-modifiers/LOC.md)"
|
||||
DomainModifierNaptr = "[`NAPTR`](language-reference/domain-modifiers/NAPTR.md)"
|
||||
DomainModifierPtr = "[`PTR`](language-reference/domain-modifiers/PTR.md)"
|
||||
DomainModifierSoa = "[`SOA`](language-reference/domain-modifiers/SOA.md)"
|
||||
DomainModifierSrv = "[`SRV`](language-reference/domain-modifiers/SRV.md)"
|
||||
DomainModifierSshfp = "[`SSHFP`](language-reference/domain-modifiers/SSHFP.md)"
|
||||
DomainModifierSvcb = "[`SVCB`](language-reference/domain-modifiers/SVCB.md)"
|
||||
DomainModifierTlsa = "[`TLSA`](language-reference/domain-modifiers/TLSA.md)"
|
||||
DomainModifierDs = "[`DS`](language-reference/domain-modifiers/DS.md)"
|
||||
DomainModifierDhcid = "[`DHCID`](language-reference/domain-modifiers/DHCID.md)"
|
||||
|
@ -106,12 +108,14 @@ func matrixData() *FeatureMatrix {
|
|||
DomainModifierAlias,
|
||||
DomainModifierCaa,
|
||||
DomainModifierDnssec,
|
||||
DomainModifierHttps,
|
||||
DomainModifierLoc,
|
||||
DomainModifierNaptr,
|
||||
DomainModifierPtr,
|
||||
DomainModifierSoa,
|
||||
DomainModifierSrv,
|
||||
DomainModifierSshfp,
|
||||
DomainModifierSvcb,
|
||||
DomainModifierTlsa,
|
||||
DomainModifierDs,
|
||||
DomainModifierDhcid,
|
||||
|
@ -207,6 +211,10 @@ func matrixData() *FeatureMatrix {
|
|||
DomainModifierDnskey,
|
||||
providers.CanUseDNSKEY,
|
||||
)
|
||||
setCapability(
|
||||
DomainModifierHttps,
|
||||
providers.CanUseHTTPS,
|
||||
)
|
||||
setCapability(
|
||||
DomainModifierLoc,
|
||||
providers.CanUseLOC,
|
||||
|
@ -231,6 +239,10 @@ func matrixData() *FeatureMatrix {
|
|||
DomainModifierSshfp,
|
||||
providers.CanUseSSHFP,
|
||||
)
|
||||
setCapability(
|
||||
DomainModifierSvcb,
|
||||
providers.CanUseSVCB,
|
||||
)
|
||||
setCapability(
|
||||
DomainModifierTlsa,
|
||||
providers.CanUseTLSA,
|
||||
|
|
|
@ -357,6 +357,8 @@ func formatDsl(rec *models.RecordConfig, defaultTTL uint32) string {
|
|||
target = fmt.Sprintf(`"%s", "%s", %d, %d, %d, %d, %d`, rec.GetTargetField(), rec.SoaMbox, rec.SoaSerial, rec.SoaRefresh, rec.SoaRetry, rec.SoaExpire, rec.SoaMinttl)
|
||||
case "SRV":
|
||||
target = fmt.Sprintf(`%d, %d, %d, "%s"`, rec.SrvPriority, rec.SrvWeight, rec.SrvPort, rec.GetTargetField())
|
||||
case "SVCB", "HTTPS":
|
||||
target = fmt.Sprintf(`%d, "%s", "%s"`, rec.SvcPriority, rec.GetTargetField(), rec.SvcParams)
|
||||
case "TLSA":
|
||||
target = fmt.Sprintf(`%d, %d, %d, "%s"`, rec.TlsaUsage, rec.TlsaSelector, rec.TlsaMatchingType, rec.GetTargetField())
|
||||
case "TXT":
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
* [DefaultTTL](language-reference/domain-modifiers/DefaultTTL.md)
|
||||
* [DnsProvider](language-reference/domain-modifiers/DnsProvider.md)
|
||||
* [FRAME](language-reference/domain-modifiers/FRAME.md)
|
||||
* [HTTPS](language-reference/domain-modifiers/HTTPS.md)
|
||||
* [IGNORE](language-reference/domain-modifiers/IGNORE.md)
|
||||
* [IGNORE_NAME](language-reference/domain-modifiers/IGNORE_NAME.md)
|
||||
* [IGNORE_TARGET](language-reference/domain-modifiers/IGNORE_TARGET.md)
|
||||
|
@ -69,6 +70,7 @@
|
|||
* [SPF_BUILDER](language-reference/domain-modifiers/SPF_BUILDER.md)
|
||||
* [SRV](language-reference/domain-modifiers/SRV.md)
|
||||
* [SSHFP](language-reference/domain-modifiers/SSHFP.md)
|
||||
* [SVCB](language-reference/domain-modifiers/SVCB.md)
|
||||
* [TLSA](language-reference/domain-modifiers/TLSA.md)
|
||||
* [TXT](language-reference/domain-modifiers/TXT.md)
|
||||
* [URL](language-reference/domain-modifiers/URL.md)
|
||||
|
|
32
documentation/language-reference/domain-modifiers/HTTPS.md
Normal file
32
documentation/language-reference/domain-modifiers/HTTPS.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
name: HTTPS
|
||||
parameters:
|
||||
- name
|
||||
- priority
|
||||
- target
|
||||
- params
|
||||
- modifiers...
|
||||
parameter_types:
|
||||
name: string
|
||||
priority: number
|
||||
target: string
|
||||
params: string
|
||||
"modifiers...": RecordModifier[]
|
||||
---
|
||||
|
||||
HTTPS adds an HTTPS record to a domain. The name should be the relative label for the record. Use `@` for the domain apex. The HTTPS record is a special form of the SVCB resource record.
|
||||
|
||||
The priority must be a positive number, the address should be an ip address, either a string, or a numeric value obtained via [IP](../top-level-functions/IP.md).
|
||||
|
||||
The params may be configured to specify the `alpn`, `ipv4hint`, `ipv6hint`, `ech` or `port` setting. Several params may be joined by a space. Not existing params may be specified as an empty string `""`
|
||||
|
||||
Modifiers can be any number of [record modifiers](https://docs.dnscontrol.org/language-reference/record-modifiers) or JSON objects, which will be merged into the record's metadata.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
|
||||
HTTPS("@", 1, ".", "ipv4hint=123.123.123.123 alpn=h3,h2 port=443"),
|
||||
HTTPS("@", 1, "test.com", "")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
31
documentation/language-reference/domain-modifiers/SVCB.md
Normal file
31
documentation/language-reference/domain-modifiers/SVCB.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
name: SVCB
|
||||
parameters:
|
||||
- name
|
||||
- priority
|
||||
- target
|
||||
- params
|
||||
- modifiers...
|
||||
parameter_types:
|
||||
name: string
|
||||
priority: number
|
||||
target: string
|
||||
params: string
|
||||
"modifiers...": RecordModifier[]
|
||||
---
|
||||
|
||||
SVCB adds an SVCB record to a domain. The name should be the relative label for the record. Use `@` for the domain apex.
|
||||
|
||||
The priority must be a positive number, the address should be an ip address, either a string, or a numeric value obtained via [IP](../top-level-functions/IP.md).
|
||||
|
||||
The params may be configured to specify the `alpn`, `ipv4hint`, `ipv6hint`, `ech` or `port` setting. Several params may be joined by a space. Not existing params may be specified as an empty string `""`
|
||||
|
||||
Modifiers can be any number of [record modifiers](https://docs.dnscontrol.org/language-reference/record-modifiers) or JSON objects, which will be merged into the record's metadata.
|
||||
|
||||
{% code title="dnsconfig.js" %}
|
||||
```javascript
|
||||
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
|
||||
SVCB("@", 1, ".", "ipv4hint=123.123.123.123 alpn=h3,h2 port=443")
|
||||
);
|
||||
```
|
||||
{% endcode %}
|
|
@ -528,6 +528,13 @@ func dnskey(name string, flags uint16, protocol, algorithm uint8, publicKey stri
|
|||
return r
|
||||
}
|
||||
|
||||
func https(name string, priority uint16, target string, params string) *models.RecordConfig {
|
||||
r := makeRec(name, target, "HTTPS")
|
||||
r.SvcPriority = priority
|
||||
r.SvcParams = params
|
||||
return r
|
||||
}
|
||||
|
||||
func ignoreName(labelSpec string) *models.RecordConfig {
|
||||
return ignore(labelSpec, "*", "*")
|
||||
}
|
||||
|
@ -620,6 +627,13 @@ func sshfp(name string, algorithm uint8, fingerprint uint8, target string) *mode
|
|||
return r
|
||||
}
|
||||
|
||||
func svcb(name string, priority uint16, target string, params string) *models.RecordConfig {
|
||||
r := makeRec(name, target, "SVCB")
|
||||
r.SvcPriority = priority
|
||||
r.SvcParams = params
|
||||
return r
|
||||
}
|
||||
|
||||
func ovhdkim(name, target string) *models.RecordConfig {
|
||||
return makeOvhNativeRecord(name, target, "DKIM")
|
||||
}
|
||||
|
@ -1016,6 +1030,23 @@ func makeTests() []*TestGroup {
|
|||
tc("Change back to CNAME", cname("foo", "google2.com.")),
|
||||
),
|
||||
|
||||
testgroup("HTTPS",
|
||||
tc("Create a HTTPS record", https("@", 1, "test.com.", "port=80")),
|
||||
tc("Change HTTPS priority", https("@", 2, "test.com.", "port=80")),
|
||||
tc("Change HTTPS target", https("@", 2, ".", "port=80")),
|
||||
tc("Change HTTPS params", https("@", 2, ".", "port=99")),
|
||||
tc("Change HTTPS params-empty", https("@", 2, ".", "")),
|
||||
tc("Change HTTPS all", https("@", 3, "example.com.", "port=100")),
|
||||
),
|
||||
|
||||
testgroup("SVCB",
|
||||
tc("Create a HTTPS record", https("@", 1, "test.com.", "port=80")),
|
||||
tc("Change HTTPS priority", https("@", 2, "test.com.", "port=80")),
|
||||
tc("Change HTTPS target", https("@", 2, ".", "port=80")),
|
||||
tc("Change HTTPS params", https("@", 2, ".", "port=99")),
|
||||
tc("Change HTTPS params-empty", https("@", 2, ".", "")),
|
||||
tc("Change HTTPS all", https("@", 3, "example.com.", "port=100")),
|
||||
),
|
||||
//// Test edge cases from various types.
|
||||
|
||||
// Narrative: Every DNS record type has some weird edge-case that
|
||||
|
|
|
@ -54,6 +54,8 @@ func helperRRtoRC(rr dns.RR, origin string, fixBug bool) (RecordConfig, error) {
|
|||
err = rc.SetTargetDS(v.KeyTag, v.Algorithm, v.DigestType, v.Digest)
|
||||
case *dns.DNSKEY:
|
||||
err = rc.SetTargetDNSKEY(v.Flags, v.Protocol, v.Algorithm, v.PublicKey)
|
||||
case *dns.HTTPS:
|
||||
err = rc.SetTargetSVCB(v.Priority, v.Target, v.Value)
|
||||
case *dns.LOC:
|
||||
err = rc.SetTargetLOC(v.Version, v.Latitude, v.Longitude, v.Altitude, v.Size, v.HorizPre, v.VertPre)
|
||||
case *dns.MX:
|
||||
|
@ -70,6 +72,8 @@ func helperRRtoRC(rr dns.RR, origin string, fixBug bool) (RecordConfig, error) {
|
|||
err = rc.SetTargetSRV(v.Priority, v.Weight, v.Port, v.Target)
|
||||
case *dns.SSHFP:
|
||||
err = rc.SetTargetSSHFP(v.Algorithm, v.Type, v.FingerPrint)
|
||||
case *dns.SVCB:
|
||||
err = rc.SetTargetSVCB(v.Priority, v.Target, v.Value)
|
||||
case *dns.TLSA:
|
||||
err = rc.SetTargetTLSA(v.Usage, v.Selector, v.MatchingType, v.Certificate)
|
||||
case *dns.TXT:
|
||||
|
|
|
@ -141,7 +141,7 @@ func (dc *DomainConfig) Punycode() error {
|
|||
rec.SetTarget(t)
|
||||
case "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE":
|
||||
rec.SetTarget(rec.GetTargetField())
|
||||
case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "LOC", "NAPTR", "SOA", "SSHFP", "TXT", "TLSA", "AZURE_ALIAS":
|
||||
case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "LOC", "NAPTR", "SOA", "SSHFP", "SVCB", "TXT", "TLSA", "AZURE_ALIAS":
|
||||
// Nothing to do.
|
||||
default:
|
||||
return fmt.Errorf("Punycode rtype %v unimplemented", rec.Type)
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
// ANAME // Technically not an official rtype yet.
|
||||
// CAA
|
||||
// CNAME
|
||||
// HTTPS
|
||||
// LOC
|
||||
// MX
|
||||
// NAPTR
|
||||
|
@ -30,6 +31,7 @@ import (
|
|||
// SOA
|
||||
// SRV
|
||||
// SSHFP
|
||||
// SVCB
|
||||
// TLSA
|
||||
// TXT
|
||||
// Pseudo-Types: (alphabetical)
|
||||
|
@ -128,6 +130,8 @@ type RecordConfig struct {
|
|||
SoaRetry uint32 `json:"soaretry,omitempty"`
|
||||
SoaExpire uint32 `json:"soaexpire,omitempty"`
|
||||
SoaMinttl uint32 `json:"soaminttl,omitempty"`
|
||||
SvcPriority uint16 `json:"svcpriority,omitempty"`
|
||||
SvcParams string `json:"svcparams,omitempty"`
|
||||
TlsaUsage uint8 `json:"tlsausage,omitempty"`
|
||||
TlsaSelector uint8 `json:"tlsaselector,omitempty"`
|
||||
TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"`
|
||||
|
@ -200,6 +204,8 @@ func (rc *RecordConfig) UnmarshalJSON(b []byte) error {
|
|||
SoaRetry uint32 `json:"soaretry,omitempty"`
|
||||
SoaExpire uint32 `json:"soaexpire,omitempty"`
|
||||
SoaMinttl uint32 `json:"soaminttl,omitempty"`
|
||||
SvcPriority uint16 `json:"svcpriority,omitempty"`
|
||||
SvcParams string `json:"svcparams,omitempty"`
|
||||
TlsaUsage uint8 `json:"tlsausage,omitempty"`
|
||||
TlsaSelector uint8 `json:"tlsaselector,omitempty"`
|
||||
TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"`
|
||||
|
@ -381,6 +387,10 @@ func (rc *RecordConfig) ToRR() dns.RR {
|
|||
rr.(*dns.DNSKEY).Protocol = rc.DnskeyProtocol
|
||||
rr.(*dns.DNSKEY).Algorithm = rc.DnskeyAlgorithm
|
||||
rr.(*dns.DNSKEY).PublicKey = rc.DnskeyPublicKey
|
||||
case dns.TypeHTTPS:
|
||||
rr.(*dns.HTTPS).Priority = rc.SvcPriority
|
||||
rr.(*dns.HTTPS).Target = rc.GetTargetField()
|
||||
rr.(*dns.HTTPS).Value = rc.GetSVCBValue()
|
||||
case dns.TypeLOC:
|
||||
// fmt.Printf("ToRR long: %d, lat:%d, sz: %d, hz:%d, vt:%d\n", rc.LocLongitude, rc.LocLatitude, rc.LocSize, rc.LocHorizPre, rc.LocVertPre)
|
||||
// fmt.Printf("ToRR rc: %+v\n", *rc)
|
||||
|
@ -424,6 +434,10 @@ func (rc *RecordConfig) ToRR() dns.RR {
|
|||
rr.(*dns.SSHFP).Algorithm = rc.SshfpAlgorithm
|
||||
rr.(*dns.SSHFP).Type = rc.SshfpFingerprint
|
||||
rr.(*dns.SSHFP).FingerPrint = rc.GetTargetField()
|
||||
case dns.TypeSVCB:
|
||||
rr.(*dns.SVCB).Priority = rc.SvcPriority
|
||||
rr.(*dns.SVCB).Target = rc.GetTargetField()
|
||||
rr.(*dns.SVCB).Value = rc.GetSVCBValue()
|
||||
case dns.TypeTLSA:
|
||||
rr.(*dns.TLSA).Usage = rc.TlsaUsage
|
||||
rr.(*dns.TLSA).MatchingType = rc.TlsaMatchingType
|
||||
|
@ -483,6 +497,20 @@ func (rc *RecordConfig) Key() RecordKey {
|
|||
return RecordKey{rc.NameFQDN, t}
|
||||
}
|
||||
|
||||
func (rc *RecordConfig) GetSVCBValue() []dns.SVCBKeyValue {
|
||||
record, err := dns.NewRR(fmt.Sprintf("%s %s %d %s %s", rc.NameFQDN, rc.Type, rc.SvcPriority, rc.target, rc.SvcParams))
|
||||
if err != nil {
|
||||
log.Fatalf("could not parse SVCB record: %s", err)
|
||||
}
|
||||
switch r := record.(type) {
|
||||
case *dns.HTTPS:
|
||||
return r.Value
|
||||
case *dns.SVCB:
|
||||
return r.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Records is a list of *RecordConfig.
|
||||
type Records []*RecordConfig
|
||||
|
||||
|
@ -580,7 +608,7 @@ func CanonicalizeTargets(recs []*RecordConfig, origin string) {
|
|||
case "ALIAS", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "PTR", "SRV":
|
||||
// Target is a hostname that might be a shortname. Turn it into a FQDN.
|
||||
r.target = dnsutil.AddOrigin(r.target, originFQDN)
|
||||
case "A", "AKAMAICDN", "CAA", "DHCID", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE", "IMPORT_TRANSFORM", "LOC", "SSHFP", "TLSA", "TXT":
|
||||
case "A", "AKAMAICDN", "CAA", "DHCID", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE", "HTTPS", "IMPORT_TRANSFORM", "LOC", "SSHFP", "SVCB", "TLSA", "TXT":
|
||||
// Do nothing.
|
||||
case "SOA":
|
||||
if r.target != "DEFAULT_NOT_SET." {
|
||||
|
|
|
@ -105,6 +105,8 @@ func (rc *RecordConfig) PopulateFromStringFunc(rtype, contents, origin string, t
|
|||
return rc.SetTargetSRVString(contents)
|
||||
case "SSHFP":
|
||||
return rc.SetTargetSSHFPString(contents)
|
||||
case "SVCB", "HTTPS":
|
||||
return rc.SetTargetSVCBString(origin, contents)
|
||||
case "TLSA":
|
||||
return rc.SetTargetTLSAString(contents)
|
||||
default:
|
||||
|
|
44
models/t_svcb.go
Normal file
44
models/t_svcb.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// SetTargetSVCB sets the SVCB fields.
|
||||
func (rc *RecordConfig) SetTargetSVCB(priority uint16, target string, params []dns.SVCBKeyValue) error {
|
||||
rc.SvcPriority = priority
|
||||
rc.SetTarget(target)
|
||||
paramsStr := []string{}
|
||||
for _, kv := range params {
|
||||
paramsStr = append(paramsStr, fmt.Sprintf("%s=%s", kv.Key(), kv.String()))
|
||||
}
|
||||
rc.SvcParams = strings.Join(paramsStr, " ")
|
||||
if rc.Type == "" {
|
||||
rc.Type = "SVCB"
|
||||
}
|
||||
if rc.Type != "SVCB" && rc.Type != "HTTPS" {
|
||||
panic("assertion failed: SetTargetSVCB called when .Type is not SVCB or HTTPS")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetTargetSVCBString is like SetTargetSVCB but accepts one big string and the origin so parsing can be done using miekg/dns.
|
||||
func (rc *RecordConfig) SetTargetSVCBString(origin, contents string) error {
|
||||
if rc.Type == "" {
|
||||
rc.Type = "SVCB"
|
||||
}
|
||||
record, err := dns.NewRR(fmt.Sprintf("%s. %s %s", origin, rc.Type, contents))
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse SVCB record: %s", err)
|
||||
}
|
||||
switch r := record.(type) {
|
||||
case *dns.HTTPS:
|
||||
return rc.SetTargetSVCB(r.Priority, r.Target, r.Value)
|
||||
case *dns.SVCB:
|
||||
return rc.SetTargetSVCB(r.Priority, r.Target, r.Value)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -131,6 +131,9 @@ func (rc *RecordConfig) GetTargetDebug() string {
|
|||
content += fmt.Sprintf(" srvpriority=%d srvweight=%d srvport=%d", rc.SrvPriority, rc.SrvWeight, rc.SrvPort)
|
||||
case "SSHFP":
|
||||
content += fmt.Sprintf(" sshfpalgorithm=%d sshfpfingerprint=%d", rc.SshfpAlgorithm, rc.SshfpFingerprint)
|
||||
case "SVCB", "HTTPS":
|
||||
// HTTPS is only a special subform of the SVCB Record
|
||||
content += fmt.Sprintf(" priority=%d params=%v", rc.SvcPriority, rc.SvcParams)
|
||||
case "TLSA":
|
||||
content += fmt.Sprintf(" tlsausage=%d tlsaselector=%d tlsamatchingtype=%d", rc.TlsaUsage, rc.TlsaSelector, rc.TlsaMatchingType)
|
||||
default:
|
||||
|
|
|
@ -449,6 +449,22 @@ var DNSKEY = recordBuilder('DNSKEY', {
|
|||
},
|
||||
});
|
||||
|
||||
// name, priority, target, params
|
||||
var HTTPS = recordBuilder('HTTPS', {
|
||||
args: [
|
||||
['name', _.isString],
|
||||
['priority', _.isNumber],
|
||||
['target', _.isString],
|
||||
['params', _.isString],
|
||||
],
|
||||
transform: function (record, args, modifiers) {
|
||||
record.name = args.name;
|
||||
record.svcpriority = args.priority;
|
||||
record.target = args.target;
|
||||
record.svcparams = args.params;
|
||||
},
|
||||
});
|
||||
|
||||
// PTR(name,target, recordModifiers...)
|
||||
var PTR = recordBuilder('PTR');
|
||||
|
||||
|
@ -530,6 +546,22 @@ var SSHFP = recordBuilder('SSHFP', {
|
|||
},
|
||||
});
|
||||
|
||||
// name, priority, target, params
|
||||
var SVCB = recordBuilder('SVCB', {
|
||||
args: [
|
||||
['name', _.isString],
|
||||
['priority', _.isNumber],
|
||||
['target', _.isString],
|
||||
['params', _.isString],
|
||||
],
|
||||
transform: function (record, args, modifiers) {
|
||||
record.name = args.name;
|
||||
record.svcpriority = args.priority;
|
||||
record.target = args.target;
|
||||
record.svcparams = args.params;
|
||||
},
|
||||
});
|
||||
|
||||
// name, usage, selector, matchingtype, certificate
|
||||
var TLSA = recordBuilder('TLSA', {
|
||||
args: [
|
||||
|
|
4
pkg/js/parse_tests/047-SVCB.js
Normal file
4
pkg/js/parse_tests/047-SVCB.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
D("foo.com","none",
|
||||
SVCB("@", 1, ".", ""),
|
||||
HTTPS("@", 2, ".", 'alpn="h3,h2" port=443 ipv4hint=123.123.123.123 ipv6hint=dead::beaf')
|
||||
);
|
27
pkg/js/parse_tests/047-SVCB.json
Normal file
27
pkg/js/parse_tests/047-SVCB.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"registrars": [],
|
||||
"dns_providers": [],
|
||||
"domains": [
|
||||
{
|
||||
"name": "foo.com",
|
||||
"registrar": "none",
|
||||
"dnsProviders": {},
|
||||
"records": [
|
||||
{
|
||||
"type": "SVCB",
|
||||
"name": "@",
|
||||
"target": ".",
|
||||
"svcpriority": 1
|
||||
},
|
||||
|
||||
{
|
||||
"type": "HTTPS",
|
||||
"name": "@",
|
||||
"svcparams": "alpn=\"h3,h2\" port=443 ipv4hint=123.123.123.123 ipv6hint=dead::beaf",
|
||||
"svcpriority": 2,
|
||||
"target": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -63,6 +63,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
|
|||
"DNAME": true,
|
||||
"DS": true,
|
||||
"DNSKEY": true,
|
||||
"HTTPS": true,
|
||||
"IMPORT_TRANSFORM": false,
|
||||
"LOC": true,
|
||||
"MX": true,
|
||||
|
@ -72,6 +73,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
|
|||
"SOA": true,
|
||||
"SRV": true,
|
||||
"SSHFP": true,
|
||||
"SVCB": true,
|
||||
"TLSA": true,
|
||||
"TXT": true,
|
||||
}
|
||||
|
@ -224,7 +226,7 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
|||
}
|
||||
case "SRV":
|
||||
check(checkTarget(target))
|
||||
case "CAA", "DHCID", "DNSKEY", "DS", "IMPORT_TRANSFORM", "SSHFP", "TLSA", "TXT":
|
||||
case "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "IMPORT_TRANSFORM", "SSHFP", "SVCB", "TLSA", "TXT":
|
||||
default:
|
||||
if rec.Metadata["orig_custom_type"] != "" {
|
||||
// it is a valid custom type. We perform no validation on target
|
||||
|
@ -685,6 +687,7 @@ var providerCapabilityChecks = []pairTypeCapability{
|
|||
capabilityCheck("DHCID", providers.CanUseDHCID),
|
||||
capabilityCheck("DNAME", providers.CanUseDNAME),
|
||||
capabilityCheck("DNSKEY", providers.CanUseDNSKEY),
|
||||
capabilityCheck("HTTPS", providers.CanUseHTTPS),
|
||||
capabilityCheck("LOC", providers.CanUseLOC),
|
||||
capabilityCheck("NAPTR", providers.CanUseNAPTR),
|
||||
capabilityCheck("PTR", providers.CanUsePTR),
|
||||
|
@ -692,6 +695,7 @@ var providerCapabilityChecks = []pairTypeCapability{
|
|||
capabilityCheck("SOA", providers.CanUseSOA),
|
||||
capabilityCheck("SRV", providers.CanUseSRV),
|
||||
capabilityCheck("SSHFP", providers.CanUseSSHFP),
|
||||
capabilityCheck("SVCB", providers.CanUseSVCB),
|
||||
capabilityCheck("TLSA", providers.CanUseTLSA),
|
||||
|
||||
// DS needs special record-level checks
|
||||
|
|
|
@ -341,6 +341,8 @@ func TestWriteZoneFileEach(t *testing.T) {
|
|||
d = append(d, mustNewRR(`dname.bosun.org. 300 IN DNAME example.com.`))
|
||||
d = append(d, mustNewRR(`dnssec.bosun.org. 300 IN DS 31334 13 2 94cc505ebc36b1f4e051268b820efb230f1572d445e833bb5bf7380d6c2cbc0a`))
|
||||
d = append(d, mustNewRR(`dnssec.bosun.org. 300 IN DNSKEY 257 3 13 rNR701yiOPHfqDP53GnsHZdlsRqI7O1ksk60rnFILZVk7Z4eTBd1U49oSkTNVNox9tb7N15N2hboXoMEyFFzcw==`))
|
||||
d = append(d, mustNewRR(`bosun.org. 300 IN HTTPS 1 . alpn="h3,h2"`))
|
||||
d = append(d, mustNewRR(`bosun.org. 300 IN SVCB 1 . alpn="h3,h2"`))
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, d, "bosun.org")
|
||||
if buf.String() != testdataZFEach {
|
||||
|
@ -359,6 +361,8 @@ var testdataZFEach = `$TTL 300
|
|||
IN TXT "my text"
|
||||
IN CAA 0 issue "letsencrypt.org"
|
||||
IN DHCID AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA=
|
||||
IN HTTPS 1 . alpn="h3,h2"
|
||||
IN SVCB 1 . alpn="h3,h2"
|
||||
4.5 IN PTR y.bosun.org.
|
||||
_443._tcp IN TLSA 3 1 1 abcdef0
|
||||
dname IN DNAME example.com.
|
||||
|
|
|
@ -80,6 +80,12 @@ func (z *ZoneGenData) Less(i, j int) bool {
|
|||
if pa != pb {
|
||||
return pa < pb
|
||||
}
|
||||
case "SVCB", "HTTPS":
|
||||
// sort by priority. If they are equal, sort by record.
|
||||
if a.SvcPriority == b.SvcPriority {
|
||||
return a.GetTargetField() < b.GetTargetField()
|
||||
}
|
||||
return a.SvcPriority < b.SvcPriority
|
||||
case "PTR":
|
||||
//ta2, tb2 := a.(*dns.PTR), b.(*dns.PTR)
|
||||
pa, pb := a.GetTargetField(), b.GetTargetField()
|
||||
|
|
|
@ -44,11 +44,13 @@ var features = providers.DocumentationNotes{
|
|||
providers.CanConcur: providers.Cannot(),
|
||||
providers.CanUseCAA: providers.Can(),
|
||||
providers.CanUseDHCID: providers.Can(),
|
||||
providers.CanUseHTTPS: providers.Can(),
|
||||
providers.CanUseLOC: providers.Unimplemented(),
|
||||
providers.CanUseNAPTR: providers.Can(),
|
||||
providers.CanUsePTR: providers.Can(),
|
||||
providers.CanUseSRV: providers.Can(),
|
||||
providers.CanUseSSHFP: providers.Can(),
|
||||
providers.CanUseSVCB: providers.Can(),
|
||||
providers.CanUseTLSA: providers.Can(),
|
||||
providers.DocCreateDomains: providers.Cannot(),
|
||||
providers.DocDualHost: providers.Cannot(),
|
||||
|
|
|
@ -40,12 +40,14 @@ var features = providers.DocumentationNotes{
|
|||
providers.CanUseDNAME: providers.Can(),
|
||||
providers.CanUseDS: providers.Can(),
|
||||
providers.CanUseDNSKEY: providers.Can(),
|
||||
providers.CanUseHTTPS: providers.Can(),
|
||||
providers.CanUseLOC: providers.Can(),
|
||||
providers.CanUseNAPTR: providers.Can(),
|
||||
providers.CanUsePTR: providers.Can(),
|
||||
providers.CanUseSOA: providers.Can(),
|
||||
providers.CanUseSRV: providers.Can(),
|
||||
providers.CanUseSSHFP: providers.Can(),
|
||||
providers.CanUseSVCB: providers.Can(),
|
||||
providers.CanUseTLSA: providers.Can(),
|
||||
providers.DocCreateDomains: providers.Can("Driver just maintains list of zone files. It should automatically add missing ones."),
|
||||
providers.DocDualHost: providers.Can(),
|
||||
|
|
|
@ -54,6 +54,9 @@ const (
|
|||
// only for children records, not at the root of the zone.
|
||||
CanUseDSForChildren
|
||||
|
||||
// CanUseHTTPS indicates the provider can handle HTTPS records
|
||||
CanUseHTTPS
|
||||
|
||||
// CanUseLOC indicates whether service provider handles LOC records
|
||||
CanUseLOC
|
||||
|
||||
|
@ -75,6 +78,9 @@ const (
|
|||
// CanUseSSHFP indicates the provider can handle SSHFP records
|
||||
CanUseSSHFP
|
||||
|
||||
// CanUseSVCB indicates the provider can handle SVCB records
|
||||
CanUseSVCB
|
||||
|
||||
// CanUseTLSA indicates the provider can handle TLSA records
|
||||
CanUseTLSA
|
||||
|
||||
|
|
|
@ -19,23 +19,25 @@ func _() {
|
|||
_ = x[CanUseDNAME-8]
|
||||
_ = x[CanUseDS-9]
|
||||
_ = x[CanUseDSForChildren-10]
|
||||
_ = x[CanUseLOC-11]
|
||||
_ = x[CanUseNAPTR-12]
|
||||
_ = x[CanUsePTR-13]
|
||||
_ = x[CanUseRoute53Alias-14]
|
||||
_ = x[CanUseSOA-15]
|
||||
_ = x[CanUseSRV-16]
|
||||
_ = x[CanUseSSHFP-17]
|
||||
_ = x[CanUseTLSA-18]
|
||||
_ = x[CanUseDNSKEY-19]
|
||||
_ = x[DocCreateDomains-20]
|
||||
_ = x[DocDualHost-21]
|
||||
_ = x[DocOfficiallySupported-22]
|
||||
_ = x[CanUseHTTPS-11]
|
||||
_ = x[CanUseLOC-12]
|
||||
_ = x[CanUseNAPTR-13]
|
||||
_ = x[CanUsePTR-14]
|
||||
_ = x[CanUseRoute53Alias-15]
|
||||
_ = x[CanUseSOA-16]
|
||||
_ = x[CanUseSRV-17]
|
||||
_ = x[CanUseSSHFP-18]
|
||||
_ = x[CanUseSVCB-19]
|
||||
_ = x[CanUseTLSA-20]
|
||||
_ = x[CanUseDNSKEY-21]
|
||||
_ = x[DocCreateDomains-22]
|
||||
_ = x[DocDualHost-23]
|
||||
_ = x[DocOfficiallySupported-24]
|
||||
}
|
||||
|
||||
const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseTLSACanUseDNSKEYDocCreateDomainsDocDualHostDocOfficiallySupported"
|
||||
const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseHTTPSCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseSVCBCanUseTLSACanUseDNSKEYDocCreateDomainsDocDualHostDocOfficiallySupported"
|
||||
|
||||
var _Capability_index = [...]uint16{0, 13, 22, 33, 48, 59, 75, 84, 95, 106, 114, 133, 142, 153, 162, 180, 189, 198, 209, 219, 231, 247, 258, 280}
|
||||
var _Capability_index = [...]uint16{0, 13, 22, 33, 48, 59, 75, 84, 95, 106, 114, 133, 144, 153, 164, 173, 191, 200, 209, 220, 230, 240, 252, 268, 279, 301}
|
||||
|
||||
func (i Capability) String() string {
|
||||
if i >= Capability(len(_Capability_index)-1) {
|
||||
|
|
Loading…
Reference in a new issue