Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xDSCWebservice: FIX Firewall Exception #614

Merged
merged 14 commits into from
Apr 30, 2019
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
- Fixes test failures in xWindowsOptionalFeatureSet.Integration.Tests.ps1 due
to accessing the windowsOptionalFeatureName variable before it is assigned.
[issue #612](https://github.com/PowerShell/xPSDesiredStateConfiguration/issues/612)
- MSFT_xDSCWebService
- Fixes [issue #536] and starts the deprecation process for configuring a windows firewall (exception) rule using xDSCWebService

## 8.6.0.0

Expand Down
101 changes: 101 additions & 0 deletions DSCResources/MSFT_xDSCWebService/Firewall.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Name and description for the Firewall rules. Used in multiple locations
$script:FireWallRuleDisplayName = 'Desired State Configuration - Pull Server Port:{0}'

<#
.SYNOPSIS
Create a firewall exception so that DSC clients are able to access the configured Pull Server

.PARAMETER firewallPort
The TCP port used to create the firewall exception
#>
function Add-PullServerFirewallConfiguration
{
[CmdletBinding()]
param
(
[Parameter()]
[ValidateRange(1, 65535)]
[System.UInt32]
$Port
)

$script:netsh = "$env:windir\system32\netsh.exe"

Write-Verbose -Message 'Disable Inbound Firewall Notification'
& $script:netsh advfirewall set currentprofile settings inboundusernotification disable

# remove all existing rules with that displayName
& $script:netsh advfirewall firewall delete rule name=DSCPullServer_IIS_Port protocol=tcp localport=$Port | Out-Null

Write-Verbose -Message "Add Firewall Rule for port $Port"
& $script:netsh advfirewall firewall add rule name=DSCPullServer_IIS_Port dir=in action=allow protocol=TCP localport=$Port | Out-Null
}

<#
.SYNOPSIS
Delete the Pull Server firewall exception

.PARAMETER firewallPort
The TCP port for which the firewall exception should be deleted
#>
function Remove-PullServerFirewallConfiguration
{
[CmdletBinding()]
param
(
[Parameter()]
[ValidateRange(1, 65535)]
[System.UInt32]
$Port
)

if (Test-PullServerFirewallConfiguration -Port $Port)
{
$script:netsh = "$env:windir\system32\netsh.exe"

# remove all existing rules with that displayName
Write-Verbose -Message "Delete Firewall Rule for port $Port"
& $script:netsh advfirewall firewall delete rule name=DSCPullServer_IIS_Port protocol=tcp localport=$Port | Out-Null

# backwards compatibility with old code
if (Get-Command -Name Get-NetFirewallRule -CommandType Cmdlet -ErrorAction:SilentlyContinue)
{
# Remove all rules with that name
$ruleName = ($($FireWallRuleDisplayName) -f $port)
Get-NetFirewallRule | Where-Object DisplayName -eq "$ruleName" | Remove-NetFirewallRule
}
}
else
{
Write-Verbose -Message "No DSC PullServer firewall rule found with port $Port. No cleanup required"
}
}

<#
.SYNOPSIS
Tests if a Pull Server firewall exception exists for a specific port

.PARAMETER firewallPort
The TCP port for which the firewall exception should be tested
#>
function Test-PullServerFirewallConfiguration
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[Parameter()]
[ValidateRange(1, 65535)]
[System.UInt32]
$Port
)

$script:netsh = "$env:windir\system32\netsh.exe"

# remove all existing rules with that displayName
Write-Verbose -Message "Testing Firewall Rule for port $Port"
$result = & $script:netsh advfirewall firewall show rule name=DSCPullServer_IIS_Port | Select-String -Pattern "LocalPort:\s*$Port"
return -not [string]::IsNullOrWhiteSpace($result)
}

Export-ModuleMember -Function '*-PullServerFirewallConfiguration'
77 changes: 65 additions & 12 deletions DSCResources/MSFT_xDSCWebService/MSFT_xDSCWebService.psm1
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Import the helper functions
Import-Module -Name $PSScriptRoot\PSWSIISEndpoint.psm1 -Verbose:$false
Import-Module -Name $PSScriptRoot\UseSecurityBestPractices.psm1 -Verbose:$false
Import-Module -Name (Join-Path $PSScriptRoot 'PSWSIISEndpoint.psm1') -Verbose:$false
Import-Module -Name (Join-Path $PSScriptRoot 'UseSecurityBestPractices.psm1') -Verbose:$false
Import-Module -NAme (Join-Path $PSScriptRoot 'Firewall.psm1') -Verbose:$false

#region LocalizedData
$script:culture = 'en-US'
Expand Down Expand Up @@ -65,7 +66,11 @@ function Get-TargetResource
# When this property is set to true, Pull Server will run on a 32 bit process on a 64 bit machine
[Parameter()]
[System.Boolean]
$Enable32BitAppOnWin64 = $false
$Enable32BitAppOnWin64 = $false,

[Parameter()]
[System.Boolean]
$ConfigureFirewall = $true
)

# If Certificate Subject is not specified then a value for CertificateThumbprint must be explicitly set instead.
Expand Down Expand Up @@ -136,6 +141,8 @@ function Get-TargetResource
{
$acceptSelfSignedCertificates = $true
}

$ConfigureFirewall = Test-PullServerFirewallConfiguration -Port $iisPort
}
else
{
Expand All @@ -158,6 +165,7 @@ function Get-TargetResource
UseSecurityBestPractices = $UseSecurityBestPractices
DisableSecurityBestPractices = $DisableSecurityBestPractices
Enable32BitAppOnWin64 = $Enable32BitAppOnWin64
ConfigureFirewall = $ConfigureFirewall
}

if ($CertificateThumbPrint -eq 'AllowUnencryptedTraffic')
Expand Down Expand Up @@ -204,6 +212,7 @@ function Set-TargetResource

# Port number of the DSC Pull Server IIS Endpoint
[Parameter()]
[ValidateRange(1, 65535)]
[System.UInt32]
$Port = 8080,

Expand Down Expand Up @@ -291,7 +300,11 @@ function Set-TargetResource
# When this property is set to true, Pull Server will run on a 32 bit process on a 64 bit machine
[Parameter()]
[System.Boolean]
$Enable32BitAppOnWin64 = $false
$Enable32BitAppOnWin64 = $false,

[Parameter()]
[System.Boolean]
$ConfigureFirewall = $true
)

# If Certificate Subject is not specified then a value for CertificateThumbprint must be explicitly set instead.
Expand All @@ -313,6 +326,10 @@ function Set-TargetResource
throw $LocalizedData.ThrowUseSecurityBestPractice
}

if ($ConfigureFirewall)
{
Write-Warning -Message $LocalizedData.ConfigFirewallDeprecated
}
# Initialize with default values

$pathPullServer = "$pshome\modules\PSDesiredStateConfiguration\PullServer"
Expand Down Expand Up @@ -354,16 +371,23 @@ function Set-TargetResource
# ============ Absent block to remove existing site =========
if(($Ensure -eq "Absent"))
{
$website = Get-Website -Name $EndpointName
if($null -ne $website)
{
if(Test-Path -LiteralPath "IIS:\Sites\$EndpointName")
{
# Get the port number for the Firewall rule
Write-Verbose -Message "Processing bindings for $EndpointName"
$portList = Get-WebBinding -Name $EndpointName | ForEach-Object {
[System.Text.RegularExpressions.Regex]::Match($_.bindingInformation,':(\d+):').Groups[1].Value
}

# there is a web site, but there shouldn't be one
Write-Verbose -Message "Removing web site $EndpointName"
PSWSIISEndpoint\Remove-PSWSEndpoint -SiteName $EndpointName
}

# we are done here, all stuff below is for 'Present'
return
$portList | ForEach-Object { Remove-PullServerFirewallConfiguration -Port $_ }
}

# we are done here, all stuff below is for 'Present'
return
}
# ===========================================================

Expand All @@ -382,10 +406,20 @@ function Set-TargetResource
-language $language `
-dependentMUIFiles "$pathPullServer\$languagePath\Microsoft.Powershell.DesiredStateConfiguration.Service.Resources.dll" `
-certificateThumbPrint $certificateThumbPrint `
-EnableFirewallException $true `
-Enable32BitAppOnWin64 $Enable32BitAppOnWin64 `
-Verbose

if ($ConfigureFirewall)
{
Write-Verbose -Message "Enabling firewall exception for port $port"
Add-PullServerFirewallConfiguration -Port $port
}
else
{
Write-Verbose -Message "Disabling firewall exception for port $port"
Remove-PullServerFirewallConfiguration -Port $port
}

Update-LocationTagInApplicationHostConfigForAuthentication -WebSite $EndpointName -Authentication "anonymous"
Update-LocationTagInApplicationHostConfigForAuthentication -WebSite $EndpointName -Authentication "basic"
Update-LocationTagInApplicationHostConfigForAuthentication -WebSite $EndpointName -Authentication "windows"
Expand Down Expand Up @@ -565,7 +599,11 @@ function Test-TargetResource
# When this property is set to true, Pull Server will run on a 32 bit process on a 64 bit machine
[Parameter()]
[System.Boolean]
$Enable32BitAppOnWin64 = $false
$Enable32BitAppOnWin64 = $false,

[Parameter()]
[System.Boolean]
$ConfigureFirewall = $true
)

# If Certificate Subject is not specified then a value for CertificateThumbprint must be explicitly set instead.
Expand Down Expand Up @@ -616,6 +654,21 @@ function Test-TargetResource
$actualCertificateHash = $website.bindings.Collection[0].certificateHash
$websiteProtocol = $website.bindings.collection[0].Protocol

Write-Verbose -Message 'Checking firewall rule settings'
$ruleExists = Test-PullServerFirewallConfiguration -Port $Port
if ($ruleExists -and -not $ConfigureFirewall)
{
$desiredConfigurationMatch = $false
Write-Verbose -Message "Firewall rule exists for $Port and should not. Configuration does not match the desired state."
break
}
elseif (-not $ruleExists -and $ConfigureFirewall)
{
$desiredConfigurationMatch = $false
Write-Verbose -Message "Firewall rule does not exist for $Port and should. Configuration does not match the desired state."
break
}

switch ($PSCmdlet.ParameterSetName)
{
'CertificateThumbprint'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[ClassVersion("1.0.0"), FriendlyName("xDSCWebService")]
[ClassVersion("1.0.0"), FriendlyName("xDSCWebService")]
class MSFT_xDSCWebService : OMI_BaseResource
{
[Key] string EndpointName;
Expand All @@ -13,12 +13,13 @@ class MSFT_xDSCWebService : OMI_BaseResource
[write] string DatabasePath;
[write] string ModulePath;
[write] string ConfigurationPath;
[read] string DSCServerUrl;
[read] string DSCServerUrl;
[write] string RegistrationKeyPath;
[write] boolean AcceptSelfSignedCertificates;
[write] boolean SqlProvider;
[write] string SqlConnectionString;
[required, Description("This property will ensure that the Pull Server is created with the most secure practices")] boolean UseSecurityBestPractices;
[write,ValueMap{"SecureTLSProtocols"},Values{"SecureTLSProtocols"}] string DisableSecurityBestPractices [];
[write, Description("When this property is set to true, Pull Server will run on a 32 bit process on a 64 bit machine")] boolean Enable32BitAppOnWin64;
[write, Description("Add firewall incoming exceptions for the configured PullServer Port. Default: true")] boolean ConfigureFirewall;
};
Loading