#3.1 Update zu meinem Powershell Skript “Öffnen von Firewall Port”

Nachdem ich meinen Beitrag zum Thema “Öffnen der Firewall Ports mit Powershell” Ende Oktober veröffentlicht hatte, habe ich mein Skript nochmals überarbeitet. Der SQL Server und seine Features wie z.B. die Analysis Services haben eigene Ports, welche auch nur geöffnet werden müssen, wenn die jeweiligen Features installiert sind.

Grundlage für meine weiteren Versuche ist der MSDN-Beitrag zu diesem Thema und der eigene Wunsch nach mehr Flexibilität beim Erstellen von Regeln.

Flexibilität durch eigene Powershell-Funktion “GET SQLServices for Firewall”

Ich habe also meine bisherige Funktion aufgesplittet, so dass ich nicht mehr wie bisher stur (per Copy&Paste) die Regel erstelle. Jetzt habe ich eine Funktion gebaut, welche alle relevanten SQL Server Dienste ermittelt, um diese dann individuell freizuschalten. Also mein erster Schritt ist die Analyse der SQL Server Installation:

function GET_SQLServices_for_Firewall($SQLServerTCPPort) {
    # TCP = 6, UDP = 17

    Write-Host "Opening Firewall ports for this Instance"
    # General Ports
    OpenFirewallPorts 4022 6 "SQL Service Broker"
    OpenFirewallPorts 1434 17 "SQL Browser"

    $Services=get-wmiobject -class win32_service | where {$_.DisplayName -like '*SQL*'} | select-object DisplayName 
    foreach ( $service in $Services ) {
        
        # DB-Engine Ports
        if ($Service.DisplayName -like '*SQL Server (*') { 
            OpenFirewallPorts $SQLServerTCPPort 6 "SQL Server"
        }

        # SSAS Ports
        if ($Service.DisplayName -like '*Analysis Services (*') {
            OpenFirewallPorts 2383 6 "SQL - Analysis Services"
            OpenFirewallPorts 2382 6 "SQL - Analysis Services Browserservice"
        }
    }
}

Wie man nun erkennen kann, rufe ich nun eine weitere Funktion auf mit der ich die Verwaltung der Windows Firewall übernehme. Die eigentlichen Teile meines bisherigen Skriptes habe ich somit relativ unverändert gelassen, nur “eingedampft” und variabler gestaltet.
Ich rufe also die eigentliche Arbeitsfunktion mit entsprechenden Parametern auf, um den jeweiligen Port, das Protokoll und eine sprechende Beschreibung zu übermitteln.

function OpenFirewallPorts ([int]$Port, [int]$Protocol, [string]$FirewallRuleDescsription) {
    
    if ($Protocol -eq 6) {$Protocol_String = "TCP"}
    if ($Protocol -eq 17) {$Protocol_String = "UDP"}

    Try {
	Write-Host "Opening Firewall on $Protocol_String Port $Port" 
	$port1 = New-Object -ComObject HNetCfg.FWOpenPort
	$port1.Port = $SQLServerTCPPort
	$port1.Name = $FirewallRuleDescsription + "(" + $Protocol_String + " " + $Port + ") " + $InstanceName 
	$port1.Enabled = $true
	$port1.Protocol = $Protocol
	$fwMgr = New-Object -ComObject HNetCfg.FwMgr
	$profiledomain=$fwMgr.LocalPolicy.GetProfileByType(0)
	$profiledomain.GloballyOpenPorts.Add($port1)
        Write-Host "[INFO] Successfully opened Firewall on $Protocol_String Port $Port." -ForegroundColor Green
	} 
    Catch { 
        Write-Host "[ERROR] Opening Firewall on $Protocol_String Port $Port failed." -ForegroundColor Red 
    }
}

Für mich und meine Zwecke funktioniert das soweit ganz gut und ist natürlich bei Bedarf individuell anpassbar. Wenn man als Beispiel einen weiteren Listener im SQL Server konfiguriert, dann könnte man dies ebenfalls ermitteln und in der Windows Firewall freischalten. Grob => Invoke-SQLcmd “Get Listener Port” => OpenFirewallPorts newListenerPortNumber 6 “Additional SQL Server Listener”

Für mich bedeutet das Niederschreiben und Erläutern der einzelnen Schritte und Veränderungen auch einen Lernprozess. Wenn jemand Anmerkungen oder Verbesserungen für mich hat, freue ich mich sehr darüber. “Please share your knowledge” 😉

#3 Firewall Ports für den SQL Server öffnen mit Powershell

Nach ein paar Tagen Ruhe kommt nun mein dritter Teil der Powershell Serie zum Thema “Firewall Ports öffnen“.
Sicherlich wird der ein oder andere sagen, “Firewall? die interne? die haben wir per Gruppenrichtlinie immer ausgeschaltet!”…was ist vielleicht in einem halben Jahr, jemand aktiviert die Windows Firewall auf dem Server manuell? Kann der SQL Server (also die Datenbank-Enigne) dann immer noch mit der Welt da draußen kommunizieren?

Sicherheit geht vor – daher nur definiert und bewußt die Firewall Ports öffnen

Windows Firewall Ports öffnen für den SQL Server

Ich empfehle nur die notwendigen Ports für die Datenbank-Enigne zu öffnen, im Beispielbild wären das die folgenden Ports

  • SQL Server DB Engine => TCP 10001
  • der SQL Browser => UDP 1434
  • der SQL Service => Broker 4022

Dies reicht völlig aus, um dem SQL Server und den nutzenden Applikationen im Notfall eine Kommunikation zu ermöglichen. Nun gibt es mehrere Möglichkeiten dies zu realisieren, die Konfiguration der Firewall über die grafische Oberfläche, was doch umständlich und “kompliziert” sein kann, aber ebenso der Weg über die Kommandozeile entweder als DOS-Befehl bzw mit dem netsh-Befehl oder mit einem Powershell-Skript.

Wer noch andere Features des SQL Servers auf dem selben Server einsetzt, muss natürlich noch weitere Ports öffnen und auch die entsprechenden Skripte erweitern, aber in der Regel reichen diese Firewall Ports für einen Datenbank Server aus.

weitere Hinweise zu den Firewall Ports des SQL Server findet man hier : https://msdn.microsoft.com/de-de/library/cc646023.aspx

Umsetzung über die Kommandozeile

netsh advfirewall firewall add rule name="SQL Server (TCP 10001) TEST_Instanz" dir=in action=allow protocol=TCP localport=10001 profile=domain
netsh advfirewall firewall add rule name="SQL Service Broker (TCP 4022)" dir=in action=allow protocol=TCP localport=4022 profile=domain
netsh advfirewall firewall add rule name="SQL Browser (UDP 1434)" dir=in action=allow protocol=UDP localport=1434 profile=domain

Der netsh-Befehl lässt sich sehr gut parametrisieren und skripten, ist daher sehr individuell einsetzbar, also recht umgänglich. Hier kommt es auf die Unternehmensstrategie oder die der Systemadministratoren an, welche Skriptsprache bevorzugt wird. Ich bevorzuge (mittlerweile) Powershell, was auch Hauptthema dieser Serie ist, daher gehe ich nun etwas tiefer in die Umsetzung “Firewall Ports öffnen” mit Powershell ein.

Umsetzung mittels Powershell

Auch die Windows-Firewall hat ein Powershell Commandlet, so dass wir die Firewall Ports recht einfach und komfortabel öffnen können. Mein Lösungsansatz ist vielleicht etwas länger und umfangreicher, der erfahrene Powershell Programmierer bekommt das bestimmt auch in eine Schleife gepackt oder gar in eine Zeile 😉
Meine Zeilen stammen aus einem Skript, welches ich für die Konfiguration nach der Installation verwende, daher sind hier zahlreiche Variablen genutzt worden, um die Flexibilität zu erhalten.

  • $SQLServerTCPPort = 10001
  • $InstanceName = TEST_Instanz

Auch ein wenig “Monitoring” habe ich implementiert, so dass man gleich das Ergebnis, den Fehlschlag bzw den Fortschritt anhand der Ausgabe erkennen kann. Für meine Zwecke im Rahmen der SQL Server Installation reichen diese Zeilen um die Firewall Ports zu öffnen, zudem erklären sich die einzelnen Parameter nahezu von selbst.

Write-Host "Opening Firewall ports for this Instance"
    Try {
		Write-Host "Opening Firewall on Port $SQLServerTCPPort" 
		$port1 = New-Object -ComObject HNetCfg.FWOpenPort
		$port1.Port = $SQLServerTCPPort
		$port1.Name = "SQL Server (TCP " + $SQLServerTCPPort + ") " + $InstanceName 
		$port1.Enabled = $true
		$port1.Protocol = 6
		$fwMgr = New-Object -ComObject HNetCfg.FwMgr
		$profiledomain=$fwMgr.LocalPolicy.GetProfileByType(0)
		$profiledomain.GloballyOpenPorts.Add($port1)
        Write-Host "[INFO] Successfully opened Firewall on Port $SQLServerTCPPort." -ForegroundColor Green
     } 
    Catch { 
        Write-Host "[ERROR] Opening Firewall on Port $SQLServerTCPPort failed." -ForegroundColor Red 
    }
   
   Try {
		Write-Host "Opening Firewall on Port 4022" 
		$port1 = New-Object -ComObject HNetCfg.FWOpenPort
		$port1.Port = 4022
		$port1.Name = "SQL Service Broker (TCP 4022)"
		$port1.Enabled = $true
		$port1.Protocol = 6
		$fwMgr = New-Object -ComObject HNetCfg.FwMgr
		$profiledomain=$fwMgr.LocalPolicy.GetProfileByType(0)
		$profiledomain.GloballyOpenPorts.Add($port1) 
        Write-Host "[INFO] Successfully opened Firewall on Port 4022." -ForegroundColor Green
    } 
    Catch { 
        Write-Host "[ERROR] Opening Firewall on Port 4022 failed." -ForegroundColor Red 
    }
   
    Try {
		Write-Host "Opening Firewall on Port UDP 1434" 
		$port1 = New-Object -ComObject HNetCfg.FWOpenPort
		$port1.Port = 1434
		$port1.Name = "SQL Browser (UDP 1434)"
		$port1.Enabled = $true
		$port1.Protocol = 17
		$fwMgr = New-Object -ComObject HNetCfg.FwMgr
		$profiledomain=$fwMgr.LocalPolicy.GetProfileByType(0)
		$profiledomain.GloballyOpenPorts.Add($port1) 
        Write-Host "[INFO] Successfully opened Firewall on Port UDP 1434." -ForegroundColor Green
    } 
    Catch { 
        Write-Host "[ERROR] Opening Firewall on Port 1434 failed." -ForegroundColor Red 
    }