gravitational / teleport

The easiest, and most secure way to access and protect all of your infrastructure.
https://goteleport.com
GNU Affero General Public License v3.0
17.41k stars 1.74k forks source link

`tsh proxy kube` accept lower durations than `max_session_ttl` #36638

Closed tigrato closed 1 month ago

tigrato commented 8 months ago

What would you like Teleport to do?

Using tsh proxy kube we should have the option to configure an intermediate duration between having to touch the MFA device with each kubectl invocation and the maximum duration allowed by max_session_ttl

What problem does this solve?

The tsh kube proxy command is restricted solely by the max_session_ttl. It is advisable to restrict it to a timeout duration shorter than the max_session_ttl since allowing it to run in the background for the entire duration of max_session_ttl essentially negates the core purpose of per-session MFA but tapping the MFA each time kubectl is invoked is too verbose.

othmane399 commented 8 months ago

I want just to add that we need to be able to set a TTL for tsh kube credentials --kube-cluster=xxx --teleport-cluster=yyy --proxy=zzz as well, as today it still hardcoded to 1 minute and some users doesn't want to use tsh proxy kube.

Touching the MFA each 1 minute by running some binaries that store k8s credentials in-memory (like k9s) is just innacceptable for our users...

@tigrato please tell me if the issue is not on the same scope, I'll create another one then 🙏

russjones commented 3 months ago

@tigrato What do you think about repurposing the ttl flag here? When the user runs tsh proxy kube --ttl=1m send that value to the proxy and terminate after 1 minute (in this example).

tigrato commented 3 months ago

@russjones that was my initial idea, but we also need to ensure that users are restricted at the cluster level by more than just max_session_ttl if the user doesn't specify the --ttl flag.

This requirement originated from a security hardening request, where it’s not acceptable to leave the background process unattended for 12 hours without MFA verification.

In the past, I wrote this but never mailed it because I had other work for TAG but if you want I can mail it quickly.

russjones commented 3 months ago

@tigrato You don't need to work on it, we'll put it in Q3 planning.

What do you mean by user need to be restricted by more than max_session_ttl. I imagine we have something that is currently checking lifetime of a connection and terminating at max_session_ttl, can't we add a hook to check for a shorter ttl there?

tigrato commented 3 months ago

@russjones this is a little bit different.

The objective of this feature is to enforce more frequent MFA verifications, overriding the max_session_ttl setting. The max_session_ttl parameter defines the validity period of login certificates in Teleport, which are retrieved upon user login. These certificates do not include any MFA device extensions. Consequently, users who are required to perform an MFA tap for device access will be prompted for this tap every time, as these certificates are never saved to disk.

This repetitive MFA prompt becomes particularly cumbersome when accessing Kubernetes clusters with kubectl, as it necessitates an MFA tap with each command execution. To mitigate this inconvenience, we introduced the tsh proxy kube command, which reduces the number of required MFA taps. When you start a proxy, it will prompt for an MFA tap once, and this authentication will remain valid for the duration specified by max_session_ttl. Typically, max_session_ttl is set to a long duration (e.g., 12 hours) to minimize the need for repeated logins and password entries, with users relying on MFA taps to confirm legitimate access.

However, this approach has a significant downside. The certificates issued by tsh proxy kube are valid for the entire max_session_ttl period, meaning no additional MFA taps are required during this time. If the kube proxy is left running, a malicious actor could potentially exploit this window to gain access until the certificates expire.

To address this, we aim to enforce MFA taps more frequently for new kubectl requests, regardless of the max_session_ttl duration. Additionally, we want to maintain existing connections until the session expires (assuming the option to disconnect expired certificates is enabled). This approach ensures enhanced security by requiring regular MFA verification while preserving session continuity for established connections. Something like min_mfa_verification_interval

I pushed my POC for this (I never actually tested it lol) and it's available here. I don't think we are far from having this feature released but it needs some unit tests and proper testing.