Separate firewall configuration between linked OUs
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Danny Bessems 2021-04-08 17:13:24 +02:00
parent ed69de5d27
commit f8a8cb80c8
4 changed files with 255 additions and 91 deletions

View File

@ -1,3 +1,6 @@
Name: 'COMP: Firewall (Clients)'
LinkedOUs:
- OU=Clients,OU=Computer accounts
FirewallRules: FirewallRules:
- Description: Rule A - Description: Rule A
Action: Block Action: Block

View File

@ -0,0 +1,65 @@
Name: 'COMP: Firewall (DomainControllers)'
LinkedOUs:
- OU=Domain Controllers
FirewallRules:
- Description: Rule A
Action: Block
Direction: Inbound
Program: ''
Port: '21-22,25'
Protocol: TCP
- Description: Rule B
Action: Allow
Direction: Inbound
Program: D:\MSSQL\sqlsvr.exe
Port: ''
Protocol: ''
FirewallProfiles:
- Name: Domain
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\domainfw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
- Name: Private
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\privatefw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
- Name: Public
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\publicfw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
# ---
# Variables:
# - Name: foo
# Expression: |
# Write-Host 'bar'

View File

@ -6,9 +6,15 @@ Param(
# Only executed on primary or standalone Domain Controller # Only executed on primary or standalone Domain Controller
If (@('primary','standalone') -contains $Parameter['deployment.type']) { If (@('primary','standalone') -contains $Parameter['deployment.type']) {
$GetContentSplat = @{ $GetItemSplat = @{
Path = "$($PSScriptRoot)\$($MyInvocation.MyCommand)".Replace('.ps1', '.yml') Path = "$($PSScriptRoot)\$($MyInvocation.MyCommand)".Replace('.ps1', '.yml')
Raw = $true }
ForEach ($File in (Get-Item @GetItemSplat)) {
Try {
Write-Host "Loading/parsing file '$($File)' ..."
$GetContentSplat = @{
Path = $File
Raw = $True
} }
$RawContent = Get-Content @GetContentSplat $RawContent = Get-Content @GetContentSplat
$ConvertFromYamlSplat = @{ $ConvertFromYamlSplat = @{
@ -16,9 +22,15 @@ If (@('primary','standalone') -contains $Parameter['deployment.type']) {
AllDocuments = $True AllDocuments = $True
} }
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat $YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
}
Catch {
$ParseErrors += "While processing '$($File)': $($_.Exception.Message)"
Continue
}
# Check if the respective .yml file declared substitutions which need to be parsed # Check if the respective .yml file declared substitutions which need to be parsed
If (($YamlDocuments.Count -gt 1) -and $YamlDocuments[-1].Variables) { If (($YamlDocuments.Count -gt 1) -and $YamlDocuments[-1].Variables) {
Try {
ForEach ($Pattern in $YamlDocuments[-1].Variables) { ForEach ($Pattern in $YamlDocuments[-1].Variables) {
$RawContent = $RawContent -replace "\{\{ ($($Pattern.Name)) \}\}", [string](Invoke-Expression -Command $Pattern.Expression) $RawContent = $RawContent -replace "\{\{ ($($Pattern.Name)) \}\}", [string](Invoke-Expression -Command $Pattern.Expression)
} }
@ -28,6 +40,12 @@ If (@('primary','standalone') -contains $Parameter['deployment.type']) {
AllDocuments = $True AllDocuments = $True
} }
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat $YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
}
Catch {
$ParseErrors += "While processing '$($File)' (after substitutions): $($_.Exception.Message)"
Continue
}
$Settings = $YamlDocuments[0..($YamlDocuments.Count - 2)] $Settings = $YamlDocuments[0..($YamlDocuments.Count - 2)]
} }
Else { Else {
@ -35,7 +53,7 @@ If (@('primary','standalone') -contains $Parameter['deployment.type']) {
} }
$NewGPOSplat = @{ $NewGPOSplat = @{
Name = 'COMP: Firewall (Servers)' Name = $Settings.Name
} }
$NewGPO = New-GPO @NewGPOSplat $NewGPO = New-GPO @NewGPOSplat
@ -95,15 +113,28 @@ If (@('primary','standalone') -contains $Parameter['deployment.type']) {
} }
Save-NetGPO @SaveNetGPOSplat Save-NetGPO @SaveNetGPOSplat
ForEach ($OU in $Settings.LinkedOUs) {
If (Test-Path "AD:\$($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))") {
Try {
Write-Host "Linking policy '$($NewGPO.DisplayName)' to OU '$($OU)' ..."
$NewGPLinkSplat = @{ $NewGPLinkSplat = @{
Name = $NewGPO.DisplayName Name = $NewGPO.DisplayName
# Should probably be configurable through yml Target = $OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext)
Target = 'OU=Servers,OU=Computer accounts,DC=' + $Parameter['addsconfig.domainname'].Replace('.', ',DC=')
} }
New-GPLink @NewGPLinkSplat New-GPLink @NewGPLinkSplat | Out-Null
$NewGPLinkSplat = @{ }
Name = $NewGPO.DisplayName Catch {
Target = 'OU=Domain Controllers,DC=' + $Parameter['addsconfig.domainname'].Replace('.', ',DC=') $ParseErrors += "Could not link GPO '$($NewGPO.DisplayName)' to OU '$($OU)'"
Continue
}
}
Else {
$ParseErrors += "Path not accessible (referred to by '$($NewGPO.DisplayName)'): 'AD:\$($OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext))'"
Continue
}
}
}
If ($ParseErrors) {
Throw "One or more errors occurred:`n$($ParseErrors -join "`n")"
} }
New-GPLink @NewGPLinkSplat
} }

View File

@ -0,0 +1,65 @@
Name: 'COMP: Firewall (Servers)'
LinkedOUs:
- OU=Servers,OU=Computer accounts
FirewallRules:
- Description: Rule A
Action: Block
Direction: Inbound
Program: ''
Port: '21-22,25'
Protocol: TCP
- Description: Rule B
Action: Allow
Direction: Inbound
Program: D:\MSSQL\sqlsvr.exe
Port: ''
Protocol: ''
FirewallProfiles:
- Name: Domain
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\domainfw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
- Name: Private
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\privatefw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
- Name: Public
Enabled: 'True'
Connections:
Inbound: Block
Outbound: Allow
Settings:
DisplayNotification: 'False'
ApplyLocalFirewallRules: 'True'
ApplyLocalConnectionSecurityRules: 'True'
Logging:
Name: '%SYSTEMROOT%\System32\Logfiles\Firewall\publicfw.log'
SizeLimit: 16384
LogDroppedPackets: 'True'
LogSuccessfullConnections: 'False'
# ---
# Variables:
# - Name: foo
# Expression: |
# Write-Host 'bar'