Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 12, 10:45 UTC
caddytls: Caddyfile support for TLS handshake matchers (#6461)
* Caddyfile support for TLS handshake matchers: - caddytls.MatchLocalIP - caddytls.MatchRemoteIP - caddytls.MatchServerName * Caddyfile support for TLS handshake matchers: - fix imports order Co-authored-by: Francis Lavoie <lavofr@gmail.com> --------- Co-authored-by: Francis Lavoie <lavofr@gmail.com>
vnxme committed
Jul 24, 2024 at 18:26 UTC
61fe152c603e6efb6ca3d3522923beebe6d6701f
1 file changed
+103
modules/caddytls/matchers.go
+103
@@ -25,6 +25,7 @@ import (
25
"go.uber.org/zap"
26
27
"github.com/caddyserver/caddy/v2"
28
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
29
)
30
31
func init() {
@@ -56,6 +57,29 @@ func (m MatchServerName) Match(hello *tls.ClientHelloInfo) bool {
57
return false
58
}
59
60
+// UnmarshalCaddyfile sets up the MatchServerName from Caddyfile tokens. Syntax:
61
+//
62
+// sni <domains...>
63
+func (m *MatchServerName) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
64
+ for d.Next() {
65
+ wrapper := d.Val()
66
+
67
+ // At least one same-line option must be provided
68
+ if d.CountRemainingArgs() == 0 {
69
+ return d.ArgErr()
70
+ }
71
+
72
+ *m = append(*m, d.RemainingArgs()...)
73
+
74
+ // No blocks are supported
75
+ if d.NextBlock(d.Nesting()) {
76
+ return d.Errf("malformed TLS handshake matcher '%s': blocks are not supported", wrapper)
77
+ }
78
+ }
79
+
80
+ return nil
81
+}
82
+
83
// MatchRemoteIP matches based on the remote IP of the
84
// connection. Specific IPs or CIDR ranges can be specified.
85
//
@@ -145,6 +169,50 @@ func (MatchRemoteIP) matches(ip netip.Addr, ranges []netip.Prefix) bool {
169
return false
170
}
171
172
+// UnmarshalCaddyfile sets up the MatchRemoteIP from Caddyfile tokens. Syntax:
173
+//
174
+// remote_ip <ranges...>
175
+//
176
+// Note: IPs and CIDRs prefixed with ! symbol are treated as not_ranges
177
+func (m *MatchRemoteIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
178
+ for d.Next() {
179
+ wrapper := d.Val()
180
+
181
+ // At least one same-line option must be provided
182
+ if d.CountRemainingArgs() == 0 {
183
+ return d.ArgErr()
184
+ }
185
+
186
+ for d.NextArg() {
187
+ val := d.Val()
188
+ if len(val) > 1 && val[0] == '!' {
189
+ prefixes, err := m.parseIPRange(val[1:])
190
+ if err != nil {
191
+ return err
192
+ }
193
+ for _, prefix := range prefixes {
194
+ m.NotRanges = append(m.NotRanges, prefix.String())
195
+ }
196
+ } else {
197
+ prefixes, err := m.parseIPRange(val)
198
+ if err != nil {
199
+ return err
200
+ }
201
+ for _, prefix := range prefixes {
202
+ m.Ranges = append(m.Ranges, prefix.String())
203
+ }
204
+ }
205
+ }
206
+
207
+ // No blocks are supported
208
+ if d.NextBlock(d.Nesting()) {
209
+ return d.Errf("malformed TLS handshake matcher '%s': blocks are not supported", wrapper)
210
+ }
211
+ }
212
+
213
+ return nil
214
+}
215
+
216
// MatchLocalIP matches based on the IP address of the interface
217
// receiving the connection. Specific IPs or CIDR ranges can be specified.
218
type MatchLocalIP struct {
@@ -219,6 +287,37 @@ func (MatchLocalIP) matches(ip netip.Addr, ranges []netip.Prefix) bool {
287
return false
288
}
289
290
+// UnmarshalCaddyfile sets up the MatchLocalIP from Caddyfile tokens. Syntax:
291
+//
292
+// local_ip <ranges...>
293
+func (m *MatchLocalIP) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
294
+ for d.Next() {
295
+ wrapper := d.Val()
296
+
297
+ // At least one same-line option must be provided
298
+ if d.CountRemainingArgs() == 0 {
299
+ return d.ArgErr()
300
+ }
301
+
302
+ for d.NextArg() {
303
+ prefixes, err := m.parseIPRange(d.Val())
304
+ if err != nil {
305
+ return err
306
+ }
307
+ for _, prefix := range prefixes {
308
+ m.Ranges = append(m.Ranges, prefix.String())
309
+ }
310
+ }
311
+
312
+ // No blocks are supported
313
+ if d.NextBlock(d.Nesting()) {
314
+ return d.Errf("malformed TLS handshake matcher '%s': blocks are not supported", wrapper)
315
+ }
316
+ }
317
+
318
+ return nil
319
+}
320
+
321
// Interface guards
322
var (
323
_ ConnectionMatcher = (*MatchServerName)(nil)
@@ -226,4 +325,8 @@ var (
325
326
_ caddy.Provisioner = (*MatchLocalIP)(nil)
327
_ ConnectionMatcher = (*MatchLocalIP)(nil)
328
+
329
+ _ caddyfile.Unmarshaler = (*MatchLocalIP)(nil)
330
+ _ caddyfile.Unmarshaler = (*MatchRemoteIP)(nil)
331
+ _ caddyfile.Unmarshaler = (*MatchServerName)(nil)
332
)