Я играю с кулинарной книгой брандмауэра : cookbook 'firewall', '~> 2.7.0'
Не уверен, что это только я, но инструкции не очень понятны, но я дал ему старую попытку колледжа ...
Я пытаюсь создать рецепт, который позволит мне использовать data_bags и окружения для определения правил. Большинство узлов будет CentOS 7, но у меня также есть несколько Ubuntu 16 (возможно, разные версии ожидают стороннего программного обеспечения). Большинство узлов будут иметь 2 сетевых адаптера, один с зоной public
, а другой с trusted
. В связи с этим я бы предпочел придерживаться поваренной книги firewall
, если это возможно.
Во время разработки я использовал rspec, и все работало как положено. Когда я пошел на Test Kitchen, тогда я узнал, что ничего не работает. Поэтому я залез в узел и понял, что правила не применяются.
В идеале сначала я хочу, чтобы зона по умолчанию была :public
.
Затем я хотел применить правила к каждой зоне из объектов json.
При тестировании с rspec все выглядело хорошо.
Когда я использовал Test Kitchen, ничего не происходило.
Надеюсь, я просто делаю глупости. Я надеюсь на толчок в правильном направлении здесь ...
Следует отметить, что я начал это некоторое время назад и остановился из-за другого проекта. Теперь я вернулся к этому и пытаюсь определить проблемы.
Спасибо за ваше время.
Пример окружения (dev):
{
"name": "dev",
"description": "DEV Environment for Nodes",
"chef_type": "environment",
"json_class": "Chef::Environment",
"default_attributes": {
"oly": {
"environment": "dev",
"type" : "node",
"firewall": {
"status": "enabled",
"zones": {
"public": {
"22": {
"private_ip_1": "10.0.0.0/8",
"private_ip_2": "172.16.0.0/12",
"private_ip_3": "192.168.0.0/16",
"private_ip_4": "169.254.0.0/16",
"private_ip_5": "100.64.0.0/10"
}
}
}
}
}
},
"cookbook_versions": {
"oly-client": "= 4.0.0"
}
}
В вышеуказанной среде есть конфигурация зоны брандмауэра, которая открывает порт 22
для всех частных IP-адресов.
Пример data_bag (межсетевой экран: глобальный):
{
"id": "global",
"zones": {
"public": {
"22": {
"office_1": "1.1.1.1/32",
"office_2": "2.2.2.2/32",
"office_3": "3.3.3.3/32",
"office_4": "4.4.4.4/32",
"office_5": "5.5.5.5/32"
}
}
}
}
В идеале это позволяет применять глобальные правила к рецепту.
Поваренная книга, над которой я работаю:
#
# Cookbook:: oly-client
# Recipe:: firewall
#
# TODO: Create a method to optimize code (code repetition is real here)
# Fetch firewall settings
_firewallSettings = node['oly']['firewall']
# Make sure we have firewall settings and that they are enabled
if (!_firewallSettings.to_a.empty? && _firewallSettings.key?("status") && 'enabled' == _firewallSettings['status'].downcase)
# include the base firewall recipe
include_recipe "firewall::default"
# Enable platform default firewall and set default zone
firewall "default" do
action [:install]
enabled_zone :public
end
# START global firewall rules
_globalFirewallRules = data_bag_item('firewall', 'global')
if (_globalFirewallRules && _globalFirewallRules.key?("zones"))
# Loop over each firewall zone and build rules from data
_globalFirewallRules['zones'].each do |_zone, _zoneData|
# Ensure we have zone data
if (_zoneData)
# Ensure the firewall is installed for the zone
firewall "#{_zone}" do
enabled_zone "#{_zone}".to_sym
action [:install]
end
# Process rules for firewall
_zoneData.each do |_port, _portRules|
# Verify rules exist
if (_portRules)
# Build rules
_portRules.each do |_ipComment, _ipAddress|
# Define rule
firewall_rule "#{_zone} - #{_port}: #{_ipComment} - #{_ipAddress}" do
firewall_name "#{_zone}"
port _port.to_i
source _ipAddress
direction :in
command :allow
end
end
end
end
# Save the firewall settings
firewall "#{_zone}" do
# action :save
action [:save]
end
end
end
end
# END global firewall rules
# Check if environment has any zones configured
if (_firewallSettings.key?("zones"))
# Loop over each firewall zone and build rules from data
_firewallSettings['zones'].each do |_zone, _zoneData|
# Ensure we have zone data
if (_zoneData)
# Ensure the firewall is installed for the zone (in case global zones does not include)
firewall "#{_zone}" do
enabled_zone "#{_zone}".to_sym
# action :install
action [:install]
end
# Process rules for firewall
_zoneData.each do |_port, _portRules|
# Verify rules exist
if (_portRules)
# Build rules
_portRules.each do |_ipComment, _ipAddress|
# Define rule
firewall_rule "#{_zone} - #{_port}: #{_ipComment} - #{_ipAddress}" do
firewall_name "#{_zone}"
port _port.to_i
source _ipAddress
direction :in
command :allow
end
end
end
end
# Save the firewall settings
firewall "#{_zone}" do
# action :save
action [:save]
end
end
end
end
# END environment firewall rules
# TODO Add logic for custom rules (with search capabilites, like users - Did not do yet as this is edge case if needed at all)
# Save the firewall settings
firewall "default" do
# action :save
action [:save]
end
else
# Firewall is disabled unless explicitly enabled
include_recipe 'firewall::disable_firewall'
end
Мой тест rspec (поменял IP-адреса, но должен работать так же):
#
# Cookbook:: oly-client
# Spec:: default
#
# Copyright:: 2017, The Authors, All Rights Reserved.
require 'spec_helper'
describe 'oly-client::firewall' do
context 'on CentOS 7 Latest' do
let(:chef_run) do
ChefSpec::SoloRunner.new(platform: 'centos', version: '7') do |node|
# Build node attributes for tests
node.normal['oly']['firewall']['status'] = "enabled"
node.normal['oly']['firewall']['zones'] = {
"public": {
"22": {
"private_ip_1": "10.0.0.0/8",
"private_ip_2": "172.16.0.0/12",
"private_ip_3": "192.168.0.0/16",
"private_ip_4": "169.254.0.0/16"
}
},
"trusted": {
"22": {
"private_ip_5": "100.64.0.0/10"
}
}
}
# Firewall rules
node.normal['firewall']['allow_icmp'] = true
node.normal['firewall']['allow_ssh'] = true
node.normal['firewall']['allow_winrm'] = false
node.normal['firewall']['allow_mosh'] = false
end.converge(described_recipe)
end
# Stub databags
before do
stub_data_bag('firewall').and_return(['global'])
stub_data_bag_item('firewall', 'global').and_return({
"id": "global",
"zones": {
"public": {
"22": {
"office_1": "1.1.1.1/32",
"office_2": "2.2.2.2/32",
"office_3": "3.3.3.3/32"
}
},
"trusted": {
"22": {
"office_1": "1.1.1.1/32",
"office_3": "3.3.3.3/32",
"office_4": "4.4.4.4/32",
"office_5": "5.5.5.5/32"
}
}
}
})
end
it 'include the recipe to enable firewall' do
expect(chef_run).to include_recipe('firewall::default')
end
it 'enables the firewall' do
expect(chef_run).to install_firewall('public')
expect(chef_run).to install_firewall('trusted')
end
it 'creates some rules' do
_rules = [
"allow loopback",
"allow icmp",
"allow world to ssh",
"established",
"ipv6_icmp",
"public - 22: private_ip_1 - 10.0.0.0/8",
"public - 22: private_ip_2 - 172.16.0.0/12",
"public - 22: private_ip_3 - 192.168.0.0/16",
"public - 22: private_ip_4 - 169.254.0.0/16",
"trusted - 22: private_ip_5 - 100.64.0.0/10",
"public - 22: office_1 - 1.1.1.1/32",
"public - 22: office_2 - 2.2.2.2/32",
"public - 22: office_3 - 3.3.3.3/32",
"trusted - 22: office_1 - 1.1.1.1/32",
"trusted - 22: office_3 - 3.3.3.3/32",
"trusted - 22: office_4 - 4.4.4.4/32",
"trusted - 22: office_5 - 5.5.5.5/32"
]
_rules.each do |r|
expect(chef_run).to create_firewall_rule(r)
end
end
it 'not to creates some rules' do
_rules = [
"allow world to winrm",
"allow world to mosh",
"public - 22: office_4 - 4.4.4.4/32",
"public - 22: office_5 - 5.5.5.5/32",
"trusted - 22: office_2 - 2.2.2.2/32"
]
_rules.each do |r|
expect(chef_run).to_not create_firewall_rule(r)
end
end
end
end