代码之家  ›  专栏  ›  技术社区  ›  Jeremy

Chef Firewall食谱不使用自定义JSON对象

  •  0
  • Jeremy  · 技术社区  · 6 年前

    我在玩 firewall cookbook : cookbook 'firewall', '~> 2.7.0'

    不确定是不是只有我一个人,但说明不太清楚,但我给了它老学院的尝试…

    我要做的是建立一个配方,允许我使用数据包和环境来指定规则。大多数节点将是Centos7,但我也有一些Ubuntu16(可能还有不同的版本等待第三方软件)。大多数节点将有2个NIC,1个带有区域 public 另一个和 trusted . 由于这个原因,我更愿意坚持 firewall 如果可能的话,食谱。

    在开发过程中,我使用了rspec,并且一切都按预期工作。当我去厨房测试的时候,我发现什么都没用。所以我深入到节点中,发现没有应用任何规则。

    理想情况下,我首先希望默认区域是 :public . 然后我想从JSON对象将规则应用到每个区域。 当使用rspec进行测试时,一切看起来都很好。 当我使用测试厨房时,什么都没有发生。

    希望我只是在做些傻事。我希望能朝着正确的方向推进… 应该注意的是,我在一段时间前就开始了这个项目,但由于另一个项目而停止了。现在我又回到了这个问题上,我正在努力找出问题所在。

    谢谢你抽出时间。

    环境(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地址。

    数据包(防火墙:全局)的一个例子是:

    {
      "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
    
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Jeremy    6 年前

    当前在食谱中不支持区域。我提交了一份 PR 添加支持。虽然这本食谱的文档还不完全清楚,但我在这里发布的问题是由于Firewalld缺少一个特性。