我正试图将thoward-windows_firewall模块应用于windows 10,但遇到了一个障碍,即大多数内置规则都可以通过模块的清除功能清除,但其他一些规则(如cortana)则不能。此问题在早期的Windows版本中没有出现。解决方法似乎是运行一个带有"netsh advfirewall reset"的exec,它会清除它们并阻止它们再次出现。
但是,如果存在我在Hiera中指定的防火墙规则以外的防火墙规则,我只想应用"netsh advfirewall reset"exec。
我的方法是只构建hiera中标题的数组(或列表),然后在PowerShell中"only-if"或"excess"对它们进行迭代。
到目前为止的代码(不起作用)是:
层次结构片段:
harden::firewall:
'Remote Desktop - User Mode (UDP-In)':
description: 'Inbound rule for the Remote Desktop service to allow RDP traffic. [UDP 3389]'
application_name: 'C:Windowssystem32svchost.exe'
service_name: 'termservice'
protocol: 17
local_ports: '3389'
remote_ports: '*'
local_addresses: '%{facts.networking.ip}'
remote_addresses: '*'
direction: 1
interface_types: 'All'
enabled: true
grouping: '@FirewallAPI.dll,-28752'
profiles: 3
action: 1
'File and Printer Sharing (Echo Request - ICMPv4-In) 1':
description: 'Echo Request messages are sent as ping requests to other nodes.'
protocol: 1
local_addresses: '%{facts.networking.ip}'
remote_addresses: 'LocalSubnet'
icmp_types_and_codes: '8:*'
direction: 1
interface_types: 'All'
enabled: true
grouping: '@FirewallAPI.dll,-28502'
profiles: 6
action: 1
清单(摘录):
class harden (
Hash $firewall_rule_names = lookup('harden::firewall'),
){
# reset firewall rules
exec { 'reset_firewall':
command => 'netsh advfirewall reset',
onlyif => 'if (Get-NetFirewallRule | where {$_.DisplayName -notmatch $firewall_rule_names}) { exit 0 } else { exit 1 }',
provider => powershell,
}
Class { 'windows_firewall':
profile_state => 'on',
in_policy => 'BlockInbound',
out_policy => 'BlockOutbound',
rule_key => 'harden::firewall',
purge_rules => true,
}
我知道我需要在其中的某个地方进行.each查找,并整理powershell"only if",以便它只查看哈希中的标题(可能会重新写入一个仅包含哈希标题的数组),如果主机上有不在Hiera中的规则,但有点丢失,则运行exec。
衷心感谢您的帮助。
您写道:
我的方法是只构建hiera中标题的数组(或列表)然后在PowerShell中对它们进行迭代"only-if"或"excess"。
显然,您试图在类参数$firewall_rule_names
中构建该数组,声明如下:
Hash $firewall_rule_names = lookup('harden::firewall'),
,然后您尝试在Exec
:的onlyif
参数中使用该列表
onlyif => 'if (Get-NetFirewallRule | where {$_.DisplayName -notmatch $firewall_rule_names}) { exit 0 } else { exit 1 }',
这有多个问题。
首先,如果要将puppet变量插入字符串,则该字符串需要用双引号("
)引起来;单引号引用('
)抑制插值(并且还将$
视为两个文字字符,而不是转义序列)。
第二个,以及您似乎不知所措的地方,以及如何提取$firewall_rule_names
哈希的密钥并对其进行适当格式化。我不确定Powershell在这里到底需要什么,但获得它的一些最佳工具是由puppetlabs/stdlib模块提供的keys()
和join()
函数,或者如果您使用的是5.5或更高版本,则由Puppet本身提供。例如,若您所需要的只是一个逗号分隔的名称列表,那个么这样的东西就可以了:
$really_the_rule_names = join(keys($firewall_rule_names), ', ')
不过,我怀疑你可能需要引用钥匙。通过巧妙地使用为join
指定的分隔符,您可以获得大部分功能,但在将结果合并为字符串之前,您可能还需要考虑使用内置的regsubst()
函数处理键数组。
我可以在Only IF语句中看到一个问题。$_DisplayName
应该是$_.DisplayName
,您需要使用Dot运算符来挑选Object的属性,而也不是必需的。
@John Bollinger-Puppet and PowerShell=PuppetHell!:)
我终于解决了这个问题,但我觉得我的代码块太长了,替换太多了。我尝试过较短的方法,但没有效果,所以如果有人能建议使用较短的代码,我将不胜感激。
简而言之,我最终不得不去
-
通过将hiera哈希键(标题)转换为合适的数组语法,用于Powershell比较
a。添加单引号和逗号作为分隔符
b。在数组的开始和结束处添加单引号和双引号
c。PowerShell将括号吐到数组中的上时,从数组中的任何位置删除括号
$firewall_hiera = regsubst(regsubst(regsubst(join(keys($firewall_rules), "', '"), '^', '"''), '$', ''"'), '[()]', '', 'G')
产生
"'Core Networking - DNS UDP-Out', 'Core Networking - Dynamic Host Configuration Protocol DHCP-Out', 'File and Printer Sharing Echo Request - ICMPv4-Out', 'Internet Browsing HTTP-Out', 'Internet Browsing HTTPS-Out'"
…
如果Puppet hiera中未定义,则使用Powershell exec清除防火墙:
a。使用exec命令清除主机防火墙规则:
command => 'netsh advfirewall firewall delete rule name=all; reg delete "HKLMSYSTEMCurrentControlSetServicesSharedAccessParametersFirewallPolicyFirewallRules" /f',
b。使用超长除非语句确保幂等性:
unless => "if (@(Compare-Object((Get-NetFirewallRule | foreach {"'"+$_.DisplayName+"'"}) -join ', ' -replace '[()]') $firewall_hiera).length -eq 0) {exit 0} else {exit 1}",
它为以下对象生成将对象与上面创建的$firewall_hiera 进行比较
'Core Networking - DNS UDP-Out', 'Core Networking - Dynamic Host Configuration Protocol DHCP-Out', 'File and Printer Sharing Echo Request - ICMPv4-Out', 'Internet Browsing HTTP-Out', 'Internet Browsing HTTPS-Out'
然后使用thoward-windows_firewall模块重新创建所需的规则(如果发生清除),该模块在同一源层次结构上迭代。该模块比cr4ppy puppetlabs-windows_firewall模块好得多,但在用户登录后无法处理windows 10可怕的防火墙添加剂。
有趣的是,只有木偶创建的数组需要外部双引号。由于puppetlabs的powershell模块不会将.ps1的文件回显到磁盘上,我不得不手动回显它们,以了解实际创建的内容,并在powershell ISE中测试它们(旧的Josh Cooper powershell模块确实创建了临时的.ps1,虽然不太安全,但很方便)
我可以在数组中放入一些regsubst或替换字符,但^和$在数组中不太好用。
所有这些都是为了解决Windows 10只在用户登录后才不断创建额外的毫无意义的防火墙规则的问题。这种情况持续了大约6次木偶运行,最终停止。例如,Server 2012 R2从未出现过此问题。
删除以下注册表项(Puppetlabs注册表模块确保=>不存在)提供了一些额外的安静,但这本身并不是目的:
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesSharedAccessParametersFirewallPolicyRestrictedServicesAppIsoFirewallRules
再次感谢您对缩短上述代码的任何帮助,特别是在regsubst和-replaces命令方面。请记住,生成的数组需要使用Powershell的"比较对象"功能或类似功能进行比较。
感谢@John Bollinger让我开始使用键和联接函数从hiera散列创建数组。