Manage the windows firewall with Puppet (netsh
and PowerShell as required).
windows_firewall_rule
)windows_firewall_group
)windows_firewall_global
)windows_firewall_profile
)Manage individual firewall rules
The type and provider is able to enumerate the firewall rules existing on the system:
C:\>puppet resource windows_firewall_rule
...
windows_firewall_rule { '{FCC26AEB-5C68-481A-96DA-8A404F73714C}':
ensure => 'present',
action => 'allow',
description => 'Mail and Calendar',
direction => 'inbound',
display_group => 'Mail and Calendar',
display_name => 'Mail and Calendar',
edge_traversal_policy => 'allow',
enabled => 'true',
icmp_type => 'any',
interface_type => ['any'],
local_address => 'any',
local_port => 'any',
profile => ['domain', 'private', 'public'],
program => 'Any',
protocol => 'any',
remote_address => 'any',
remote_port => 'any',
}
You can limit output to a single rule by passing its name as an argument, eg:
C:\>puppet resource windows_firewall_rule winrm
windows_firewall_rule { 'winrm':
ensure => 'present',
action => 'allow',
direction => 'inbound',
display_name => 'winrm',
edge_traversal_policy => 'block',
enabled => 'true',
interface_type => ['any'],
local_address => 'any',
local_port => '5985',
profile => ['domain', 'private', 'public'],
protocol => 'tcp',
remote_address => 'any',
remote_port => 'any',
}
The basic syntax for ensuring rules is:
windows_firewall_rule { "name of rule":
ensure => present,
...
}
If a rule with the same name but different properties already exists, it will be
deleted and re-created to ensure it is defined correctly. To delete a rule, set
ensure => absent
.
windows_firewall_rule { "puppet - all icmpv4":
ensure => present,
direction => "inbound",
action => "allow",
protocol => "icmpv4",
}
You can also create a rule that only allows a specific ICMP type and code:
windows_firewall_rule { "puppet - allow icmp echo":
ensure => present,
direction => "inbound",
action => "allow",
protocol => "icmpv4",
icmp_type => "8:10",
}
You need to create one rule for each icmp_type
value (see limitations).
Use the local_port
and remote_port
properties to set the ports a rule refers
to. You can set an individual ports, a range or combination:
windows_firewall_rule { "puppet - allow ports 1000-2000":
ensure => present,
direction => "inbound",
action => "allow",
protocol => "tcp",
local_port => "80,443,4243,5000-5010",
}
Use the local_address
and remote_address
properties to target rules at
particular address. You can use individual or multiple addresses:
windows_firewall_rule { "puppet - multiple remote and local addresses":
ensure => present,
direction => "inbound",
action => "allow",
protocol => "tcp",
profile => ["private", "domain"],
local_port => 7777,
remote_port => 7777,
local_address => "192.168.1.1,10.10.10.10",
remote_address => "192.168.1.2,192.168.2.11",
}
windows_firewall_rule { "puppet - allow messenger":
ensure => present,
direction => "inbound",
action => "allow",
program => "C:\\programfiles\\messenger\\msnmsgr.exe",
}
windows_firewall_rule { "puppet - open port in specific profiles":
ensure => present,
direction => "inbound",
action => "allow",
protocol => "tcp",
profile => ["private", "domain"],
local_port => "666",
}
You can choose to purge unmanaged rules from the system (be careful! - this will remove any rule that is not manged by Puppet including those created by Windows itself):
resources { "windows_firewall_rule":
purge => true,
}
windows_firewall_rule { "puppet - allow all":
ensure => present,
direction => "inbound",
action => "allow",
protocol => "tcp",
local_port => "any",
}
Enable/Disable named groups of firewall rules. Not that it is only possible to enable/disable existing groups, not create or edit them.
windows_firewall_group { "File and Printer Sharing":
enabled => true,
}
windows_firewall_group { "File and Printer Sharing":
enabled => false,
}
Global settings always exist (there is no ensure
).
You can use puppet resource windows_firewall_global
to check what Puppet
thinks the current values are:
C:\vagrant>puppet resource windows_firewall_global
windows_firewall_global { 'global':
authzcomputergrp => 'none',
authzcomputergrptransport => 'none',
authzusergrp => 'none',
authzusergrptransport => 'none',
boottimerulecategory => 'windows firewall',
consecrulecategory => 'windows firewall',
defaultexemptions => ['dhcp', 'neighbordiscovery'],
firewallrulecategory => 'windows firewall',
forcedh => 'yes',
ipsecthroughnat => 'serverbehindnat',
keylifetime => '485min,0sess',
saidletimemin => '6',
secmethods => 'dhgroup2:aes128-sha1,dhgroup2:3des-sha1',
statefulftp => 'disable',
statefulpptp => 'disable',
stealthrulecategory => 'windows firewall',
strongcrlcheck => '1',
}
Note: some properties are read-only.
A single resource with an arbitrary title should be used to manage the desired settings, eg:
windows_firewall_global { 'global':
authzcomputergrp => 'none',
authzusergrp => 'none',
defaultexemptions => ['neighbordiscovery','dhcp'],
forcedh => 'yes',
ipsecthroughnat => 'serverbehindnat',
keylifetime => '485min,0sess',
saidletimemin => '6',
secmethods => 'dhgroup2:aes128-sha1,dhgroup2:3des-sha1',
statefulftp => 'disable',
statefulpptp => 'disable',
strongcrlcheck => '1',
}
There are three firewall profiles that the module supports:
Depending on the network the node is connected to, one of these profiles will be active. They map to three Puppet resources which cannot be ensured:
Windows_firewall_profile[private]
Windows_firewall_profile[domain]
Windows_firewall_profile[public]
Use puppet resource windows_firewall_profile
to see what puppet thinks the
settings are:
C:\vagrant>puppet resource windows_firewall_profile
windows_firewall_profile { 'domain':
filename => '%systemroot%\system32\logfiles\firewall\pfirewall.log',
firewallpolicy => 'blockinbound,allowoutbound',
inboundusernotification => 'disable',
localconsecrules => 'n/a (gpo-store only)',
localfirewallrules => 'n/a (gpo-store only)',
logallowedconnections => 'disable',
logdroppedconnections => 'disable',
maxfilesize => '4096',
remotemanagement => 'disable',
state => 'on',
unicastresponsetomulticast => 'enable',
}
windows_firewall_profile { 'private':
filename => '%systemroot%\system32\logfiles\firewall\pfirewall.log',
firewallpolicy => 'blockinbound,allowoutbound',
inboundusernotification => 'disable',
localconsecrules => 'n/a (gpo-store only)',
...
Note that some settings are read-only
Use the state
property on some or all of the profiles:
windows_firewall_profile { 'private':
state => false, # off
}
windows_firewall_profile { ['public', 'domain']:
state => true, # on
}
The values true
/on
or false
/off
are acceptable. If supplying data from
YAML files in Hiera, on
and off
will be implicitly
converted to boolean
Manage the settings for each of the three profiles you want to manage. To set
everything to the same value, use an array for title
:
windows_firewall_profile { ['domain', 'private']:
inboundusernotification => 'enable',
firewallpolicy => 'allowinbound,allowoutbound',
logallowedconnections => 'enable',
logdroppedconnections => 'enable',
maxfilesize => '4000',
remotemanagement => 'enable',
state => 'on',
unicastresponsetomulticast => 'disable',
}
--debug
)netsh advfirewall reset
You need this
if your getting no rules match
errors or errors from global settingsmissing parameter
errors from Puppet after upgrading the module.
These can normally be fixed by removing older versions and restarting Puppet
Masternetsh advfirewall firewall show rule all verbose
powershell -file lib\ps\windows_firewall\ps-bridge.ps1 show
netsh advfirewall show global
netsh advfirewall show allprofiles
netsh advfirewall set global
)netsh advfirewall set private
)netsh
is used to enumerate most rules and is very fast. In some cases
netsh
will be unable to resolve names for some rules so we fallback to
PowerShell instead. This is handled by the ps-bridge.ps1
netsh advfirewall
command and PowerShell netsh
for
everything else so there is inconsistency in the equivalent puppet property
names and values (some names are run-together, others separated by
underscores). This is deliberate and makes the module code much simpler as
names map exactlygrouping
for rules (netsh does not support
this)localfirewallrules
or localconsecrules
for
profiles (this needs corresponding group policy)The Windows Advanced Firewall GUI allows multiple individual types to be set
for ICMPv4 and ICMPv6 however this does not seem to be possible through the
netsh
CLI. Therefore you must create individual rules if for each type you
wish to allow if you want to limit a rule in this way, eg:
windows_firewall_rule { "allow icmp echo":
ensure => present,
protocol => "icmpv4",
icmp_type => "8",
action => "allow",
}
windows_firewall_rule { "allow icmp time exceeded":
ensure => present,
protocol => "icmpv4",
icmp_type => "11",
action => "allow",
}
PRs accepted :)
Automatic testing using PDQTest 2. Needs to be run in a throw-away VM since its impossible to manage the firewall in containerised Windows: