Usare l'API Valutazione SQL per SQL Server in Linux

Si applica a:SQL Server in Linux

L'API di valutazione SQL fornisce un meccanismo per valutare la configurazione di SQL Server per le migliori pratiche. L'API viene fornita con un set di regole contenente le procedure consigliate dal team di SQL Server. Questo set di regole è stato migliorato con il rilascio di nuove versioni. È utile assicurarsi che la configurazione di SQL Server sia conforme alle procedure consigliate.

Il set di regole fornito da Microsoft è disponibile su GitHub. È possibile visualizzare l'intero set di regole nel repository degli esempi.

In questo articolo, usa PowerShell per eseguire l'API di valutazione SQL per SQL Server in Linux e container.

Prerequisiti

  1. Assicurarsi di installare PowerShell su Linux.

  2. Installare il modulo PowerShell SqlServer dalla PowerShell Gallery eseguendolo come utente mssql.

    su mssql -c "/usr/bin/pwsh -Command Install-Module SqlServer"
    

Configurare la valutazione

L'API di valutazione SQL fornisce output in formato JSON. Per configurare l'API di valutazione SQL, completare i seguenti passaggi:

  1. Crea un login per le valutazioni di SQL Server usando l'autenticazione SQL nell'istanza che vuoi valutare. Usa il seguente script Transact-SQL per creare un login e una password forte. La password deve seguire i criteri password predefiniti di SQL Server. Per impostazione predefinita, la password deve essere composta da almeno otto caratteri e contenere caratteri di tre delle quattro categorie seguenti: lettere maiuscole, lettere minuscole, cifre in base 10 e simboli. Le password possono contenere fino a 128 caratteri. Usare password il più possibile lunghe e complesse.

    USE [master];
    GO
    
    CREATE LOGIN [assessmentLogin]
        WITH PASSWORD = N'<password>';
    
    GRANT CONTROL SERVER TO [assessmentLogin];
    GO
    

    Il CONTROL SERVER permesso funziona per la maggior parte delle valutazioni. Tuttavia, alcune verifiche potrebbero richiedere privilegi di sysadmin . Se non esegui queste valutazioni, usa le autorizzazioni CONTROL SERVER.

  2. Memorizza le credenziali per la connessione all'istanza. Sostituisci <password> con la password che hai usato nel passaggio precedente.

    echo "assessmentLogin" > /var/opt/mssql/secrets/assessment
    echo "<password>" >> /var/opt/mssql/secrets/assessment
    
  3. Proteggere le nuove credenziali di valutazione assicurandosi che solo l'utente mssql possa accedere alle credenziali.

    chmod 600 /var/opt/mssql/secrets/assessment
    chown mssql:mssql /var/opt/mssql/secrets/assessment
    

Scaricare lo script di valutazione

Il seguente script di esempio chiama l'API di valutazione SQL utilizzando le credenziali che hai creato nei passaggi precedenti. Lo script genera output JSON nella /var/opt/mssql/log/assessments directory.

Nota

L'API Valutazione SQL può anche generare output nei formati CSV e XML.

Questo script è disponibile per il download da GitHub.

È possibile salvare questo file come /opt/mssql/bin/runassessment.ps1.

[CmdletBinding()] param ()

$Error.Clear()

# Create output directory if not exists

$outDir = '/var/opt/mssql/log/assessments'
if (-not ( Test-Path $outDir )) { mkdir $outDir }
$outPath = Join-Path $outDir 'assessment-latest'

$errorPath = Join-Path $outDir 'assessment-latest-errors'
if ( Test-Path $errorPath ) { remove-item $errorPath }

function ConvertTo-LogOutput {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline = $true)]
        $input
    )
    process {
        switch ($input) {
            { $_ -is [System.Management.Automation.WarningRecord] } {
                $result = @{
                    'TimeStamp' = $(Get-Date).ToString("O");
                    'Warning'   = $_.Message
                }
            }
            default {
                $result = @{
                    'TimeStamp'      = $input.TimeStamp;
                    'Severity'       = $input.Severity;
                    'TargetType'     = $input.TargetType;
                    'ServerName'     = $serverName;
                    'HostName'       = $hostName;
                    'TargetName'     = $input.TargetObject.Name;
                    'TargetPath'     = $input.TargetPath;
                    'CheckId'        = $input.Check.Id;
                    'CheckName'      = $input.Check.DisplayName;
                    'Message'        = $input.Message;
                    'RulesetName'    = $input.Check.OriginName;
                    'RulesetVersion' = $input.Check.OriginVersion.ToString();
                    'HelpLink'       = $input.HelpLink
                }

                if ( $input.TargetType -eq 'Database') {
                    $result['AvailabilityGroup'] = $input.TargetObject.AvailabilityGroupName
                }
            }
        }

        $result
    }
}

function Get-TargetsRecursive {

    [CmdletBinding()]
    Param (
        [Parameter(ValueFromPipeline = $true)]
        [Microsoft.SqlServer.Management.Smo.Server] $server
    )

    $server
    $server.Databases
}

function Get-ConfSetting {
    [CmdletBinding()]
    param (
        $confFile,
        $section,
        $name,
        $defaultValue = $null
    )

    $inSection = $false

    switch -regex -file $confFile {
        "^\s*\[\s*(.+?)\s*\]" {
            $inSection = $matches[1] -eq $section
        }
        "^\s*$($name)\s*=\s*(.+?)\s*$" {
            if ($inSection) {
                return $matches[1]
            }
        }
    }

    return $defaultValue
}

try {
    Write-Verbose "Acquiring credentials"

    $login, $pwd = Get-Content '/var/opt/mssql/secrets/assessment' -Encoding UTF8NoBOM -TotalCount 2
    $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force
    $credential = New-Object System.Management.Automation.PSCredential ($login, $securePassword)
    $securePassword.MakeReadOnly()

    Write-Verbose "Acquired credentials"

    $serverInstance = '.'

    if (Test-Path /var/opt/mssql/mssql.conf) {
        $port = Get-ConfSetting /var/opt/mssql/mssql.conf network tcpport

        if (-not [string]::IsNullOrWhiteSpace($port)) {
            Write-Verbose "Using port $($port)"
            $serverInstance = "$($serverInstance),$($port)"
        }
    }

    # IMPORTANT: If the script is run in trusted environments and there is a prelogin handshake error,
    # add -TrustServerCertificate flag in the commands for $serverName, $hostName and Get-SqlInstance lines below.
    $serverName = (Invoke-SqlCmd -ServerInstance $serverInstance -Credential $credential -Query "SELECT @@SERVERNAME")[0]
    $hostName = (Invoke-SqlCmd -ServerInstance $serverInstance -Credential $credential -Query "SELECT HOST_NAME()")[0]

    # Invoke assessment and store results.
    # Replace 'ConvertTo-Json' with 'ConvertTo-Csv' to change output format.
    # Available output formats: JSON, CSV, XML.
    # Encoding parameter is optional.

    Get-SqlInstance -ServerInstance $serverInstance -Credential $credential -ErrorAction Stop
    | Get-TargetsRecursive
    | ForEach-Object { Write-Verbose "Invoke assessment on $($_.Urn)"; $_ }
    | Invoke-SqlAssessment 3>&1
    | ConvertTo-LogOutput
    | ConvertTo-Json -AsArray
    | Set-Content $outPath -Encoding UTF8NoBOM
}
finally {
    Write-Verbose "Error count: $($Error.Count)"

    if ($Error) {
        $Error
        | ForEach-Object { @{ 'TimeStamp' = $(Get-Date).ToString("O"); 'Message' = $_.ToString() } }
        | ConvertTo-Json -AsArray
        | Set-Content $errorPath -Encoding UTF8NoBOM
    }
}

Nota

Quando esegui questo script in ambienti attendibili e si verifica un errore di handshake di pre-login, aggiungi il flag -TrustServerCertificate ai comandi nelle righe $serverName, $hostName e Get-SqlInstance del codice.

Eseguire la valutazione

  1. Assicurati che l'utente mssql possieda lo script e possa eseguirlo.

    chown mssql:mssql /opt/mssql/bin/runassessment.ps1
    chmod 700 /opt/mssql/bin/runassessment.ps1
    
  2. Crea una cartella di log e dai i permessi all'utente mssql per quella cartella.

    mkdir /var/opt/mssql/log/assessments/
    chown mssql:mssql /var/opt/mssql/log/assessments/
    chmod 0700 /var/opt/mssql/log/assessments/
    
  3. Ora puoi creare la tua prima valutazione come mssql utente. Eseguire valutazioni come questo utente è più sicuro, specialmente quando si esegue automaticamente valutazioni successive tramite cron o systemd.

    su mssql -c "pwsh -File /opt/mssql/bin/runassessment.ps1"
    
  4. Quando il comando termina, viene creato l'output in formato JSON. Puoi usare questo output con qualsiasi strumento che supporti l'analisi dei file JSON, incluso Visual Studio Code.