@marcel91200 / caddy Mirror · read-only / commits / 61fe152c
Fork 0

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 )