feat(chei-ssh): inventar de chei publice si script de adaugare/revocare in masa

Cheile publice ale angajatilor (VM 303, VM 304) se tin versionate in
docs/chei-publice/ — acelasi fisier serveste si pentru "Add File", si pentru
"Remove File", deci revocarea nu mai depinde de un fingerprint copiat de mana.

scripts/bitvise-chei.ps1 tine lista celor 11 servere Bitvise valide si ruleaza
spksc cu -unat=y (List / Add / Remove) fara sa se blocheze in prompturi.

Doua lucruri descoperite si notate in doc:
- romfast_bitvise.tlp si 10.0.20.36:22122 sunt acelasi server (liste de chei
  identice); intrarea a doua ramane ca ruta de rezerva, fiindca parola din
  bitvise_10.0.20.36.bscp a expirat si se conecteaza cu -keypairFile;
- abcval (Bitvise SSH Server 9.32) respinge Ed25519 cu KeyNotSupported — acolo
  e nevoie de o pereche RSA.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FnMP82sffxQYxWRjy5sfKo
This commit is contained in:
Marius
2026-09-01 22:39:58 +03:00
parent a01cac0657
commit 5e60394c20
4 changed files with 149 additions and 1 deletions

View File

@@ -223,10 +223,87 @@ La plecarea angajatului:
adaugata cheia:
- varianta A: sterge linia angajatului din `.ssh/authorized_keys`, re-uploadeaza, deconecteaza-te
curat — sincronizarea de la logout inlatura cheia;
- varianta B: `spksc ... -cmd="Remove File C:\temp\angajat.pub"` (sau `Remove Fingerprint ...`).
- varianta B: `spksc ... -cmd="Remove File C:\temp\angajat.pub"` (sau `Remove Fingerprint ...`);
pe toate serverele deodata: `scripts\bitvise-chei.ps1 -Actiune Remove` — sectiunea 6.
3. Optional: verifica in logurile Bitvise SSH Server ultima conectare cu fingerprint-ul lui,
ca sa sti ce a accesat in perioada de gratie.
## 6. Unde stau cheile publice si pe ce servere sunt copiate
### Unde se salveaza cheia publica a unui angajat
`docs/chei-publice/<vm>.pub`, in acest repo. Cheile **publice** nu sunt secrete — se tin
versionate tocmai ca sa se stie, peste un an, exact ce sir trebuie revocat. Cheia **privata** nu
ajunge niciodata aici (vezi Capcane).
Fisierul e si sursa pentru revocare: `Remove File <acelasi .pub>` sterge exact ce a adaugat
`Add File`, fara sa fie nevoie de fingerprint copiat de mana.
```powershell
ssh-keygen -lf docs\chei-publice\vm304.pub # amprenta, pentru corelare cu logurile serverului
```
| Fisier | Amprenta SHA-256 | Cine |
|---|---|---|
| `docs/chei-publice/vm303.pub` | `BDidUbM24Do2ySosEeVuP9wYSRo2+soOg4UhlNcUzTQ` | `romfast@VM-303` |
| `docs/chei-publice/vm304.pub` | `g1HHsnnqmbwEas7SFJuaUDcQLdsZKwNTklSXZO2mbLw` | `romfast@VM-304` |
VM 304 e clona lui VM 303, deci a pornit cu **aceeasi** cheie privata; a fost regenerata pe VM
304 (`ssh-keygen -t ed25519 -C "romfast@VM-304"`, plus stergerea keypair-ului mostenit din
**Bitvise User keypair manager** si regenerarea cheilor de host `C:\ProgramData\ssh\ssh_host_*`
daca VM-ul ruleaza sshd). Fara pasul din keypair manager, clona continua sa se autentifice cu
identitatea VM 303 si nu se vede diferenta in loguri.
### Serverele pe care sunt copiate cheile
Lista traieste in `scripts/bitvise-chei.ps1` (variabila `$Servere`) — se actualizeaza acolo,
nu aici, ca sa nu existe doua adevaruri.
| Server (profil din `D:\GoogleDrive`) | VM-303 | VM-304 |
|---|---|---|
| `automotive.tlp` | da | da |
| `avis.tlp` | da | da |
| `clever-motors.tlp` | da | da |
| `conpress_romfast.tlp` | da | da |
| `eduard.tlp` | da | da |
| `ems.tlp` | da | da |
| `romconstruct.bscp` | da | da |
| `romfast_bitvise.tlp` = **10.0.20.36:22122** (Oracle productie) | da | da |
| `sigma.tlp` | da | da |
| `vadeco.tlp` | da | da |
| `vending.tlp` | da | da |
| `abcval.tlp` | **nu** | **nu** |
`romfast_bitvise.tlp` si intrarea `10.0.20.36` sunt **acelasi server** (liste de chei identice) —
a doua e pastrata ca ruta de rezerva, fiindca parola din `bitvise_10.0.20.36.bscp` a expirat si
ruta aceea se conecteaza cu `-keypairFile` in loc de parola.
`abcval` ruleaza Bitvise SSH Server 9.32 si respinge Ed25519 cu `KeyNotSupported`. Daca un
angajat chiar are nevoie de el, genereaza o pereche RSA 3072/4096 in paralel si urca **acel** `.pub`.
Restul profilelor din `D:\GoogleDrive` sunt clienti expirati (timeout / conexiune refuzata) sau
servere Linux/OpenSSH, unde SPKS nu exista (`cod 201: Failed to request PublicKey subsystem`) —
acolo cheia se pune direct in `~/.ssh/authorized_keys`.
### Adaugare si revocare in masa
```powershell
cd E:\proiecte\ROMFASTSQL\scripts
.\bitvise-chei.ps1 -Actiune List # ce chei sunt pe fiecare server
.\bitvise-chei.ps1 -Actiune Add -Cheie ..\docs\chei-publice\vm304.pub
.\bitvise-chei.ps1 -Actiune Remove -Cheie ..\docs\chei-publice\vm304.pub # revocare la plecare
```
Scriptul ruleaza `spksc` cu `-unat=y`, deci nu se blocheaza niciodata intr-un prompt: orice
server picat iese cu un cod de retur, nu cu o fereastra care asteapta. Coduri utile:
`101` conexiune esuata, `102` host key neacceptat in profil, `103` autentificare respinsa,
`201` serverul nu suporta SPKS, `233` algoritm de cheie nesuportat.
**Verificarea de dupa revocare nu e optionala**: `-Actiune List` si cauta comentariul cheii.
Un `Remove` care raporteaza "cheie inexistenta" pe un server unde cheia chiar era inseamna ca
te-ai conectat pe alt cont decat cel pe care a fost adaugata.
## Capcane
- Cheia privata nu se primeste niciodata "in avans" de la angajat ca backup — daca se pierde, se

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBvKDrtJ7YbyONI/ITkZce4eGIxQWHXhTG+sMRwIwP0k romfast@VM-303

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID7z0um00jj5RsQR70kOfQblJfmVWredVk6ZyJBrdv32 romfast@VM-304

69
scripts/bitvise-chei.ps1 Normal file
View File

@@ -0,0 +1,69 @@
<#
.SYNOPSIS
Adauga / listeaza / revoca o cheie publica pe toate serverele Bitvise ale angajatilor.
.DESCRIPTION
Serverele sunt cele din $Servere de mai jos — profilele Bitvise din D:\GoogleDrive, plus
serverul Oracle de productie 10.0.20.36 care are parola expirata in profil si se conecteaza
cu cheia mea OpenSSH. Lista se actualizeaza aici cand apare/dispare un client.
Cheile publice ale angajatilor stau in docs\chei-publice\*.pub (nu sunt secrete) — de acolo
se ia fisierul si pentru adaugare, si pentru revocare.
.EXAMPLE
.\bitvise-chei.ps1 -Actiune List
.\bitvise-chei.ps1 -Actiune Add -Cheie ..\docs\chei-publice\vm304.pub
.\bitvise-chei.ps1 -Actiune Remove -Cheie ..\docs\chei-publice\vm304.pub
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)][ValidateSet('Add','Remove','List')][string]$Actiune,
[string]$Cheie
)
$spksc = 'C:\Program Files (x86)\Bitvise SSH Client\spksc.exe'
# Fiecare intrare: eticheta + argumentele de conexiune pentru spksc.
$Servere = @(
@{ N='automotive'; A=@('-profile=D:\GoogleDrive\automotive.tlp') }
@{ N='avis'; A=@('-profile=D:\GoogleDrive\avis.tlp') }
@{ N='clever-motors'; A=@('-profile=D:\GoogleDrive\clever-motors.tlp') }
@{ N='conpress_romfast'; A=@('-profile=D:\GoogleDrive\conpress_romfast.tlp') }
@{ N='eduard'; A=@('-profile=D:\GoogleDrive\eduard.tlp') }
@{ N='ems'; A=@('-profile=D:\GoogleDrive\ems.tlp') }
@{ N='romconstruct'; A=@('-profile=D:\GoogleDrive\romconstruct.bscp') }
@{ N='romfast_bitvise'; A=@('-profile=D:\GoogleDrive\romfast_bitvise.tlp') }
@{ N='sigma'; A=@('-profile=D:\GoogleDrive\sigma.tlp') }
@{ N='vadeco'; A=@('-profile=D:\GoogleDrive\vadeco.tlp') }
@{ N='vending'; A=@('-profile=D:\GoogleDrive\vending.tlp') }
# abcval: Bitvise 9.32, refuza Ed25519 (KeyNotSupported) — doar cu cheie RSA
@{ N='abcval'; A=@('-profile=D:\GoogleDrive\abcval.tlp') }
# Oracle prod = ACELASI server ca romfast_bitvise.tlp (verificat: liste de chei identice).
# Ramane in lista ca ruta de rezerva: parola din profil e expirata, deci host/port/user
# expliciti + cheia mea OpenSSH. La Remove, a doua trecere raporteaza "cheie inexistenta".
@{ N='10.0.20.36 Oracle'; A=@('-host=10.0.20.36','-port=22122','-user=romfast',
'-hostKeyFp=UijzzgAZVz+xOSZ8de/6BEAkyogQL+6hzp55jl8VDXc',
'-keypairFile=C:\Users\mmari\.ssh\id_ed25519') }
)
if ($Actiune -ne 'List') {
if (-not $Cheie) { throw "-Cheie e obligatoriu pentru actiunea $Actiune" }
$Cheie = (Resolve-Path $Cheie).Path
$comanda = "$Actiune File $Cheie"
$amprenta = (ssh-keygen -lf $Cheie)
Write-Host "$Actiune $amprenta" -ForegroundColor Cyan
} else {
$comanda = 'List Server'
}
foreach ($s in $Servere) {
$out = & $spksc @($s.A) -initialKexTimeout=20 -unat=y "-cmd=$comanda" 2>&1 | Out-String
$rc = $LASTEXITCODE
$err = ($out -split "`n" | Where-Object { $_ -match 'ERROR' } | Select-Object -Last 1)
if ($err) { $err = $err.Trim() } else { $err = '' }
$stare = if ($rc -eq 0) { 'OK' } else { "rc=$rc" }
'{0,-6} {1,-20} {2}' -f $stare, $s.N, $err
if ($Actiune -eq 'List') {
$out -split "`n" | Select-String 'Comment:' | ForEach-Object { ' ' + $_.ToString().Trim() }
}
}