-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Implement basic SSH server handler with russh #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add the core SSH server implementation using the russh library's server API. This provides the foundation for all SSH server functionality including authentication, command execution, and subsystems. Implementation includes: - BsshServer struct with russh configuration and session management - russh::server::Server trait implementation for creating handlers - russh::server::Handler trait with all required methods: - auth_none, auth_publickey, auth_password (placeholder rejections) - channel_open_session, channel_close, channel_eof - pty_request, exec_request, shell_request, subsystem_request - data handling - ServerConfig with builder pattern for configuration - SessionManager for tracking active sessions with capacity limits - SessionInfo and SessionId for session metadata - ChannelState and ChannelMode for channel tracking - PtyConfig for terminal configuration storage - Host key loading from OpenSSH format files - Comprehensive logging for connection events All authentication methods are placeholder implementations that reject and advertise available methods. These will be implemented in follow-up issues (#126 for publickey, #127 for password). The implementation follows russh 0.56.0 API patterns and includes 25 unit tests covering session management, configuration, and handler creation. Closes #125
Security and Performance Review: PR #146Date: 2026-01-22 Executive SummaryThis PR implements a foundational SSH server handler using the russh library. The code is well-structured with proper use of Rust idioms, comprehensive unit tests (25 passing), and passes all clippy checks. While this is a placeholder implementation with authentication methods that reject all attempts, there are several security and quality considerations for the foundation that should be addressed before real authentication is implemented. 1. Analysis Summary
2. Prioritized Issue RoadmapHIGH (2 issues)H1: Session Not Removed on Handler DropFile: impl Drop for SshHandler {
fn drop(&mut self) {
if let Some(ref info) = self.session_info {
tracing::info!(...);
// Missing: sessions.remove(info.id)
}
}
}Impact: Server will become unable to accept new connections after serving Recommendation: The session must be removed from
H2: Authenticated Count Method InefficiencyFile: pub fn authenticated_count(&self) -> usize {
self.sessions.values().filter(|s| s.authenticated).collect::<Vec<_>>().len()
}Impact: Unnecessary memory allocation on every call. In high-load scenarios with many sessions, this wastes memory and CPU cycles. Recommendation: Use pub fn authenticated_count(&self) -> usize {
self.sessions.values().filter(|s| s.authenticated).count()
}MEDIUM (3 issues)M1: SessionId Counter Overflow Not HandledFile: pub fn new() -> Self {
static COUNTER: AtomicU64 = AtomicU64::new(1);
Self(COUNTER.fetch_add(1, Ordering::Relaxed))
}Impact: Very low probability but could cause session confusion if IDs collide. Recommendation: For long-running servers, consider adding a timestamp component or using UUIDs. This is acceptable for now but should be documented. M2: Missing Rate Limiting for Authentication AttemptsFile: Impact: The server is vulnerable to brute-force attacks that cycle through many connections. The russh library provides Recommendation: For future implementation, add:
M3: Configuration Validation MissingFile:
Impact: Runtime failures instead of early validation errors. Recommendation: Add validation in pub fn build(self) -> Result<ServerConfig, ConfigError> {
if self.config.max_connections == 0 {
return Err(ConfigError::InvalidMaxConnections);
}
// ... more validation
Ok(self.config)
}LOW (2 issues)L1: Potential Timing Attack in Auth Attempts CheckFile: fn auth_attempts_exceeded(&self) -> bool {
self.session_info
.as_ref()
.is_some_and(|s| s.auth_attempts >= self.config.max_auth_attempts)
}Impact: Minor - russh already provides Recommendation: Ensure consistent timing regardless of session state (already handled by russh's rejection delay). L2: Missing Debug Implementation for BsshServerFile: pub struct BsshServer {
config: Arc<ServerConfig>,
sessions: Arc<RwLock<SessionManager>>,
}Impact: Inconvenient for debugging but not a functional issue. Recommendation: Add 3. Positive ObservationsSecurity Strengths
Code Quality
Performance
4. Recommendations Summary
5. Action ItemsMust Fix Before Merge
Should Fix
Nice to Have
Future Work (not blocking this PR)
6. VerdictThe PR is well-implemented with good Rust practices and comprehensive testing. The identified issues are primarily around resource management (session cleanup) and minor performance optimizations. Recommendation: Fix H1 and H2 before merging. The session leak (H1) is particularly important as it would cause production issues. |
Fixed two HIGH severity issues found in PR #146 review: 1. Session resource leak: SshHandler Drop now properly removes sessions from SessionManager using try_write(). Previously, sessions were only logged on drop but never removed, causing session slots to accumulate. The implementation uses try_write() to avoid blocking in Drop and logs a warning if lock acquisition fails. 2. Inefficient authenticated_count(): Replaced the inefficient .collect::<Vec<_>>().len() pattern with direct .count() method. This eliminates unnecessary heap allocation and improves performance. Both changes maintain all existing tests and pass clippy checks.
- Add 17 new unit tests for comprehensive server module coverage (42 total) - Update ARCHITECTURE.md with SSH server module documentation - Update docs/architecture/README.md with server component references - Fix code formatting issues in server module - All tests passing, clippy clean, format verified
PR Finalization ReportProject Structure
ChecklistTests
New tests added:
Documentation
Code Quality
Changes Made
SummaryThe PR now has:
Ready for merge. |
Summary
Changes
This PR implements the foundation for SSH server functionality in bssh-server:
Server Module Structure
Key Components
BsshServer (
mod.rs)russh::server::Servertrait through BsshServerRunnerSshHandler (
handler.rs)russh::server::HandlertraitSessionManager (
session.rs)ServerConfig (
config.rs)Test plan
cargo test server::shows 25 passing)-D warningsRelated Issues
Closes #125
Follow-up Issues