cloudflared/ingress/rule.go
Sudarsan Reddy de07da02cd TUN-6772: Add a JWT Validator as an ingress verifier
This adds a new verifier interface that can be attached to ingress.Rule.
This would act as a middleware layer that gets executed at the start of
proxy.ProxyHTTP.

A jwt validator implementation for this verifier is also provided. The
validator downloads the public key from the access teams endpoint and
uses it to verify the JWT sent to cloudflared with the audtag (clientID)
information provided in the config.
2022-09-22 08:42:25 +00:00

69 lines
2.0 KiB
Go

package ingress
import (
"encoding/json"
"regexp"
"strings"
)
// Rule routes traffic from a hostname/path on the public internet to the
// service running on the given URL.
type Rule struct {
// Requests for this hostname will be proxied to this rule's service.
Hostname string `json:"hostname"`
// Path is an optional regex that can specify path-driven ingress rules.
Path *Regexp `json:"path"`
// A (probably local) address. Requests for a hostname which matches this
// rule's hostname pattern will be proxied to the service running on this
// address.
Service OriginService `json:"service"`
// Handlers is a list of functions that acts as a middleware during ProxyHTTP
// TODO TUN-6774: Uncomment when we parse ingress to this. This serves as a demonstration on how
// we want to plug in Verifiers.
// Handlers []middleware.Handler
// Configure the request cloudflared sends to this specific origin.
Config OriginRequestConfig `json:"originRequest"`
}
// MultiLineString is for outputting rules in a human-friendly way when Cloudflared
// is used as a CLI tool (not as a daemon).
func (r Rule) MultiLineString() string {
var out strings.Builder
if r.Hostname != "" {
out.WriteString("\thostname: ")
out.WriteString(r.Hostname)
out.WriteRune('\n')
}
if r.Path != nil && r.Path.Regexp != nil {
out.WriteString("\tpath: ")
out.WriteString(r.Path.Regexp.String())
out.WriteRune('\n')
}
out.WriteString("\tservice: ")
out.WriteString(r.Service.String())
return out.String()
}
// Matches checks if the rule matches a given hostname/path combination.
func (r *Rule) Matches(hostname, path string) bool {
hostMatch := r.Hostname == "" || r.Hostname == "*" || matchHost(r.Hostname, hostname)
pathMatch := r.Path == nil || r.Path.Regexp == nil || r.Path.Regexp.MatchString(path)
return hostMatch && pathMatch
}
// Regexp adds unmarshalling from json for regexp.Regexp
type Regexp struct {
*regexp.Regexp
}
func (r *Regexp) MarshalJSON() ([]byte, error) {
if r.Regexp == nil {
return json.Marshal(nil)
}
return json.Marshal(r.Regexp.String())
}