From 05943dad70ce17ff61b8c0352abeec0964ca14f0 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 8 Nov 2026 15:39:06 +0000 Subject: login: logins by key capped per user Review 6: a node remembers the challenges used until they expire, 10 000 at most, and refused every login by key once full. One user holding a key could make 10 000 logins within five minutes and keep everyone else out. A user may now log in by key at most --key-logins-per-user times (100) on a node within a challenge's lifetime, past which that user waits and others don't; the 10 000 stay as the cap for all users together. The lifetime, five minutes until now, is --challenge-lifetime. --- src/config/mod.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/config') diff --git a/src/config/mod.rs b/src/config/mod.rs index 9d918f7..9279f40 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -144,6 +144,20 @@ pub(crate) const OPTIONS: &[OptionSpec] = &[ Some("7d"), "How long after a login (POST /auth/login) its tokens may be refreshed; then the user logs in again.", ), + option( + "challenge-lifetime", + Kind::Duration, + "DURATION", + Some("5m"), + "How long a challenge to log in by key (POST /auth/challenge) is valid: the node remembers each used until then, and counts a user's logins by key over it (key-logins-per-user).", + ), + option( + "key-logins-per-user", + Kind::Integer, + "COUNT", + Some("100"), + "Logins by key a user may make on this node within a challenge's lifetime (challenge-lifetime); past it, that user waits, others don't. 10 000 by all users together at most.", + ), option( "cors-origins", Kind::List, @@ -594,6 +608,13 @@ pub(crate) struct Settings { with = "crate::units::duration_option" )] pub(crate) session_lifetime: Duration, + #[serde( + default = "default_challenge_lifetime", + with = "crate::units::duration_option" + )] + pub(crate) challenge_lifetime: Duration, + #[serde(default = "default_key_logins_per_user")] + pub(crate) key_logins_per_user: usize, #[serde(default)] pub(crate) debug_api: bool, #[serde(default = "default_log_format")] @@ -757,6 +778,12 @@ fn default_token_lifetime() -> Duration { fn default_session_lifetime() -> Duration { Duration::from_secs(7 * 24 * 3600) } +fn default_challenge_lifetime() -> Duration { + Duration::from_secs(5 * 60) +} +fn default_key_logins_per_user() -> usize { + 100 +} fn default_keepalive() -> Duration { Duration::from_secs(60) } -- cgit v1.3.1