我正在尝试将thoward-windows_firewall模块应用于Windows 10并遇到一个障碍,即可以使用该模块的清除功能清除大多数内置规则,而其他一些规则(例如cortana)则不能。在早期的Windows版本中未发生此问题。解决方法似乎是使用“ netsh advfirewall reset”运行一个exec,以清除它们并阻止其重新出现。
但是,如果存在除我在Hiera中指定的防火墙规则以外的防火墙规则,我只想应用“ netsh advfirewall reset” exec。
我的方法是在hiera中仅构建标题的数组(或列表),然后在PowerShell中“仅当”或“除非”时对它们进行迭代。
到目前为止(无效)的代码为:
希拉片段:
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:\Windows\system32\svchost.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,以便它仅查看哈希中的标题(也许重写为仅包含哈希标题的数组) ),并在主机上存在Hiera不在使用的规则的情况下运行该exec,但会有所遗漏。
任何帮助都由衷地感谢。
答案 0 :(得分:1)
您写道:
我的方法是在hiera中仅构建标题的数组(或列表) 然后在PowerShell中“仅当”或“除非”时对它们进行迭代。
显然,您尝试使用以下声明在类参数$firewall_rule_names
中构建该数组:
Hash $firewall_rule_names = lookup('harden::firewall'),
,然后尝试在onlyif
的{{1}}参数中使用该列表:
Exec
有很多问题。
首先,如果要将人偶变量内插到字符串中,则该字符串需要用双引号引起来( onlyif => 'if (Get-NetFirewallRule | where {\$_.DisplayName -notmatch $firewall_rule_names}) { exit 0 } else { exit 1 }',
);用单引号("
引号可以抑制插值(也可以将'
视为两个文字字符,而不是转义序列)。
第二,以及您似乎不知所措的地方,例如如何提取\$
哈希的键并对其进行适当格式化。我不确定Powershell在这里到底需要什么,但是要获得它,最好的一些工具是puppetlabs / stdlib模块或Puppet本身提供的$firewall_rule_names
和keys()
函数。重新使用5.5版或更高版本。例如,如果您只需要一个用逗号分隔的名称列表,则可以执行以下操作:
join()
但是,我很怀疑您可能需要引用密钥。您可以通过巧妙地使用为$really_the_rule_names = join(keys($firewall_rule_names), ', ')
指定的定界符来获得大部分信息,但是您可能还需要考虑在将结果连接到字符串之前,使用内置的join
函数处理键数组。
答案 1 :(得分:0)
我在Only IF语句中看到一个问题。
mysql> DROP TRIGGER tri_Test_Insert_Trigger;
mysql> CREATE TRIGGER tri_Test_Insert_Trigger
-> AFTER INSERT
-> ON persons
-> FOR Each row
-> UPDATE persons
-> SET review_date = date_add(birth_date, interval 1 year);
Query OK, 0 rows affected (0.17 sec)
mysql> insert into persons(lastname,birth_date) values('Özhan',date'2018-05-15');
ERROR 1442 (HY000): Cant update table 'persons' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
mysql> DROP TRIGGER tri_Test_Insert_Trigger;
Query OK, 0 rows affected (0.17 sec)
mysql> CREATE TRIGGER tri_Test_Insert_Trigger
-> BEFORE INSERT
-> ON persons
-> FOR Each row
-> SET new.review_date = date_add(new.birth_date, interval 1 year);
Query OK, 0 rows affected (0.13 sec)
mysql> insert into persons(lastname,birth_date) values('Özhan',date'2018-05-15');
Query OK, 1 row affected (0.09 sec)
mysql> select * from persons;
+----+----------+-----------+------------+-------------+
| ID | LastName | FirstName | Birth_Date | Review_Date |
+----+----------+-----------+------------+-------------+
| 2 | Özhan | NULL | 2018-05-15 | 2019-05-15 |
+----+----------+-----------+------------+-------------+
1 row in set (0.00 sec)
应该是$_DisplayName
,您需要使用Dot运算符来挑选对象的属性,并且也不需要$_.DisplayName
。
答案 2 :(得分:0)
@ John-Bollinger-Puppet和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'"
...
使用Powershell exec清除Puppet hiera中未定义的防火墙,方法是:
a。使用exec命令清除以下内容的主机防火墙规则:
command => 'netsh advfirewall firewall delete rule name=all; reg delete "HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules" /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模块(在相同的源层次结构上迭代)重新创建所需的规则(如果发生清除)。该模块比相当简陋的puppetlabs-windows_firewall模块要好,但在用户登录后无法处理Windows 10的可怕防火墙添加剂。
有趣的是,只有人偶创建的数组需要外部双引号。由于puppetlabs-powershell模块没有在磁盘上回显.ps1的内容,因此我不得不手动将它们回显,以了解实际创建的内容并在Powershell ISE中对其进行测试(较早的Josh Cooper powershell模块确实创建了临时的。 ps1,虽然安全性较差,但还是很方便)我能够在数组中放置一些regsubst或替换字符,但是^和$在数组中的表现不理想。
所有这些都是为了解决Windows 10仅在用户登录后不断创建其他无意义防火墙规则的情况。这间歇地继续进行约6次木偶跑,最后停止。例如,Server 2012 R2从未遇到此问题。
删除以下注册表项(使用Puppetlabs注册表模块,确保=>缺失)提供了一些额外的静默功能,但它本身并没有目的:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\AppIso\FirewallRules
再次,希望对缩短上述代码,特别是关于regsubst和-replace命令有任何帮助。请记住,生成的数组需要使用Powershell的“比较对象”功能或类似功能进行比较。
感谢@ John-Bollinger让我开始使用键和联接函数从hiera哈希创建数组。