Separate firewall configuration between linked OUs
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
ed69de5d27
commit
f8a8cb80c8
@ -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
|
@ -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'
|
@ -6,104 +6,135 @@ 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
|
|
||||||
}
|
}
|
||||||
$RawContent = Get-Content @GetContentSplat
|
ForEach ($File in (Get-Item @GetItemSplat)) {
|
||||||
$ConvertFromYamlSplat = @{
|
Try {
|
||||||
Yaml = $RawContent
|
Write-Host "Loading/parsing file '$($File)' ..."
|
||||||
AllDocuments = $True
|
$GetContentSplat = @{
|
||||||
}
|
Path = $File
|
||||||
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
|
Raw = $True
|
||||||
|
}
|
||||||
# Check if the respective .yml file declared substitutions which need to be parsed
|
$RawContent = Get-Content @GetContentSplat
|
||||||
If (($YamlDocuments.Count -gt 1) -and $YamlDocuments[-1].Variables) {
|
$ConvertFromYamlSplat = @{
|
||||||
ForEach ($Pattern in $YamlDocuments[-1].Variables) {
|
Yaml = $RawContent
|
||||||
$RawContent = $RawContent -replace "\{\{ ($($Pattern.Name)) \}\}", [string](Invoke-Expression -Command $Pattern.Expression)
|
AllDocuments = $True
|
||||||
|
}
|
||||||
|
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
|
||||||
}
|
}
|
||||||
# Perform conversion to Yaml again, now with parsed file contents
|
Catch {
|
||||||
$ConvertFromYamlSplat = @{
|
$ParseErrors += "While processing '$($File)': $($_.Exception.Message)"
|
||||||
Yaml = $RawContent
|
Continue
|
||||||
AllDocuments = $True
|
|
||||||
}
|
}
|
||||||
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
|
|
||||||
$Settings = $YamlDocuments[0..($YamlDocuments.Count - 2)]
|
# Check if the respective .yml file declared substitutions which need to be parsed
|
||||||
}
|
If (($YamlDocuments.Count -gt 1) -and $YamlDocuments[-1].Variables) {
|
||||||
Else {
|
Try {
|
||||||
$Settings = $YamlDocuments
|
ForEach ($Pattern in $YamlDocuments[-1].Variables) {
|
||||||
}
|
$RawContent = $RawContent -replace "\{\{ ($($Pattern.Name)) \}\}", [string](Invoke-Expression -Command $Pattern.Expression)
|
||||||
|
}
|
||||||
|
# Perform conversion to Yaml again, now with parsed file contents
|
||||||
|
$ConvertFromYamlSplat = @{
|
||||||
|
Yaml = $RawContent
|
||||||
|
AllDocuments = $True
|
||||||
|
}
|
||||||
|
$YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
$ParseErrors += "While processing '$($File)' (after substitutions): $($_.Exception.Message)"
|
||||||
|
Continue
|
||||||
|
}
|
||||||
|
|
||||||
$NewGPOSplat = @{
|
$Settings = $YamlDocuments[0..($YamlDocuments.Count - 2)]
|
||||||
Name = 'COMP: Firewall (Servers)'
|
|
||||||
}
|
|
||||||
$NewGPO = New-GPO @NewGPOSplat
|
|
||||||
|
|
||||||
$OpenNetGPOSplat = @{
|
|
||||||
PolicyStore = "$($Parameter['addsconfig.domainname'])\$($NewGPO.DisplayName)"
|
|
||||||
}
|
|
||||||
$GPOSession = Open-NetGPO @OpenNetGPOSplat
|
|
||||||
|
|
||||||
ForEach ($Rule in $Settings.FirewallRules) {
|
|
||||||
$NewNetFirewallRuleSplat = @{
|
|
||||||
# Using so-called string formatting with the '-f' operator (looks more complicated than it is) to create consistent policy names:
|
|
||||||
# Examples:
|
|
||||||
# 'DENY: Inbound port 443 (TCP)'
|
|
||||||
# 'ALLOW: Inbound 'D:\MSSQL\bin\sqlservr.exe'
|
|
||||||
DisplayName = ("{0}: {1} {2} {3} {4}" -f
|
|
||||||
$Rule.Action.ToUpper(),
|
|
||||||
$Rule.Direction,
|
|
||||||
("'$($Rule.Program)'", $NULL)[!($Rule.Program)],
|
|
||||||
("Port $($Rule.Port)", $NULL)[!($Rule.Port)],
|
|
||||||
("($($Rule.Protocol))", $NULL)[!($Rule.Protocol)]
|
|
||||||
) -replace '\s+',' '
|
|
||||||
Description = $Rule.Description
|
|
||||||
Action = $Rule.Action
|
|
||||||
Direction = $Rule.Direction
|
|
||||||
Program = ($Rule.Program, 'Any')[!($Rule.Program)]
|
|
||||||
LocalPort = ($Rule.Port.Split(','), 'Any')[!($Rule.Port)]
|
|
||||||
Protocol = ($Rule.Protocol, 'Any')[!($Rule.Protocol)]
|
|
||||||
GPOSession = $GPOSession
|
|
||||||
PolicyStore = $NewGPO.DisplayName
|
|
||||||
Confirm = $False
|
|
||||||
}
|
}
|
||||||
New-NetFirewallRule @NewNetFirewallRuleSplat
|
Else {
|
||||||
}
|
$Settings = $YamlDocuments
|
||||||
|
}
|
||||||
ForEach ($Profile in $Settings.FirewallProfiles) {
|
|
||||||
$SetNetFirewallProfileSplat = @{
|
$NewGPOSplat = @{
|
||||||
Name = $Profile.Name
|
Name = $Settings.Name
|
||||||
Enabled = $Profile.Enabled
|
}
|
||||||
DefaultInboundAction = $Profile.Connections.Inbound
|
$NewGPO = New-GPO @NewGPOSplat
|
||||||
DefaultOutboundAction = $Profile.Connections.Outbound
|
|
||||||
LogAllowed = $Profile.Logging.LogSuccessfullConnections
|
$OpenNetGPOSplat = @{
|
||||||
LogBlocked = $Profile.Logging.LogDroppedPackets
|
PolicyStore = "$($Parameter['addsconfig.domainname'])\$($NewGPO.DisplayName)"
|
||||||
LogFileName = $Profile.Logging.Name
|
}
|
||||||
LogMaxSizeKilobytes = $Profile.Logging.SizeLimit
|
$GPOSession = Open-NetGPO @OpenNetGPOSplat
|
||||||
AllowLocalFirewallRules = $Profile.Settings.ApplyLocalFirewallRules
|
|
||||||
AllowLocalIPsecRules = $Profile.Settings.ApplyLocalConnectionSecurityRules
|
ForEach ($Rule in $Settings.FirewallRules) {
|
||||||
NotifyOnListen = $Profile.Settings.DisplayNotification
|
$NewNetFirewallRuleSplat = @{
|
||||||
GPOSession = $GPOSession
|
# Using so-called string formatting with the '-f' operator (looks more complicated than it is) to create consistent policy names:
|
||||||
PolicyStore = $NewGPO.DisplayName
|
# Examples:
|
||||||
Confirm = $False
|
# 'DENY: Inbound port 443 (TCP)'
|
||||||
|
# 'ALLOW: Inbound 'D:\MSSQL\bin\sqlservr.exe'
|
||||||
|
DisplayName = ("{0}: {1} {2} {3} {4}" -f
|
||||||
|
$Rule.Action.ToUpper(),
|
||||||
|
$Rule.Direction,
|
||||||
|
("'$($Rule.Program)'", $NULL)[!($Rule.Program)],
|
||||||
|
("Port $($Rule.Port)", $NULL)[!($Rule.Port)],
|
||||||
|
("($($Rule.Protocol))", $NULL)[!($Rule.Protocol)]
|
||||||
|
) -replace '\s+',' '
|
||||||
|
Description = $Rule.Description
|
||||||
|
Action = $Rule.Action
|
||||||
|
Direction = $Rule.Direction
|
||||||
|
Program = ($Rule.Program, 'Any')[!($Rule.Program)]
|
||||||
|
LocalPort = ($Rule.Port.Split(','), 'Any')[!($Rule.Port)]
|
||||||
|
Protocol = ($Rule.Protocol, 'Any')[!($Rule.Protocol)]
|
||||||
|
GPOSession = $GPOSession
|
||||||
|
PolicyStore = $NewGPO.DisplayName
|
||||||
|
Confirm = $False
|
||||||
|
}
|
||||||
|
New-NetFirewallRule @NewNetFirewallRuleSplat
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEach ($Profile in $Settings.FirewallProfiles) {
|
||||||
|
$SetNetFirewallProfileSplat = @{
|
||||||
|
Name = $Profile.Name
|
||||||
|
Enabled = $Profile.Enabled
|
||||||
|
DefaultInboundAction = $Profile.Connections.Inbound
|
||||||
|
DefaultOutboundAction = $Profile.Connections.Outbound
|
||||||
|
LogAllowed = $Profile.Logging.LogSuccessfullConnections
|
||||||
|
LogBlocked = $Profile.Logging.LogDroppedPackets
|
||||||
|
LogFileName = $Profile.Logging.Name
|
||||||
|
LogMaxSizeKilobytes = $Profile.Logging.SizeLimit
|
||||||
|
AllowLocalFirewallRules = $Profile.Settings.ApplyLocalFirewallRules
|
||||||
|
AllowLocalIPsecRules = $Profile.Settings.ApplyLocalConnectionSecurityRules
|
||||||
|
NotifyOnListen = $Profile.Settings.DisplayNotification
|
||||||
|
GPOSession = $GPOSession
|
||||||
|
PolicyStore = $NewGPO.DisplayName
|
||||||
|
Confirm = $False
|
||||||
|
}
|
||||||
|
Set-NetFirewallProfile @SetNetFirewallProfileSplat
|
||||||
|
}
|
||||||
|
|
||||||
|
$SaveNetGPOSplat = @{
|
||||||
|
GPOSession = $GPOSession
|
||||||
|
}
|
||||||
|
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 = @{
|
||||||
|
Name = $NewGPO.DisplayName
|
||||||
|
Target = $OU + (',{0}' -f (Get-ADRootDSE).rootDomainNamingContext)
|
||||||
|
}
|
||||||
|
New-GPLink @NewGPLinkSplat | Out-Null
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
$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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Set-NetFirewallProfile @SetNetFirewallProfileSplat
|
|
||||||
}
|
}
|
||||||
|
If ($ParseErrors) {
|
||||||
$SaveNetGPOSplat = @{
|
Throw "One or more errors occurred:`n$($ParseErrors -join "`n")"
|
||||||
GPOSession = $GPOSession
|
|
||||||
}
|
}
|
||||||
Save-NetGPO @SaveNetGPOSplat
|
|
||||||
|
|
||||||
$NewGPLinkSplat = @{
|
|
||||||
Name = $NewGPO.DisplayName
|
|
||||||
# Should probably be configurable through yml
|
|
||||||
Target = 'OU=Servers,OU=Computer accounts,DC=' + $Parameter['addsconfig.domainname'].Replace('.', ',DC=')
|
|
||||||
}
|
|
||||||
New-GPLink @NewGPLinkSplat
|
|
||||||
$NewGPLinkSplat = @{
|
|
||||||
Name = $NewGPO.DisplayName
|
|
||||||
Target = 'OU=Domain Controllers,DC=' + $Parameter['addsconfig.domainname'].Replace('.', ',DC=')
|
|
||||||
}
|
|
||||||
New-GPLink @NewGPLinkSplat
|
|
||||||
}
|
}
|
||||||
|
65
scripts/ADDS/payload/scripts/05.Firewall.servers.yml
Normal file
65
scripts/ADDS/payload/scripts/05.Firewall.servers.yml
Normal 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'
|
Loading…
Reference in New Issue
Block a user