Documentation ¶
Overview ¶
Package reversetunnel sets up persistent reverse tunnel between remote site and teleport proxy, when site agents dial to teleport proxy's socket and teleport proxy can connect to any server through this tunnel.
Copyright 2022 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Package reversetunnel provides interfaces for accessing remote clusters
via reverse tunnels and directly.
Reverse Tunnels
Proxy server Proxy agent Reverse tunnel +----------+ +---------+ | <----------------------+ | | | | |
+-----+----------+ +---------+-----+ | | | | | | | | +----------------+ +---------------+
Proxy Cluster "A" Proxy Cluster "B"
Reverse tunnel is established from a cluster "B" Proxy to the a cluster "A" proxy, and clients of the cluster "A" can access servers of the cluster "B" via reverse tunnel connection, even if the cluster "B" is behind the firewall.
Multiple Proxies and Revese Tunnels ¶
With multiple proxies behind the load balancer, proxy agents will eventually discover and establish connections to all proxies in cluster.
* Initially Proxy Agent connects to Proxy 1. * Proxy 1 starts sending information about all available proxies to the the Proxy Agent . This process is called "sending discovery request".
+----------+ | <--------+ | | | +----------+ | +-----------+ +----------+
Proxy 1 +-------------------------------+ | | | | | +-----------+ +----------+ Load Balancer Proxy Agent
+----------+ | | | | +----------+
Proxy 2
* Agent will use the discovery request to establish new connections and check if it has connected and "discovered" all the proxies specified
in the discovery request.
* Assuming that load balancer uses fair load balancing algorithm, agent will eventually discover and connect back to all the proxies.
+----------+ | <--------+ | | | +----------+ | +-----------+ +----------+
Proxy 1 +-------------------------------+ | | | | | | | +-----------+ +----------+ | Load Balancer Proxy Agent
+----------+ | | <--------+ | | +----------+
Proxy 2
Index ¶
- Constants
- func UseTunnel(logger *log.Logger, c *sshutils.ChConn) bool
- type Agent
- type AgentPool
- type AgentPoolConfig
- type AgentState
- type AgentStateCallback
- type ClusterGetter
- type Config
- type ConnectedProxyGetter
- type DialParams
- type FakeRemoteSite
- func (s *FakeRemoteSite) CachingAccessPoint() (auth.RemoteProxyAccessPoint, error)
- func (s *FakeRemoteSite) Close() error
- func (s *FakeRemoteSite) Dial(params DialParams) (net.Conn, error)
- func (s *FakeRemoteSite) DialCount() int64
- func (s *FakeRemoteSite) GetName() string
- func (s *FakeRemoteSite) ProxyConn() <-chan net.Conn
- type FakeServer
- type RemoteClusterTunnelManager
- type RemoteClusterTunnelManagerConfig
- type RemoteSite
- type Resolver
- type SSHClient
- type Server
- type ServerHandler
- type ServerHandlerToListener
- type Tunnel
- type TunnelAuthDialer
- type TunnelAuthDialerConfig
- type TunnelWithRoles
Constants ¶
const ( // LocalNode is a special non-resolvable address that indicates the request // wants to connect to a dialed back node. LocalNode = "@local-node" // RemoteAuthServer is a special non-resolvable address that indicates client // requests a connection to the remote auth server. RemoteAuthServer = "@remote-auth-server" // LocalKubernetes is a special non-resolvable address that indicates that clients // requests a connection to the kubernetes endpoint of the local proxy. // This has to be a valid domain name, so it lacks @ LocalKubernetes = "remote.kube.proxy." + constants.APIDomain // LocalWindowsDesktop is a special non-resolvable address that indicates // that clients requests a connection to the windows service endpoint of // the local proxy. // This has to be a valid domain name, so it lacks @ LocalWindowsDesktop = "remote.windows_desktop.proxy." + constants.APIDomain )
const ( // NoApplicationTunnel is the error message returned when application // reverse tunnel cannot be found. // // It usually happens when an app agent has shut down (or crashed) but // hasn't expired from the backend yet. NoApplicationTunnel = "could not find reverse tunnel, check that Application Service agent proxying this application is up and running" // NoDatabaseTunnel is the error message returned when database reverse // tunnel cannot be found. // // It usually happens when a database agent has shut down (or crashed) but // hasn't expired from the backend yet. NoDatabaseTunnel = "could not find reverse tunnel, check that Database Service agent proxying this database is up and running" )
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Agent ¶
type Agent interface { // Start starts the agent in the background. Start(context.Context) error // Stop closes the agent and releases resources. Stop() error // GetState returns the current state of the agent. GetState() AgentState // GetProxyID returns the proxy id of the proxy the agent is connected to. GetProxyID() (string, bool) }
Agent represents a reverse tunnel agent.
type AgentPool ¶ added in v1.0.0
type AgentPool struct { AgentPoolConfig // contains filtered or unexported fields }
AgentPool manages a pool of reverse tunnel agents.
func NewAgentPool ¶ added in v1.0.0
func NewAgentPool(ctx context.Context, config AgentPoolConfig) (*AgentPool, error)
NewAgentPool returns new instance of the agent pool.
func (*AgentPool) GetConnectedProxyGetter ¶
func (p *AgentPool) GetConnectedProxyGetter() *ConnectedProxyGetter
GetConnectedProxyGetter returns the ConnectedProxyGetter for this agent pool.
type AgentPoolConfig ¶ added in v1.0.0
type AgentPoolConfig struct { // Client is client to the auth server this agent connects to receive // a list of pools Client auth.ClientI // AccessPoint is a lightweight access point // that can optionally cache some values AccessPoint auth.AccessCache // HostSigner is a host signer this agent presents itself as HostSigner ssh.Signer // HostUUID is a unique ID of this host HostUUID string // LocalCluster is a cluster name this client is a member of. LocalCluster string // Clock is a clock used to get time, if not set, // system clock is used Clock clockwork.Clock // KubeDialAddr is an address of a kubernetes proxy KubeDialAddr utils.NetAddr // Server is either an SSH or application server. It can handle a connection // (perform handshake and handle request). Server ServerHandler // Component is the Teleport component this agent pool is running in. It can // either be proxy (trusted clusters) or node (dial back). Component string // ReverseTunnelServer holds all reverse tunnel connections. ReverseTunnelServer Server // Resolver retrieves the reverse tunnel address Resolver Resolver // Cluster is a cluster name of the proxy. Cluster string // FIPS indicates if Teleport was started in FIPS mode. FIPS bool // ProxiedServiceUpdater updates a proxied service with the proxies it is connected to. ConnectedProxyGetter *ConnectedProxyGetter // IsRemoteCluster indicates the agent pool is connecting to a remote cluster. // This means the tunnel strategy should be ignored and tls routing is determined // by the remote cluster. IsRemoteCluster bool // DisableCreateHostUser disables host user creation on a node. DisableCreateHostUser bool // LocalAuthAddresses is a list of auth servers to use when dialing back to // the local cluster. LocalAuthAddresses []string }
AgentPoolConfig holds configuration parameters for the agent pool
func (*AgentPoolConfig) CheckAndSetDefaults ¶
func (cfg *AgentPoolConfig) CheckAndSetDefaults() error
CheckAndSetDefaults checks and sets defaults.
type AgentState ¶
type AgentState string
const ( // AgentInitial is the state of an agent when first created. AgentInitial AgentState = "initial" // AgentConnecting is the state when an agent is starting but not yet connected. AgentConnecting AgentState = "connecting" // AgentConnected is the state of an agent when is successfully connects // to a server and sends its first heartbeat. AgentConnected AgentState = "connected" // AgentClosed is the state of an agent when the connection and all other // resources are cleaned up. AgentClosed AgentState = "closed" )
type AgentStateCallback ¶
type AgentStateCallback func(AgentState)
AgentStateCallback is called when an agent's state changes.
type ClusterGetter ¶
type ClusterGetter interface { // GetRemoteCluster returns a remote cluster by name GetRemoteCluster(clusterName string) (types.RemoteCluster, error) }
ClusterGetter is an interface that defines GetRemoteCluster method
type Config ¶
type Config struct { // ID is the ID of this server proxy ID string // ClusterName is a name of this cluster ClusterName string // ClientTLS is a TLS config associated with this proxy // used to connect to remote auth servers on remote clusters ClientTLS *tls.Config // Listener is a listener address for reverse tunnel server Listener net.Listener // HostSigners is a list of host signers HostSigners []ssh.Signer // HostKeyCallback // Limiter is optional request limiter Limiter *limiter.Limiter // LocalAuthClient provides access to a full AuthClient for the local cluster. LocalAuthClient auth.ClientI // AccessPoint provides access to a subset of AuthClient of the cluster. // AccessPoint caches values and can still return results during connection // problems. LocalAccessPoint auth.ProxyAccessPoint // NewCachingAccessPoint returns new caching access points // per remote cluster NewCachingAccessPoint auth.NewRemoteProxyCachingAccessPoint // Context is a signaling context Context context.Context // Clock is a clock used in the server, set up to // wall clock if not set Clock clockwork.Clock // KeyGen is a process wide key generator. It is shared to speed up // generation of public/private keypairs. KeyGen sshca.Authority // Ciphers is a list of ciphers that the server supports. If omitted, // the defaults will be used. Ciphers []string // KEXAlgorithms is a list of key exchange (KEX) algorithms that the // server supports. If omitted, the defaults will be used. KEXAlgorithms []string // MACAlgorithms is a list of message authentication codes (MAC) that // the server supports. If omitted the defaults will be used. MACAlgorithms []string // DataDir is a local server data directory DataDir string // PollingPeriod specifies polling period for internal sync // goroutines, used to speed up sync-ups in tests. PollingPeriod time.Duration // Component is a component used in logs Component string // Log specifies the logger Log log.FieldLogger // FIPS means Teleport was started in a FedRAMP/FIPS 140-2 compliant // configuration. FIPS bool // Emitter is event emitter Emitter events.StreamEmitter // DELETE IN: 8.0.0 // // NewCachingAccessPointOldProxy is an access point that can be configured // with the old access point policy until all clusters are migrated to 7.0.0 // and above. NewCachingAccessPointOldProxy auth.NewRemoteProxyCachingAccessPoint // PeerClient is a client to peer proxy servers. PeerClient *proxy.Client // LockWatcher is a lock watcher. LockWatcher *services.LockWatcher // NodeWatcher is a node watcher. NodeWatcher *services.NodeWatcher // CertAuthorityWatcher is a cert authority watcher. CertAuthorityWatcher *services.CertAuthorityWatcher // CircuitBreakerConfig configures the auth client circuit breaker CircuitBreakerConfig breaker.Config // LocalAuthAddresses is a list of auth servers to use when dialing back to // the local cluster. LocalAuthAddresses []string }
Config is a reverse tunnel server configuration
func (*Config) CheckAndSetDefaults ¶
CheckAndSetDefaults checks parameters and sets default values
type ConnectedProxyGetter ¶
type ConnectedProxyGetter struct {
// contains filtered or unexported fields
}
ConnectedProxyGetter gets the proxy ids that the a reverse tunnel pool is connected to. This is used to communicate the connected proxies between reversetunnel.AgentPool and service implementations to include the connected proxy ids in the service's heartbeats.
func NewConnectedProxyGetter ¶
func NewConnectedProxyGetter() *ConnectedProxyGetter
NewConnectedProxyGetter creates a new ConnectedProxyGetter instance.
func (*ConnectedProxyGetter) GetProxyIDs ¶
func (g *ConnectedProxyGetter) GetProxyIDs() []string
GetProxyIDs gets the list of connected proxy ids.
type DialParams ¶
type DialParams struct { // From is the source address. From net.Addr // To is the destination address. To net.Addr // GetUserAgent gets an SSH agent for use in connecting to the remote host. Used by the // forwarding proxy. GetUserAgent teleagent.Getter // Address is used by the forwarding proxy to generate a host certificate for // the target node. This is needed because while dialing occurs via IP // address, tsh thinks it's connecting via DNS name and that's how it // validates the host certificate. Address string // Principals are additional principals that need to be added to the host // certificate. Used by the recording proxy to correctly generate a host // certificate. Principals []string // ServerID the hostUUID.clusterName of a Teleport node. Used with nodes // that are connected over a reverse tunnel. ServerID string // ProxyIDs is a list of proxy ids the node is connected to. ProxyIDs []string // ConnType is the type of connection requested, either node or application. // Only used when connecting through a tunnel. ConnType types.TunnelType // FromPeerProxy indicates that the dial request is being tunneled from // a peer proxy. FromPeerProxy bool }
DialParams is a list of parameters used to Dial to a node within a cluster.
func (DialParams) String ¶
func (params DialParams) String() string
type FakeRemoteSite ¶
type FakeRemoteSite struct { RemoteSite // Name is the remote site name. Name string // AccessPoint is the auth server client. AccessPoint auth.RemoteProxyAccessPoint // OfflineTunnels is a list of server IDs that will return connection error. OfflineTunnels map[string]struct{} // contains filtered or unexported fields }
FakeRemoteSite is a fake reversetunnel.RemoteSite implementation used in tests.
func NewFakeRemoteSite ¶
func NewFakeRemoteSite(clusterName string, accessPoint auth.RemoteProxyAccessPoint) *FakeRemoteSite
NewFakeRemoteSite is a FakeRemoteSite constructor.
func (*FakeRemoteSite) CachingAccessPoint ¶
func (s *FakeRemoteSite) CachingAccessPoint() (auth.RemoteProxyAccessPoint, error)
CachingAccessPoint returns caching auth server client.
func (*FakeRemoteSite) Close ¶
func (s *FakeRemoteSite) Close() error
func (*FakeRemoteSite) Dial ¶
func (s *FakeRemoteSite) Dial(params DialParams) (net.Conn, error)
Dial returns the connection to the remote site.
func (*FakeRemoteSite) DialCount ¶
func (s *FakeRemoteSite) DialCount() int64
func (*FakeRemoteSite) GetName ¶
func (s *FakeRemoteSite) GetName() string
GetName returns the remote site name.
func (*FakeRemoteSite) ProxyConn ¶
func (s *FakeRemoteSite) ProxyConn() <-chan net.Conn
ProxyConn returns proxy connection channel with incoming connections.
type FakeServer ¶
type FakeServer struct { Server // Sites is a list of sites registered via this fake reverse tunnel. Sites []RemoteSite }
FakeServer is a fake reversetunnel.Server implementation used in tests.
func (*FakeServer) GetSite ¶
func (s *FakeServer) GetSite(name string) (RemoteSite, error)
GetSite returns the remote site by name.
func (*FakeServer) GetSites ¶
func (s *FakeServer) GetSites() ([]RemoteSite, error)
GetSites returns all available remote sites.
type RemoteClusterTunnelManager ¶
type RemoteClusterTunnelManager struct {
// contains filtered or unexported fields
}
RemoteClusterTunnelManager manages AgentPools for trusted (remote) clusters. It polls the auth server for ReverseTunnel resources and spins AgentPools for each one as needed.
Note: ReverseTunnel resources on the auth server represent the desired tunnels, not actually active ones.
func NewRemoteClusterTunnelManager ¶
func NewRemoteClusterTunnelManager(cfg RemoteClusterTunnelManagerConfig) (*RemoteClusterTunnelManager, error)
NewRemoteClusterTunnelManager creates a new stopped tunnel manager with the provided config. Call Run() to start the manager.
func (*RemoteClusterTunnelManager) Close ¶
func (w *RemoteClusterTunnelManager) Close() error
Close cleans up all outbound tunnels and stops the manager.
func (*RemoteClusterTunnelManager) Counts ¶
func (w *RemoteClusterTunnelManager) Counts() map[string]int
Counts returns the number of tunnels for each remote cluster.
func (*RemoteClusterTunnelManager) Run ¶
func (w *RemoteClusterTunnelManager) Run(ctx context.Context)
Run runs the manager polling loop. Run is blocking, start it in a goroutine.
type RemoteClusterTunnelManagerConfig ¶
type RemoteClusterTunnelManagerConfig struct { // AuthClient is client to the auth server. AuthClient auth.ClientI // AccessPoint is a lightweight access point that can optionally cache some // values. AccessPoint auth.ProxyAccessPoint // HostSigners is a signer for the host private key. HostSigner ssh.Signer // HostUUID is a unique ID of this host HostUUID string // LocalCluster is a cluster name this client is a member of. LocalCluster string // Local ReverseTunnelServer to reach other cluster members connecting to // this proxy over a tunnel. ReverseTunnelServer Server // Clock is a mock-able clock. Clock clockwork.Clock // KubeDialAddr is an optional address of a local kubernetes proxy. KubeDialAddr utils.NetAddr // FIPS indicates if Teleport was started in FIPS mode. FIPS bool // Log is the logger Log logrus.FieldLogger // LocalAuthAddresses is a list of auth servers to use when dialing back to // the local cluster. LocalAuthAddresses []string }
RemoteClusterTunnelManagerConfig is a bundle of parameters used by a RemoteClusterTunnelManager.
func (*RemoteClusterTunnelManagerConfig) CheckAndSetDefaults ¶
func (c *RemoteClusterTunnelManagerConfig) CheckAndSetDefaults() error
type RemoteSite ¶
type RemoteSite interface { // DialAuthServer returns a net.Conn to the Auth Server of a site. DialAuthServer() (net.Conn, error) // Dial dials any address within the site network, in terminating // mode it uses local instance of forwarding server to terminate // and record the connection Dial(DialParams) (net.Conn, error) // DialTCP dials any address within the site network, // ignores recording mode and always uses TCP dial, used // in components that need direct dialer. DialTCP(DialParams) (net.Conn, error) // GetLastConnected returns last time the remote site was seen connected GetLastConnected() time.Time // GetName returns site name (identified by authority domain's name) GetName() string // GetStatus returns status of this site (either offline or connected) GetStatus() string // GetClient returns client connected to remote auth server GetClient() (auth.ClientI, error) // CachingAccessPoint returns access point that is lightweight // but is resilient to auth server crashes CachingAccessPoint() (auth.RemoteProxyAccessPoint, error) // NodeWatcher returns the node watcher that maintains the node set for the site NodeWatcher() (*services.NodeWatcher, error) // GetTunnelsCount returns the amount of active inbound tunnels // from the remote cluster GetTunnelsCount() int // IsClosed reports whether this RemoteSite has been closed and should no // longer be used. IsClosed() bool // Closer allows the site to be closed io.Closer }
RemoteSite represents remote teleport site that can be accessed via teleport tunnel or directly by proxy
There are two implementations of this interface: local and remote sites.
type Resolver ¶
Resolver looks up reverse tunnel addresses
func CachingResolver ¶
func CachingResolver(ctx context.Context, resolver Resolver, clock clockwork.Clock) (Resolver, error)
CachingResolver wraps the provided Resolver with one that will cache the previous result for 3 seconds to reduce the number of resolutions in an effort to mitigate potentially overwhelming the Resolver source.
func StaticResolver ¶
func StaticResolver(address string, mode types.ProxyListenerMode) Resolver
StaticResolver returns a Resolver which will always resolve to the provided address
type SSHClient ¶
type SSHClient interface { ssh.ConnMetadata io.Closer Wait() error OpenChannel(ctx context.Context, name string, data []byte) (*tracessh.Channel, <-chan *ssh.Request, error) SendRequest(ctx context.Context, name string, wantReply bool, payload []byte) (bool, []byte, error) Principals() []string GlobalRequests() <-chan *ssh.Request HandleChannelOpen(channelType string) <-chan ssh.NewChannel Reply(*ssh.Request, bool, []byte) error }
SSHClient is a client for an ssh connection.
type Server ¶
type Server interface { Tunnel // Start starts server Start() error // Close closes server's operations immediately Close() error // DrainConnections closes listeners and begins draining connections without // closing open connections. DrainConnections(context.Context) error // Shutdown performs graceful server shutdown closing open connections. Shutdown(context.Context) error // Wait waits for server to close all outstanding operations Wait() // GetProxyPeerClient returns the proxy peer client GetProxyPeerClient() *proxy.Client }
Server is a TCP/IP SSH server which listens on an SSH endpoint and remote/local sites connect and register with it.
type ServerHandler ¶
type ServerHandler interface { // HandleConnection performs a handshake then process the connection. HandleConnection(conn net.Conn) }
ServerHandler implements an interface which can handle a connection (perform a handshake then process). This is needed because importing lib/srv in lib/reversetunnel causes a circular import.
type ServerHandlerToListener ¶
type ServerHandlerToListener struct {
// contains filtered or unexported fields
}
ServerHandlerToListener is an adapter from ServerHandler to net.Listener. It can be used as a Server field in AgentPoolConfig, while also being passed to http.Server.Serve (or any other func Serve(net.Listener)).
func NewServerHandlerToListener ¶
func NewServerHandlerToListener(tunnelAddr string) ServerHandlerToListener
NewServerHandlerToListener creates a new ServerHandlerToListener adapter.
func (ServerHandlerToListener) Addr ¶
func (l ServerHandlerToListener) Addr() net.Addr
func (ServerHandlerToListener) Close ¶
func (l ServerHandlerToListener) Close() error
func (ServerHandlerToListener) HandleConnection ¶
func (l ServerHandlerToListener) HandleConnection(c net.Conn)
type Tunnel ¶
type Tunnel interface { // GetSites returns a list of connected remote sites GetSites() ([]RemoteSite, error) // GetSite returns remote site this node belongs to GetSite(domainName string) (RemoteSite, error) }
Tunnel provides access to connected local or remote clusters using unified interface.
type TunnelAuthDialer ¶
type TunnelAuthDialer struct { // TunnelAuthDialerConfig is the TunnelAuthDialer configuration. TunnelAuthDialerConfig }
TunnelAuthDialer connects to the Auth Server through the reverse tunnel.
func NewTunnelAuthDialer ¶
func NewTunnelAuthDialer(config TunnelAuthDialerConfig) (*TunnelAuthDialer, error)
NewTunnelAuthDialer creates a new instance of TunnelAuthDialer
func (*TunnelAuthDialer) DialContext ¶
DialContext dials auth server via SSH tunnel
type TunnelAuthDialerConfig ¶
type TunnelAuthDialerConfig struct { // Resolver retrieves the address of the proxy Resolver Resolver // ClientConfig is SSH tunnel client config ClientConfig *ssh.ClientConfig // Log is used for logging. Log logrus.FieldLogger // InsecureSkipTLSVerify is whether to skip certificate validation. InsecureSkipTLSVerify bool }
TunnelAuthDialerConfig specifies TunnelAuthDialer configuration.
func (*TunnelAuthDialerConfig) CheckAndSetDefaults ¶
func (c *TunnelAuthDialerConfig) CheckAndSetDefaults() error
type TunnelWithRoles ¶
type TunnelWithRoles struct {
// contains filtered or unexported fields
}
TunnelWithRoles authorizes requests
func NewTunnelWithRoles ¶
func NewTunnelWithRoles(tunnel Tunnel, accessChecker services.AccessChecker, access ClusterGetter) *TunnelWithRoles
NewTunnelWithRoles returns new authorizing tunnel
func (*TunnelWithRoles) GetSite ¶
func (t *TunnelWithRoles) GetSite(clusterName string) (RemoteSite, error)
GetSite returns remote site this node belongs to
func (*TunnelWithRoles) GetSites ¶
func (t *TunnelWithRoles) GetSites() ([]RemoteSite, error)
GetSites returns a list of connected remote sites
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package track provides a simple interface for tracking known proxies by endpoint/name and correctly handling expiration and exclusivity.
|
Package track provides a simple interface for tracking known proxies by endpoint/name and correctly handling expiration and exclusivity. |