refactor(git): remove SSH rate limiting
SSH is deployed inside Kubernetes cluster where rate limiting at the application layer is unnecessary. Remove all SSH rate limiter code: - SshRateLimiter from SSHandle and SSHServer structs - is_user_allowed checks in auth_publickey, auth_publickey_offered - is_repo_access_allowed in exec_request - is_ip_allowed in server::new_client - rate_limiter module and start_cleanup
This commit is contained in:
parent
9368df54da
commit
0a998affbb
@ -2,7 +2,6 @@ use crate::ssh::ReceiveSyncService;
|
||||
use crate::ssh::RepoReceiveSyncTask;
|
||||
use crate::ssh::SshTokenService;
|
||||
use crate::ssh::authz::SshAuthService;
|
||||
use crate::ssh::rate_limit::SshRateLimiter;
|
||||
use db::cache::AppCache;
|
||||
use db::database::AppDatabase;
|
||||
use models::repos::{repo, repo_branch_protect};
|
||||
@ -20,7 +19,6 @@ use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Stdio;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWriteExt};
|
||||
use tokio::process::ChildStdin;
|
||||
@ -80,7 +78,6 @@ pub struct SSHandle {
|
||||
pub sync: ReceiveSyncService,
|
||||
pub upload_pack_eof_sent: HashSet<ChannelId>,
|
||||
pub logger: Logger,
|
||||
pub rate_limiter: Arc<SshRateLimiter>,
|
||||
pub token_service: SshTokenService,
|
||||
pub client_addr: Option<SocketAddr>,
|
||||
}
|
||||
@ -91,7 +88,6 @@ impl SSHandle {
|
||||
cache: AppCache,
|
||||
sync: ReceiveSyncService,
|
||||
logger: Logger,
|
||||
rate_limiter: Arc<SshRateLimiter>,
|
||||
token_service: SshTokenService,
|
||||
client_addr: Option<SocketAddr>,
|
||||
) -> Self {
|
||||
@ -115,7 +111,6 @@ impl SSHandle {
|
||||
sync,
|
||||
upload_pack_eof_sent: HashSet::new(),
|
||||
logger,
|
||||
rate_limiter,
|
||||
token_service,
|
||||
client_addr,
|
||||
}
|
||||
@ -201,17 +196,6 @@ impl russh::server::Handler for SSHandle {
|
||||
}
|
||||
};
|
||||
|
||||
let user_id = user_model.uid.to_string();
|
||||
if !self.rate_limiter.is_user_allowed(&user_id).await {
|
||||
warn!(
|
||||
self.logger,
|
||||
"SSH token auth rate limit exceeded: {}, client: {}",
|
||||
user_model.username,
|
||||
client_info
|
||||
);
|
||||
return Err(russh::Error::NotAuthenticated);
|
||||
}
|
||||
|
||||
info!(
|
||||
self.logger,
|
||||
"SSH token authentication successful: user={}, client={}",
|
||||
@ -278,16 +262,6 @@ impl russh::server::Handler for SSHandle {
|
||||
}
|
||||
};
|
||||
|
||||
let user_id = user_model.uid.to_string();
|
||||
if !self.rate_limiter.is_user_allowed(&user_id).await {
|
||||
let msg = format!(
|
||||
"User rate limit exceeded: {}, client: {}",
|
||||
user_model.username, client_info
|
||||
);
|
||||
warn!(self.logger, "{}", msg);
|
||||
return Err(russh::Error::NotAuthenticated);
|
||||
}
|
||||
|
||||
info!(
|
||||
self.logger,
|
||||
"SSH authentication successful: user={}, client={}", user_model.username, client_info
|
||||
@ -345,16 +319,6 @@ impl russh::server::Handler for SSHandle {
|
||||
}
|
||||
};
|
||||
|
||||
let user_id = user_model.uid.to_string();
|
||||
if !self.rate_limiter.is_user_allowed(&user_id).await {
|
||||
let msg = format!(
|
||||
"User rate limit exceeded: {}, client: {}",
|
||||
user_model.username, client_info
|
||||
);
|
||||
warn!(self.logger, "{}", msg);
|
||||
return Err(russh::Error::NotAuthenticated);
|
||||
}
|
||||
|
||||
info!(
|
||||
self.logger,
|
||||
"SSH authentication successful: user={}, client={}", user_model.username, client_info
|
||||
@ -371,10 +335,7 @@ impl russh::server::Handler for SSHandle {
|
||||
channel: ChannelId,
|
||||
_: &mut Session,
|
||||
) -> Result<(), Self::Error> {
|
||||
info!(self.logger, "channel_close";
|
||||
"channel" => ?channel,
|
||||
"client" => ?self.client_addr
|
||||
);
|
||||
info!(self.logger, "{}", format!("channel_close channel={:?} client={:?}", channel, self.client_addr));
|
||||
self.cleanup_channel(channel);
|
||||
Ok(())
|
||||
}
|
||||
@ -682,19 +643,6 @@ impl russh::server::Handler for SSHandle {
|
||||
return Err(russh::Error::Disconnect);
|
||||
}
|
||||
|
||||
let user_id = operator.uid.to_string();
|
||||
let repo_path = format!("{}/{}", owner, &repo.repo_name);
|
||||
if !self
|
||||
.rate_limiter
|
||||
.is_repo_access_allowed(&user_id, &repo_path)
|
||||
.await
|
||||
{
|
||||
let msg = format!("Rate limit exceeded for repository access: {}", repo_path);
|
||||
warn!(self.logger, "{}", format!("Repo access rate limit exceeded user={} repo={}", operator.username, repo.repo_name));
|
||||
session.disconnect(Disconnect::ByApplication, &msg, "").ok();
|
||||
return Err(russh::Error::Disconnect);
|
||||
}
|
||||
|
||||
info!(self.logger, "{}", format!("Access granted user={} repo={} is_write={}", operator.username, repo.repo_name, is_write));
|
||||
|
||||
let repo_path = PathBuf::from(&repo.storage_path);
|
||||
|
||||
@ -19,7 +19,6 @@ use std::time::Duration;
|
||||
|
||||
pub mod authz;
|
||||
pub mod handle;
|
||||
pub mod rate_limit;
|
||||
pub mod server;
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -148,7 +147,6 @@ impl SSHHandle {
|
||||
|
||||
// Start the rate limiter cleanup background task so the HashMap
|
||||
// doesn't grow unbounded over time.
|
||||
let _cleanup = server.rate_limiter.clone().start_cleanup();
|
||||
let ssh_port = self.app.ssh_port()?;
|
||||
let bind_addr = format!("0.0.0.0:{}", ssh_port);
|
||||
let public_host = self.app.ssh_domain()?;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
use crate::ssh::ReceiveSyncService;
|
||||
use crate::ssh::SshTokenService;
|
||||
use crate::ssh::handle::SSHandle;
|
||||
use crate::ssh::rate_limit::SshRateLimiter;
|
||||
use db::cache::AppCache;
|
||||
use db::database::AppDatabase;
|
||||
use deadpool_redis::cluster::Pool as RedisPool;
|
||||
@ -9,14 +8,12 @@ use russh::server::Handler;
|
||||
use slog::{Logger, info, warn};
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct SSHServer {
|
||||
pub db: AppDatabase,
|
||||
pub cache: AppCache,
|
||||
pub redis_pool: RedisPool,
|
||||
pub logger: Logger,
|
||||
pub rate_limiter: Arc<SshRateLimiter>,
|
||||
pub token_service: SshTokenService,
|
||||
}
|
||||
|
||||
@ -33,7 +30,6 @@ impl SSHServer {
|
||||
cache,
|
||||
redis_pool,
|
||||
logger,
|
||||
rate_limiter: Arc::new(SshRateLimiter::new()),
|
||||
token_service,
|
||||
}
|
||||
}
|
||||
@ -43,21 +39,12 @@ impl russh::server::Server for SSHServer {
|
||||
|
||||
fn new_client(&mut self, addr: Option<SocketAddr>) -> Self::Handler {
|
||||
if let Some(addr) = addr {
|
||||
let ip = addr.ip().to_string();
|
||||
info!(
|
||||
self.logger,
|
||||
"New SSH connection from {}:{}",
|
||||
ip,
|
||||
addr.ip(),
|
||||
addr.port()
|
||||
);
|
||||
|
||||
let rate_limiter = self.rate_limiter.clone();
|
||||
let logger = self.logger.clone();
|
||||
tokio::spawn(async move {
|
||||
if !rate_limiter.is_ip_allowed(&ip).await {
|
||||
warn!(logger, "{}", format!("IP rate limit exceeded ip={}", ip));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
info!(self.logger, "New SSH connection from unknown address");
|
||||
}
|
||||
@ -67,7 +54,6 @@ impl russh::server::Server for SSHServer {
|
||||
self.cache.clone(),
|
||||
sync_service,
|
||||
self.logger.clone(),
|
||||
self.rate_limiter.clone(),
|
||||
self.token_service.clone(),
|
||||
addr,
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user