* PIV authentication for RDP
This uncomfortably large change fully implements smartcard PIV
authentication for RDP clients using the Teleport CA:
- PIV applet implementation in emulated RDP smartcard
- generating Windows-compatible certificates using Teleport CA with a
dedicated RPC
- generating dummy CRLs for Teleport CA and publishing it via LDAP
The CRLs are required by Windows for any smartcard login certificate, we
can't avoid that. But we can avoid making it public: the CRL can live in
ActiveDirectory instead of a public endpoint of a Teleport service.
Here, we use LDAP to publish the CRL on startup, valid for a year.
There are a few unhandled cases in the current implementation:
- LDAP server certificate is not validated when upgrading to TLS
- multiple active CAs (with HSMs) are not supported, only one CRL is
published
- CA rotation is not supported, CRL is not re-published on rotation
All of the above issues will be handled in future PRs as this one is
already too large.
* Address review feedback
* Fix linter errors
Give Teleport clients a consistent hint of which MFA method they should
favor when facing multiple options.
To be used by tsh and Web UI to decide whether they should refer to
"U2F" or "WebAuthn" during the transitional period.
* Return preferred MFA method on ping endpoints
- 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)
Following allows for UI dashboard mfa and recovery code management:
- Adds new rpc AddMFADeviceSync (nonstream) so users can add device
- Adds new rpc GetAccountRecoveryCodes to retrieve nonsensitive data
about a users recovery codes e.g. created date to display in the users
dashboard
- Added privilege access to DeleteMFADeviceSync and
CreateAccountRecoveryCodes
One endpoint is now responsible for creating/returning
MFA register challenges:
- Deprecates RotateUserTokenSecrets
- Deprecates GetSignupU2FRegisterRequest
Add Webauthn support to a few outstanding endpoints and RPCs.
* Refactor and add Webauthn support to ChangePassword
* Add explicit JSON tag to AuthenticateUserRequest.Webauthn
* Add Webauthn support to /webapi/users/password/token
* Add Webauthn to /webapi/ping
* Add default Webauthn device name to ChangeUserAuthentication
* Tidy Ping tests
- Privilege tokens are obtained after a logged in user successfully
re-authenticates with their second factor. This token allows
access to protected actions and will last 5 minutes.
- There is one exception where a user can obtain `PrivilegeException`
token without re-authenticating if a user doesn't have any second factors.
Currently used to allow users to add their first MFA devices for
auth type optional.
- Added web handlers
Replaces the local device type in AddMFADeviceRequestInit for a global enum.
Useful for future RPCs.
* Add the DeviceType proto to Auth Service
* Generate protos
* Use new DeviceType in implementations
Using the standard logger results in log messages being routed to the
console even in non-debug mode, so reverting to `logrus` which will
honour the debug setting
This patch will allow the web api to (optionally) fall back from HTTPS
to HTTP under very particular circumstances:
1. The appropriate `insecure` flag was set, and
2. The target host is the loopback
If both conditions are met, this patch will allow the WebAPI client to
fall back to plain HTTP when attempting to login to the auth server.
Created a new rpc `CreateAuthenticateChallenge` that
replaces/deprecates `GetMFAAuthenticateChallenge`
Allows 3 ways to invoke this request:
1. with username + password
2. with token ID (username retrieved from token)
3. with empty request (username retrieved from context)
- Implemented `DeleteMFADeviceSynce`, which takes in a token
that allows users to delete devices during the recovery process
- Refactored `GetMFADevices` to take in recovery token
- Pulled out deleting MFA device (from stream version) into helper func to be re-used
- Added delete MFA web handler
WebauthnDevice is a prerequisite for registration, as are the message changes in
AuthService.
This lays the groundwork for registration and ensures only valid devices may
enter storage.
* Add WebauthnDevice to MFADevice
* Add Webauthn to AuthService registration messages
* Validate WebauthnDevice on upsert
This commit contains 2 changes:
1. Rename GenerateServerKeys to GenerateHostCerts.
This is a more accurate name and consistent with the existing
GenerateUserCerts endpoint.
2. Change the request type to include a single role, rather than a
list of roles. We only ever allowed a single role in the list
anyway, so this change will prevent future mis-use of the API.
Note: a side effect of this change is we now have two similar endpoints:
- GenerateHostCert: old API that generates SSH cert only
- GenerateHostCerts: a newer API that generates SSH and TLS certs
To avoid making this change too big, we'll aim to deprecate
GenerateHostCert in the future.
Since #8176[1] landed, tsh login favors Webauthn challenges over U2F, a behavior
recommended to other clients as well (such as the Web UI). This creates a
problem: until the Webauthn implementation if proven in the wild, if there are
issues with it, then clients could consistently fail login.
This change introduces a fallback for disabling Webauthn regardless of the
cluster's second_factor:on or second_factor:optional setting. By stopping
challenge generation we automatically push clients over to U2F or TOTP as a
fallback, allowing breaking issues to be fixed without impact. (Note that using
second_factor:u2f as a fallback isn't always possible, since it disables OTP as
well.)
The added setting is meant as a safety switch - once Webauthn is proved in the
wild it is to be removed.
This affects both teleport.yaml and cloud resource configs.
teleport.yaml:
```yaml
auth_service:
authentication:
type: local
second_factor: on # or "optional"
u2f: {} # omitted
webauthn:
disabled: true
```
Resource configuration:
```yaml
kind: cluster_auth_preference
version: v2
spec:
type: local
second_factor: on
webauthn:
disabled: true
```
[1] https://github.com/gravitational/teleport/pull/8176
* Add global disable flag for Webauthn
* Generate protos
* Apply Webauthn global disable flag
* 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 CompleteAccountRecovery, Step 3 in Account Recovery
after ApproveAccountReocvery. After success, users authn is changed
which allows a user to login with new credentials.
* Added a verifyMFARespAndAddDevice helper func to unify adding a
device through stream or by a user 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.
Allow login using Webauthn instead of U2F.
Installs with second_factor:on will automatically support Webauthn, generating
challenges for any U2F devices and allowing Webauthn to be used throughout the
entire login process.
Web REST API modified as follows:
Added /webapi/mfa/login/begin (1st login step)
Added /webapi/mfa/login/finish (2nd login step, SSH)
Added /webapi/mfa/login/finishsession (2nd login step, web session)
U2F endpoints deprecated, but support full breadth of MFA login options
(/webapi/u2f/signrequest, /webapi/u2f/certs and /webapi/u2f/sessions,
respectively)
Auth REST API modified as follows:
Added /:version/mfa/users/:user/login/begin (1st login step)
ssh/authenticate and web/authenticate now support Webauthn (2nd login step)
U2F endpoints deprecated, but support full breadth of MFA options as well
(/:version/u2f/users/:user/sign)
RFD: https://github.com/gravitational/teleport/pull/7808.
* Plug Webauthn into MFAAuth protos
* Generate protos
* Make CredentialAssertionResponse json-friendly
* Add Webauthn proto conversions
* Wire Webauthn to auth apiserver
* Wire Webauthn login to web apiserver
* Wire Webauthn to web login
* Add missing license headers
* Delete login_identity_test.go
* Use previously acquired devices on mfaAuthChallenge
* Take U2F App ID literally if it's not a proper URL
* Add direct tests for auth.Server
* Use trace.BadParameter consistently
* Include user name in "failed to authenticate" logs
* Add more login-related tests to auth.Server
* 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
Introduce new make targets to check and add license headers to files
("make lint-license" and "make fix-license"). License checking is now a part of
"make lint" as well.
Initial attempts used goheader, but it caused "make lint-go" to become about 9x
slower (if not more), plus it only targets go files. Google's addlicense is fast
enough and targets however many file types we want.
Existing files that were missing licenses got the header added, using the
current year as the license date.
* Introduce lint-license and fix-license make targets
* Ignore generated files
* Add license to go files
* Replace irregular licenses with standard copyright/license
* Add license to proto files
* Install addlicense in build.assets Dockerfile
* Add withSecrets bool parameter to identity service GetMFADevices
that removes secret (totp key) if true
* Add web handlers for getting devices for authenticated users
* Fix data race with RecoveryAttemptsCRUD test
* 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
Boilerplate for a new service and API objects:
- windows_desktop_service config section
- service registration and heartbeats
- static host registration and heartbeats
- caching, permissions, etc
- "tctl get" support
For new connections the service aborts after authentication, since the
RDP client implementation is not ready yet (pending in
https://github.com/gravitational/teleport/pull/7824).
Tested that the service starts, registers (both over a tunnel and
directly) and creates the API objects.
Adds a configurable MotD to the auth service. If a message is set, any
attempt to login into a cluster via `tsh` will display that message and
not begin to log the user in until that message is acknowledged.
Adds the ability to block network traffic on SSH sessions.
The deny/allow lists of IPs are specified in teleport.yaml file.
Supports both IPv4 and IPv6 communication.
This feature currently relies on enhanced recording for
cgroup management so that needs to be enabled as well.
-- Design rationale:
This patch uses Linux Security Module (LSM) hooks, specifically
security_socket_connect and security_socket_sendmsg, to control
egress traffic. The LSM provides two advantages over socket filtering
program types.
- It's executed early enough that the task information is available.
This makes it easy to report PID, COMM, etc.
- It becomes a model for extending restrictions beyond networking.
The set of enforced cgroups is stored in a BPF hash map and the
deny/allow lists are stored in BPF trie maps. An IP address is
first checked against the allow list. If found, it's checked for
an override in the deny list. The policy is default deny. However,
the absence of the NetworkRestrictions API object is allow all.
IPv4 addresses are additionally registered in IPv6 trie (as mapped)
to account for dual stacks. However it is unclear if this is sufficient
as 4-to-6 transition methods utilize a multitude of translation and
tunneling methods.