Puppet - сборка массива из заголовков хешей для проверки содержимого в exec - PullRequest
0 голосов
/ 29 сентября 2018

Я пытаюсь применить модуль thoward-windows_firewall к Windows 10 и попадаю в ловушку, в результате которой большинство встроенных правил можно очистить с помощью функции очистки модуля, но некоторые другие (например, cortana) не могут.Эта проблема не возникала в более ранних сборках Windows.Обходной путь к этому, кажется, состоит в том, чтобы запустить exec с «netsh advfirewall reset», который очищает их и останавливает их повторное появление.

Однако я хочу применить exec «netsh advfirewall reset» только если правила брандмауэра отличны отто, что я указал в Hiera, существует.

Мой подход состоит в том, чтобы создать массив (или список) только заголовков в hiera, а затем перебирать их в PowerShell «только если» или «если».

Код на данный момент (который не работает):

Фрагмент Hiera:

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 «только если», чтобы он смотрел только заголовки в хэше (возможно, переписал в массив только заголовков хешей) и запускает exec, еслина хосте есть правила, которых нет в Hiera, но я немного теряюсь.

Любая помощь искренне приветствуется.

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Вы писали:

Мой подход состоит в том, чтобы создать массив (или список) только заголовков в hiera, а затем перебирать их в PowerShell «только если» или «если».

Очевидно, вы пытаетесь построить этот массив в параметре класса $firewall_rule_names, с помощью этого объявления:

Hash     $firewall_rule_names = lookup('harden::firewall'),

, а затем вы пытаетесь использовать этот списокв параметре onlyif вашего Exec:

    onlyif   => 'if (Get-NetFirewallRule | where {\$_.DisplayName -notmatch $firewall_rule_names}) { exit 0 } else { exit 1 }',

Есть несколько проблем с этим.

Сначала , если выхотите интерполировать переменную puppet в строку, тогда эта строка должна быть заключена в двойные кавычки (");цитирование одинарными кавычками (') подавляет интерполяцию (а также обрабатывает \$ как два буквенных символа, а не как escape-последовательность).

Second и где вы находитесьпотеря, как извлечь ключи из вашего хэша $firewall_rule_names и отформатировать их соответствующим образом.Я не совсем уверен, что именно здесь требуется Powershell, но некоторые из лучших инструментов, которые можно использовать для его получения, - это функции keys() и join(), предоставляемые модулем puppetlabs / stdlib или самой Puppet, если вы используете версию 5.5.или позже.Например, если все, что вам нужно, это список имен, разделенных запятыми, то это можно сделать примерно так:

$really_the_rule_names = join(keys($firewall_rule_names), ', ')

Я подозреваю, что вам, возможно, понадобится процитировать ключи.Вы можете получить большую часть этого, будучи умным с разделителем, который вы задаете для join, но вы также можете рассмотреть обработку массива ключей с помощью встроенной функции regsubst() перед объединением результатов в строку.

0 голосов
/ 13 октября 2018

@ Джон Боллинджер - Puppet и PowerShell = PuppetHell!:)

Мне, наконец, удалось решить эту проблему, но я чувствую, что мои блоки кода слишком длинные с большим количеством замен.Я пробовал более короткие методы безрезультатно, поэтому, если кто-нибудь может предложить работать с более коротким кодом, который будет оценен по достоинству.

Короче говоря, мне пришлось получить

  1. getключи хешей (заголовки) в подходящем синтаксисе массива для сравнения 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'"

Используйте exec Powershell для очистки Брандмауэра, если он не определен в 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 (более ранний модуль 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 с использованием ключей ифункции соединения.

0 голосов
/ 29 сентября 2018

Я вижу проблему в операторе Only IF.$_DisplayName должно быть $_.DisplayName, вам нужно использовать оператор Dot, чтобы черри выбрать свойства объекта, и \ также не требуется.

...