Sets `http.Server.IdleTimeout` and `http.Client.IdleConnTimeout`
on clients and servers which didn't have them set. A default of
360s was chosen to be on par with the default of an NLB without
being identical.
This was added as another safety measure to prevent leaking any
idle connections indefinitely as seen in #22757.
`apidefaults.DefaultDialTimeout` was also renamed to
`apidefaults.DefaultIOTimeout` to better reflect its usage.
* Move the authorizer into its own package.
The Authorizer and associated functions and constants have been moved into
their own package `authz`. This will allow us to more easily create separate
services for gRPC functionality so that we're not pushing as much into the
`lib/auth` package.
Though this PR is large, the only actual code change here is making
`ContextForLocalUser` exported and changing the `permissions_test.go` so that
it doesn't rely on the `lib/auth` package.
* Use context functions.
* Test and linting fixes.
* Add in a temporary alias file to ensure e still compiles.
* Use functions instead of var aliases for performance reasons.
* Adding in godocs, cleaning up tests.
* Fix tests.
* Add a few more aliases.
`auth.Middleware` to make use of them. This allows for less redundancy
per RPC and provides the ability to perform session control when grpc
connections are established.
The `auth.Middleware.withAuthenticatedUser` function was called from all
interceptors of any gRPC server that leveraged `auth.Middleware`. This
was constructing the identity of the client from the TLS certificate
per RPC. Since the identity of a connection cannot change between RPCs
there is no need to construct the identity in an interceptor. Instead,
the new `auth.TransportCredentials` can build the identity once after the
TLS handshake completes. When interceptors or gRPC handlers need to
acquire the identity they can do so using the same
mechanism via `peer.Peer.AuthInfo` and assert on the new `auth.IdentityInfo`
type:
```go
peerInfo, ok := peer.FromContext(ctx)
if !ok {
return
}
connInfo, ok := peerInfo.AuthInfo.(auth.IdentityInfo)
if !ok {
return
}
identity := connInfo.IdentityGetter.GetIdentity()
connState := connInfo.TLSInfo.State
```
The gRPC server that is served on the Proxy ssh port needs to hold the
same invariants as the ssh server available on the same port. This
means that connection limits need to be enforced when new connections
are established. To achieve this the new `auth.TransportCredentials` can
be provided with an `auth.ConnectionEnforcer` and an `auth.Authorizer`
to first build an identity, then ensures that the user is authorized and
finally that the user has not exceeded their connection limits.
Other minor changes include providing the cluster name to the
`auth.Middleware` instead of it looking the value up from the cache every
time an identity is created. Some interceptors were also moved around or
removed to eliminate the chances of having duplicate interceptors end up in
the interceptor chain.
Part of #19812
WrapContextWithUser has been split into two functions that allows for using
the TLS connection state logic without having an actual TLS connection. This
will be used by the SAML IdP logic to wrap the user context information into
the request context.
Allow issuance of augmented, device-aware user certificates via auth.Server.
Device-aware certificate issuance takes as input existing user certificates and
augments them with the appropriate device extensions. The certificates to
augment must be valid, issued by the Teleport CA, match each other and the
current user, and share the same public key, among other criteria.
Device authentication is performed by Teleport Enterprise. The present PR adds
only the means to issue the certificates, but doesn't wire that functionality
to any endpoints.
gravitational/teleport.e#514
Our need for customizing our security response headers primarily exists with the Content-Security-Policy. Other headers can be applied more broadly to provide safe defaults across our service.
This commit changes httpheaders.go to allow for the CSP to be applied separate from the other headers. Then the changes to httplib.go's handlers help make sure these headers are set generally (which we were already partially doing for caching directives).
Other changes were primarily making sure these tools are configured or used. Or a removal of previous settings as this function is now being handled more centrally.
We were inconsistent throughout the codebase and would sometimes
use the slices package and other times use our own equivalents
in api/.
This removes our versions in favor of the golang.org/x package that
does the same, which has the added benefit of reducing the surface
area of the public API module.
Note: despite existing uses of the slices package, for some reason
it didn't show up in go.mod or go.sum. Fixed that too.
Tracing handlers consume a large amount of memory over time, which
makes using one per route suboptimal (See https://github.com/open-telemetry/opentelemetry-go-contrib/issues/2413).
Wrapping all `http.Server` handlers with a tracing handler provides
the same tracing abilities for a fraction of the memory usage. A new
span formatter is added which allows servers to still contain the
request span in the span name.
* Tag forwarded spans with custom attributes
Adds a `teleport.forwarded.for` attribute to a resource or
all spans that are forwarded to the auth server. This allows
consumers of the spans to identify where the spans are coming
from and take possible action. In some scenarios it may
be desirable to drop forwarded spans along the collection
process, by tagging them we can provide a way for those
consumers to identify them. It also allows for potentially
identifying a malicious user that may be trying to spam the
telemetry backend with spans.
Part of #12241
This adds proxy peering support. A configurable setting that allows for agents
to connect to a subset of proxies and be reachable through any proxy in the
cluster. This is achieved by creating grpc connections between each proxy
server. Client connections can then be passed between proxies to the desired
agent.
* Span forwarding
Modifies the auth grpc server to implement the OTLP Collector
RegisterTraceServiceServer API (https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/collector/trace/v1/trace_service.proto).
This allows the auth server to receive spans from other services
like `tsh`, `tctl`, and `tbot`. Any spans received by the auth
server will be forwarded to the exporter configured via the
`tracing_service` if it is enabled. All received spans will be
dropped in the event that the`tracing_service` disabled. By
forwarding spans to the auth server, `tsh` doesn't need to
be provided with any of the telemetry backend information
to have its spans exported.
Adds a new `--trace` flag to `tsh` to enable collecting and
forwarding spans to the auth server. When set, the tracing
provider is initialized with a sampling rate of 1.0 to force
all spans to be recorded. Teleport respects the sampling rate
from remote spans, which means that when `--trace` is set, all
spans from `tsh` and any downstream Teleport services will be
recorded and exported regardless of the sampling rate that each
Teleport service is configured with.
* add hostlogin to proxy config for windows
* Set ProxyClient's HostLogin to the Windows username
Also convert a few TLS handshakes to a context-aware version
for better timeout/cancelation behavior.
Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
Co-authored-by: Zac Bergquist <zmb3@users.noreply.github.com>
This deprecation was kind of a pain, because x509.CertPool becomes
a black box - there is no public API to determine how many certs
have been added to the pool. To account for this, some of our method
signatures needed to be updated to report the number of certs that
were added.
Introduce Database Certificate Authority. New CA is used by Database Access to sign database certificates making them independent from Host CA.
Co-authored-by: Marek Smoliński <marek@goteleport.com>
* Fix goroutine and memory leak in watchCertAuthorities
The CA Watcher was blocking both on writing to a channel when the watcher
was closed and on HTTP calls that had no request timeout or context passed
to cause cancellation.
All resourceWatcher implementations that had a bug which may cause them to block
on writing to a channel forever were fixed by selecting on the write and ctx.Done.
Adding context.Context to all Get/Put/Post/Delete methods on the auth HTTPClient to
force callers to propagate context. Prior all calls used context.TODO which
prevents requests from being properly cancelled.
Add context propagation to RotateCertAuthority, RotateExternalCertAuthority,
GetCertAuthority, GetCertAuthorities. This is needed to get the correct ctx
from the CertAtuhorityWatcher all the way down to the HTTPClient that makes
the call.
Closes#10648
Passwordless endpoints are rate limited because they allow unauthenticated
challenge generation. The endpoint rate limits are applied in addition to
(pre-existing) storage limits.
Setting limits to Auth only would be sufficient, but it seems best to apply
limits to Proxy as well, so we may spare Auth of unnecessary load.
Auth already has a framework for RPC rate limiting, so we took advantage of it.
The solution for the Proxy is rather simple - the handler is decorated with the
appropriate limits.
#9160
* Fix shadowing of grpcServer variable
* Add rate limiting for CreateAuthenticateChallenge
* Add rate limiting for /mfa/login/begin
* Safe parallel tests
- Rename ApproveAccountRecovery to VerifyAccountRecovery
to match the language we use for the UI
- Use generic TokenID field naming for requests where more
than one type of token is accepted or a single token use
may be unlikely (MFA related rpcs)
* Define new rpc CreateAccountRecoveryCodes that
creates new recovery codes for users who meet requirements,
invalidating their previous existing codes
* Define new rpc GetAccountRecoveryToken that
validates and retrieves a recovery token
* Define new RPC ApproveAccountRecovery Step 2 in Account Recovery after
StartAccountRecovery that after successful invocation produces
a recovery approved token that allows a user to change authn,
view/delete their MFA devices and get new recovery codes.
* Placed rate limit to this endpoint
* Added a verifyUserToken helper method that verifies
that a user token is not expired and is of the allowed subkinds.
* Define new RPC StartAccountRecovery
* Placed rate limit to this endpoint
* Define new user token type `UserTokenTypeRecoveryStart`
that allows users to begin recovery process
* Added new field to UserTokenSpec, `UserTokenUsage` to
store data about how a user token will be used
* Connect proxy <-> windows_desktop_service <-> RDP server
Link together the proxy (websocket), service (mTPS) and RDP client. Pass
target desktop UUID via SNI on the TLS connection from the proxy.
* Use client CAs to validate incoming desktop_service connections
* Send binary frames on desktop websocket
* Add dice-ware library to create the recovery codes
* Add new recovery code "generated" and "used" events
* Implement create, upsert, and get recovery codes
* Create ChangeUserAuthentication grpc endpoint that is essentially a rework
of ChangePasswordWithToken that returns both a web session and
recovery codes (if user meets requirement)
* Add custom rate limit for grpc endpoint for ChangeUserAuthentication
* This commit also includes unused methods related to verifying recovery
code and recovery attempts that isn't utilized until later PRs
* hsm: migrate CA storage schema
Migrate types.CertAuthorityV2 schema according to
https://github.com/gravitational/teleport/blob/master/rfd/0025-hsm.md#backend-storage
Includes proto changes, types.CertAuthority wrapper changes and data
migration.
Note that we keep and update the old fields for backwards-compatibility.
If a cluster is upgraded to v7 and then downgraded back to v6,
everything should keep working.
* Address review feedback
* grpc: call trail.ToGRPC from gRPC interceptors
The reduces the boilerplate a bit in the gRPC handlers and ensures you
won't forget the conversion.
* Update lib/auth/grpcserver.go
Co-authored-by: Andrej Tokarčík <andrej@goteleport.com>
Co-authored-by: Andrej Tokarčík <andrej@goteleport.com>
* Remove JSON schema validation
Removing JSON schema validation from all resource unmarshalers.
--- what JSON schema gets us
Looking at the JSON schema spec and our usage, here are the supposed benefits:
- type validation - make sure incoming data uses the right types for the right fields
- required fields - make sure that mandatory fields are set
- defaulting - set defaults for fields
- documentation - schema definition for our API objects
Note that it does _not_ do:
- fail on unknown fields in data
- fail on a required field with an empty value
--- what replaces it
Based on the above, it may seem like JSON schema provides value.
But it's not the case, let's break it down one by one:
- type validation - unmarshaling JSON into a typed Go struct does this
- required fields - only checks that the field was provided, doesn't actually check that a value is set (e.g. `"name": ""` will pass the `required` check)
- so it's pretty useless for any real validation
- and we already have a separate place for proper validation - `CheckAndSetDefaults` methods
- defaulting - done in `CheckAndSetDefaults` methods
- `Version` is the only annoying field, had to add it in a bunch of objects
- documentation - protobuf definitions are the source of truth for our API schema
--- the benefits
- performance - schema validation does a few rounds of `json.Marshal/Unmarshal` in addition to actual validation; now we simply skip all that
- maintenance - no need to keep protobuf and JSON schema definitions in sync anymore
- creating new API objects - one error-prone step removed
- (future) fewer dependencies - we can _almost_ remove the Go libraries for schema validation (one transient dependency keeping them around)
* Remove services.SkipValidation
No more JSON schema validation so this option is a noop.
This change has several parts: cluster registration, cache updates,
routing and a new tctl flag.
> cluster registration
Cluster registration means adding `KubernetesClusters` to `ServerSpec`
for servers with `KindKubeService`.
`kubernetes_service` instances will parse their kubeconfig or local
`kube_cluster_name` and add them to their `ServerSpec` sent to the auth
server. They are effectively declaring that "I can serve k8s requests
for k8s cluster X".
> cache updates
This is just cache plumbing for `kubernetes_service` presence, so that
other teleport processes can fetch all of kube services. It was missed
in the previous PR implementing CRUD for `kubernetes_service`.
> routing
Now the fun part - routing logic. This logic lives in
`/lib/kube/proxy/forwarder.go` and is shared by both `proxy_service`
(with kubernetes integration enabled) and `kubernetes_service`.
The target k8s cluster name is passed in the client cert, along with k8s
users/groups information.
`kubernetes_service` only serves requests for its direct k8s cluster
(from `Forwarder.creds`) and doesn't route requests to other teleport
instances.
`proxy_service` can serve requests:
- directly to a k8s cluster (the way it works pre-5.0)
- to a leaf teleport cluster (also same as pre-5.0, based on
`RouteToCluster` field in the client cert)
- to a `kubernetes_service` (directly or over a tunnel)
The last two modes require the proxy to generate an ephemeral client TLS
cert to do an outbound mTLS connection.
> tctl flag
A flag `--kube-cluster-name` for `tctl auth sign --format=kubernetes`
which allows generating client certs for non-default k8s cluster name
(as long as it's registered in a cluster).
I used this for testing, but it could be used for automation too.