Skip to content

Commit 3897771

Browse files
authored
Merge pull request #1926 from smallstep/mariano/dns
Add a flag to enable strict DNS resolution
2 parents 0a9dd62 + 3e61796 commit 3897771

File tree

3 files changed

+73
-23
lines changed

3 files changed

+73
-23
lines changed

acme/challenge.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ var (
6363
//
6464
// This variable can be used for testing purposes.
6565
InsecurePortTLSALPN01 int
66+
67+
// StrictFQDN allows to enforce a fully qualified domain name in the DNS
68+
// resolution. By default it allows domain resolution using a search list
69+
// defined in the resolv.conf or similar configuration.
70+
StrictFQDN bool
6671
)
6772

6873
// Challenge represents an ACME response Challenge type.
@@ -163,8 +168,10 @@ func http01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSONWeb
163168

164169
// rootedName adds a trailing "." to a given domain name.
165170
func rootedName(name string) string {
166-
if name == "" || name[len(name)-1] != '.' {
167-
return name + "."
171+
if StrictFQDN {
172+
if name == "" || name[len(name)-1] != '.' {
173+
return name + "."
174+
}
168175
}
169176
return name
170177
}

acme/challenge_test.go

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,19 +2767,34 @@ func Test_serverName(t *testing.T) {
27672767

27682768
func Test_http01ChallengeHost(t *testing.T) {
27692769
tests := []struct {
2770-
name string
2771-
value string
2772-
want string
2770+
name string
2771+
strictFQDN bool
2772+
value string
2773+
want string
27732774
}{
27742775
{
2775-
name: "dns",
2776-
value: "www.example.com",
2777-
want: "www.example.com.",
2776+
name: "dns",
2777+
strictFQDN: false,
2778+
value: "www.example.com",
2779+
want: "www.example.com",
27782780
},
27792781
{
2780-
name: "rooted dns",
2781-
value: "www.example.com.",
2782-
want: "www.example.com.",
2782+
name: "dns strict",
2783+
strictFQDN: true,
2784+
value: "www.example.com",
2785+
want: "www.example.com.",
2786+
},
2787+
{
2788+
name: "rooted dns",
2789+
strictFQDN: false,
2790+
value: "www.example.com.",
2791+
want: "www.example.com.",
2792+
},
2793+
{
2794+
name: "rooted dns strict",
2795+
strictFQDN: true,
2796+
value: "www.example.com.",
2797+
want: "www.example.com.",
27832798
},
27842799
{
27852800
name: "ipv4",
@@ -2794,6 +2809,11 @@ func Test_http01ChallengeHost(t *testing.T) {
27942809
}
27952810
for _, tt := range tests {
27962811
t.Run(tt.name, func(t *testing.T) {
2812+
tmp := StrictFQDN
2813+
t.Cleanup(func() {
2814+
StrictFQDN = tmp
2815+
})
2816+
StrictFQDN = tt.strictFQDN
27972817
if got := http01ChallengeHost(tt.value); got != tt.want {
27982818
t.Errorf("http01ChallengeHost() = %v, want %v", got, tt.want)
27992819
}
@@ -4500,17 +4520,25 @@ func Test_tlsAlpn01ChallengeHost(t *testing.T) {
45004520
name string
45014521
}
45024522
tests := []struct {
4503-
name string
4504-
args args
4505-
want string
4523+
name string
4524+
strictFQDN bool
4525+
args args
4526+
want string
45064527
}{
4507-
{"dns", args{"smallstep.com"}, "smallstep.com."},
4508-
{"rooted dns", args{"smallstep.com."}, "smallstep.com."},
4509-
{"ipv4", args{"1.2.3.4"}, "1.2.3.4"},
4510-
{"ipv6", args{"2607:f8b0:4023:1009::71"}, "2607:f8b0:4023:1009::71"},
4528+
{"dns", false, args{"smallstep.com"}, "smallstep.com"},
4529+
{"dns strict", true, args{"smallstep.com"}, "smallstep.com."},
4530+
{"rooted dns", false, args{"smallstep.com."}, "smallstep.com."},
4531+
{"rooted dns strict", true, args{"smallstep.com."}, "smallstep.com."},
4532+
{"ipv4", true, args{"1.2.3.4"}, "1.2.3.4"},
4533+
{"ipv6", true, args{"2607:f8b0:4023:1009::71"}, "2607:f8b0:4023:1009::71"},
45114534
}
45124535
for _, tt := range tests {
45134536
t.Run(tt.name, func(t *testing.T) {
4537+
tmp := StrictFQDN
4538+
t.Cleanup(func() {
4539+
StrictFQDN = tmp
4540+
})
4541+
StrictFQDN = tt.strictFQDN
45144542
assert.Equal(t, tt.want, tlsAlpn01ChallengeHost(tt.args.name))
45154543
})
45164544
}
@@ -4521,15 +4549,23 @@ func Test_dns01ChallengeHost(t *testing.T) {
45214549
domain string
45224550
}
45234551
tests := []struct {
4524-
name string
4525-
args args
4526-
want string
4552+
name string
4553+
strictFQDN bool
4554+
args args
4555+
want string
45274556
}{
4528-
{"dns", args{"smallstep.com"}, "_acme-challenge.smallstep.com."},
4529-
{"rooted dns", args{"smallstep.com."}, "_acme-challenge.smallstep.com."},
4557+
{"dns", false, args{"smallstep.com"}, "_acme-challenge.smallstep.com"},
4558+
{"dns strict", true, args{"smallstep.com"}, "_acme-challenge.smallstep.com."},
4559+
{"rooted dns", false, args{"smallstep.com."}, "_acme-challenge.smallstep.com."},
4560+
{"rooted dns strict", true, args{"smallstep.com."}, "_acme-challenge.smallstep.com."},
45304561
}
45314562
for _, tt := range tests {
45324563
t.Run(tt.name, func(t *testing.T) {
4564+
tmp := StrictFQDN
4565+
t.Cleanup(func() {
4566+
StrictFQDN = tmp
4567+
})
4568+
StrictFQDN = tt.strictFQDN
45334569
assert.Equal(t, tt.want, dns01ChallengeHost(tt.args.domain))
45344570
})
45354571
}

commands/app.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ Requires **--insecure** flag.`,
8383
Usage: `the <port> used on tls-alpn-01 challenges. It can be changed for testing purposes.
8484
Requires **--insecure** flag.`,
8585
},
86+
cli.BoolFlag{
87+
Name: "acme-strict-fqdn",
88+
Usage: `enable strict DNS resolution using a fully qualified domain name.`,
89+
},
8690
cli.StringFlag{
8791
Name: "pidfile",
8892
Usage: "the path to the <file> to write the process ID.",
@@ -126,6 +130,9 @@ func appAction(ctx *cli.Context) error {
126130
}
127131
}
128132

133+
// Set the strict DNS resolution on ACME challenges. Defaults to false.
134+
acme.StrictFQDN = ctx.Bool("acme-strict-fqdn")
135+
129136
// Allow custom contexts.
130137
if caCtx := ctx.String("context"); caCtx != "" {
131138
if _, ok := step.Contexts().Get(caCtx); ok {

0 commit comments

Comments
 (0)