serve.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package ipn
  4. // ServeConfigKey returns a StateKey that stores the
  5. // JSON-encoded ServeConfig for a config profile.
  6. func ServeConfigKey(profileID ProfileID) StateKey {
  7. return StateKey("_serve/" + profileID)
  8. }
  9. // ServeConfig is the JSON type stored in the StateStore for
  10. // StateKey "_serve/$PROFILE_ID" as returned by ServeConfigKey.
  11. type ServeConfig struct {
  12. // TCP are the list of TCP port numbers that tailscaled should handle for
  13. // the Tailscale IP addresses. (not subnet routers, etc)
  14. TCP map[uint16]*TCPPortHandler `json:",omitempty"`
  15. // Web maps from "$SNI_NAME:$PORT" to a set of HTTP handlers
  16. // keyed by mount point ("/", "/foo", etc)
  17. Web map[HostPort]*WebServerConfig `json:",omitempty"`
  18. // AllowFunnel is the set of SNI:port values for which funnel
  19. // traffic is allowed, from trusted ingress peers.
  20. AllowFunnel map[HostPort]bool `json:",omitempty"`
  21. }
  22. // HostPort is an SNI name and port number, joined by a colon.
  23. // There is no implicit port 443. It must contain a colon.
  24. type HostPort string
  25. // WebServerConfig describes a web server's configuration.
  26. type WebServerConfig struct {
  27. Handlers map[string]*HTTPHandler // mountPoint => handler
  28. }
  29. // TCPPortHandler describes what to do when handling a TCP
  30. // connection.
  31. type TCPPortHandler struct {
  32. // HTTPS, if true, means that tailscaled should handle this connection as an
  33. // HTTPS request as configured by ServeConfig.Web.
  34. //
  35. // It is mutually exclusive with TCPForward.
  36. HTTPS bool `json:",omitempty"`
  37. // TCPForward is the IP:port to forward TCP connections to.
  38. // Whether or not TLS is terminated by tailscaled depends on
  39. // TerminateTLS.
  40. //
  41. // It is mutually exclusive with HTTPS.
  42. TCPForward string `json:",omitempty"`
  43. // TerminateTLS, if non-empty, means that tailscaled should terminate the
  44. // TLS connections before forwarding them to TCPForward, permitting only the
  45. // SNI name with this value. It is only used if TCPForward is non-empty.
  46. // (the HTTPS mode uses ServeConfig.Web)
  47. TerminateTLS string `json:",omitempty"`
  48. }
  49. // HTTPHandler is either a path or a proxy to serve.
  50. type HTTPHandler struct {
  51. // Exactly one of the following may be set.
  52. Path string `json:",omitempty"` // absolute path to directory or file to serve
  53. Proxy string `json:",omitempty"` // http://localhost:3000/, localhost:3030, 3030
  54. Text string `json:",omitempty"` // plaintext to serve (primarily for testing)
  55. // TODO(bradfitz): bool to not enumerate directories? TTL on mapping for
  56. // temporary ones? Error codes? Redirects?
  57. }
  58. // WebHandlerExists checks if the ServeConfig Web handler exists for
  59. // the given host:port and mount point.
  60. func (sc *ServeConfig) WebHandlerExists(hp HostPort, mount string) bool {
  61. h := sc.GetWebHandler(hp, mount)
  62. return h != nil
  63. }
  64. // GetWebHandler returns the HTTPHandler for the given host:port and mount point.
  65. // Returns nil if the handler does not exist.
  66. func (sc *ServeConfig) GetWebHandler(hp HostPort, mount string) *HTTPHandler {
  67. if sc == nil || sc.Web[hp] == nil {
  68. return nil
  69. }
  70. return sc.Web[hp].Handlers[mount]
  71. }
  72. // GetTCPPortHandler returns the TCPPortHandler for the given port.
  73. // If the port is not configured, nil is returned.
  74. func (sc *ServeConfig) GetTCPPortHandler(port uint16) *TCPPortHandler {
  75. if sc == nil {
  76. return nil
  77. }
  78. return sc.TCP[port]
  79. }
  80. // IsTCPForwardingAny checks if ServeConfig is currently forwarding
  81. // in TCPForward mode on any port.
  82. // This is exclusive of Web/HTTPS serving.
  83. func (sc *ServeConfig) IsTCPForwardingAny() bool {
  84. if sc == nil || len(sc.TCP) == 0 {
  85. return false
  86. }
  87. for _, h := range sc.TCP {
  88. if h.TCPForward != "" {
  89. return true
  90. }
  91. }
  92. return false
  93. }
  94. // IsTCPForwardingOnPort checks if ServeConfig is currently forwarding
  95. // in TCPForward mode on the given port.
  96. // This is exclusive of Web/HTTPS serving.
  97. func (sc *ServeConfig) IsTCPForwardingOnPort(port uint16) bool {
  98. if sc == nil || sc.TCP[port] == nil {
  99. return false
  100. }
  101. return !sc.TCP[port].HTTPS
  102. }
  103. // IsServingWeb checks if ServeConfig is currently serving
  104. // Web/HTTPS on the given port.
  105. // This is exclusive of TCPForwarding.
  106. func (sc *ServeConfig) IsServingWeb(port uint16) bool {
  107. if sc == nil || sc.TCP[port] == nil {
  108. return false
  109. }
  110. return sc.TCP[port].HTTPS
  111. }
  112. // IsFunnelOn checks if ServeConfig is currently allowing
  113. // funnel traffic for any host:port.
  114. func (sc *ServeConfig) IsFunnelOn() bool {
  115. if sc == nil {
  116. return false
  117. }
  118. for _, b := range sc.AllowFunnel {
  119. if b {
  120. return true
  121. }
  122. }
  123. return false
  124. }