diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 67f20d7e0e..b1c004c621 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -36,7 +36,7 @@ lookup_options: ccs_software::udp_properties: merge: strategy: "unique" - profile::core::ipset::set: + ipset::sets: merge: strategy: "deep" rsyslog::config::actions: @@ -63,6 +63,9 @@ lookup_options: profile::core::ipa::default: merge: strategy: "deep" + profile::core::firewall::firewall: + merge: + strategy: "deep" profile::core::systemd::tmpfile: merge: strategy: "deep" @@ -321,9 +324,9 @@ yum::manage_os_default_repos: true letsencrypt::email: "rubinobs-it-las@lsst.org" -profile::core::ipset::set: - # lsst/aura "internal" prefixes - lsst: +ipset::sets: + # rubin/aura "internal" prefixes + aura: ensure: "present" type: "hash:net" set: @@ -331,6 +334,24 @@ profile::core::ipset::set: - "139.229.0.0/16" - "198.19.0.0/16" - "10.0.0.0/8" + # rubin "internal" prefixes + rubin: + ensure: "present" + type: "hash:net" + set: + - "139.229.134.0/23" + - "139.229.136.0/21" + - "139.229.144.0/20" + - "139.229.160.0/19" + - "139.229.192.0/18" + - "140.252.146.0/23" + - "198.19.0.0/16" + - "10.0.0.0/8" + ayekan: # ayekan cluster + ensure: "present" + type: "hash:net" + set: + - "139.229.144.0/26" # sssd ipa client setup -- do not use on ipa servers sssd::main_config: @@ -465,3 +486,47 @@ nm::conf: dns: "none" prometheus::node_exporter::version: "1.6.1" + +# profile::core::firewall is not included by default; including it in a role is +# used to opt-in to configuring filtering instead of the default of disabling +# it. Eventually, filtering should be enabled by default and roles would have +# to opt-out. +profile::core::firewall::purge_firewall: true +profile::core::firewall::firewall: + # 000-099 reserved for common rules + # 100-199 reserved for site rules + # 200-299 reserved for role rules + # 400-599 reserved for host specific rules + # 700-899 reserved for role rules + # 800-899 reserved for site rules + # 900-999 reserved for common rules + "000 accept established": + proto: "all" + state: ["RELATED", "ESTABLISHED"] + action: "accept" + "001 accept all icmp": + proto: "icmp" + action: "accept" + "002 accept all loopback": + proto: "all" + iniface: "lo" + action: "accept" + "010 accept ssh": + proto: "tcp" + state: "NEW" + ipset: "rubin src" + dport: "22" + action: "accept" + require: "Ipset::Set[rubin]" + "020 accept dhcp": + proto: "udp" + sport: ["67", "68"] + dport: ["67", "68"] + action: "accept" + "990 reject all": + proto: "all" + action: "reject" + "991 reject forward all": + chain: "FORWARD" + proto: "all" + action: "reject" diff --git a/hieradata/role/perfsonar.yaml b/hieradata/role/perfsonar.yaml index 29d4367d8c..71d7938947 100644 --- a/hieradata/role/perfsonar.yaml +++ b/hieradata/role/perfsonar.yaml @@ -4,7 +4,6 @@ classes: - "profile::core::common" - "profile::core::debugutils" - "profile::core::firewall" - - "profile::core::ipset" - "profile::core::perfsonar" - "profile::core::perfsonar::sysctl" - "profile::core::sysctl::rp_filter" @@ -17,40 +16,14 @@ chrony::service_enable: false chrony::service_ensure: "stopped" firewall::ensure: "running" -profile::core::firewall::purge_firewall: true profile::core::firewall::firewall: - # centos 7 defaults - "000 accept established": - proto: "all" - state: ["RELATED", "ESTABLISHED"] - action: "accept" - "001 accept all icmp": - proto: "icmp" - action: "accept" - "002 accept all loopback": - proto: "all" - iniface: "lo" - action: "accept" - "010 accept ssh": + "400 accept ssh": # allow aura but non-rubin subnets proto: "tcp" state: "NEW" - ipset: "lsst src" + ipset: "aura src" dport: "22" action: "accept" - require: "Ipset::Set[lsst]" - "990 reject all": - proto: "all" - action: "reject" - "991 reject forward all": - chain: "FORWARD" - proto: "all" - action: "reject" - # dhcp client - "020 accept dhcp": - proto: "udp" - sport: ["67", "68"] - dport: ["67", "68"] - action: "accept" + require: "Ipset::Set[aura]" files: # perfsonar packaging installs this one file with the wrong mode diff --git a/hieradata/site/dev.yaml b/hieradata/site/dev.yaml index ba43184c4a..60d804360a 100644 --- a/hieradata/site/dev.yaml +++ b/hieradata/site/dev.yaml @@ -48,3 +48,12 @@ accounts::user_list: letsencrypt::server: "https://acme-staging.api.letsencrypt.org/directory" # testing url profile::core::common::disable_ipv6: true + +profile::core::firewall::firewall: + "100 accept node_exporter": + proto: "tcp" + state: "NEW" + ipset: "ayekan src" + dport: "9100" + action: "accept" + require: "Ipset::Set[ayekan]" diff --git a/hieradata/site/ls.yaml b/hieradata/site/ls.yaml index 94c20922d1..0650acb533 100644 --- a/hieradata/site/ls.yaml +++ b/hieradata/site/ls.yaml @@ -47,3 +47,12 @@ accounts::user_list: - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDsF9VQ7wjm0Rm/1HA6Zc94IAkhqol5cwT44MwwR6uzDyo+/tqa8awUnmVF+RyiJaR6NEKO6YhjkIPga7rDQJerCMLg/xfFzpRcKSi+Xw5YCQ3Z+4P8XZrICM2vzDV6rBELl4n8Bzk6ncXOcKwbUitw3aj6bJNduv6hGrhkJKlWob+cXGH+KZwDiLX82hxsWmktRWcwDEaXTFWq6dahg3/0niAojkfo2ZlJtRblSEgUBf7JITeXBGYAunAeUYE93xUC9tB1OIzisQLQKCFM2OgSjnO4NSx2r4nIPYhEOEhBnNBqF9mPqalRjoyimvF+lu/vsZ43r7nZyV4RwYbyfmVL foreman-proxy@foreman.ls.lsst.org" profile::core::common::disable_ipv6: true + +profile::core::firewall::firewall: + "100 accept node_exporter": + proto: "tcp" + state: "NEW" + ipset: "ayekan src" + dport: "9100" + action: "accept" + require: "Ipset::Set[ayekan]" diff --git a/site/profile/manifests/core/firewall.pp b/site/profile/manifests/core/firewall.pp index 0c4e1b8e81..306dc0b47c 100644 --- a/site/profile/manifests/core/firewall.pp +++ b/site/profile/manifests/core/firewall.pp @@ -12,6 +12,7 @@ Boolean $purge_firewall = false, ) { include firewall + include ipset if $purge_firewall { resources { 'firewall': purge => true } diff --git a/site/profile/manifests/core/ipset.pp b/site/profile/manifests/core/ipset.pp deleted file mode 100644 index c766c5cbd0..0000000000 --- a/site/profile/manifests/core/ipset.pp +++ /dev/null @@ -1,13 +0,0 @@ -# @summary -# Manage ipset resources. -# -# @param set -# `ipset::set` resources to create. -# -class profile::core::ipset ( - Optional[Hash[String, Hash]] $set = undef, -) { - if $set { - ensure_resources('ipset::set', $set) - } -} diff --git a/spec/classes/core/firewall_spec.rb b/spec/classes/core/firewall_spec.rb new file mode 100644 index 0000000000..1cf9c79696 --- /dev/null +++ b/spec/classes/core/firewall_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'profile::core::firewall' do + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) { facts } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_class('firewall') } + it { is_expected.to contain_class('ipset') } + it { is_expected.to have_resources_resource_count(0) } + it { is_expected.to have_firewall_resource_count(0) } + + context 'with purge_firewall param' do + let(:params) { { purge_firewall: true } } + + it { is_expected.to contain_resources('firewall').with_purge(true) } + end + + context 'with firewall param' do + let(:params) do + { + firewall: { + '001 accept all icmp' => { + 'proto' => 'icmp', + 'action' => 'accept', + }, + }, + } + end + + it do + is_expected.to contain_firewall('001 accept all icmp').with( + 'proto' => 'icmp', + 'action' => 'accept', + ) + end + end + end + end +end diff --git a/spec/hosts/roles/perfsonar_spec.rb b/spec/hosts/roles/perfsonar_spec.rb index 19de9eccf9..aae57c53d4 100644 --- a/spec/hosts/roles/perfsonar_spec.rb +++ b/spec/hosts/roles/perfsonar_spec.rb @@ -29,12 +29,26 @@ include_examples 'common', facts: facts include_examples 'generic perfsonar', facts: facts + include_examples 'ipset' + include_examples 'firewall default', facts: facts + include_examples 'firewall node_exporter scraping', site: site it do is_expected.to contain_yum__versionlock('perfsonar-toolkit').with( version: perfsonar_version, ) end + + it do + is_expected.to contain_firewall('400 accept ssh').with( + proto: 'tcp', + state: 'NEW', + ipset: 'aura src', + dport: '22', + action: 'accept', + require: 'Ipset::Set[aura]', + ) + end end # host end # lsst_sites end # on os diff --git a/spec/support/spec/firewall.rb b/spec/support/spec/firewall.rb new file mode 100644 index 0000000000..32caa5c5fb --- /dev/null +++ b/spec/support/spec/firewall.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +shared_examples 'firewall default' do |facts:| + if (facts[:os]['family'] == 'RedHat') && (facts[:os]['release']['major'] == '9') + it { is_expected.to contain_service('nftables').with_enable(true) } + end + + it { is_expected.to contain_service('iptables').with_enable(true) } + it { is_expected.to contain_resources('firewall').with_purge(true) } + + it do + is_expected.to contain_firewall('000 accept established').with( + proto: 'all', + state: %w[RELATED ESTABLISHED], + action: 'accept', + ) + end + + it do + is_expected.to contain_firewall('001 accept all icmp').with( + proto: 'icmp', + action: 'accept', + ) + end + + it do + is_expected.to contain_firewall('002 accept all loopback').with( + proto: 'all', + iniface: 'lo', + action: 'accept', + ) + end + + it do + is_expected.to contain_firewall('020 accept dhcp').with( + proto: 'udp', + sport: %w[67 68], + dport: %w[67 68], + action: 'accept', + ) + end + + it do + is_expected.to contain_firewall('990 reject all').with( + proto: 'all', + action: 'reject', + ) + end + + it do + is_expected.to contain_firewall('991 reject forward all').with( + chain: 'FORWARD', + proto: 'all', + action: 'reject', + ) + end +end + +shared_examples 'firewall node_exporter scraping' do |site:| + case site + when 'dev', 'ls' + it do + is_expected.to contain_firewall('100 accept node_exporter').with( + proto: 'tcp', + state: 'NEW', + ipset: 'ayekan src', + dport: '9100', + action: 'accept', + require: 'Ipset::Set[ayekan]', + ) + end + end +end diff --git a/spec/support/spec/ipset.rb b/spec/support/spec/ipset.rb new file mode 100644 index 0000000000..27a97700e5 --- /dev/null +++ b/spec/support/spec/ipset.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +shared_examples 'ipset' do + it { is_expected.to contain_class('ipset') } + + it do + is_expected.to contain_ipset__set('aura').with_set( + %w[ + 140.252.0.0/16 + 139.229.0.0/16 + 198.19.0.0/16 + 10.0.0.0/8 + ], + ) + end + + it do + is_expected.to contain_ipset__set('rubin').with_set( + %w[ + 139.229.134.0/23 + 139.229.136.0/21 + 139.229.144.0/20 + 139.229.160.0/19 + 139.229.192.0/18 + 140.252.146.0/23 + 198.19.0.0/16 + 10.0.0.0/8 + ], + ) + end + + it do + is_expected.to contain_ipset__set('ayekan').with_set( + %w[ + 139.229.144.0/26 + ], + ) + end +end