Blocul de instalare/migrare Oracle 21c XE, terminat si validat pe VM 302. Kit de instalare (nou) scripts/build-client-kit.ps1 exporta CONTAFIN_ORACLE si FIRMANOUA de pe LXC 108 (PDB ROA2, nu ROA - ROA e productia ROA_CENTRAL), le aduce local prin cele trei hopuri container -> LXC -> host -> statie, le redenumeste la numele pe care le asteapta scripturile si le impacheteaza cu o copie a directorului roa-windows-setup. Citeste logul expdp si raporteaza cate firme are NOM_FIRME, ca sa nu plece din greseala datele unui client. roa-windows-setup/INSTALEAZA.cmd ruleaza pasii 01..08 fara "set /p", deci merge si prin SSH - RunAll.cmd nu poate fi rulat neinteractiv. Trateaza corect codul 5 de la pasul 03 si se opreste la prima eroare reala. Corectii 01-setup-database.ps1 nu mai scrie SQLNET.RECV_TIMEOUT / SEND_TIMEOUT in sqlnet.ora. Le hardcoda la 30 s, iar fisierul e citit si de impdp: in timpul unui import serverul poate lucra minute fara sa trimita un pachet, clientul murea cu ORA-12609 iar scriptul raporta esec pentru un import care se terminase cu bine pe server. Reprodus si reparat pe VM 302. 01-setup-database.ps1: Step 4c optional (-ResetSystemPassword) care curata EXPIRED(GRACE) pe SYSTEM in CDB root; ALTER PROFILE opreste expirarile viitoare dar nu reseteaza un cont deja intrat in gratie. uninstall-roa.sql: retry la DROP USER dupa KILL SESSION, plus un bloc final de verdict care numara ce a ramas si iese cu ORA-20900 daca baza nu e curata. Pana acum toate sectiunile prindeau exceptiile in WHEN OTHERS si scriptul tiparea "UNINSTALL COMPLETE" chiar si cand un user supravietuise, iar instalarea urmatoare dadea ORA-31684 in lant. 99-uninstall-roa.ps1 propaga codul de iesire. 08-post-install-config.ps1: Step 7b seteaza SMTP_OUT_SERVER si ACL-ul de retea pentru CONTAFIN_ORACLE. UTL_MAIL se instala si primea EXECUTE, adica destul cat sa compileze, dar nu si cat sa trimita. Privilegiul resolve nu accepta interval de porturi (ORA-24244), deci se acorda separat de connect. 07-verify-installation.ps1: sectiune noua care verifica prezenta lui FIRMANOUA.dmp in DMPDIR si o raporteaza ca eroare daca lipseste. Fara el, adaugarea unei firme noi pica in DBMS_DATAPUMP.ADD_FILE peste luni de la instalare, cand nimeni nu mai leaga eroarea de instalare. configure-profile.sql: antetul spune ca e unealta de remediere manuala, nu parte din flux; pas nou la final pentru CDB root. Documentatie README-ul roa-windows-setup descrie acum explicit cele doua scenarii - instalare pe curat si migrare - de unde se iau DMP-urile sablon, si capcana ORA-12609. Handoff-urile de sesiune au fost sterse; ce era durabil in ele a intrat in README-uri si in docs/diagnostic-spatiu-clienti.md. Validare pe VM 302: ciclu complet din kit, instalare pe curat, verificarea finala "[OK] All checks passed!". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SzF1hf4aFS1tmJWpPMiwGp
8.5 KiB
Acces administrativ la un server de client prin Tailscale + SSH
De ce: pentru instalări/migrări Oracle la client avem nevoie de shell text pe serverul lui. RustDesk nu ajută — e sesiune grafică, nu se poate automatiza. Iar la mulți clienți nu se pot face forward-uri de porturi pe router. Tailscale rezolvă exact asta: nodul face doar conexiuni de ieșire (UDP 41641 pentru NAT traversal, cu cădere pe releu DERP peste 443), deci merge și în spatele CGNAT, fără nicio regulă pe router.
RustDesk rămâne util pentru bootstrap-ul de o singură dată — pașii de mai jos se execută manual, o dată, prin el.
Primul caz aplicat: VADECO — vadeco-server, Windows Server 2019 Standard, Tailscale
100.93.100.75 (2026-08-25).
Context conex: acces-ssh-chei-angajati.md (Bitvise pe chei, capcana LSA protection).
1. Tailscale pe serverul clientului
- Instalezi Tailscale, te loghezi cu contul ROMFAST.
- Run unattended — din tray → Preferences, sau
tailscale up --unattended. Fără el, tailscaled pornește abia după ce cineva face login în Windows; pe un server la care nu se loghează nimeni, accesul e mort după fiecare reboot. - Cere acordul clientului înainte — e VPN pe serverul lui.
2. Izolarea nodului: tag + ACL
Fără asta, serverul clientului intră în tailnet ca device obișnuit și vede toată infrastructura ROMFAST. Dacă e vreodată compromis, atacatorul sare mai departe.
Modelul Tailscale, pe scurt:
- ACL-ul e default-deny: ce nu e permis explicit, e blocat. Nu scrii interdicții.
- Regulile au direcție:
src= cine deschide conexiunea,dst= cine o primește. - Fiecare device are o identitate: fie contul care l-a logat (user-owned), fie tag-ul. Aplicarea unui tag înlocuiește proprietatea contului, nu se adaugă la ea.
autogroup:member= conturile umane din tailnet. Un device tagged nu e member.
Politica
Admin console → Access controls. UI-ul nou are editor vizual (Definitions / Grants); fișierul
HuJSON brut e la https://login.tailscale.com/admin/acls/file.
{
"tagOwners": {
"tag:client": ["autogroup:admin"],
},
"acls": [
// device-urile noastre (ne-tagged) ajung oriunde
{ "action": "accept", "src": ["autogroup:member"], "dst": ["*:*"] },
// NU exista nicio regula cu "src": ["tag:client"]
// => serverul clientului nu poate initia nimic in tailnet
],
}
Obligatoriu: șterge regula implicită
src: ["*"]→dst: ["*:*"]. Cât timp există,*include șitag:clientși toată izolarea e degeaba.
Înainte de a șterge, verifică în Machines că niciun nod ROMFAST nu e deja tagged — ar rămâne fără acces.
Aplicarea tag-ului
Machines → nodul → ... → Edit ACL tags → tag:client.
Efecte: proprietatea trece la tag (dispare din „owned by you" — normal), iar expirarea cheii se dezactivează automat la device-urile tagged, deci nu mai trebuie dezactivată manual.
Verificare rapidă în tailscale status — nodul apare cu owner tagged-devices:
100.93.100.75 vadeco-server tagged-devices windows -
Testul de izolare
Rulează aceeași comandă înainte și după aplicarea tag-ului, de pe serverul clientului:
Test-NetConnection 100.95.55.51 -Port 22 # 100.95.55.51 = LXC 171, are sshd pornit
- înainte de tag:
TcpTestSucceeded : True(nodul e încă member) — confirmă că testul e valid - după tag:
TcpTestSucceeded : False(~20s până expiră) — confirmă izolarea
Nu folosi
tailscale pingca test de ACL. Lucrează sub filtrul de pachete și poate reuși chiar când ACL-ul blochează traficul real. Doar un test TCP pe un port concret spune adevărul.
Sensul invers (noi → client) se testează la punctul 4, cu serverul SSH pornit.
„Dacă nodul nu poate ajunge la noi, cum îmi răspunde SSH-ul?" — ACL-ul reglementează cine deschide o conexiune, nu direcția octeților. Sesiunea deschisă dinspre noi funcționează normal în ambele sensuri; clientul doar nu poate iniția el ceva spre tailnet.
3. Serverul SSH pe mașina clientului
Două variante; ambele merg, alege după context.
Bitvise SSH Server (consecvent cu restul clienților)
Control Panel → Easy settings:
- Windows accounts →
Administrator(sau alt cont din grupul Administrators) → Public keys → Import cheia publică. Shell access: terminal + exec. - Conturile virtuale rămân pentru tuneluri (la VADECO:
romfast,vadeco, s2c pe 1521/80).
Capcana conturilor virtuale: implicit sunt mapate pe contul Windows
bvssh_virtualusers, cu privilegii minime. Prin ele obții shell, darGet-Service,Get-CimInstanceșiGet-PSDriveîntorc gol — nu erori, ci nimic — și nu se poate instala Oracle. Simptom:whoamiîntoarce<host>\bvssh_virtualusersși verificarea de admin dăFalse.Fie folosești un cont Windows real (mai simplu), fie mapezi contul virtual pe un cont admin din Advanced settings → Access control → grup → Windows account + parolă, plus setarea Elevation (fără ea, token filtrat de UAC și instalarea Oracle pică pe permisiuni obscure). Dezavantaj: parola de admin ajunge stocată în configul Bitvise.
Capcana LSA protection: pe Windows recent (~2025+) cu Bitvise < 9.51, autentificarea cu cheie pe conturi Windows eșuează (parola merge, cheia nu) — vezi
acces-ssh-chei-angajati.md. Pe Server 2019 nu se aplică. Conturile virtuale nu sunt afectate niciodată.
OpenSSH nativ Windows (alternativă, fără licențiere)
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service -Name sshd -StartupType Automatic
Start-Service sshd
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell `
-Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
-PropertyType String -Force
$f = "$env:ProgramData\ssh\administrators_authorized_keys"
Set-Content -Path $f -Encoding ascii -Value 'ssh-ed25519 AAAA... comentariu'
icacls $f /inheritance:r /grant "*S-1-5-32-544:F" /grant "*S-1-5-18:F"
Restart-Service sshd
administrators_authorized_keyse fișierul corect pentru conturi admin (nu~/.ssh).- ACL-ul de la
icaclse obligatoriu: cu moștenire de permisiuni, sshd ignoră fișierul în tăcere și vezi doar „Permission denied". SID-urile evită problema pe Windows localizat. -Encoding asciiintenționat —utf8în PowerShell 5.1 scrie BOM, iar sshd nu digeră cheia.
Firewall
Set-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -RemoteAddress 100.64.0.0/10
# Bitvise:
Get-NetFirewallRule -DisplayName '*Bitvise*' | Set-NetFirewallRule -RemoteAddress 100.64.0.0/10
Restricția se face pe firewall, nu prin bind pe adresa 100.x în configul serverului SSH: la boot, interfața Tailscale urcă adesea după serviciu, bind-ul eșuează și serverul rămâne mort.
4. Testul de acceptanță
De pe orice device ROMFAST din tailnet:
ssh Administrator@100.93.100.75 "powershell -c (Get-Item 'C:\').FullName"
Pentru comenzi mai complexe, ghilimelele se pierd prin lanțul ssh → Bitvise → PowerShell.
Folosește -EncodedCommand:
ENC=$(iconv -f UTF-8 -t UTF-16LE script.ps1 | base64 -w0)
ssh Administrator@100.93.100.75 "powershell -NoProfile -EncodedCommand $ENC"
Output-ul PowerShell prin exec vine cu antet #< CLIXML și un bloc <Objs Version=...> —
se filtrează cu grep -v.
5. Verificare de mediu înainte de instalarea Oracle
"ADMIN = $(([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))"
"OS = $((Get-CimInstance Win32_OperatingSystem).Caption)"
"RAM_GB = $([math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory/1GB,1))"
Get-Service | Where-Object {$_.Name -like 'Oracle*'} | Select-Object Name,Status,StartType
Get-PSDrive -PSProvider FileSystem | Select-Object Name,@{n='FreeGB';e={[math]::Round($_.Free/1GB,1)}}
ADMIN = True e condiția minimă — dacă e False, restul câmpurilor vin goale din lipsă de
drepturi, nu pentru că lipsesc, și orice concluzie despre mașină e falsă.
Revocarea accesului
- Machines → nodul → Remove (îl scoate din tailnet complet); și/sau
- ștergerea cheii publice din contul de pe serverul SSH.
Pasul 1 e suficient și instantaneu — fără el, ștergerea cheii lasă nodul în rețea.