diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..a0159a2b --- /dev/null +++ b/docs/README.md @@ -0,0 +1,158 @@ +# bssh Documentation + +Welcome to the bssh documentation. This documentation covers both the bssh client and bssh-server. + +## Quick Links + +- **[Quick Start Guide](./quick-start.md)** - Get bssh-server running in minutes +- **[Server Configuration](./architecture/server-configuration.md)** - Complete configuration reference +- **[Security Guide](./security.md)** - Security best practices +- **[Container Deployment](./container-deployment.md)** - Docker and Kubernetes deployment + +## Documentation Index + +### Getting Started + +| Document | Description | +|----------|-------------| +| [Quick Start](./quick-start.md) | Installation and first run guide | +| [Container Deployment](./container-deployment.md) | Docker and Kubernetes deployment | + +### Server Administration + +| Document | Description | +|----------|-------------| +| [Server Configuration](./architecture/server-configuration.md) | Complete configuration reference | +| [Security Guide](./security.md) | Security best practices and hardening | +| [Audit Logging](./audit-logging.md) | Audit logging setup and integration | + +### Client Documentation + +| Document | Description | +|----------|-------------| +| [CLI Interface](./architecture/cli-interface.md) | Command-line interface documentation | +| [Interactive Mode](./architecture/interactive-mode.md) | TUI and interactive shell mode | +| [SSH Jump Hosts](./architecture/ssh-jump-hosts.md) | ProxyJump and jump host support | +| [Port Forwarding](./architecture/ssh-port-forwarding.md) | Local, remote, and dynamic forwarding | + +### Migration Guides + +| Document | Description | +|----------|-------------| +| [pdsh Migration](./pdsh-migration.md) | Migrating from pdsh to bssh | +| [pdsh Examples](./pdsh-examples.md) | pdsh-style command examples | +| [pdsh Options](./pdsh-options.md) | pdsh option compatibility | + +### Architecture + +| Document | Description | +|----------|-------------| +| [Architecture Overview](./architecture/README.md) | System architecture overview | +| [SSH Client](./architecture/ssh-client.md) | SSH client implementation | +| [SSH Config Parser](./architecture/ssh-config-parser.md) | SSH config file parsing | +| [Executor](./architecture/executor.md) | Parallel execution engine | +| [TUI](./architecture/tui.md) | Terminal user interface | +| [Exit Codes](./architecture/exit-code-strategy.md) | Exit code handling | + +### Man Pages + +Man pages are located in [docs/man/](./man/): + +| Man Page | Section | Description | +|----------|---------|-------------| +| [bssh(1)](./man/bssh.1) | 1 | bssh client manual | +| [bssh-server(8)](./man/bssh-server.8) | 8 | bssh-server administration manual | +| [bssh-keygen(1)](./man/bssh-keygen.1) | 1 | SSH key generation tool manual | + +### Shell Integration + +| Document | Description | +|----------|-------------| +| [Shell Config](./shell-config/README.md) | Shell integration and completion | + +## Installation + +### From Binary + +```bash +# Download and install binaries +curl -LO https://github.com/lablup/bssh/releases/latest/download/bssh-linux-amd64.tar.gz +tar xzf bssh-linux-amd64.tar.gz +sudo mv bssh bssh-server bssh-keygen /usr/local/bin/ +``` + +### From Source + +```bash +git clone https://github.com/lablup/bssh.git +cd bssh +cargo build --release +sudo cp target/release/bssh /usr/local/bin/ +sudo cp target/release/bssh-server /usr/local/bin/ +sudo cp target/release/bssh-keygen /usr/local/bin/ +``` + +### Man Page Installation + +```bash +sudo install -Dm644 docs/man/bssh.1 /usr/share/man/man1/bssh.1 +sudo install -Dm644 docs/man/bssh-keygen.1 /usr/share/man/man1/bssh-keygen.1 +sudo install -Dm644 docs/man/bssh-server.8 /usr/share/man/man8/bssh-server.8 +sudo mandb +``` + +## Components + +### bssh (Client) + +A high-performance SSH client that can be used as a drop-in replacement for OpenSSH while also providing parallel execution capabilities for cluster management. + +```bash +# Single host (SSH compatibility) +bssh user@host + +# Multiple hosts +bssh -H host1,host2,host3 'uptime' + +# Using clusters +bssh -C mycluster 'hostname' +``` + +### bssh-server + +A lightweight SSH server designed for container environments with built-in audit logging, file transfer filtering, and comprehensive security controls. + +```bash +# Generate configuration +bssh-server gen-config -o /etc/bssh/server.yaml + +# Generate host key +bssh-server gen-host-key -t ed25519 -o /etc/bssh/ssh_host_ed25519_key + +# Start server +bssh-server -c /etc/bssh/server.yaml +``` + +### bssh-keygen + +SSH key generation tool compatible with OpenSSH key formats. + +```bash +# Generate Ed25519 key (recommended) +bssh-keygen + +# Generate RSA key +bssh-keygen -t rsa -b 4096 + +# Generate with custom comment +bssh-keygen -C "user@hostname" +``` + +## Support + +- **Issues**: [GitHub Issues](https://github.com/lablup/bssh/issues) +- **Repository**: [GitHub](https://github.com/lablup/bssh) + +## License + +Apache License 2.0 diff --git a/docs/audit-logging.md b/docs/audit-logging.md new file mode 100644 index 00000000..58cae968 --- /dev/null +++ b/docs/audit-logging.md @@ -0,0 +1,505 @@ +# Audit Logging Guide + +[Back to Documentation Index](./README.md) + +This guide covers setting up and using audit logging in bssh-server for security monitoring, +compliance, and troubleshooting. + +## Table of Contents + +- [Overview](#overview) +- [Configuration](#configuration) +- [Audit Events](#audit-events) +- [Exporters](#exporters) +- [Log Analysis](#log-analysis) +- [Integration Examples](#integration-examples) +- [Best Practices](#best-practices) + +## Overview + +bssh-server provides comprehensive audit logging that captures security-relevant events including: + +- Authentication attempts (success and failure) +- Session lifecycle (start, end, duration) +- Command execution +- File operations (read, write, delete, rename) +- Security events (IP blocks, suspicious activity) + +Audit logs can be exported to multiple destinations simultaneously for flexibility in log management. + +## Configuration + +### Basic Configuration + +Enable audit logging with file output: + +```yaml +audit: + enabled: true + exporters: + - type: file + path: /var/log/bssh/audit.log +``` + +### Multiple Exporters + +Send logs to multiple destinations: + +```yaml +audit: + enabled: true + exporters: + # Local file for backup/compliance + - type: file + path: /var/log/bssh/audit.log + + # OpenTelemetry for observability platform + - type: otel + endpoint: http://otel-collector:4317 + + # Logstash for ELK stack + - type: logstash + host: logstash.example.com + port: 5044 +``` + +## Audit Events + +### Event Types + +| Event Type | Description | Logged Fields | +|------------|-------------|---------------| +| `AuthSuccess` | Successful authentication | user, method, client_ip | +| `AuthFailure` | Failed authentication attempt | user, method, client_ip, reason | +| `AuthRateLimited` | Authentication rate limited | client_ip, attempts | +| `SessionStart` | Session started | session_id, user, client_ip | +| `SessionEnd` | Session ended | session_id, user, duration | +| `CommandExecuted` | Command executed | session_id, user, command | +| `CommandBlocked` | Command blocked by policy | session_id, user, command, reason | +| `FileOpenRead` | File opened for reading | path, user | +| `FileOpenWrite` | File opened for writing | path, user | +| `FileRead` | File read operation | path, bytes | +| `FileWrite` | File write operation | path, bytes | +| `FileClose` | File closed | path | +| `FileUploaded` | File upload completed | path, bytes, user | +| `FileDownloaded` | File download completed | path, bytes, user | +| `FileDeleted` | File deleted | path, user | +| `FileRenamed` | File renamed | path, dest_path, user | +| `DirectoryCreated` | Directory created | path, user | +| `DirectoryDeleted` | Directory deleted | path, user | +| `DirectoryListed` | Directory listed | path, user | +| `TransferDenied` | Transfer blocked by filter | path, rule, user | +| `TransferAllowed` | Transfer explicitly allowed | path, rule, user | +| `IpBlocked` | IP address blocked | client_ip, reason | +| `IpUnblocked` | IP address unblocked | client_ip | +| `SuspiciousActivity` | Suspicious activity detected | client_ip, details | + +### Event Structure + +Each audit event contains: + +```json +{ + "id": "550e8400-e29b-41d4-a716-446655440000", + "timestamp": "2026-01-24T12:00:00.000Z", + "event_type": "AuthSuccess", + "session_id": "session-123", + "user": "johndoe", + "client_ip": "192.168.1.100", + "protocol": "ssh", + "result": "success", + "details": { + "method": "publickey", + "key_type": "ssh-ed25519" + } +} +``` + +## Exporters + +### File Exporter + +Writes events to a file in JSON Lines format (one JSON object per line). + +```yaml +audit: + exporters: + - type: file + path: /var/log/bssh/audit.log +``` + +**Output Format:** +```json +{"id":"...","timestamp":"2026-01-24T12:00:00Z","event_type":"SessionStart",...} +{"id":"...","timestamp":"2026-01-24T12:00:01Z","event_type":"CommandExecuted",...} +``` + +**File Rotation:** + +Use logrotate for log rotation: + +```bash +# /etc/logrotate.d/bssh +/var/log/bssh/*.log { + daily + rotate 90 + compress + delaycompress + missingok + notifempty + create 0600 root root + postrotate + # Signal bssh-server to reopen log files if needed + systemctl reload bssh-server 2>/dev/null || true + endscript +} +``` + +### OpenTelemetry Exporter + +Sends events to an OpenTelemetry Collector via OTLP/gRPC. + +```yaml +audit: + exporters: + - type: otel + endpoint: http://otel-collector:4317 +``` + +**OpenTelemetry Collector Configuration:** + +```yaml +# otel-collector-config.yaml +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + +processors: + batch: + timeout: 1s + send_batch_size: 100 + +exporters: + # Export to Jaeger + jaeger: + endpoint: jaeger:14250 + tls: + insecure: true + + # Export to Elasticsearch + elasticsearch: + endpoints: ["https://elasticsearch:9200"] + logs_index: bssh-audit + + # Export to file + file: + path: /var/log/otel/bssh-audit.json + +service: + pipelines: + logs: + receivers: [otlp] + processors: [batch] + exporters: [elasticsearch, file] +``` + +### Logstash Exporter + +Sends events directly to Logstash over TCP. + +```yaml +audit: + exporters: + - type: logstash + host: logstash.example.com + port: 5044 +``` + +**Logstash Configuration:** + +```ruby +# logstash.conf +input { + tcp { + port => 5044 + codec => json_lines + } +} + +filter { + # Parse timestamp + date { + match => ["timestamp", "ISO8601"] + } + + # Add geo-IP for client addresses + if [client_ip] { + geoip { + source => "client_ip" + } + } + + # Tag security events + if [event_type] in ["AuthFailure", "IpBlocked", "SuspiciousActivity"] { + mutate { + add_tag => ["security_event"] + } + } +} + +output { + elasticsearch { + hosts => ["elasticsearch:9200"] + index => "bssh-audit-%{+YYYY.MM.dd}" + } +} +``` + +## Log Analysis + +### Common Queries + +**Failed Authentication Attempts:** +```bash +# From JSON Lines file +grep '"event_type":"AuthFailure"' /var/log/bssh/audit.log | \ + jq -r '[.timestamp, .user, .client_ip] | @tsv' +``` + +**Sessions by User:** +```bash +grep '"event_type":"SessionStart"' /var/log/bssh/audit.log | \ + jq -r '.user' | sort | uniq -c | sort -rn +``` + +**File Transfers:** +```bash +grep -E '"event_type":"(FileUploaded|FileDownloaded)"' /var/log/bssh/audit.log | \ + jq -r '[.timestamp, .event_type, .user, .path, .bytes] | @tsv' +``` + +**Blocked IPs:** +```bash +grep '"event_type":"IpBlocked"' /var/log/bssh/audit.log | \ + jq -r '[.timestamp, .client_ip, .details.reason] | @tsv' +``` + +### Elasticsearch Queries + +**Authentication Failures in Last Hour:** +```json +{ + "query": { + "bool": { + "must": [ + {"term": {"event_type": "AuthFailure"}}, + {"range": {"timestamp": {"gte": "now-1h"}}} + ] + } + }, + "aggs": { + "by_ip": { + "terms": {"field": "client_ip"} + } + } +} +``` + +**Top Users by Session Count:** +```json +{ + "query": { + "term": {"event_type": "SessionStart"} + }, + "aggs": { + "by_user": { + "terms": {"field": "user", "size": 10} + } + } +} +``` + +## Integration Examples + +### Grafana Dashboard + +Create alerts for security events: + +```yaml +# Grafana alert rule +groups: + - name: bssh-security + rules: + - alert: HighAuthFailureRate + expr: | + sum(rate(bssh_auth_failures_total[5m])) > 10 + for: 5m + labels: + severity: warning + annotations: + summary: High authentication failure rate + + - alert: IPBlocked + expr: | + increase(bssh_ip_blocked_total[1m]) > 0 + for: 0m + labels: + severity: info + annotations: + summary: IP address blocked due to failed auth attempts +``` + +### SIEM Integration + +**Splunk:** + +Configure HTTP Event Collector (HEC) via OpenTelemetry Collector: + +```yaml +exporters: + splunk_hec: + token: "" + endpoint: "https://splunk:8088/services/collector" + source: "bssh-server" + sourcetype: "bssh:audit" +``` + +**Datadog:** + +```yaml +exporters: + datadog: + api: + key: "" + logs: + enabled: true +``` + +### Security Automation + +**Automatic IP Blocking with fail2ban:** + +```ini +# /etc/fail2ban/filter.d/bssh.conf +[Definition] +failregex = "event_type":"AuthFailure".*"client_ip":"" +ignoreregex = + +# /etc/fail2ban/jail.d/bssh.conf +[bssh] +enabled = true +filter = bssh +logpath = /var/log/bssh/audit.log +maxretry = 5 +bantime = 3600 +findtime = 600 +``` + +## Best Practices + +### 1. Enable Audit Logging in Production + +Always enable audit logging for production deployments: + +```yaml +audit: + enabled: true +``` + +### 2. Use Multiple Exporters + +Send logs to multiple destinations for redundancy: + +```yaml +audit: + exporters: + - type: file + path: /var/log/bssh/audit.log + - type: otel + endpoint: http://otel-collector:4317 +``` + +### 3. Protect Audit Logs + +Secure audit log files: + +```bash +chmod 600 /var/log/bssh/audit.log +chown root:root /var/log/bssh/audit.log +``` + +### 4. Retain Logs Appropriately + +Configure retention based on compliance requirements: +- SOC 2: Minimum 1 year +- HIPAA: Minimum 6 years +- PCI DSS: Minimum 1 year +- GDPR: As long as necessary, minimize data + +### 5. Monitor Security Events + +Set up alerts for: +- High authentication failure rates +- IP blocks +- Unusual session patterns +- Suspicious file access + +### 6. Regular Log Review + +Schedule regular review of audit logs: +- Daily: Security events (AuthFailure, IpBlocked) +- Weekly: Session patterns, user activity +- Monthly: Overall trends, compliance reports + +### 7. Avoid Logging Sensitive Data + +Be aware that command execution events may contain sensitive data. Consider: +- Filtering commands before logging +- Encrypting audit logs at rest +- Restricting access to audit logs + +## Troubleshooting + +### Logs Not Being Written + +1. Check if audit is enabled: + ```yaml + audit: + enabled: true + ``` + +2. Verify file permissions: + ```bash + ls -la /var/log/bssh/ + ``` + +3. Check disk space: + ```bash + df -h /var/log + ``` + +### OpenTelemetry Connection Failed + +1. Verify endpoint is reachable: + ```bash + nc -zv otel-collector 4317 + ``` + +2. Check collector logs: + ```bash + docker logs otel-collector + ``` + +### High Log Volume + +1. Consider sampling for high-traffic deployments +2. Adjust log rotation settings +3. Filter verbose events (FileRead/FileWrite) + +## See Also + +- [Server Configuration](./architecture/server-configuration.md) +- [Security Guide](./security.md) +- [Container Deployment](./container-deployment.md) diff --git a/docs/container-deployment.md b/docs/container-deployment.md new file mode 100644 index 00000000..b04869e3 --- /dev/null +++ b/docs/container-deployment.md @@ -0,0 +1,534 @@ +# Container Deployment Guide + +[Back to Documentation Index](./README.md) + +This guide covers deploying bssh-server in containerized environments including Docker and Kubernetes. + +## Table of Contents + +- [Docker Deployment](#docker-deployment) +- [Docker Compose](#docker-compose) +- [Kubernetes Deployment](#kubernetes-deployment) +- [Configuration Best Practices](#configuration-best-practices) +- [Health Checks](#health-checks) +- [Logging and Monitoring](#logging-and-monitoring) + +## Docker Deployment + +### Dockerfile + +Create a minimal Dockerfile for bssh-server: + +```dockerfile +FROM debian:bookworm-slim + +# Install dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + openssh-client \ + && rm -rf /var/lib/apt/lists/* + +# Create bssh user and directories +RUN useradd -m -s /bin/bash bsshuser \ + && mkdir -p /etc/bssh /var/log/bssh \ + && chmod 755 /etc/bssh /var/log/bssh + +# Copy binaries +COPY --chmod=755 bssh-server /usr/local/bin/ +COPY --chmod=755 bssh-keygen /usr/local/bin/ + +# Generate host keys at build time (or mount at runtime) +RUN bssh-keygen -t ed25519 -f /etc/bssh/ssh_host_ed25519_key -y -q + +# Copy configuration +COPY server.yaml /etc/bssh/server.yaml + +# Expose SSH port +EXPOSE 22 + +# Health check +HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ + CMD nc -z localhost 22 || exit 1 + +# Run server +ENTRYPOINT ["bssh-server"] +CMD ["-c", "/etc/bssh/server.yaml", "-D"] +``` + +### Minimal Configuration for Containers + +```yaml +# server.yaml for container deployment +server: + bind_address: "0.0.0.0" + port: 22 + host_keys: + - /etc/bssh/ssh_host_ed25519_key + max_connections: 100 + timeout: 300 + keepalive_interval: 60 + +auth: + methods: + - publickey + publickey: + authorized_keys_dir: /etc/bssh/authorized_keys + +shell: + default: /bin/bash + command_timeout: 3600 + +sftp: + enabled: true + +scp: + enabled: true + +security: + max_auth_attempts: 5 + ban_time: 300 + max_sessions_per_user: 10 + idle_timeout: 3600 +``` + +### Build and Run + +```bash +# Build the image +docker build -t bssh-server:latest . + +# Run with mounted authorized_keys +docker run -d \ + --name bssh-server \ + -p 2222:22 \ + -v /path/to/authorized_keys:/etc/bssh/authorized_keys/myuser/authorized_keys:ro \ + bssh-server:latest + +# Connect +ssh -p 2222 myuser@localhost +``` + +### Runtime Host Key Generation + +For production, generate host keys at runtime to ensure each container has unique keys: + +```dockerfile +FROM debian:bookworm-slim + +# ... base setup ... + +# Entrypoint script for key generation +COPY --chmod=755 entrypoint.sh /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] +``` + +```bash +#!/bin/bash +# entrypoint.sh + +# Generate host key if not exists +if [ ! -f /etc/bssh/ssh_host_ed25519_key ]; then + echo "Generating host key..." + bssh-keygen -t ed25519 -f /etc/bssh/ssh_host_ed25519_key -y -q +fi + +# Start server +exec bssh-server -c /etc/bssh/server.yaml -D "$@" +``` + +## Docker Compose + +### Basic Setup + +```yaml +# docker-compose.yml +version: '3.8' + +services: + bssh-server: + image: bssh-server:latest + build: + context: . + dockerfile: Dockerfile + ports: + - "2222:22" + volumes: + - ./config/server.yaml:/etc/bssh/server.yaml:ro + - ./authorized_keys:/etc/bssh/authorized_keys:ro + - ssh_host_keys:/etc/bssh/keys + environment: + - BSSH_PORT=22 + restart: unless-stopped + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "22"] + interval: 30s + timeout: 5s + retries: 3 + +volumes: + ssh_host_keys: +``` + +### With Audit Logging + +```yaml +# docker-compose.yml with audit logging +version: '3.8' + +services: + bssh-server: + image: bssh-server:latest + ports: + - "2222:22" + volumes: + - ./config/server.yaml:/etc/bssh/server.yaml:ro + - ./authorized_keys:/etc/bssh/authorized_keys:ro + - audit_logs:/var/log/bssh + depends_on: + - otel-collector + restart: unless-stopped + + otel-collector: + image: otel/opentelemetry-collector:latest + ports: + - "4317:4317" + volumes: + - ./otel-config.yaml:/etc/otel/config.yaml:ro + command: ["--config=/etc/otel/config.yaml"] + +volumes: + audit_logs: +``` + +### Environment Variable Configuration + +```yaml +services: + bssh-server: + image: bssh-server:latest + environment: + - BSSH_PORT=22 + - BSSH_BIND_ADDRESS=0.0.0.0 + - BSSH_HOST_KEY=/etc/bssh/ssh_host_ed25519_key + - BSSH_AUTH_METHODS=publickey + - BSSH_AUTHORIZED_KEYS_DIR=/etc/bssh/authorized_keys + - BSSH_SHELL=/bin/bash + - BSSH_MAX_CONNECTIONS=100 +``` + +## Kubernetes Deployment + +### ConfigMap for Configuration + +```yaml +# configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: bssh-server-config +data: + server.yaml: | + server: + bind_address: "0.0.0.0" + port: 22 + host_keys: + - /etc/bssh/keys/ssh_host_ed25519_key + max_connections: 100 + + auth: + methods: + - publickey + publickey: + authorized_keys_dir: /etc/bssh/authorized_keys + + shell: + default: /bin/bash + + sftp: + enabled: true + + scp: + enabled: true + + security: + max_auth_attempts: 5 + ban_time: 300 +``` + +### Secret for Host Keys + +```yaml +# secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: bssh-host-keys +type: Opaque +data: + # Base64-encoded host key (generate with bssh-server gen-host-key, then base64 encode) + ssh_host_ed25519_key: +``` + +### Deployment + +```yaml +# deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bssh-server + labels: + app: bssh-server +spec: + replicas: 1 + selector: + matchLabels: + app: bssh-server + template: + metadata: + labels: + app: bssh-server + spec: + containers: + - name: bssh-server + image: bssh-server:latest + ports: + - containerPort: 22 + name: ssh + args: + - "-c" + - "/etc/bssh/server.yaml" + - "-D" + volumeMounts: + - name: config + mountPath: /etc/bssh/server.yaml + subPath: server.yaml + readOnly: true + - name: host-keys + mountPath: /etc/bssh/keys + readOnly: true + - name: authorized-keys + mountPath: /etc/bssh/authorized_keys + readOnly: true + resources: + requests: + memory: "64Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "500m" + livenessProbe: + tcpSocket: + port: 22 + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + tcpSocket: + port: 22 + initialDelaySeconds: 5 + periodSeconds: 5 + securityContext: + readOnlyRootFilesystem: true + runAsNonRoot: false # Required for port 22 + volumes: + - name: config + configMap: + name: bssh-server-config + - name: host-keys + secret: + secretName: bssh-host-keys + defaultMode: 0600 + - name: authorized-keys + configMap: + name: bssh-authorized-keys +``` + +### Service + +```yaml +# service.yaml +apiVersion: v1 +kind: Service +metadata: + name: bssh-server +spec: + type: LoadBalancer # or NodePort, ClusterIP + ports: + - port: 22 + targetPort: 22 + name: ssh + selector: + app: bssh-server +``` + +### Complete Kubernetes Deployment + +```bash +# Create namespace +kubectl create namespace bssh + +# Generate host key and create secret +bssh-server gen-host-key -t ed25519 -o /tmp/ssh_host_ed25519_key -y +kubectl create secret generic bssh-host-keys \ + --from-file=ssh_host_ed25519_key=/tmp/ssh_host_ed25519_key \ + -n bssh +rm /tmp/ssh_host_ed25519_key + +# Create authorized keys configmap +kubectl create configmap bssh-authorized-keys \ + --from-file=myuser/authorized_keys=$HOME/.ssh/id_ed25519.pub \ + -n bssh + +# Apply configuration +kubectl apply -f configmap.yaml -n bssh +kubectl apply -f deployment.yaml -n bssh +kubectl apply -f service.yaml -n bssh + +# Check status +kubectl get pods -n bssh +kubectl get svc -n bssh +``` + +## Configuration Best Practices + +### 1. Use Read-Only Mounts + +Mount configuration and keys as read-only to prevent modification: + +```yaml +volumes: + - name: config + mountPath: /etc/bssh/server.yaml + readOnly: true +``` + +### 2. Separate Host Keys Per Instance + +For security, each container instance should have unique host keys. Use: +- Init containers to generate keys +- Persistent volumes for key storage +- Or accept ephemeral keys for disposable containers + +### 3. Resource Limits + +Always set resource limits: + +```yaml +resources: + requests: + memory: "64Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "500m" +``` + +### 4. Security Context + +Minimize container privileges: + +```yaml +securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE # Only if binding to port < 1024 +``` + +## Health Checks + +### TCP Health Check + +```bash +# Simple TCP check +nc -z localhost 22 +``` + +### SSH Banner Check + +```bash +# Check SSH banner +timeout 5 bash -c 'echo | nc localhost 22' | grep -q SSH +``` + +### Docker Health Check + +```dockerfile +HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ + CMD nc -z localhost 22 || exit 1 +``` + +### Kubernetes Probes + +```yaml +livenessProbe: + tcpSocket: + port: 22 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + +readinessProbe: + tcpSocket: + port: 22 + initialDelaySeconds: 5 + periodSeconds: 5 +``` + +## Logging and Monitoring + +### Log Collection with Audit + +```yaml +# server.yaml +audit: + enabled: true + exporters: + - type: file + path: /var/log/bssh/audit.log +``` + +### OpenTelemetry Integration + +```yaml +# server.yaml +audit: + enabled: true + exporters: + - type: otel + endpoint: http://otel-collector:4317 +``` + +### Prometheus Metrics (via OTEL) + +Configure OpenTelemetry Collector to export metrics to Prometheus: + +```yaml +# otel-config.yaml +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + +exporters: + prometheus: + endpoint: 0.0.0.0:8889 + +service: + pipelines: + metrics: + receivers: [otlp] + exporters: [prometheus] +``` + +## See Also + +- [Quick Start Guide](./quick-start.md) +- [Server Configuration](./architecture/server-configuration.md) +- [Audit Logging](./audit-logging.md) +- [Security Guide](./security.md) diff --git a/docs/man/bssh-keygen.1 b/docs/man/bssh-keygen.1 new file mode 100644 index 00000000..97d24191 --- /dev/null +++ b/docs/man/bssh-keygen.1 @@ -0,0 +1,245 @@ +.\" Manpage for bssh-keygen +.\" Contact the maintainers to correct errors or typos. +.TH BSSH-KEYGEN 1 "January 2026" "v1.7.0" "User Commands" + +.SH NAME +bssh-keygen \- SSH key pair generation tool + +.SH SYNOPSIS +.B bssh-keygen +[\fB\-t\fR \fItype\fR] +[\fB\-b\fR \fIbits\fR] +[\fB\-f\fR \fIfile\fR] +[\fB\-C\fR \fIcomment\fR] +[\fB\-y\fR] +[\fB\-q\fR] + +.SH DESCRIPTION +.B bssh-keygen +generates SSH key pairs in OpenSSH format. It supports Ed25519 (recommended) and RSA algorithms. +Generated keys are compatible with OpenSSH and can be used for SSH authentication. + +By default, bssh-keygen generates an Ed25519 key pair and saves it to +\fI~/.ssh/id_ed25519\fR (private key) and \fI~/.ssh/id_ed25519.pub\fR (public key). + +.SH OPTIONS +.TP +.BR \-t ", " \-\-type " " \fITYPE\fR +Specifies the type of key to generate. Supported types: +.RS +.IP \fBed25519\fR 10 +(default, recommended) Ed25519 elliptic curve key. Provides strong security with compact key size +and fast operations. +.IP \fBrsa\fR 10 +RSA key. Use \fB-b\fR to specify key size. Supported for compatibility with legacy systems. +.RE + +.TP +.BR \-f ", " \-\-file " " \fIFILE\fR +Output file path for the private key. The public key is saved to \fIFILE.pub\fR. +Default: \fI~/.ssh/id_\fR (e.g., ~/.ssh/id_ed25519 for Ed25519 keys) + +.TP +.BR \-b ", " \-\-bits " " \fIBITS\fR +Number of bits for RSA key. Only applicable when \fB-t rsa\fR is specified. +.RS +.IP "Minimum:" 10 +2048 bits +.IP "Maximum:" 10 +16384 bits +.IP "Default:" 10 +4096 bits +.IP "Recommended:" 10 +4096 bits for new deployments +.RE + +.TP +.BR \-C ", " \-\-comment " " \fICOMMENT\fR +Comment to include in the public key. Typically used to identify the key owner. +Default: "bssh-keygen" + +Example: \fB-C "user@hostname"\fR + +.TP +.BR \-y ", " \-\-yes +Overwrite existing key files without prompting for confirmation. + +.TP +.BR \-q ", " \-\-quiet +Quiet mode. Suppress all output except error messages. + +.TP +.BR \-v ", " \-\-verbose +Increase verbosity level. Can be specified multiple times (\fB-vvv\fR) for maximum verbosity. + +.TP +.BR \-h ", " \-\-help +Display help message and exit. + +.TP +.BR \-V ", " \-\-version +Display version information and exit. + +.SH KEY TYPES +.SS Ed25519 (Recommended) +Ed25519 is a modern elliptic curve signature algorithm that provides: +.IP \(bu 2 +128-bit security level (equivalent to RSA-3072) +.IP \(bu 2 +Fast key generation and signing operations +.IP \(bu 2 +Compact key size (32 bytes public key, 64 bytes private key) +.IP \(bu 2 +Deterministic signatures +.IP \(bu 2 +Resistance to side-channel attacks +.PP +Ed25519 is recommended for all new key generation. + +.SS RSA +RSA is a widely-used public key algorithm. While still secure with sufficient key sizes +(2048+ bits), Ed25519 is preferred due to: +.IP \(bu 2 +Faster key generation and operations +.IP \(bu 2 +Smaller key sizes for equivalent security +.IP \(bu 2 +Better resistance to implementation errors +.PP +RSA support is provided for compatibility with legacy systems. + +.SH OUTPUT +.B bssh-keygen +creates two files: + +.TP +.I FILE +Private key in OpenSSH format. This file has permissions 0600 (owner read/write only) and should +be kept secret. + +.TP +.I FILE.pub +Public key in OpenSSH format. This file can be shared and added to remote servers' +\fIauthorized_keys\fR files. + +.PP +Unless \fB-q\fR is specified, bssh-keygen displays: +.IP \(bu 2 +Path to the saved private key +.IP \(bu 2 +Path to the saved public key +.IP \(bu 2 +SHA256 fingerprint of the key +.IP \(bu 2 +The public key content + +.SH EXAMPLES +.SS Generate Ed25519 Key (Recommended) +.nf +$ bssh-keygen +Your identification has been saved in /home/user/.ssh/id_ed25519 +Your public key has been saved in /home/user/.ssh/id_ed25519.pub +The key fingerprint is: +SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +Public key: +ssh-ed25519 AAAA... bssh-keygen +.fi + +.SS Generate Ed25519 Key with Custom Path +.nf +$ bssh-keygen -f ~/.ssh/my_server_key +.fi + +.SS Generate Ed25519 Key with Custom Comment +.nf +$ bssh-keygen -C "john@workstation" +.fi + +.SS Generate RSA Key with 4096 Bits +.nf +$ bssh-keygen -t rsa -b 4096 +.fi + +.SS Generate Key Non-Interactively +.nf +$ bssh-keygen -f /tmp/deploy_key -C "deploy@server" -y -q +.fi + +.SS Generate Key for CI/CD Pipeline +.nf +#!/bin/bash +# Generate a deployment key +bssh-keygen -t ed25519 -f ./deploy_key -C "ci-deploy" -y -q + +# Display public key for adding to server +cat ./deploy_key.pub +.fi + +.SH FILES +.TP +.I ~/.ssh/id_ed25519 +Default Ed25519 private key. + +.TP +.I ~/.ssh/id_ed25519.pub +Default Ed25519 public key. + +.TP +.I ~/.ssh/id_rsa +Default RSA private key. + +.TP +.I ~/.ssh/id_rsa.pub +Default RSA public key. + +.TP +.I ~/.ssh/ +Default directory for SSH keys. Created with permissions 0700 if it doesn't exist. + +.SH SECURITY CONSIDERATIONS +.IP \(bu 2 +Private key files are created with permissions 0600 (owner read/write only). +Never share or expose private key files. +.IP \(bu 2 +The ~/.ssh directory is created with permissions 0700 (owner only) if it doesn't exist. +.IP \(bu 2 +Ed25519 is recommended over RSA for new keys due to its stronger security properties +and resistance to various attack classes. +.IP \(bu 2 +For RSA keys, use at least 2048 bits. 4096 bits is recommended. +.IP \(bu 2 +Store private keys securely. Consider using encrypted backup solutions. +.IP \(bu 2 +Rotate keys periodically, especially for high-security environments. + +.SH EXIT STATUS +.TP +.B 0 +Successful key generation. +.TP +.B 1 +Error occurred (invalid options, write failure, etc.) + +.SH SEE ALSO +.BR bssh (1), +.BR bssh-server (8), +.BR ssh-keygen (1), +.BR ssh (1) + +.SH COMPATIBILITY +Keys generated by bssh-keygen are fully compatible with OpenSSH and can be used with: +.IP \(bu 2 +OpenSSH client and server +.IP \(bu 2 +bssh client +.IP \(bu 2 +bssh-server +.IP \(bu 2 +Any SSH implementation supporting OpenSSH key formats + +.SH BUGS +Report bugs at https://github.com/lablup/bssh/issues + +.SH AUTHORS +Lablup Inc. diff --git a/docs/man/bssh-server.8 b/docs/man/bssh-server.8 new file mode 100644 index 00000000..3eb92a95 --- /dev/null +++ b/docs/man/bssh-server.8 @@ -0,0 +1,293 @@ +.\" Manpage for bssh-server +.\" Contact the maintainers to correct errors or typos. +.TH BSSH-SERVER 8 "January 2026" "v1.7.0" "System Administration Commands" + +.SH NAME +bssh-server \- Backend.AI SSH Server for container environments + +.SH SYNOPSIS +.B bssh-server +[\fIOPTIONS\fR] [\fICOMMAND\fR] + +.SH DESCRIPTION +.B bssh-server +is a lightweight SSH server designed for container environments. It provides SSH, SFTP, and SCP +functionality with built-in audit logging, file transfer filtering, and comprehensive security +controls. + +The server supports multiple authentication methods including public key and password authentication, +with fine-grained access control through IP allowlists/blocklists and per-user session limits. + +.SH COMMANDS +.TP +.B run +Start the SSH server (default command if none specified). + +.TP +.B gen-config +Generate a configuration file template. Use \fB-o\fR to write to a file instead of stdout. + +.TP +.B hash-password +Interactively hash a password using Argon2id algorithm for use in configuration files. + +.TP +.B check-config +Validate the configuration file and display all settings. + +.TP +.B gen-host-key +Generate SSH host key files in OpenSSH format. + +.TP +.B version +Display version and build information. + +.SH OPTIONS +.SS Global Options +These options can be used with any command: + +.TP +.BR \-c ", " \-\-config " " \fIFILE\fR +Path to configuration file. If not specified, searches default locations in order: +.RS +.IP 1. 3 +\fI./bssh-server.yaml\fR (current directory) +.IP 2. 3 +\fI/etc/bssh/server.yaml\fR (system-wide) +.IP 3. 3 +\fI$XDG_CONFIG_HOME/bssh/server.yaml\fR or \fI~/.config/bssh/server.yaml\fR (user-specific) +.RE + +.TP +.BR \-b ", " \-\-bind-address " " \fIADDR\fR +Address to bind the server to. Overrides configuration file setting. +Default: 0.0.0.0 + +.TP +.BR \-p ", " \-\-port " " \fIPORT\fR +Port to listen on. Overrides configuration file setting. +Default: 2222 + +.TP +.BR \-k ", " \-\-host-key " " \fIFILE\fR +Path to host key file. Can be specified multiple times for multiple keys. +Overrides configuration file setting. + +.TP +.BR \-v ", " \-\-verbose +Increase verbosity level. Can be specified up to three times (\fB-vvv\fR) for maximum verbosity. +.RS +.IP \fB-v\fR 6 +Info level logging +.IP \fB-vv\fR 6 +Debug level logging +.IP \fB-vvv\fR 6 +Trace level logging +.RE + +.TP +.BR \-D ", " \-\-foreground +Run in foreground (do not daemonize). Useful for debugging and container deployments. + +.TP +.BR \-\-pid-file " " \fIFILE\fR +Write process ID to specified file. Used for init systems and process management. + +.SS gen-config Options +.TP +.BR \-o ", " \-\-output " " \fIFILE\fR +Write configuration template to specified file instead of stdout. +File is created with secure permissions (0600). + +.SS gen-host-key Options +.TP +.BR \-t ", " \-\-type " " \fITYPE\fR +Key type to generate: \fBed25519\fR (recommended) or \fBrsa\fR. +Default: ed25519 + +.TP +.BR \-o ", " \-\-output " " \fIFILE\fR +Output file path for the generated key. Required. + +.TP +.BR \-\-bits " " \fIBITS\fR +Key size in bits for RSA keys. Minimum: 2048, Maximum: 16384. +Default: 4096 + +.SH CONFIGURATION +The configuration file uses YAML format. Configuration values can be overridden by environment +variables with the \fBBSSH_\fR prefix, and by CLI arguments. + +.SS Configuration Precedence (highest to lowest) +.IP 1. 3 +CLI arguments +.IP 2. 3 +Environment variables (\fBBSSH_*\fR) +.IP 3. 3 +Configuration file +.IP 4. 3 +Default values + +.SS Environment Variables +.TP +.B BSSH_PORT +Server port (default: 2222) +.TP +.B BSSH_BIND_ADDRESS +Bind address (default: 0.0.0.0) +.TP +.B BSSH_HOST_KEY +Comma-separated list of host key paths +.TP +.B BSSH_MAX_CONNECTIONS +Maximum concurrent connections (default: 100) +.TP +.B BSSH_KEEPALIVE_INTERVAL +Keepalive interval in seconds (default: 60) +.TP +.B BSSH_AUTH_METHODS +Comma-separated authentication methods (publickey,password) +.TP +.B BSSH_AUTHORIZED_KEYS_DIR +Directory containing per-user authorized_keys files +.TP +.B BSSH_AUTHORIZED_KEYS_PATTERN +Pattern for authorized_keys file paths ({user} placeholder) +.TP +.B BSSH_SHELL +Default shell path (default: /bin/sh) +.TP +.B BSSH_COMMAND_TIMEOUT +Command timeout in seconds (default: 3600) + +.SS Configuration Sections +.TP +.B server +Network and connection settings (bind_address, port, host_keys, max_connections, timeout, keepalive_interval) +.TP +.B auth +Authentication methods and settings (methods, publickey, password) +.TP +.B shell +Shell execution settings (default, command_timeout, env) +.TP +.B sftp +SFTP subsystem settings (enabled, root) +.TP +.B scp +SCP protocol settings (enabled) +.TP +.B filter +File transfer filtering (enabled, rules) +.TP +.B audit +Audit logging settings (enabled, exporters) +.TP +.B security +Security and access control (max_auth_attempts, ban_time, allowed_ips, blocked_ips, etc.) + +.SH EXAMPLES +.SS Generate Configuration Template +.nf +# Output to stdout +bssh-server gen-config + +# Write to file +bssh-server gen-config -o /etc/bssh/server.yaml +.fi + +.SS Generate Host Keys +.nf +# Generate Ed25519 key (recommended) +bssh-server gen-host-key -t ed25519 -o /etc/bssh/ssh_host_ed25519_key + +# Generate RSA key +bssh-server gen-host-key -t rsa -o /etc/bssh/ssh_host_rsa_key --bits 4096 +.fi + +.SS Hash Password for Configuration +.nf +bssh-server hash-password +# Enter password interactively, copy the hash to config file +.fi + +.SS Validate Configuration +.nf +bssh-server check-config -c /etc/bssh/server.yaml +.fi + +.SS Start Server +.nf +# Start with default configuration +bssh-server + +# Start with specific config file +bssh-server -c /etc/bssh/server.yaml + +# Start in foreground with verbose logging +bssh-server -c /etc/bssh/server.yaml -D -vvv + +# Start with CLI overrides +bssh-server -c /etc/bssh/server.yaml -p 2222 -b 0.0.0.0 +.fi + +.SS Docker Deployment +.nf +docker run -d \\ + -p 2222:22 \\ + -v /path/to/config.yaml:/etc/bssh/server.yaml:ro \\ + -v /path/to/host_key:/etc/bssh/ssh_host_ed25519_key:ro \\ + bssh-server +.fi + +.SH FILES +.TP +.I /etc/bssh/server.yaml +Default system-wide configuration file. + +.TP +.I /etc/bssh/ssh_host_*_key +Default location for host key files. + +.TP +.I ~/.config/bssh/server.yaml +User-specific configuration file. + +.TP +.I ./bssh-server.yaml +Local configuration file (checked first). + +.SH SECURITY CONSIDERATIONS +.IP \(bu 2 +Host key files should have permissions 0600 (owner read/write only) +.IP \(bu 2 +Configuration files may contain password hashes; protect with permissions 0600 +.IP \(bu 2 +Use Ed25519 keys instead of RSA for better security and performance +.IP \(bu 2 +Enable IP allowlists in production to restrict access to trusted networks +.IP \(bu 2 +Configure rate limiting to prevent brute-force attacks +.IP \(bu 2 +Enable audit logging for security monitoring and compliance + +.SH EXIT STATUS +.TP +.B 0 +Successful operation. +.TP +.B 1 +Error occurred (configuration error, runtime error, etc.) + +.SH SEE ALSO +.BR bssh (1), +.BR bssh-keygen (1), +.BR sshd (8), +.BR ssh (1) + +.SH BUGS +Report bugs at https://github.com/lablup/bssh/issues + +.SH AUTHORS +Lablup Inc. diff --git a/docs/quick-start.md b/docs/quick-start.md new file mode 100644 index 00000000..dc815a5e --- /dev/null +++ b/docs/quick-start.md @@ -0,0 +1,278 @@ +# Quick Start Guide + +[Back to Documentation Index](./README.md) + +This guide helps you get bssh-server running quickly. + +## Table of Contents + +- [Prerequisites](#prerequisites) +- [Installation](#installation) +- [First Run](#first-run) +- [Basic Configuration](#basic-configuration) +- [Testing the Server](#testing-the-server) +- [Next Steps](#next-steps) + +## Prerequisites + +- Linux operating system (x86_64 or aarch64) +- Root or sudo access for port 22, or use alternative port (e.g., 2222) +- OpenSSH client for testing (`ssh` command) + +## Installation + +### From Binary Release + +```bash +# Download the latest release +curl -LO https://github.com/lablup/bssh/releases/latest/download/bssh-server-linux-amd64.tar.gz + +# Extract +tar xzf bssh-server-linux-amd64.tar.gz + +# Install to system +sudo mv bssh-server /usr/local/bin/ +sudo mv bssh-keygen /usr/local/bin/ + +# Verify installation +bssh-server version +bssh-keygen --version +``` + +### From Source + +```bash +# Clone the repository +git clone https://github.com/lablup/bssh.git +cd bssh + +# Build with Cargo +cargo build --release --bin bssh-server --bin bssh-keygen + +# Install binaries +sudo cp target/release/bssh-server /usr/local/bin/ +sudo cp target/release/bssh-keygen /usr/local/bin/ +``` + +## First Run + +### 1. Create Configuration Directory + +```bash +sudo mkdir -p /etc/bssh +sudo chmod 755 /etc/bssh +``` + +### 2. Generate Host Keys + +Host keys are required for the SSH server to identify itself to clients. + +```bash +# Generate Ed25519 key (recommended) +sudo bssh-server gen-host-key -t ed25519 -o /etc/bssh/ssh_host_ed25519_key + +# Optionally generate RSA key for compatibility +sudo bssh-server gen-host-key -t rsa -o /etc/bssh/ssh_host_rsa_key +``` + +### 3. Create Configuration File + +```bash +# Generate configuration template +sudo bssh-server gen-config -o /etc/bssh/server.yaml +``` + +### 4. Configure Authentication + +Edit `/etc/bssh/server.yaml` and configure authentication: + +#### Option A: Public Key Authentication (Recommended) + +```yaml +auth: + methods: + - publickey + publickey: + # Use standard authorized_keys location + authorized_keys_pattern: "/home/{user}/.ssh/authorized_keys" +``` + +Ensure the user's public key is in their `~/.ssh/authorized_keys` file. + +#### Option B: Password Authentication + +First, generate a password hash: + +```bash +bssh-server hash-password +# Enter your password when prompted +# Copy the generated hash +``` + +Then edit the configuration: + +```yaml +auth: + methods: + - password + password: + users: + - name: myuser + password_hash: "$argon2id$v=19$m=19456,t=2,p=1$..." # paste hash here +``` + +### 5. Start the Server + +```bash +# Start in foreground for testing +sudo bssh-server -c /etc/bssh/server.yaml -D -v + +# Or run as daemon +sudo bssh-server -c /etc/bssh/server.yaml +``` + +## Basic Configuration + +Here's a minimal working configuration: + +```yaml +# /etc/bssh/server.yaml + +server: + bind_address: "0.0.0.0" + port: 2222 + host_keys: + - /etc/bssh/ssh_host_ed25519_key + +auth: + methods: + - publickey + publickey: + authorized_keys_pattern: "/home/{user}/.ssh/authorized_keys" + +shell: + default: /bin/bash + +sftp: + enabled: true + +scp: + enabled: true +``` + +## Testing the Server + +### Test SSH Connection + +```bash +# From another terminal or machine +ssh -p 2222 youruser@localhost + +# With verbose output for debugging +ssh -v -p 2222 youruser@localhost +``` + +### Test SFTP + +```bash +sftp -P 2222 youruser@localhost +``` + +### Test SCP + +```bash +# Upload a file +scp -P 2222 localfile.txt youruser@localhost:/tmp/ + +# Download a file +scp -P 2222 youruser@localhost:/etc/hostname ./ +``` + +## Troubleshooting + +### Server Won't Start + +1. Check if the port is already in use: + ```bash + sudo lsof -i :2222 + ``` + +2. Verify host key permissions: + ```bash + ls -la /etc/bssh/ssh_host_* + # Should be -rw------- (600) + ``` + +3. Validate configuration: + ```bash + bssh-server check-config -c /etc/bssh/server.yaml + ``` + +### Authentication Fails + +1. Check verbose output from client: + ```bash + ssh -vvv -p 2222 user@localhost + ``` + +2. For public key auth, verify: + - Public key is in `~/.ssh/authorized_keys` + - File permissions: `~/.ssh` is 700, `authorized_keys` is 600 + - Home directory is not world-writable + +3. For password auth, verify: + - Password hash is correct (regenerate with `bssh-server hash-password`) + - Username matches exactly + +### View Server Logs + +Run server in foreground with verbose logging: + +```bash +sudo bssh-server -c /etc/bssh/server.yaml -D -vvv +``` + +## Next Steps + +- [Server Configuration Guide](./architecture/server-configuration.md) - Complete configuration reference +- [Security Guide](./security.md) - Security best practices +- [Container Deployment](./container-deployment.md) - Docker and Kubernetes deployment +- [Audit Logging](./audit-logging.md) - Setting up audit logging + +## Running as a Service + +### systemd Service File + +Create `/etc/systemd/system/bssh-server.service`: + +```ini +[Unit] +Description=Backend.AI SSH Server +After=network.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/bssh-server -c /etc/bssh/server.yaml -D +ExecReload=/bin/kill -HUP $MAINPID +Restart=always +RestartSec=5 +User=root + +[Install] +WantedBy=multi-user.target +``` + +Enable and start: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable bssh-server +sudo systemctl start bssh-server +sudo systemctl status bssh-server +``` + +View logs: + +```bash +sudo journalctl -u bssh-server -f +``` diff --git a/docs/security.md b/docs/security.md new file mode 100644 index 00000000..8292823f --- /dev/null +++ b/docs/security.md @@ -0,0 +1,482 @@ +# Security Guide + +[Back to Documentation Index](./README.md) + +This guide covers security best practices for deploying and configuring bssh-server. + +## Table of Contents + +- [Overview](#overview) +- [Authentication Security](#authentication-security) +- [Network Security](#network-security) +- [Session Security](#session-security) +- [File Transfer Security](#file-transfer-security) +- [Host Key Management](#host-key-management) +- [Audit and Compliance](#audit-and-compliance) +- [Hardening Checklist](#hardening-checklist) + +## Overview + +bssh-server is designed with security as a primary concern. It implements multiple layers of protection: + +- **Authentication**: Public key and password authentication with rate limiting +- **Network**: IP allowlists/blocklists with CIDR support +- **Sessions**: Per-user session limits, idle timeouts, and maximum duration +- **File Transfers**: Path traversal prevention and file filtering +- **Audit**: Comprehensive logging with multiple export options + +## Authentication Security + +### Public Key Authentication (Recommended) + +Public key authentication is more secure than passwords because: +- No secrets are transmitted over the network +- Keys are computationally infeasible to brute-force +- Keys can be protected with passphrases locally + +**Configuration:** + +```yaml +auth: + methods: + - publickey + publickey: + # Per-user directory structure + authorized_keys_dir: /etc/bssh/authorized_keys + # Structure: /etc/bssh/authorized_keys/{username}/authorized_keys + + # OR pattern-based (for existing systems) + authorized_keys_pattern: "/home/{user}/.ssh/authorized_keys" +``` + +**Best Practices:** +- Use Ed25519 keys (`bssh-keygen -t ed25519`) +- Protect private keys with passphrases +- Restrict authorized_keys file permissions to 0600 +- Regularly rotate keys (annually or when personnel changes) + +### Password Authentication + +If password authentication is required, use strong passwords with Argon2id hashing: + +```yaml +auth: + methods: + - password + password: + users: + - name: username + password_hash: "$argon2id$v=19$m=19456,t=2,p=1$..." +``` + +**Generating Password Hashes:** + +```bash +bssh-server hash-password +# Uses Argon2id with: +# - 19 MiB memory cost (resistant to GPU attacks) +# - 2 iterations +# - 1 degree of parallelism +``` + +**Best Practices:** +- Require minimum 12-character passwords +- Use unique passwords per user +- Consider disabling password auth in favor of keys +- Never store plaintext passwords + +### Rate Limiting and Banning + +Protect against brute-force attacks: + +```yaml +security: + # Ban IP after 5 failed attempts + max_auth_attempts: 5 + + # Time window for counting failures (5 minutes) + auth_window: 300 + + # Ban duration (5 minutes) + ban_time: 300 + + # IPs exempt from rate limiting + whitelist_ips: + - "127.0.0.1" + - "::1" + - "10.0.0.0/8" # Internal network +``` + +## Network Security + +### IP Access Control + +Restrict access to trusted networks: + +```yaml +security: + # Allow only these IP ranges (whitelist mode) + allowed_ips: + - "192.168.1.0/24" # Office network + - "10.0.0.0/8" # Internal network + - "2001:db8::/32" # IPv6 range + + # Always block these IPs (takes priority) + blocked_ips: + - "192.168.1.100/32" # Compromised host + - "203.0.113.0/24" # Known bad actors +``` + +**Priority Rules:** +1. Blocked IPs are always denied (highest priority) +2. If allowed_ips is configured, only those IPs are permitted +3. If allowed_ips is empty, all IPs (except blocked) are permitted + +**Best Practices:** +- Use CIDR notation for precise control +- Block entire ranges known for abuse +- Use allowlists in high-security environments +- Monitor blocked connection attempts + +### Network Binding + +Bind to specific interfaces when possible: + +```yaml +server: + # Bind to specific internal interface + bind_address: "10.0.0.1" + + # Or all interfaces (for containers) + bind_address: "0.0.0.0" +``` + +### Port Selection + +```yaml +server: + # Use non-standard port to reduce automated scans + port: 2222 + + # Or standard port 22 (requires root or capabilities) + port: 22 +``` + +## Session Security + +### Session Limits + +Prevent resource exhaustion and detect compromised accounts: + +```yaml +security: + # Maximum sessions per user + max_sessions_per_user: 10 + + # Idle session timeout (1 hour) + idle_timeout: 3600 + + # Maximum session duration (24 hours, 0 = disabled) + session_timeout: 86400 + +server: + # Maximum total connections + max_connections: 100 + + # Connection timeout (5 minutes) + timeout: 300 + + # SSH keepalive interval + keepalive_interval: 60 +``` + +### Shell Security + +```yaml +shell: + # Use restricted shell if available + default: /bin/rbash + + # Command execution timeout + command_timeout: 3600 + + # Minimal environment + env: + PATH: /usr/bin:/bin + LANG: C.UTF-8 +``` + +**Per-User Shell Restrictions:** + +```yaml +auth: + password: + users: + - name: sftp-only + password_hash: "..." + shell: /usr/sbin/nologin # No shell access +``` + +## File Transfer Security + +### SFTP/SCP Control + +```yaml +# Disable if not needed +sftp: + enabled: false + +scp: + enabled: false + +# Or enable with restrictions +sftp: + enabled: true + root: /data/sftp # Chroot to this directory +``` + +### File Transfer Filtering + +Block dangerous file types: + +```yaml +filter: + enabled: true + rules: + # Block executable uploads + - pattern: "*.exe" + action: deny + - pattern: "*.sh" + action: deny + - pattern: "*.py" + action: deny + + # Block uploads to sensitive directories + - path_prefix: "/etc/" + action: deny + - path_prefix: "/usr/" + action: deny + + # Log all transfers to temp + - path_prefix: "/tmp/" + action: log +``` + +**Filter Actions:** +- `deny`: Block the transfer +- `allow`: Explicitly allow (overrides other rules) +- `log`: Allow but log the transfer + +### Path Traversal Prevention + +bssh-server automatically prevents path traversal attacks: +- All paths are normalized before processing +- `..` components cannot escape the root directory +- Symlinks are resolved and validated +- Absolute paths are stripped and joined with the user's root + +## Host Key Management + +### Key Generation + +```bash +# Generate Ed25519 key (recommended) +bssh-server gen-host-key -t ed25519 -o /etc/bssh/ssh_host_ed25519_key + +# Generate RSA key (for compatibility) +bssh-server gen-host-key -t rsa -o /etc/bssh/ssh_host_rsa_key --bits 4096 +``` + +### Key Permissions + +```bash +# Ensure secure permissions +chmod 600 /etc/bssh/ssh_host_*_key +chown root:root /etc/bssh/ssh_host_*_key +``` + +### Key Rotation + +Rotate host keys periodically (annually) or when: +- Key may have been compromised +- Significant personnel changes occur +- Migrating to new infrastructure + +**Rotation Process:** +1. Generate new host key +2. Update configuration to include both old and new keys +3. Notify users of host key change +4. After transition period, remove old key + +## Audit and Compliance + +### Enable Audit Logging + +```yaml +audit: + enabled: true + exporters: + # Local file (JSON Lines format) + - type: file + path: /var/log/bssh/audit.log + + # Send to SIEM via OpenTelemetry + - type: otel + endpoint: http://otel-collector:4317 + + # Send to Logstash + - type: logstash + host: logstash.example.com + port: 5044 +``` + +### Audit Events + +The following events are logged: +- **Authentication**: Success, failure, rate limiting +- **Sessions**: Start, end, duration +- **Commands**: Executed commands (can contain sensitive data) +- **File Operations**: Read, write, delete, rename +- **Security**: IP blocks, suspicious activity + +### Log Protection + +```bash +# Protect audit logs +chmod 600 /var/log/bssh/audit.log +chown root:root /var/log/bssh/audit.log + +# Configure log rotation +cat > /etc/logrotate.d/bssh << EOF +/var/log/bssh/*.log { + daily + rotate 90 + compress + delaycompress + missingok + notifempty + create 0600 root root +} +EOF +``` + +## Hardening Checklist + +### Minimal Configuration + +- [ ] Use public key authentication only +- [ ] Disable password authentication +- [ ] Disable unused subsystems (SFTP/SCP) +- [ ] Set appropriate timeouts +- [ ] Configure session limits + +### Network Hardening + +- [ ] Configure IP allowlists for production +- [ ] Use non-standard port if appropriate +- [ ] Bind to specific interface if possible +- [ ] Deploy behind firewall/load balancer + +### Key Management + +- [ ] Use Ed25519 keys +- [ ] Set correct file permissions (0600) +- [ ] Rotate keys periodically +- [ ] Store keys securely (HSM for high security) + +### Monitoring and Audit + +- [ ] Enable audit logging +- [ ] Configure log shipping to SIEM +- [ ] Set up alerts for security events +- [ ] Regularly review access logs + +### File Security + +- [ ] Enable file transfer filtering +- [ ] Block dangerous file types +- [ ] Restrict upload directories +- [ ] Use SFTP chroot when possible + +### Container Security + +- [ ] Use minimal base image +- [ ] Run as non-root if possible +- [ ] Set resource limits +- [ ] Use read-only filesystem +- [ ] Generate unique host keys per instance + +## Security Configuration Example + +Complete security-focused configuration: + +```yaml +# /etc/bssh/server.yaml - High Security Configuration + +server: + bind_address: "10.0.0.1" + port: 2222 + host_keys: + - /etc/bssh/ssh_host_ed25519_key + max_connections: 50 + timeout: 120 + keepalive_interval: 30 + +auth: + methods: + - publickey + publickey: + authorized_keys_dir: /etc/bssh/authorized_keys + +shell: + default: /bin/rbash + command_timeout: 1800 + env: + PATH: /usr/bin:/bin + +sftp: + enabled: true + root: /data/sftp + +scp: + enabled: false + +filter: + enabled: true + rules: + - pattern: "*.exe" + action: deny + - pattern: "*.dll" + action: deny + - path_prefix: "/etc/" + action: deny + +audit: + enabled: true + exporters: + - type: file + path: /var/log/bssh/audit.log + - type: otel + endpoint: http://siem:4317 + +security: + max_auth_attempts: 3 + auth_window: 300 + ban_time: 900 + whitelist_ips: + - "127.0.0.1" + max_sessions_per_user: 5 + idle_timeout: 1800 + session_timeout: 28800 + allowed_ips: + - "10.0.0.0/8" + - "192.168.0.0/16" + blocked_ips: + - "0.0.0.0/8" +``` + +## See Also + +- [Server Configuration](./architecture/server-configuration.md) +- [Audit Logging](./audit-logging.md) +- [Quick Start Guide](./quick-start.md)