mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 20:50:00 +00:00
TUN-5702: Allow to deserialize config from JSON
This commit is contained in:
387
ingress/config.go
Normal file
387
ingress/config.go
Normal file
@@ -0,0 +1,387 @@
|
||||
package ingress
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/cloudflare/cloudflared/config"
|
||||
"github.com/cloudflare/cloudflared/ipaccess"
|
||||
"github.com/cloudflare/cloudflared/tlsconfig"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultConnectTimeout = 30 * time.Second
|
||||
defaultTLSTimeout = 10 * time.Second
|
||||
defaultTCPKeepAlive = 30 * time.Second
|
||||
defaultKeepAliveConnections = 100
|
||||
defaultKeepAliveTimeout = 90 * time.Second
|
||||
defaultProxyAddress = "127.0.0.1"
|
||||
|
||||
SSHServerFlag = "ssh-server"
|
||||
Socks5Flag = "socks5"
|
||||
ProxyConnectTimeoutFlag = "proxy-connect-timeout"
|
||||
ProxyTLSTimeoutFlag = "proxy-tls-timeout"
|
||||
ProxyTCPKeepAliveFlag = "proxy-tcp-keepalive"
|
||||
ProxyNoHappyEyeballsFlag = "proxy-no-happy-eyeballs"
|
||||
ProxyKeepAliveConnectionsFlag = "proxy-keepalive-connections"
|
||||
ProxyKeepAliveTimeoutFlag = "proxy-keepalive-timeout"
|
||||
HTTPHostHeaderFlag = "http-host-header"
|
||||
OriginServerNameFlag = "origin-server-name"
|
||||
NoTLSVerifyFlag = "no-tls-verify"
|
||||
NoChunkedEncodingFlag = "no-chunked-encoding"
|
||||
ProxyAddressFlag = "proxy-address"
|
||||
ProxyPortFlag = "proxy-port"
|
||||
)
|
||||
|
||||
const (
|
||||
socksProxy = "socks"
|
||||
)
|
||||
|
||||
// RemoteConfig models ingress settings that can be managed remotely, for example through the dashboard.
|
||||
type RemoteConfig struct {
|
||||
Ingress Ingress
|
||||
WarpRouting config.WarpRoutingConfig
|
||||
}
|
||||
|
||||
type remoteConfigJSON struct {
|
||||
GlobalOriginRequest config.OriginRequestConfig `json:"originRequest"`
|
||||
IngressRules []config.UnvalidatedIngressRule `json:"ingress"`
|
||||
WarpRouting config.WarpRoutingConfig `json:"warp-routing"`
|
||||
}
|
||||
|
||||
func (rc *RemoteConfig) UnmarshalJSON(b []byte) error {
|
||||
var rawConfig remoteConfigJSON
|
||||
if err := json.Unmarshal(b, &rawConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
ingress, err := validateIngress(rawConfig.IngressRules, originRequestFromConfig(rawConfig.GlobalOriginRequest))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rc.Ingress = ingress
|
||||
rc.WarpRouting = rawConfig.WarpRouting
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func originRequestFromSingeRule(c *cli.Context) OriginRequestConfig {
|
||||
var connectTimeout time.Duration = defaultConnectTimeout
|
||||
var tlsTimeout time.Duration = defaultTLSTimeout
|
||||
var tcpKeepAlive time.Duration = defaultTCPKeepAlive
|
||||
var noHappyEyeballs bool
|
||||
var keepAliveConnections int = defaultKeepAliveConnections
|
||||
var keepAliveTimeout time.Duration = defaultKeepAliveTimeout
|
||||
var httpHostHeader string
|
||||
var originServerName string
|
||||
var caPool string
|
||||
var noTLSVerify bool
|
||||
var disableChunkedEncoding bool
|
||||
var bastionMode bool
|
||||
var proxyAddress = defaultProxyAddress
|
||||
var proxyPort uint
|
||||
var proxyType string
|
||||
if flag := ProxyConnectTimeoutFlag; c.IsSet(flag) {
|
||||
connectTimeout = c.Duration(flag)
|
||||
}
|
||||
if flag := ProxyTLSTimeoutFlag; c.IsSet(flag) {
|
||||
tlsTimeout = c.Duration(flag)
|
||||
}
|
||||
if flag := ProxyTCPKeepAliveFlag; c.IsSet(flag) {
|
||||
tcpKeepAlive = c.Duration(flag)
|
||||
}
|
||||
if flag := ProxyNoHappyEyeballsFlag; c.IsSet(flag) {
|
||||
noHappyEyeballs = c.Bool(flag)
|
||||
}
|
||||
if flag := ProxyKeepAliveConnectionsFlag; c.IsSet(flag) {
|
||||
keepAliveConnections = c.Int(flag)
|
||||
}
|
||||
if flag := ProxyKeepAliveTimeoutFlag; c.IsSet(flag) {
|
||||
keepAliveTimeout = c.Duration(flag)
|
||||
}
|
||||
if flag := HTTPHostHeaderFlag; c.IsSet(flag) {
|
||||
httpHostHeader = c.String(flag)
|
||||
}
|
||||
if flag := OriginServerNameFlag; c.IsSet(flag) {
|
||||
originServerName = c.String(flag)
|
||||
}
|
||||
if flag := tlsconfig.OriginCAPoolFlag; c.IsSet(flag) {
|
||||
caPool = c.String(flag)
|
||||
}
|
||||
if flag := NoTLSVerifyFlag; c.IsSet(flag) {
|
||||
noTLSVerify = c.Bool(flag)
|
||||
}
|
||||
if flag := NoChunkedEncodingFlag; c.IsSet(flag) {
|
||||
disableChunkedEncoding = c.Bool(flag)
|
||||
}
|
||||
if flag := config.BastionFlag; c.IsSet(flag) {
|
||||
bastionMode = c.Bool(flag)
|
||||
}
|
||||
if flag := ProxyAddressFlag; c.IsSet(flag) {
|
||||
proxyAddress = c.String(flag)
|
||||
}
|
||||
if flag := ProxyPortFlag; c.IsSet(flag) {
|
||||
// Note TUN-3758 , we use Int because UInt is not supported with altsrc
|
||||
proxyPort = uint(c.Int(flag))
|
||||
}
|
||||
if c.IsSet(Socks5Flag) {
|
||||
proxyType = socksProxy
|
||||
}
|
||||
return OriginRequestConfig{
|
||||
ConnectTimeout: connectTimeout,
|
||||
TLSTimeout: tlsTimeout,
|
||||
TCPKeepAlive: tcpKeepAlive,
|
||||
NoHappyEyeballs: noHappyEyeballs,
|
||||
KeepAliveConnections: keepAliveConnections,
|
||||
KeepAliveTimeout: keepAliveTimeout,
|
||||
HTTPHostHeader: httpHostHeader,
|
||||
OriginServerName: originServerName,
|
||||
CAPool: caPool,
|
||||
NoTLSVerify: noTLSVerify,
|
||||
DisableChunkedEncoding: disableChunkedEncoding,
|
||||
BastionMode: bastionMode,
|
||||
ProxyAddress: proxyAddress,
|
||||
ProxyPort: proxyPort,
|
||||
ProxyType: proxyType,
|
||||
}
|
||||
}
|
||||
|
||||
func originRequestFromConfig(c config.OriginRequestConfig) OriginRequestConfig {
|
||||
out := OriginRequestConfig{
|
||||
ConnectTimeout: defaultConnectTimeout,
|
||||
TLSTimeout: defaultTLSTimeout,
|
||||
TCPKeepAlive: defaultTCPKeepAlive,
|
||||
KeepAliveConnections: defaultKeepAliveConnections,
|
||||
KeepAliveTimeout: defaultKeepAliveTimeout,
|
||||
ProxyAddress: defaultProxyAddress,
|
||||
}
|
||||
if c.ConnectTimeout != nil {
|
||||
out.ConnectTimeout = *c.ConnectTimeout
|
||||
}
|
||||
if c.TLSTimeout != nil {
|
||||
out.TLSTimeout = *c.TLSTimeout
|
||||
}
|
||||
if c.TCPKeepAlive != nil {
|
||||
out.TCPKeepAlive = *c.TCPKeepAlive
|
||||
}
|
||||
if c.NoHappyEyeballs != nil {
|
||||
out.NoHappyEyeballs = *c.NoHappyEyeballs
|
||||
}
|
||||
if c.KeepAliveConnections != nil {
|
||||
out.KeepAliveConnections = *c.KeepAliveConnections
|
||||
}
|
||||
if c.KeepAliveTimeout != nil {
|
||||
out.KeepAliveTimeout = *c.KeepAliveTimeout
|
||||
}
|
||||
if c.HTTPHostHeader != nil {
|
||||
out.HTTPHostHeader = *c.HTTPHostHeader
|
||||
}
|
||||
if c.OriginServerName != nil {
|
||||
out.OriginServerName = *c.OriginServerName
|
||||
}
|
||||
if c.CAPool != nil {
|
||||
out.CAPool = *c.CAPool
|
||||
}
|
||||
if c.NoTLSVerify != nil {
|
||||
out.NoTLSVerify = *c.NoTLSVerify
|
||||
}
|
||||
if c.DisableChunkedEncoding != nil {
|
||||
out.DisableChunkedEncoding = *c.DisableChunkedEncoding
|
||||
}
|
||||
if c.BastionMode != nil {
|
||||
out.BastionMode = *c.BastionMode
|
||||
}
|
||||
if c.ProxyAddress != nil {
|
||||
out.ProxyAddress = *c.ProxyAddress
|
||||
}
|
||||
if c.ProxyPort != nil {
|
||||
out.ProxyPort = *c.ProxyPort
|
||||
}
|
||||
if c.ProxyType != nil {
|
||||
out.ProxyType = *c.ProxyType
|
||||
}
|
||||
if len(c.IPRules) > 0 {
|
||||
for _, r := range c.IPRules {
|
||||
rule, err := ipaccess.NewRuleByCIDR(r.Prefix, r.Ports, r.Allow)
|
||||
if err == nil {
|
||||
out.IPRules = append(out.IPRules, rule)
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// OriginRequestConfig configures how Cloudflared sends requests to origin
|
||||
// services.
|
||||
// Note: To specify a time.Duration in go-yaml, use e.g. "3s" or "24h".
|
||||
type OriginRequestConfig struct {
|
||||
// HTTP proxy timeout for establishing a new connection
|
||||
ConnectTimeout time.Duration `yaml:"connectTimeout"`
|
||||
// HTTP proxy timeout for completing a TLS handshake
|
||||
TLSTimeout time.Duration `yaml:"tlsTimeout"`
|
||||
// HTTP proxy TCP keepalive duration
|
||||
TCPKeepAlive time.Duration `yaml:"tcpKeepAlive"`
|
||||
// HTTP proxy should disable "happy eyeballs" for IPv4/v6 fallback
|
||||
NoHappyEyeballs bool `yaml:"noHappyEyeballs"`
|
||||
// HTTP proxy timeout for closing an idle connection
|
||||
KeepAliveTimeout time.Duration `yaml:"keepAliveTimeout"`
|
||||
// HTTP proxy maximum keepalive connection pool size
|
||||
KeepAliveConnections int `yaml:"keepAliveConnections"`
|
||||
// Sets the HTTP Host header for the local webserver.
|
||||
HTTPHostHeader string `yaml:"httpHostHeader"`
|
||||
// Hostname on the origin server certificate.
|
||||
OriginServerName string `yaml:"originServerName"`
|
||||
// Path to the CA for the certificate of your origin.
|
||||
// This option should be used only if your certificate is not signed by Cloudflare.
|
||||
CAPool string `yaml:"caPool"`
|
||||
// Disables TLS verification of the certificate presented by your origin.
|
||||
// Will allow any certificate from the origin to be accepted.
|
||||
// Note: The connection from your machine to Cloudflare's Edge is still encrypted.
|
||||
NoTLSVerify bool `yaml:"noTLSVerify"`
|
||||
// Disables chunked transfer encoding.
|
||||
// Useful if you are running a WSGI server.
|
||||
DisableChunkedEncoding bool `yaml:"disableChunkedEncoding"`
|
||||
// Runs as jump host
|
||||
BastionMode bool `yaml:"bastionMode"`
|
||||
// Listen address for the proxy.
|
||||
ProxyAddress string `yaml:"proxyAddress"`
|
||||
// Listen port for the proxy.
|
||||
ProxyPort uint `yaml:"proxyPort"`
|
||||
// What sort of proxy should be started
|
||||
ProxyType string `yaml:"proxyType"`
|
||||
// IP rules for the proxy service
|
||||
IPRules []ipaccess.Rule `yaml:"ipRules"`
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setConnectTimeout(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.ConnectTimeout; val != nil {
|
||||
defaults.ConnectTimeout = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setTLSTimeout(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.TLSTimeout; val != nil {
|
||||
defaults.TLSTimeout = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setNoHappyEyeballs(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.NoHappyEyeballs; val != nil {
|
||||
defaults.NoHappyEyeballs = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setKeepAliveConnections(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.KeepAliveConnections; val != nil {
|
||||
defaults.KeepAliveConnections = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setKeepAliveTimeout(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.KeepAliveTimeout; val != nil {
|
||||
defaults.KeepAliveTimeout = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setTCPKeepAlive(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.TCPKeepAlive; val != nil {
|
||||
defaults.TCPKeepAlive = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setHTTPHostHeader(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.HTTPHostHeader; val != nil {
|
||||
defaults.HTTPHostHeader = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setOriginServerName(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.OriginServerName; val != nil {
|
||||
defaults.OriginServerName = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setCAPool(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.CAPool; val != nil {
|
||||
defaults.CAPool = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setNoTLSVerify(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.NoTLSVerify; val != nil {
|
||||
defaults.NoTLSVerify = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setDisableChunkedEncoding(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.DisableChunkedEncoding; val != nil {
|
||||
defaults.DisableChunkedEncoding = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setBastionMode(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.BastionMode; val != nil {
|
||||
defaults.BastionMode = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setProxyPort(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.ProxyPort; val != nil {
|
||||
defaults.ProxyPort = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setProxyAddress(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.ProxyAddress; val != nil {
|
||||
defaults.ProxyAddress = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setProxyType(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.ProxyType; val != nil {
|
||||
defaults.ProxyType = *val
|
||||
}
|
||||
}
|
||||
|
||||
func (defaults *OriginRequestConfig) setIPRules(overrides config.OriginRequestConfig) {
|
||||
if val := overrides.IPRules; len(val) > 0 {
|
||||
ipAccessRule := make([]ipaccess.Rule, len(overrides.IPRules))
|
||||
for i, r := range overrides.IPRules {
|
||||
rule, err := ipaccess.NewRuleByCIDR(r.Prefix, r.Ports, r.Allow)
|
||||
if err == nil {
|
||||
ipAccessRule[i] = rule
|
||||
}
|
||||
}
|
||||
defaults.IPRules = ipAccessRule
|
||||
}
|
||||
}
|
||||
|
||||
// SetConfig gets config for the requests that cloudflared sends to origins.
|
||||
// Each field has a setter method which sets a value for the field by trying to find:
|
||||
// 1. The user config for this rule
|
||||
// 2. The user config for the overall ingress config
|
||||
// 3. Defaults chosen by the cloudflared team
|
||||
// 4. Golang zero values for that type
|
||||
// If an earlier option isn't set, it will try the next option down.
|
||||
func setConfig(defaults OriginRequestConfig, overrides config.OriginRequestConfig) OriginRequestConfig {
|
||||
cfg := defaults
|
||||
cfg.setConnectTimeout(overrides)
|
||||
cfg.setTLSTimeout(overrides)
|
||||
cfg.setNoHappyEyeballs(overrides)
|
||||
cfg.setKeepAliveConnections(overrides)
|
||||
cfg.setKeepAliveTimeout(overrides)
|
||||
cfg.setTCPKeepAlive(overrides)
|
||||
cfg.setHTTPHostHeader(overrides)
|
||||
cfg.setOriginServerName(overrides)
|
||||
cfg.setCAPool(overrides)
|
||||
cfg.setNoTLSVerify(overrides)
|
||||
cfg.setDisableChunkedEncoding(overrides)
|
||||
cfg.setBastionMode(overrides)
|
||||
cfg.setProxyPort(overrides)
|
||||
cfg.setProxyAddress(overrides)
|
||||
cfg.setProxyType(overrides)
|
||||
cfg.setIPRules(overrides)
|
||||
return cfg
|
||||
}
|
Reference in New Issue
Block a user