origin_request_config.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. package ingress
  2. import (
  3. "time"
  4. "github.com/cloudflare/cloudflared/ipaccess"
  5. "github.com/urfave/cli/v2"
  6. "github.com/cloudflare/cloudflared/config"
  7. "github.com/cloudflare/cloudflared/tlsconfig"
  8. )
  9. const (
  10. defaultConnectTimeout = 30 * time.Second
  11. defaultTLSTimeout = 10 * time.Second
  12. defaultTCPKeepAlive = 30 * time.Second
  13. defaultKeepAliveConnections = 100
  14. defaultKeepAliveTimeout = 90 * time.Second
  15. defaultProxyAddress = "127.0.0.1"
  16. SSHServerFlag = "ssh-server"
  17. Socks5Flag = "socks5"
  18. ProxyConnectTimeoutFlag = "proxy-connect-timeout"
  19. ProxyTLSTimeoutFlag = "proxy-tls-timeout"
  20. ProxyTCPKeepAlive = "proxy-tcp-keepalive"
  21. ProxyNoHappyEyeballsFlag = "proxy-no-happy-eyeballs"
  22. ProxyKeepAliveConnectionsFlag = "proxy-keepalive-connections"
  23. ProxyKeepAliveTimeoutFlag = "proxy-keepalive-timeout"
  24. HTTPHostHeaderFlag = "http-host-header"
  25. OriginServerNameFlag = "origin-server-name"
  26. NoTLSVerifyFlag = "no-tls-verify"
  27. NoChunkedEncodingFlag = "no-chunked-encoding"
  28. ProxyAddressFlag = "proxy-address"
  29. ProxyPortFlag = "proxy-port"
  30. )
  31. const (
  32. socksProxy = "socks"
  33. )
  34. func originRequestFromSingeRule(c *cli.Context) OriginRequestConfig {
  35. var connectTimeout time.Duration = defaultConnectTimeout
  36. var tlsTimeout time.Duration = defaultTLSTimeout
  37. var tcpKeepAlive time.Duration = defaultTCPKeepAlive
  38. var noHappyEyeballs bool
  39. var keepAliveConnections int = defaultKeepAliveConnections
  40. var keepAliveTimeout time.Duration = defaultKeepAliveTimeout
  41. var httpHostHeader string
  42. var originServerName string
  43. var caPool string
  44. var noTLSVerify bool
  45. var disableChunkedEncoding bool
  46. var bastionMode bool
  47. var proxyAddress = defaultProxyAddress
  48. var proxyPort uint
  49. var proxyType string
  50. if flag := ProxyConnectTimeoutFlag; c.IsSet(flag) {
  51. connectTimeout = c.Duration(flag)
  52. }
  53. if flag := ProxyTLSTimeoutFlag; c.IsSet(flag) {
  54. tlsTimeout = c.Duration(flag)
  55. }
  56. if flag := ProxyTCPKeepAlive; c.IsSet(flag) {
  57. tcpKeepAlive = c.Duration(flag)
  58. }
  59. if flag := ProxyNoHappyEyeballsFlag; c.IsSet(flag) {
  60. noHappyEyeballs = c.Bool(flag)
  61. }
  62. if flag := ProxyKeepAliveConnectionsFlag; c.IsSet(flag) {
  63. keepAliveConnections = c.Int(flag)
  64. }
  65. if flag := ProxyKeepAliveTimeoutFlag; c.IsSet(flag) {
  66. keepAliveTimeout = c.Duration(flag)
  67. }
  68. if flag := HTTPHostHeaderFlag; c.IsSet(flag) {
  69. httpHostHeader = c.String(flag)
  70. }
  71. if flag := OriginServerNameFlag; c.IsSet(flag) {
  72. originServerName = c.String(flag)
  73. }
  74. if flag := tlsconfig.OriginCAPoolFlag; c.IsSet(flag) {
  75. caPool = c.String(flag)
  76. }
  77. if flag := NoTLSVerifyFlag; c.IsSet(flag) {
  78. noTLSVerify = c.Bool(flag)
  79. }
  80. if flag := NoChunkedEncodingFlag; c.IsSet(flag) {
  81. disableChunkedEncoding = c.Bool(flag)
  82. }
  83. if flag := config.BastionFlag; c.IsSet(flag) {
  84. bastionMode = c.Bool(flag)
  85. }
  86. if flag := ProxyAddressFlag; c.IsSet(flag) {
  87. proxyAddress = c.String(flag)
  88. }
  89. if flag := ProxyPortFlag; c.IsSet(flag) {
  90. // Note TUN-3758 , we use Int because UInt is not supported with altsrc
  91. proxyPort = uint(c.Int(flag))
  92. }
  93. if c.IsSet(Socks5Flag) {
  94. proxyType = socksProxy
  95. }
  96. return OriginRequestConfig{
  97. ConnectTimeout: connectTimeout,
  98. TLSTimeout: tlsTimeout,
  99. TCPKeepAlive: tcpKeepAlive,
  100. NoHappyEyeballs: noHappyEyeballs,
  101. KeepAliveConnections: keepAliveConnections,
  102. KeepAliveTimeout: keepAliveTimeout,
  103. HTTPHostHeader: httpHostHeader,
  104. OriginServerName: originServerName,
  105. CAPool: caPool,
  106. NoTLSVerify: noTLSVerify,
  107. DisableChunkedEncoding: disableChunkedEncoding,
  108. BastionMode: bastionMode,
  109. ProxyAddress: proxyAddress,
  110. ProxyPort: proxyPort,
  111. ProxyType: proxyType,
  112. }
  113. }
  114. func originRequestFromYAML(y config.OriginRequestConfig) OriginRequestConfig {
  115. out := OriginRequestConfig{
  116. ConnectTimeout: defaultConnectTimeout,
  117. TLSTimeout: defaultTLSTimeout,
  118. TCPKeepAlive: defaultTCPKeepAlive,
  119. KeepAliveConnections: defaultKeepAliveConnections,
  120. KeepAliveTimeout: defaultKeepAliveTimeout,
  121. ProxyAddress: defaultProxyAddress,
  122. }
  123. if y.ConnectTimeout != nil {
  124. out.ConnectTimeout = *y.ConnectTimeout
  125. }
  126. if y.TLSTimeout != nil {
  127. out.TLSTimeout = *y.TLSTimeout
  128. }
  129. if y.TCPKeepAlive != nil {
  130. out.TCPKeepAlive = *y.TCPKeepAlive
  131. }
  132. if y.NoHappyEyeballs != nil {
  133. out.NoHappyEyeballs = *y.NoHappyEyeballs
  134. }
  135. if y.KeepAliveConnections != nil {
  136. out.KeepAliveConnections = *y.KeepAliveConnections
  137. }
  138. if y.KeepAliveTimeout != nil {
  139. out.KeepAliveTimeout = *y.KeepAliveTimeout
  140. }
  141. if y.HTTPHostHeader != nil {
  142. out.HTTPHostHeader = *y.HTTPHostHeader
  143. }
  144. if y.OriginServerName != nil {
  145. out.OriginServerName = *y.OriginServerName
  146. }
  147. if y.CAPool != nil {
  148. out.CAPool = *y.CAPool
  149. }
  150. if y.NoTLSVerify != nil {
  151. out.NoTLSVerify = *y.NoTLSVerify
  152. }
  153. if y.DisableChunkedEncoding != nil {
  154. out.DisableChunkedEncoding = *y.DisableChunkedEncoding
  155. }
  156. if y.BastionMode != nil {
  157. out.BastionMode = *y.BastionMode
  158. }
  159. if y.ProxyAddress != nil {
  160. out.ProxyAddress = *y.ProxyAddress
  161. }
  162. if y.ProxyPort != nil {
  163. out.ProxyPort = *y.ProxyPort
  164. }
  165. if y.ProxyType != nil {
  166. out.ProxyType = *y.ProxyType
  167. }
  168. return out
  169. }
  170. // OriginRequestConfig configures how Cloudflared sends requests to origin
  171. // services.
  172. // Note: To specify a time.Duration in go-yaml, use e.g. "3s" or "24h".
  173. type OriginRequestConfig struct {
  174. // HTTP proxy timeout for establishing a new connection
  175. ConnectTimeout time.Duration `yaml:"connectTimeout"`
  176. // HTTP proxy timeout for completing a TLS handshake
  177. TLSTimeout time.Duration `yaml:"tlsTimeout"`
  178. // HTTP proxy TCP keepalive duration
  179. TCPKeepAlive time.Duration `yaml:"tcpKeepAlive"`
  180. // HTTP proxy should disable "happy eyeballs" for IPv4/v6 fallback
  181. NoHappyEyeballs bool `yaml:"noHappyEyeballs"`
  182. // HTTP proxy maximum keepalive connection pool size
  183. KeepAliveConnections int `yaml:"keepAliveConnections"`
  184. // HTTP proxy timeout for closing an idle connection
  185. KeepAliveTimeout time.Duration `yaml:"keepAliveTimeout"`
  186. // Sets the HTTP Host header for the local webserver.
  187. HTTPHostHeader string `yaml:"httpHostHeader"`
  188. // Hostname on the origin server certificate.
  189. OriginServerName string `yaml:"originServerName"`
  190. // Path to the CA for the certificate of your origin.
  191. // This option should be used only if your certificate is not signed by Cloudflare.
  192. CAPool string `yaml:"caPool"`
  193. // Disables TLS verification of the certificate presented by your origin.
  194. // Will allow any certificate from the origin to be accepted.
  195. // Note: The connection from your machine to Cloudflare's Edge is still encrypted.
  196. NoTLSVerify bool `yaml:"noTLSVerify"`
  197. // Disables chunked transfer encoding.
  198. // Useful if you are running a WSGI server.
  199. DisableChunkedEncoding bool `yaml:"disableChunkedEncoding"`
  200. // Runs as jump host
  201. BastionMode bool `yaml:"bastionMode"`
  202. // Listen address for the proxy.
  203. ProxyAddress string `yaml:"proxyAddress"`
  204. // Listen port for the proxy.
  205. ProxyPort uint `yaml:"proxyPort"`
  206. // What sort of proxy should be started
  207. ProxyType string `yaml:"proxyType"`
  208. // IP rules for the proxy service
  209. IPRules []ipaccess.Rule `yaml:"ipRules"`
  210. }
  211. func (defaults *OriginRequestConfig) setConnectTimeout(overrides config.OriginRequestConfig) {
  212. if val := overrides.ConnectTimeout; val != nil {
  213. defaults.ConnectTimeout = *val
  214. }
  215. }
  216. func (defaults *OriginRequestConfig) setTLSTimeout(overrides config.OriginRequestConfig) {
  217. if val := overrides.TLSTimeout; val != nil {
  218. defaults.TLSTimeout = *val
  219. }
  220. }
  221. func (defaults *OriginRequestConfig) setNoHappyEyeballs(overrides config.OriginRequestConfig) {
  222. if val := overrides.NoHappyEyeballs; val != nil {
  223. defaults.NoHappyEyeballs = *val
  224. }
  225. }
  226. func (defaults *OriginRequestConfig) setKeepAliveConnections(overrides config.OriginRequestConfig) {
  227. if val := overrides.KeepAliveConnections; val != nil {
  228. defaults.KeepAliveConnections = *val
  229. }
  230. }
  231. func (defaults *OriginRequestConfig) setKeepAliveTimeout(overrides config.OriginRequestConfig) {
  232. if val := overrides.KeepAliveTimeout; val != nil {
  233. defaults.KeepAliveTimeout = *val
  234. }
  235. }
  236. func (defaults *OriginRequestConfig) setTCPKeepAlive(overrides config.OriginRequestConfig) {
  237. if val := overrides.TCPKeepAlive; val != nil {
  238. defaults.TCPKeepAlive = *val
  239. }
  240. }
  241. func (defaults *OriginRequestConfig) setHTTPHostHeader(overrides config.OriginRequestConfig) {
  242. if val := overrides.HTTPHostHeader; val != nil {
  243. defaults.HTTPHostHeader = *val
  244. }
  245. }
  246. func (defaults *OriginRequestConfig) setOriginServerName(overrides config.OriginRequestConfig) {
  247. if val := overrides.OriginServerName; val != nil {
  248. defaults.OriginServerName = *val
  249. }
  250. }
  251. func (defaults *OriginRequestConfig) setCAPool(overrides config.OriginRequestConfig) {
  252. if val := overrides.CAPool; val != nil {
  253. defaults.CAPool = *val
  254. }
  255. }
  256. func (defaults *OriginRequestConfig) setNoTLSVerify(overrides config.OriginRequestConfig) {
  257. if val := overrides.NoTLSVerify; val != nil {
  258. defaults.NoTLSVerify = *val
  259. }
  260. }
  261. func (defaults *OriginRequestConfig) setDisableChunkedEncoding(overrides config.OriginRequestConfig) {
  262. if val := overrides.DisableChunkedEncoding; val != nil {
  263. defaults.DisableChunkedEncoding = *val
  264. }
  265. }
  266. func (defaults *OriginRequestConfig) setBastionMode(overrides config.OriginRequestConfig) {
  267. if val := overrides.BastionMode; val != nil {
  268. defaults.BastionMode = *val
  269. }
  270. }
  271. func (defaults *OriginRequestConfig) setProxyPort(overrides config.OriginRequestConfig) {
  272. if val := overrides.ProxyPort; val != nil {
  273. defaults.ProxyPort = *val
  274. }
  275. }
  276. func (defaults *OriginRequestConfig) setProxyAddress(overrides config.OriginRequestConfig) {
  277. if val := overrides.ProxyAddress; val != nil {
  278. defaults.ProxyAddress = *val
  279. }
  280. }
  281. func (defaults *OriginRequestConfig) setProxyType(overrides config.OriginRequestConfig) {
  282. if val := overrides.ProxyType; val != nil {
  283. defaults.ProxyType = *val
  284. }
  285. }
  286. // SetConfig gets config for the requests that cloudflared sends to origins.
  287. // Each field has a setter method which sets a value for the field by trying to find:
  288. // 1. The user config for this rule
  289. // 2. The user config for the overall ingress config
  290. // 3. Defaults chosen by the cloudflared team
  291. // 4. Golang zero values for that type
  292. // If an earlier option isn't set, it will try the next option down.
  293. func setConfig(defaults OriginRequestConfig, overrides config.OriginRequestConfig) OriginRequestConfig {
  294. cfg := defaults
  295. cfg.setConnectTimeout(overrides)
  296. cfg.setTLSTimeout(overrides)
  297. cfg.setNoHappyEyeballs(overrides)
  298. cfg.setKeepAliveConnections(overrides)
  299. cfg.setKeepAliveTimeout(overrides)
  300. cfg.setTCPKeepAlive(overrides)
  301. cfg.setHTTPHostHeader(overrides)
  302. cfg.setOriginServerName(overrides)
  303. cfg.setCAPool(overrides)
  304. cfg.setNoTLSVerify(overrides)
  305. cfg.setDisableChunkedEncoding(overrides)
  306. cfg.setBastionMode(overrides)
  307. cfg.setProxyPort(overrides)
  308. cfg.setProxyAddress(overrides)
  309. cfg.setProxyType(overrides)
  310. return cfg
  311. }