Skip to content

SSH-KLM Quickstart

Get SSH-KLM running in 5 minutes and discover your first SSH keys.

This guide walks you through deploying SSH-KLM locally, running your first discovery scan, and viewing discovered keys in the dashboard.

  • Evaluate SSH-KLM features quickly
  • Development and testing environments
  • Proof of concept deployments
  • Learning the platform before production rollout
RequirementDetails
DockerVersion 20.10+ with Docker Compose
Ports8081 (UI), 5432 (PostgreSQL), 6379 (Redis)
MemoryMinimum 4GB RAM available
Target ServerSSH access to at least one Linux server (for testing)
Terminal window
# Clone the repository
git clone https://github.com/qcecuring/ssh-klm.git
cd ssh-klm
# Start all services
docker-compose up -d
# Verify services are running
docker-compose ps

Expected output:

NAME STATUS PORTS
ssh-klm-api Up 0.0.0.0:8081->8081/tcp
ssh-klm-db Up 0.0.0.0:5432->5432/tcp
ssh-klm-redis Up 0.0.0.0:6379->6379/tcp
ssh-klm-worker Up
  1. Open http://localhost:8081 in your browser
  2. Login with default credentials:
    • Username: admin@qcecuring.local
    • Password: changeme123
  3. Important: Change the default password immediately

Navigate to Inventory → Add Host and enter:

Host: server01.example.com
Port: 22
Username: root # or your SSH user
Authentication: Password # or SSH Key

Alternatively, use the SDK:

import { QcClient } from '@qcecuring/ssh-sdk';
const client = new QcClient({
apiKey: process.env.QC_API_KEY,
baseUrl: 'http://localhost:8081'
});
// Add a host
await client.ssh.addHost({
hostname: 'server01.example.com',
port: 22,
username: 'root',
authMethod: 'password',
credential: process.env.SSH_PASSWORD
});
  1. Go to Discovery → New Scan
  2. Select your host from the inventory
  3. Click Start Discovery

Or via SDK:

// Trigger discovery
const scan = await client.ssh.startDiscovery({
hosts: ['server01.example.com'],
scanType: 'full' // 'full' | 'incremental'
});
console.log(`Scan started: ${scan.id}`);

After the scan completes (typically 1-2 minutes):

  1. Navigate to Keys → All Keys
  2. View discovered SSH keys with details:
    • Key fingerprint
    • Algorithm (RSA, ED25519, ECDSA)
    • Key age and last used
    • Risk score
// List discovered keys
const keys = await client.ssh.listKeys({
host: 'server01.example.com',
status: 'active'
});
keys.forEach(key => {
console.log(`${key.fingerprint} - ${key.algorithm} - Risk: ${key.riskScore}`);
});

Test key rotation on a non-production key:

  1. Select a key from the list
  2. Click Actions → Rotate Key
  3. Choose rotation options:
    • Generate new key pair
    • Update authorized_keys
    • Archive old key
// Rotate a specific key
await client.ssh.rotateKey({
keyId: 'KEY-12345',
algorithm: 'ed25519',
archiveOld: true
});
import { QcClient } from '@qcecuring/ssh-sdk';
async function discoverAndReport() {
const client = new QcClient({ apiKey: process.env.QC_API_KEY });
// Add hosts
const hosts = ['server01', 'server02', 'server03'];
for (const host of hosts) {
await client.ssh.addHost({ hostname: `${host}.example.com` });
}
// Run discovery
const scan = await client.ssh.startDiscovery({
hosts: hosts.map(h => `${h}.example.com`)
});
// Wait for completion
await client.ssh.waitForScan(scan.id);
// Get results
const keys = await client.ssh.listKeys({ scanId: scan.id });
console.log(`Discovered ${keys.length} SSH keys`);
console.log(`High risk keys: ${keys.filter(k => k.riskScore > 80).length}`);
}

Issue: Docker containers fail to start

Solution:

Terminal window
# Check logs
docker-compose logs -f
# Restart services
docker-compose down
docker-compose up -d

Issue: Discovery fails with connection error

Solution:

  • Verify SSH port (22) is accessible
  • Check firewall rules
  • Validate credentials
  • Test manually: ssh user@host

Issue: Scan completes but no keys found

Solution:

  • Verify user has permission to read ~/.ssh/ and /etc/ssh/
  • Check scan logs in Discovery → Scan History
  • Try running with elevated privileges

Now that you have SSH-KLM running:

GuideDescription
Docker InstallationProduction Docker deployment
Kubernetes SetupDeploy on K8s
Discovery ConceptsHow discovery works
Rotation PoliciesConfigure automated rotation
API OverviewFull API documentation