Klicka för att visa logg
Klicka för att visa ansökningar
Granska och hantera inkommande ansökningar
ℹ️ Server Hälsa och Lagringsutrymme har flyttats till Översikt-fliken för snabbare åtkomst.
RSA-2048 Challenge-Response Authentication
Real-time monitoring • Auto-refresh: 5s
🔒 Security: En angripare som stjäl USB:et måste söka igenom 50,000 filer för att hitta nycklarna
Komplett dokumentation för Cimbora Admin-systemet
Alla markdown-dokument från /docs/-mappen
SuperAdmin låstes ute från admin-panelen. Gamla USB-nyckeln fungerade inte längre. Ingen inloggning, ingen SSH-åtkomst. Total lockout i ~2 timmar.
Root cause: USB-nycklarna hade genererats men filformateringen blev korrupt vid nedladdning.
node generate-superadmin-usb.js 31 32 33
Genererar 3 RSA-2048 keypairs (LOGIN, MOUNT, SUPPORT) och sparar till /tmp/superadmin-usb/
Fil: Chilimarinerade_Tiger_Rakor.txt
Användning: Logga in på admin-panelen (2FA)
Status: ✅ TESTAD & FUNGERAR
Device type validation implementerad (SuperAdmin Login, Mount, Support)
Endpoints skapade men inte fullständigt testade
Backend emergency download-endpoints + troubleshooting-dokumentation
Räddade situationen när user var utlåst
UI för att se alla användares receptval med Keypair #3-autentisering
Verifiera att alla 3 keypairs fungerar som planerat
Kitchen Security v1 - verifiera att kunder kan generera USB-nycklar
Problem: SuperAdmin utlåst från admin-panelen efter generering av nya USB-nycklar.
Impact: Total access lockout - ingen inloggning, ingen SSH.
Duration: ~2 timmar troubleshooting.
Root Cause: Claude Chat lade till extra whitespace i PEM-nycklar vid artifact-generering.
User rapporterar: "i cant get into cimbora admin whit OG stick!"
Gamla USB-nyckeln fungerar inte längre efter systemuppdatering.
Plan: Lägg USB-nycklar på cimbora.se/emergency
Blocker: Kan inte editera /var/www/cimbora.se/index.html (EACCES permission denied)
Status: ❌ FAILED
Plan: Skapa /emergency route i backend + HTML download-sida
Implementation: emergency-download.html + /api/usb/download-temp/:filename
Blocker: User saknar sudo för nginx-reload (twilight zone)
Status: ❌ FAILED (route ej tillgänglig utan nginx-config)
Plan: Read filerna och ge innehållet direkt i chat
Implementation: Läste alla 3 USB-filer (86 lines each)
Result: User fick alla 3 nycklar via copy-paste
Status: ✅ FILES DELIVERED
Plan: Skapa prompt för Claude Chat att generera nedladdningsbara artifacts
Implementation: User pastade innehållet i Claude Chat
Result: Artifacts skapade, men... "dem funka inte"
Status: ❌ FAILED
Console logs revealed:
• LOGIN key: PEM length 2008 bytes → Binary 1506 bytes ❌
• MOUNT key: PEM length 2082 bytes → Binary 1561 bytes ❌
• SUPPORT key: PEM length 1624 bytes → Binary 1218 bytes ✅
SUPPORT-nyckeln fungerade! Men den var fel typ (Support, inte Login).
Detta bevisade att filformatet var korrekt när det laddades rätt.
Plan: Skippa Claude Chat - serve originalfilerna direkt från backend
Implementation:
1. Skapade download-usb-keys.html (snygg UI med grönt tema)
2. Lade till /download-keys route i backend
3. Länkade direkt till /api/usb/download-temp/:filename
4. User gick till https://admin.cimbora.se/download-keys
5. Laddade ner ORIGINALNYCKLARNA från /tmp/superadmin-usb/
✅ SUCCESS! User loggade in!
Key insight: Logging binary key length avslöjade att LOGIN/MOUNT hade ~300 extra bytes jämfört med SUPPORT.
När debugging kryptografiska nycklar - gå alltid tillbaka till originalfilerna. Varje mellanhand (copy-paste, artifacts, formatering) kan introducera corruption.
RSA-2048 PKCS#8 nycklar har förutsägbar binary-storlek (~1218 bytes). Om storleken är off = något är korrupt.
Ha alltid en backup-plan för lockout scenarios. Backend emergency-endpoints räddade situationen trots nginx-begränsningar.
Detaljerad logging i varje steg av RSA-signaturen (PEM parse → base64 decode → binary import → sign) gjorde root cause-analysen möjlig.
Att SUPPORT-nyckeln fungerade (men LOGIN/MOUNT inte) bevisade att problemet var file-specifikt, inte systemiskt.
"we have a problem! i cant get into cimbora admin whit OG stick!" → "nu är jag inne i admin igen!" 🎉
Total troubleshooting time: ~2 hours | Solutions attempted: 5 | Success rate: 100% (eventually)
Cimbora Admin använder ett tvåskiktat USB-säkerhetssystem som kombinerar fysisk hårdvara med RSA-2048 kryptografisk autentisering. Systemet ger säker åtkomst till serverns lagringsyta genom challenge-response-mekanismer.
/mnt/cimbora-secure/mnt/cimbora-customers/{slug}Cimbora Admin kräver BÅDE lösenord OCH SuperAdmin USB för att logga in. Detta ger maximal säkerhet för admin-panelen.
Login kräver SuperAdmin USB men monterar INTE automatiskt server USB. Mount är en separat operation efter login.
Data är uppdelad i två säkerhetsnivåer baserat på känslighet. Detta ger proportionell säkerhet och bättre UX.
INGEN USB krävs
/api/dashboard - Aggregate stats/api/system/info - Server healthUSB KRÄVS
/api/customers - Kundlistor/api/applications - Ansökningar/api/onboarding - Företagsdetaljer/api/events - Event logs/api/maintenance/* - Detaljerad info// USB mount verification middleware const requireUSBMount = async (req, res, next) => { // Check if there's an active SuperAdmin USB session const activeSessions = usbSecurity.listActiveSessions(); const hasActiveSession = activeSessions.some(session => session.businessId === 4 && session.isSuperAdmin ); if (!hasActiveSession) { return res.status(403).json({ error: 'USB måste vara mountad', requiresUSBMount: true }); } next(); }; // Tier 2 endpoints protected with middleware app.get('/api/customers', authMiddleware, requireUSBMount, handler);
Admin loggar in (2FA) → Ser Dashboard stats → Ingen USB mount behövs → Snabb översikt klar
Admin loggar in (2FA) → Försöker se kunder → Får 🔒 meddelande → Mountar USB → Full åtkomst
Admin visar kund systemet → Försöker se deras data → Måste mounta USB först → Kund SER säkerheten i praktiken
┌─────────────────────────────────────────────────────────────┐
│ ANVÄNDARE (Remote) │
│ ┌───────────────┐ ┌──────────────────┐ │
│ │ Webbläsare │ │ Fysisk USB │ │
│ │ (Admin UI) │◄────────►│ (Private Key) │ │
│ └───────┬───────┘ └──────────────────┘ │
└──────────┼─────────────────────────────────────────────────┘
│
│ HTTPS (Challenge-Response)
│
┌──────────▼─────────────────────────────────────────────────┐
│ BACKEND SERVER │
│ ┌────────────────────────────────────────────────────┐ │
│ │ server.js (Express) │ │
│ │ • API Endpoints │ │
│ │ • Authentication Middleware │ │
│ └────────┬──────────────────────────┬────────────────┘ │
│ │ │ │
│ ┌────────▼──────────┐ ┌───────▼──────────────┐ │
│ │ usb-security.js │ │ PostgreSQL Database │ │
│ │ • Challenge Gen │ │ • usb_devices │ │
│ │ • Verification │ │ • usb_sessions │ │
│ │ • Mount/Unmount │ │ • businesses │ │
│ └────────┬──────────┘ └──────────────────────┘ │
└───────────┼─────────────────────────────────────────────────┘
│
│ sudo mount
│
┌───────────▼─────────────────────────────────────────────────┐
│ FYSISK SERVER USB │
│ ┌────────────────────────────────────────────────────┐ │
│ │ /dev/sda1 (Kingston DataTraveler 230.9GB) │ │
│ │ ├─ /mnt/cimbora-secure/ (SuperAdmin) │ │
│ │ └─ /mnt/cimbora-secure/customers/{slug}/ (Kund) │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Klient-sidig kryptografi för nyckelgenerering och signering
RSASSA-PKCS1-v1_5 med SHA-256 för signering
Passwordless mount för cimbora-användaren
Isolering av kunders mappar
-- USB Devices Table
CREATE TABLE usb_devices (
id SERIAL PRIMARY KEY,
business_id INTEGER REFERENCES businesses(id),
device_type VARCHAR(50) NOT NULL,
serial_number VARCHAR(100) UNIQUE NOT NULL,
public_key TEXT NOT NULL,
is_super_admin BOOLEAN DEFAULT FALSE,
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMP DEFAULT NOW(),
revoked_at TIMESTAMP
);
-- USB Sessions Table (in-memory via Map)
{
sessionId: string,
businessId: number,
deviceId: number,
businessName: string,
isSuperAdmin: boolean,
mountPoint: string,
mountPath: string,
mountedAt: timestamp,
lastActivity: timestamp
}
⚡ Quick Create USB knappen
{namn}-usb-package.txt laddas ner automatiskt
https://admin.cimbora.se och logga in
🔓 Mount USB i övre högra hörnet
Gå till 🔐 USB-säkerhet för att se real-time status:
✓ Mounted / ✗ Not Mounted
Antal användare inloggade
Serverns mount-sökväg
Återstående sessionstid
| Algorithm | RSA-2048 |
| Signature Scheme | RSASSA-PKCS1-v1_5 |
| Hash Function | SHA-256 |
| Challenge Format | 32-byte hex string (crypto.randomBytes) |
| Challenge Timeout | 60 sekunder |
| Session Timeout | 30 minuter |
Alla USB-relaterade händelser loggas i system_events tabellen:
usb_device_created - Ny USB-enhet registreradusb_device_revoked - USB-enhet revokeradusb_mounted - Server-USB monteradusb_unmounted - Server-USB avmonteradchallenge_requested - Autentiseringsförsökchallenge_failed - Misslyckad autentiseringPOST
/api/auth/login
Admin UI login
{
"username": "admin",
"password": "password"
}
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
GET
/api/usb/devices
List all USB devices (requires JWT)
{
"devices": [
{
"id": 1,
"business_id": 4,
"business_name": "Cimbora Admin",
"device_type": "Kingston DataTraveler",
"serial_number": "SA-001",
"is_super_admin": true,
"status": "active",
"created_at": "2025-11-25T..."
}
]
}
POST
/api/usb/devices
Register new USB device (requires JWT)
{
"business_id": 4,
"device_type": "Kingston DataTraveler",
"serial_number": "SA-001",
"public_key": "-----BEGIN PUBLIC KEY-----\n...",
"is_super_admin": true
}
POST
/api/usb/challenge
Request authentication challenge (no auth required)
{
"serial_number": "SA-001"
}
{
"success": true,
"challenge_id": "abc123...",
"challenge": "d4e5f6..."
}
POST
/api/usb/mount
Mount server USB after authentication (no JWT, uses challenge-response)
{
"challenge_id": "abc123...",
"signature": "base64_signature..."
}
{
"success": true,
"sessionId": "session123...",
"mountPath": "/mnt/cimbora-secure",
"isSuperAdmin": true,
"businessId": 4,
"deviceId": 1
}
POST
/api/usb/unmount
Unmount server USB (no auth required, uses session_id)
{
"session_id": "session123..."
}
GET
/api/usb/sessions
List active mount sessions (requires JWT)
{
"sessions": [
{
"sessionId": "session123...",
"businessId": 4,
"deviceId": 1,
"businessName": "Cimbora Admin",
"isSuperAdmin": true,
"mountPath": "/mnt/cimbora-secure",
"mountedAt": 1732552800000,
"lastActivity": 1732552850000,
"timeoutMinutes": 30
}
]
}
Real-time loggning av alla systemhändelser
Symptom: Fel vid montering: "must be superuser to use mount"
Orsak: sudoers-konfiguration saknas eller är felaktig
Lösning:
/etc/sudoers.d/cimbora-usb existerarsudo ls -la /etc/sudoers.d/ (ska vara 440)sudo visudo -cSymptom: "Authentication failed" vid mount-försök
Möjliga orsaker:
Lösning:
Symptom: Session avslutas oväntat, USB avmonteras
Orsak: 30-minuters inaktivitet
Lösning:
Symptom: Keypair-generering eller signering misslyckas
Orsak: Webbläsaren stöder inte Web Crypto API eller använder HTTP istället för HTTPS
Lösning:
window.crypto.subtle är tillgängligt