Lompat ke konten
dokumentasi.id
Commit 0da916f
v1
Star0

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

1

Ringkasan Proyek Termimus

Termimus adalah SSH client sekaligus server management suite yang berjalan local-first: database-nya hidup di mesin pengguna, dan sinkronisasi multi-device bersifat opsional menuju relay yang di-host sendiri. README menyebutnya sebagai alternatif Termius yang self-hosted untuk Linux, macOS, dan Windows pada versi v0.7.0 (README.md:8-9). Karena kredensial produksi tidak boleh disimpan di cloud pihak ketiga, basis datanya berjalan 100% offline lewat SQLite tertanam, dan private key maupun password tidak pernah meninggalkan mesin dalam bentuk terdekripsi (README.md:29-34).

Desktop client dibangun dengan Tauri v2 + Rust backend + React frontend (AGENTS.md:7). Versi 0.7.0 konsisten di tiga berkas manifes: package.json, src-tauri/Cargo.toml, dan src-tauri/tauri.conf.json (package.json:1-11, src-tauri/Cargo.toml:1-6, src-tauri/tauri.conf.json:1-11).

Tiga Komponen dan Batas Kepercayaan

Sistem terdiri atas tiga bagian yang batas kepercayaannya berbeda tajam: desktop client, SQLite lokal, dan relay Go. Hanya dua komponen pertama yang pernah melihat plaintext.

graph TD
  subgraph Client["Desktop client (Tauri v2 + Rust + React 19)"]
    UI["UI React<br/>src/components"]
    Core["IPC commands<br/>commands/mod.rs"]
    Vault["VaultManager<br/>AES-256-GCM + Argon2id"]
  end

  DB["SQLite lokal<br/>termimus.db"]
  Relay["Go sync relay<br/>termimus-sync"]

  UI --> Core
  Core --> Vault
  Vault --> DB
  Core --> DB
  Core -->|"POST ciphertext bundle"| Relay
  Relay -->|"SYNC_UPDATED"| Core

  style DB fill:#336791,color:#fff
  style Relay fill:#336791,color:#fff
  style Vault fill:#f59e0b,color:#000
  style Core fill:#8b5cf6,color:#fff
%% fig: Tiga komponen Termimus dan batas kepercayaannya
%% desc: Client memegang kunci dan plaintext, SQLite lokal menyimpan data terenkripsi, sedangkan relay Go hanya menerima ciphertext dan mengirim notifikasi SYNC_UPDATED.
Fig. 1: Tiga komponen Termimus dan batas kepercayaannyaClient memegang kunci dan plaintext, SQLite lokal menyimpan data terenkripsi, sedangkan relay Go hanya menerima ciphertext dan mengirim notifikasi SYNC_UPDATED.

Pembagian itu juga terlihat pada diagram arsitektur di README, yang menggambarkan dua mesin pengguna yang sama-sama memegang kunci enkripsi dan sebuah relay di antaranya yang hanya menerima ciphertext bundle (README.md:99-118).

Local-First: Data Dimulai dari Disk

Saat aplikasi dijalankan, Database::new membuka SQLite di config_dir()/termimus/termimus.db (src-tauri/src/db/mod.rs:1250-1255). Objek itu dibungkus Arc bersama VaultManager, SessionManager, SftpManager, TunnelManager, dan PtyManager, lalu dimasukkan ke satu AppState yang dipakai seluruh handler Tauri (src-tauri/src/lib.rs:22-30).

VaultManager hanya menyimpan derived_key: RwLock<Option<[u8; 32]>> di memori; lock() menulis nol ke seluruh byte kunci lewat zeroize sebelum melepasnya, dan is_unlocked() menjadi gerbang sebelum secret apa pun disentuh (src-tauri/src/vault/mod.rs:10-34).

Relay Buta Isi

Server sinkronisasi adalah relay Go yang tidak bisa membaca payload. Dokumen server menyatakan bahwa semua host, folder, snippet, tunnel, dan credential dienkripsi di sisi client dengan AES-256-GCM memakai kunci turunan Argon2id, dan server hanya menyimpan serta meneruskan EncryptedBackupEnvelope (server/README.md:3-10). Client mengirim envelope dengan format_version: 2, dan import menolak versi lain lewat pesan Unsupported encrypted backup version: {} (src-tauri/src/commands/mod.rs:1460-1461).

Route yang tersedia dibagi antara satu health check publik dan lima endpoint sinkronisasi yang dilindungi (server/cmd/server/main.go:48-67):

MethodPathHandlerKegunaan
GET/healthh.Healthhealth check publik, tanpa auth
GET/api/v1/sync/statush.SyncStatusversi terakhir dan metadata device
GET/api/v1/sync/bundleh.GetBundleunduh ciphertext bundle terbaru
POST/api/v1/sync/bundleh.PostBundleunggah ciphertext bundle baru
GET/api/v1/sync/devicesh.GetDevicesdaftar device yang pernah sync
GET/api/v1/sync/wsh.WebSocketstream notifikasi WebSocket

Autentikasi memakai AuthMiddleware: Authorization: Bearer <token> atau query ?token= untuk WebSocket, dibandingkan dengan subtle.ConstantTimeCompare, dan request yang gagal menerima 401 beserta body Unauthorized: invalid or missing authentication token (server/internal/middleware/auth.go:18-49).

⚠️ Bila TERMIMUS_AUTH_TOKEN kosong, middleware meneruskan semua request tanpa pemeriksaan. Server juga mencetak [Security Warning] TERMIMUS_AUTH_TOKEN is not set! Running in OPEN mode. saat start. Jangan pernah menjalankan relay tanpa token di host yang dapat dijangkau publik (server/internal/middleware/auth.go:18-49).

Di sisi client, useSyncStore memodelkan sinkronisasi sebagai empat keadaan: idle, syncing, connected, dan error (src/stores/useSyncStore.ts:18-28). Ketika autoSync aktif, useLiveSync membuka WebSocket ke /api/v1/sync/ws, dan setiap pesan SYNC_UPDATED dari device lain langsung memicu pull(); pesan dari device sendiri diabaikan (src/hooks/useLiveSync.ts:46-59).

Tumpukan Teknologi

Dua manifes menentukan seluruh dependensi runtime. Sisi Rust memakai russh untuk SSH, russh-sftp untuk SFTP, rusqlite (feature bundled) untuk SQLite, aes-gcm + argon2 + zeroize untuk vault, keyring untuk OS keychain, dan portable-pty untuk shell lokal (src-tauri/Cargo.toml:20-43). Sisi frontend memakai React 19 dan @xterm/xterm 6 dengan Zustand sebagai store (package.json:12-33).

LapisanPustakaVersi
SSH enginerussh0.50
SFTPrussh-sftp3.0.0
Database lokalrusqlite (bundled)0.33
Enkripsiaes-gcm0.10
Key derivationargon20.5
Zeroizationzeroize1
Terminal@xterm/xterm^6.0.0
State managementzustand^5.0.15
UIreact^19.1.0

Dokumen kontribusi merangkum tumpukan yang sama: React 19 + TypeScript + Vite + Tailwind CSS v4 di frontend, Tauri v2 + Rust dengan russh, russh-sftp, rusqlite, AES-256-GCM, dan Argon2id di backend (CONTRIBUTING.md:23-25).

Aturan yang Mengikat Seluruh Kode

Tiga aturan berlaku lintas domain dan menjadi alasan banyak keputusan desain di halaman lain:

  1. Setiap koneksi keluarga SSH — terminal, SFTP, port forwarding — wajib melewati SshClientHandler dengan db: Arc<Database>, agar verifikasi host key TOFU berlaku seragam (CONTRIBUTING.md:31-39).
  2. Password, private key, dan passphrase tidak pernah disimpan atau dikirim sebagai plaintext; enkripsi dan dekripsi hanya lewat VaultManager setelah is_unlocked() terpenuhi (CONTRIBUTING.md:31-39).
  3. Command Tauri baru harus didaftarkan di tiga tempat: handler di commands/mod.rs, entri generate_handler![...] di lib.rs, dan wrapper bertipe di src/lib/api.ts (AGENTS.md:11-22).

AGENTS.md juga menetapkan pemetaan direktori backend per domain — ssh/, sftp/, tunnel/, vault/, sshkey/, db/, commands/ — dan satu Zustand store per domain di src/stores/ (AGENTS.md:11-22). Struktur tingkat atas repository mengikuti pembagian itu: src/ untuk frontend, src-tauri/ untuk backend Rust, dan server/ untuk relay Go (README.md:226-264).

Rilis dan Distribusi

Penomoran versi mengikuti SemVer vMAJOR.MINOR.PATCH, dan setiap tag wajib berawalan huruf v kecil; breaking change pada schema database atau format enkripsi menuntut bump MAJOR (RELEASE.md:7-17). Desktop client dan sync server dirilis dengan nomor yang sama, saat ini v0.7.0 untuk keduanya (README.md:120-125).

Mendorong tag memicu dua workflow GitHub Actions secara paralel: release.yml membangun tiga runner (ubuntu-22.04 untuk .deb dan .AppImage, macos-latest dengan universal-apple-darwin untuk .dmg, windows-latest untuk .msi dan .exe), sedangkan docker.yml membangun image multi-arch linux/amd64 + linux/arm64 ke GHCR dengan tag :vX.Y.Z, :X.Y, :latest, dan :edge (RELEASE.md:96-122).

Peta Dokumentasi

Halaman-halaman berikut membahas tiap bagian sistem secara mendalam.

HalamanCakupan
Arsitektur Sistem dan Batas Modulpembagian modul Rust, store Zustand, dan arah dependensi
Memulai Pengembangan dan Buildprasyarat, bun run tauri dev, dan bun run tauri build
Vault dan Model KriptografiArgon2id, AES-256-GCM, keyring, dan auto-lock
Skema Database Lokaltabel di init_tables() dan model baris
Siklus Hidup Koneksi SSHSessionManager dan streaming PTY
Verifikasi Host Key TOFUSshClientHandler dan penolakan saat fingerprint berubah
Manajemen Host dan Keychainfolder, host, credential, dan derivasi public key
Terminal, Split Pane, dan WorkspaceterminalPool, split layout, dan preset workspace
SFTP Dual-Pane dan Editor RemoteSftpManager dan editor di atas SFTP
Port Forwarding dan TunnelTunnelManager dan channel_open_direct_tcpip
Backup, Sync Relay, dan API ServerBackupBundle, endpoint relay, dan EncryptedBackupEnvelope