sqlinsight-pro/docs/servere-og-databaser.md
Søren Eggert Lundsteen Olsen 2adeef4597 Review 1.3: local Administrators may change the configuration until AdminGroups is set; MSI property ADMIN_GROUPS
With SQLInsight:Web:AdminGroups empty nobody could add the first server. The
installer now takes ADMIN_GROUPS (';'-separated) and writes it to the web's
sqlinsight.ini; while the setting is empty, members of the web server's
BUILTIN\Administrators (S-1-5-32-544 among the user's group SIDs; a remote
Negotiate login has the full token, a UAC-filtered deny-only SID does not count)
may change it. The page says who may.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 13:22:42 +02:00

91 lines
10 KiB
Markdown

# Servere og databaser
Fra version 1.3 tilmeldes SQL Servere i webbrugerfladen: **Overvågning → Servere og databaser**. Man tilføjer en server, agenten tester forbindelsen og finder alle de databaser, den kan se, og man sætter flueben ved dem, der skal overvåges. Alt kan også gøres gennem API'et (se [nedenfor](#api)).
## Hvem må ændre opsætningen
Alle med adgang til webbrugerfladen kan **se** opsætningen. Kun medlemmer af en gruppe i `SQLInsight:Web:AdminGroups` kan **ændre** den:
```json
"SQLInsight": {
"Web": {
"AllowedGroups": [ "DOMÆNE\\SQL-Brugere" ],
"AdminGroups": [ "DOMÆNE\\SQL-Admins" ]
}
}
```
Installeren kan sætte gruppen med egenskaben `ADMIN_GROUPS` (flere grupper adskilt af `;`, fx `ADMIN_GROUPS="DOMÆNE\SQL-Admins;DOMÆNE\DBA"`); den skrives i webbens `sqlinsight.ini`. Genstart tjenesten `SQLInsight Web` efter en ændring.
Er `AdminGroups` tom (standard ved en installation uden `ADMIN_GROUPS`), kan medlemmer af den **lokale gruppe Administratorer på webserveren** (`BUILTIN\Administrators`, SID `S-1-5-32-544`) ændre opsætningen, så den første server kan tilføjes med det samme. Det afgøres ud fra brugerens Windows-grupper ved login. En Windows-login fra en anden computer (Negotiate/Kerberos) har den fulde token, så en domænekonto, der er administrator på webserveren (fx via Domain Admins), genkendes. Åbnes webbrugerfladen i en browser på selve webserveren, er brugerens token filtreret af UAC (Administratorer er kun *deny-only*), og så tæller det ikke; brug en anden computer, eller sæt `AdminGroups`. Så snart `AdminGroups` indeholder en gruppe, er det kun den, der gælder. Siden *Servere og databaser* viser, hvem der må ændre opsætningen.
## Tilføj en server
Angiv serveren som `server` eller `server\instans`, og eventuelt en port (så bruges porten, og SQL Server Browser er ikke nødvendig). Navnet er det, serveren hedder i SQLInsight (fund, rapporter, SQLInsight Hub); standard er servernavnet, og det kan ikke ændres bagefter.
- **Godkendelse:** *Windows* er standard og at foretrække: agenten forbinder med sin egen tjenestekonto, og der gemmes ingen adgangskode. *SQL-login* kan bruges, hvor Windows-godkendelse ikke er mulig.
- **Kryptering:** *Påkrævet* er standard. *Valgfri* er kun til gamle instanser, der ikke kan TLS 1.2 (fx SQL Server 2005); agenten falder selv tilbage til ODBC-driveren for SQL Server 2000 og 2005 (se [legacy-versions.md](legacy-versions.md)).
- **Overvåg automatisk nye databaser:** databaser, der oprettes på serveren senere, overvåges med det samme. Ellers vises de på listen og overvåges først, når de vælges.
**Find instanser** beder agenten spørge SQL Server Browser på en computer (UDP 1434) og, på agentens egen computer, registreringsdatabasen. Instanser, der er skjult, eller hvor en firewall blokerer, findes ikke; dem tilføjer man manuelt.
## Forbindelsestest og rettigheder
Forbindelsestesten og søgningen efter databaser udføres af **agenten**, med agentens identitet, fordi det er agenten, der forbinder i drift. Webbrugerfladen lægger en anmodning i repositoriet (`insight.AgentRequests`); agenten tager den op inden for få sekunder og skriver resultatet tilbage, og siden opdaterer sig selv, mens der ventes. Kører agenten ikke, står anmodningen som ventende og fejles efter 30 minutter med en forklaring.
Testen viser version, udgave, hvilken driver der blev brugt, og det login, agenten ankom som. Derefter vises hver rettighed fra [`grant-least-privilege.sql`](../db/permissions/grant-least-privilege.sql), og om agenten har den: *Har*, *Mangler* eller *Valgfri, mangler* (ALTER TRACE). Er agenten sysadmin, siges det tydeligt: det virker, men er langt mere, end den har brug for. På SQL Server 2000 kan rettighederne ikke aflæses (der er ingen `HAS_PERMS_BY_NAME`).
Under **Rettigheder til agentens login** står scriptet udfyldt med det rigtige login: det login, testen så, eller ellers det login, agentens konto får på serveren (en virtuel konto som `NT SERVICE\SQLInsight Agent` ankommer til en anden server som computerkontoen `DOMÆNE\COMPUTER$`). For Windows-logins opretter scriptet login'et, hvis det mangler. SQLInsight kører aldrig scriptet selv: en sysadmin kører det på instansen, og det kan køres igen uden skade.
## Databaser
Agenten finder alle databaser på serveren, når serveren tilføjes, og derefter hver time. For hver database vises tilstand, størrelse, recovery model, compatibility level, om agenten kan åbne den, og om den er en Dynamics AX-database (AX 3.0 eller 4.0 og nyere, genkendt på AX' systemtabeller som AX-reglerne). Søgningen læser kun metadata og skifter aldrig database.
Valget styrer de **databasespecifikke** tjek: indstillinger, backup, CHECKDB, VLF'er, indexes, Query Store og community-regler. Instansdækkende målinger (ventetyper, CPU, blokeringer, job, fejllog, rettigheder) gælder altid hele instansen, og systemdatabaserne (master, model, msdb, tempdb) overvåges altid. Fravælges en database, løses dens åbne fund ved næste runde.
### Dynamics AX-fund og SQLInsight Hub
AX-fund sendes som standard **ikke** til SQLInsight Hub. Kolonnen *AX-fund til SQLInsight Hub* slår det til for én AX-database ad gangen. Det har kun betydning, når deling med hubben er slået til (`SQLInsight:Hub:Enabled`, se [databehandling.md](databehandling.md)).
## Servere fra konfigurationsfilen
Servere under `SQLInsight:Instances` i agentens `appsettings.json` eller `sqlinsight.ini` (fx `MONITOR_SERVER` fra installeren) virker som før: ved hver start spejler agenten dem ind i repositoriet, hvor de vises som **fra konfigurationsfil**. Forbindelsen (og en eventuel adgangskode) bliver i filen; den kopieres aldrig til repositoriet. Her kan de sættes på pause, og databaserne kan vælges, men de rettes og fjernes i filen. Fjernes en server fra filen, markeres den som fjernet ved agentens næste start (det indsamlede bevares); sættes den i filen igen, får den sin pause og sine databasevalg tilbage. Som standard overvåges alle deres databaser, også nye, præcis som i 1.2. Bruges samme navn både i filen og i webbrugerfladen, vinder filen.
Ændringer i webbrugerfladen (nye servere, pause, fjernelse, valg af databaser) bruges af agenten inden for et minut, uden genstart. Ændringer i konfigurationsfilen kræver stadig en genstart af agenten.
**Pause og fjernelse.** En server på pause overvåges ikke, men vises stadig i overblikket, tydeligt markeret *Sat på pause* med de seneste data før pausen. Den tæller ikke med i overblikkets tal, i *Kritiske og høje fund*, under *Alle fund* eller i alarmer (Prometheus). En fjernet server forsvinder fra overblikket, fundlisterne og alarmerne; det indsamlede bevares og indgår stadig i rapporterne for perioden, og instansens side kan stadig åbnes. Tilføjes en server igen med samme navn, fortsætter den med sin historik.
## SQL-login-adgangskoder
En adgangskode krypteres i webbrugerfladen, i det øjeblik den modtages, med **agentens offentlige nøgle** (RSA-OAEP-SHA256 om en AES-256-GCM-nøgle). Kun agenten har den private nøgle, så hverken webbrugerfladen, API'et eller nogen, der kan læse repositoriet, kan få adgangskoden tilbage. Den vises aldrig igen og returneres aldrig af API'et (kun `hasPassword`).
- Agentens nøglepar ligger i `C:\ProgramData\SQLInsight\keys`, beskyttet med DPAPI (LocalMachine) og en mappe, kun SYSTEM, Administrators og agentens konto har adgang til. Den offentlige nøgle står i `insight.AgentKeys`.
- Den krypterede adgangskode er bundet til server, port og login. Ændres en af dem, skal adgangskoden indtastes igen, så den aldrig kan sendes til en anden server, end den blev indtastet til.
- Geninstalleres agentens server (eller slettes nøglen), laves en ny nøgle. Gemte adgangskoder kan så ikke længere bruges; siden viser det, og de indtastes igen. Windows-godkendelse berøres ikke.
Hvorfor ikke ASP.NET Data Protection eller DPAPI alene: agent og web kan ligge på forskellige servere og køre som forskellige konti, og webbrugerfladen skal aldrig kunne læse en adgangskode. Med et nøglepar har webbrugerfladen kun den offentlige nøgle.
## Rettigheder i repositoriet
Webbrugerfladens login har stadig kun `db_datareader` og ellers præcis det, den skal bruge: `INSERT` på `insight.ConfiguredInstances` og `insight.AgentRequests` og `UPDATE` på navngivne kolonner af `insight.ConfiguredInstances` og `insight.ConfiguredDatabases` (migrering 0016). Den kan ikke slette (en server fjernes ved at markere den), ikke ændre navn eller kilde, og ikke skrive det, agenten registrerer. SQLInsight skriver aldrig til de overvågede databaser.
## API
Alt på siden findes i API v1 (se [integration.md](integration.md#json-api)). Læsning kræver scope `read`; ændringer kræver scope `config:write` for tokens eller medlemskab af `AdminGroups` for Windows-brugere (er den tom: den lokale gruppe Administratorer på webserveren). Opret et token med `SQLInsight.Web.exe new-api-token automation --scope read,config:write`.
| Endpoint | |
|---|---|
| `GET /api/v1/monitored-instances` | Overvågede servere |
| `POST /api/v1/monitored-instances` | Tilføj (body: `name`, `server`, `port`, `authentication` = `Windows`/`SqlLogin`, `userName`, `password`, `encryption`, `trustServerCertificate`, `monitorNewDatabases`). Svar `201` med `connectionTestRequestId` |
| `GET /api/v1/monitored-instances/{id}` | Én server |
| `PATCH /api/v1/monitored-instances/{id}` | `paused`, `monitorNewDatabases` |
| `PUT /api/v1/monitored-instances/{id}/connection` | Ret forbindelsen (kun servere fra webbrugerfladen) |
| `DELETE /api/v1/monitored-instances/{id}` | Stop overvågningen; det indsamlede bevares. `409` for servere fra konfigurationsfilen |
| `POST /api/v1/monitored-instances/{id}/connection-test` | Test forbindelsen fra agenten (`202` med anmodningens id) |
| `GET /api/v1/monitored-instances/{id}/connection-test` | Seneste test med `missingPermissions` |
| `POST /api/v1/monitored-instances/{id}/discovery` | Søg efter databaser (`202`) |
| `GET /api/v1/monitored-instances/{id}/databases` | Fundne databaser og valg |
| `PUT /api/v1/monitored-instances/{id}/databases` | `{ "monitorNewDatabases": true, "databases": [ { "name": "AX30", "monitored": true, "sendDynamicsAxToHub": false } ] }`. Databaser, der ikke nævnes, beholder deres valg |
| `GET /api/v1/monitored-instances/{id}/grant-script` | GRANT-scriptet til agentens login |
| `POST /api/v1/instance-discovery` | Find instanser på en computer (`{ "host": "sql01" }`, tom = agentens egen) |
| `GET /api/v1/agent-requests/{id}` | Status (`Pending`, `Running`, `Done`, `Failed`) og resultat af en anmodning |