2020-10-15 21:41:03 +00:00
|
|
|
package ingress
|
|
|
|
|
|
|
|
import (
|
2022-01-28 14:37:17 +00:00
|
|
|
"encoding/json"
|
2020-10-15 21:41:03 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/urfave/cli/v2"
|
2021-03-08 16:46:23 +00:00
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/config"
|
2021-03-23 14:30:43 +00:00
|
|
|
"github.com/cloudflare/cloudflared/ipaccess"
|
2021-03-08 16:46:23 +00:00
|
|
|
"github.com/cloudflare/cloudflared/tlsconfig"
|
2020-10-15 21:41:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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"
|
2021-05-06 20:10:47 +00:00
|
|
|
ProxyTCPKeepAliveFlag = "proxy-tcp-keepalive"
|
2020-10-15 21:41:03 +00:00
|
|
|
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"
|
|
|
|
)
|
|
|
|
|
2022-01-28 14:37:17 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2020-10-15 21:41:03 +00:00
|
|
|
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
|
2020-11-13 23:27:55 +00:00
|
|
|
var proxyAddress = defaultProxyAddress
|
2020-10-15 21:41:03 +00:00
|
|
|
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)
|
|
|
|
}
|
2021-05-06 20:10:47 +00:00
|
|
|
if flag := ProxyTCPKeepAliveFlag; c.IsSet(flag) {
|
2020-10-15 21:41:03 +00:00
|
|
|
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) {
|
2021-01-14 13:08:55 +00:00
|
|
|
// Note TUN-3758 , we use Int because UInt is not supported with altsrc
|
|
|
|
proxyPort = uint(c.Int(flag))
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-28 14:37:17 +00:00
|
|
|
func originRequestFromConfig(c config.OriginRequestConfig) OriginRequestConfig {
|
2020-10-15 21:41:03 +00:00
|
|
|
out := OriginRequestConfig{
|
|
|
|
ConnectTimeout: defaultConnectTimeout,
|
|
|
|
TLSTimeout: defaultTLSTimeout,
|
|
|
|
TCPKeepAlive: defaultTCPKeepAlive,
|
|
|
|
KeepAliveConnections: defaultKeepAliveConnections,
|
|
|
|
KeepAliveTimeout: defaultKeepAliveTimeout,
|
|
|
|
ProxyAddress: defaultProxyAddress,
|
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.ConnectTimeout != nil {
|
2022-03-08 16:10:24 +00:00
|
|
|
out.ConnectTimeout = c.ConnectTimeout.Duration
|
2022-01-28 14:37:17 +00:00
|
|
|
}
|
|
|
|
if c.TLSTimeout != nil {
|
2022-03-08 16:10:24 +00:00
|
|
|
out.TLSTimeout = c.TLSTimeout.Duration
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.TCPKeepAlive != nil {
|
2022-03-08 16:10:24 +00:00
|
|
|
out.TCPKeepAlive = c.TCPKeepAlive.Duration
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.NoHappyEyeballs != nil {
|
|
|
|
out.NoHappyEyeballs = *c.NoHappyEyeballs
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.KeepAliveConnections != nil {
|
|
|
|
out.KeepAliveConnections = *c.KeepAliveConnections
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.KeepAliveTimeout != nil {
|
2022-03-08 16:10:24 +00:00
|
|
|
out.KeepAliveTimeout = c.KeepAliveTimeout.Duration
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.HTTPHostHeader != nil {
|
|
|
|
out.HTTPHostHeader = *c.HTTPHostHeader
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.OriginServerName != nil {
|
|
|
|
out.OriginServerName = *c.OriginServerName
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.CAPool != nil {
|
|
|
|
out.CAPool = *c.CAPool
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.NoTLSVerify != nil {
|
|
|
|
out.NoTLSVerify = *c.NoTLSVerify
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.DisableChunkedEncoding != nil {
|
|
|
|
out.DisableChunkedEncoding = *c.DisableChunkedEncoding
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.BastionMode != nil {
|
|
|
|
out.BastionMode = *c.BastionMode
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.ProxyAddress != nil {
|
|
|
|
out.ProxyAddress = *c.ProxyAddress
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.ProxyPort != nil {
|
|
|
|
out.ProxyPort = *c.ProxyPort
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
if c.ProxyType != nil {
|
|
|
|
out.ProxyType = *c.ProxyType
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
2022-01-28 14:37:17 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
|
|
|
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"`
|
2022-01-28 14:37:17 +00:00
|
|
|
// HTTP proxy maximum keepalive connection pool size
|
|
|
|
KeepAliveConnections int `yaml:"keepAliveConnections"`
|
2020-10-15 21:41:03 +00:00
|
|
|
// 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"`
|
2021-03-01 22:26:37 +00:00
|
|
|
// IP rules for the proxy service
|
|
|
|
IPRules []ipaccess.Rule `yaml:"ipRules"`
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (defaults *OriginRequestConfig) setConnectTimeout(overrides config.OriginRequestConfig) {
|
|
|
|
if val := overrides.ConnectTimeout; val != nil {
|
2022-03-08 16:10:24 +00:00
|
|
|
defaults.ConnectTimeout = val.Duration
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (defaults *OriginRequestConfig) setTLSTimeout(overrides config.OriginRequestConfig) {
|
|
|
|
if val := overrides.TLSTimeout; val != nil {
|
2022-03-08 16:10:24 +00:00
|
|
|
defaults.TLSTimeout = val.Duration
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2022-03-08 16:10:24 +00:00
|
|
|
defaults.KeepAliveTimeout = val.Duration
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (defaults *OriginRequestConfig) setTCPKeepAlive(overrides config.OriginRequestConfig) {
|
|
|
|
if val := overrides.TCPKeepAlive; val != nil {
|
2022-03-08 16:10:24 +00:00
|
|
|
defaults.TCPKeepAlive = val.Duration
|
2020-10-15 21:41:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-28 14:37:17 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-15 21:41:03 +00:00
|
|
|
// 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.
|
2020-10-30 21:37:40 +00:00
|
|
|
func setConfig(defaults OriginRequestConfig, overrides config.OriginRequestConfig) OriginRequestConfig {
|
2020-10-15 21:41:03 +00:00
|
|
|
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)
|
2022-01-28 14:37:17 +00:00
|
|
|
cfg.setIPRules(overrides)
|
2020-10-15 21:41:03 +00:00
|
|
|
return cfg
|
|
|
|
}
|