diff --git a/Puppetfile b/Puppetfile index 4702cd205..ec271eeaf 100644 --- a/Puppetfile +++ b/Puppetfile @@ -3,39 +3,38 @@ forge "https://forgeapi.puppetlabs.com" mod 'cmdntrf-consul_template', '2.3.8' -mod 'derdanne-nfs', '2.1.11' -mod 'heini-wait_for', '2.2.0' -mod 'puppet-augeasproviders_core', '4.0.1' +mod 'heini-wait_for', '3.0.0' +mod 'puppet-augeasproviders_core', '4.1.0' mod 'puppet-augeasproviders_pam', '4.0.0' -mod 'puppet-augeasproviders_shellvar', '6.0.0' -mod 'puppet-augeasproviders_ssh', '6.0.0' -mod 'puppet-augeasproviders_sysctl', '3.1.0' -mod 'petems-swap_file', '4.0.2' -mod 'puppet-archive', '4.6.0' -mod 'puppet-consul', '7.3.1' +mod 'puppet-augeasproviders_shellvar', '6.0.1' +mod 'puppet-augeasproviders_ssh', '7.0.0' +mod 'puppet-augeasproviders_sysctl', '3.2.0' +mod 'puppet-swap_file', '5.0.0' +mod 'puppet-archive', '7.1.0' +mod 'puppet-consul', '9.0.0' mod 'puppet-epel', '5.0.0' -mod 'puppet-extlib', '7.0.0' -mod 'puppet-fail2ban', '4.2.0' -mod 'puppet-healthcheck', '1.0.1' -mod 'puppet-kmod', '4.0.0' -mod 'puppet-logrotate', '5.0.0' -mod 'puppet-prometheus', '12.5.0' +mod 'puppet-extlib', '7.2.0' +mod 'puppet-fail2ban', '5.0.2' +mod 'puppet-healthcheck', '2.1.0' +mod 'puppet-kmod', '4.0.1' +mod 'puppet-logrotate', '7.1.0' +mod 'puppet-nfs', '3.0.0' +mod 'puppet-nftables', '4.0.0' +mod 'puppet-prometheus', '15.0.0' mod 'puppet-rsyslog', '7.1.0' -mod 'puppet-selinux', '3.4.1' -mod 'puppet-squid', '3.0.0' -mod 'puppet-systemd', '3.10.0' -mod 'puppet-yum', '6.2.0' -mod 'puppetlabs-concat', '7.4.0' -mod 'puppetlabs-firewall', '5.0.0' -mod 'puppetlabs-inifile', '6.1.0' -mod 'puppetlabs-lvm', '1.4.0' +mod 'puppet-selinux', '5.0.0' +mod 'puppet-squid', '5.1.0' +mod 'puppet-systemd', '7.1.0' +mod 'puppet-yum', '7.1.0' +mod 'puppetlabs-concat', '9.0.2' +mod 'puppetlabs-inifile', '6.1.1' +mod 'puppetlabs-lvm', '2.3.0' mod 'puppetlabs-motd', '7.1.0' -mod 'puppetlabs-mount_core', '1.0.4' -mod 'puppetlabs-mysql', '13.3.0' -mod 'puppetlabs-stdlib', '5.2.0' -mod 'puppetlabs-transition', '0.1.3' -mod 'treydock-globus', '9.0.0' -mod 'saz-limits', '3.0.4' +mod 'puppetlabs-mount_core', '1.3.0' +mod 'puppetlabs-mysql', '16.0.0' +mod 'puppetlabs-stdlib', '9.6.0' +mod 'puppetlabs-transition', '2.0.0' +mod 'saz-limits', '5.0.0' mod 'computecanada-jupyterhub', :git => 'https://github.com/ComputeCanada/puppet-jupyterhub.git', diff --git a/data/site.yaml b/data/site.yaml index 94abeca49..d5423675e 100644 --- a/data/site.yaml +++ b/data/site.yaml @@ -10,6 +10,7 @@ lookup_options: magic_castle::site::all: - profile::base - profile::consul + - profile::firewall - profile::freeipa - profile::users::local - profile::sssd::client @@ -58,5 +59,7 @@ magic_castle::site::tags: - profile::jupyterhub::hub - profile::jupyterhub::hub::keytab - profile::reverse_proxy + puppet: + - profile::puppetserver efa: - profile::efa diff --git a/site/profile/manifests/base.pp b/site/profile/manifests/base.pp index 85b04ef94..124102223 100644 --- a/site/profile/manifests/base.pp +++ b/site/profile/manifests/base.pp @@ -56,31 +56,6 @@ ensure => 'installed', } - package { 'firewalld': - ensure => 'absent', - } - - class { 'firewall': - tag => 'mc_bootstrap', - } - - firewall { '001 accept all from local network': - chain => 'INPUT', - proto => 'all', - source => profile::getcidr(), - action => 'accept', - tag => 'mc_bootstrap', - } - - firewall { '001 drop access to metadata server': - chain => 'OUTPUT', - proto => 'tcp', - destination => '169.254.169.254', - action => 'drop', - uid => '! root', - tag => 'mc_bootstrap', - } - package { 'haveged': ensure => 'installed', require => Yumrepo['epel'], @@ -97,7 +72,7 @@ require => Package['haveged'], } - ensure_packages($packages, { ensure => 'installed', require => Yumrepo['epel'] }) + stdlib::ensure_packages($packages, { ensure => 'installed', require => Yumrepo['epel'] }) if $::facts.dig('cloud', 'provider') == 'azure' { include profile::base::azure diff --git a/site/profile/manifests/consul.pp b/site/profile/manifests/consul.pp index 120cd7741..6c6540acb 100644 --- a/site/profile/manifests/consul.pp +++ b/site/profile/manifests/consul.pp @@ -14,6 +14,13 @@ $retry_join = $servers } + nftables::rule { 'default_in-consul_tcp': + content => 'tcp dport {8300,8301,8302,8500,8501,8502,8503,8600} accept comment "Accept consul"', + } + nftables::rule { 'default_in-consul_udp': + content => 'udp dport {8301,8302,8600} accept comment "Accept consul"', + } + class { 'consul': config_mode => '0640', acl_api_token => lookup('profile::consul::acl_api_token'), @@ -66,7 +73,7 @@ # consul config file like this: # jq -r .acl_agent_token /etc/consul/config.json include epel - ensure_packages(['jq'], { ensure => 'present', require => Yumrepo['epel'] }) + stdlib::ensure_packages(['jq'], { ensure => 'present', require => Yumrepo['epel'] }) # Ensure consul can read the state of agent_catalog_run.lock file { '/opt/puppetlabs/puppet/cache': diff --git a/site/profile/manifests/fail2ban.pp b/site/profile/manifests/fail2ban.pp index 29a64d61c..8602eb650 100644 --- a/site/profile/manifests/fail2ban.pp +++ b/site/profile/manifests/fail2ban.pp @@ -4,7 +4,9 @@ include epel class { 'fail2ban' : - whitelist => ['127.0.0.1/8', profile::getcidr()] + $ignoreip, + banaction => 'nftables-multiport', + iptables_chain => 'input', + whitelist => ['127.0.0.1/8', lookup('terraform.network.cidr')] + $ignoreip, } file_line { 'fail2ban_sshd_recv_disconnect': diff --git a/site/profile/manifests/firewall.pp b/site/profile/manifests/firewall.pp new file mode 100644 index 000000000..b91b9275e --- /dev/null +++ b/site/profile/manifests/firewall.pp @@ -0,0 +1,14 @@ +class profile::firewall { + tag 'mc_bootstrap' + class { 'nftables': + out_all => true, + noflush_tables => ['inet-f2b-table'], + } + + # Do not let user get access to cloud-init metadata server as it could + # include sensitive information. + nftables::rule { 'default_out-drop_metadata': + content => 'ip daddr 169.254.169.254 skuid != 0 drop comment "Drop metadata server"', + order => '89', + } +} diff --git a/site/profile/manifests/freeipa.pp b/site/profile/manifests/freeipa.pp index e1733c140..984744616 100644 --- a/site/profile/manifests/freeipa.pp +++ b/site/profile/manifests/freeipa.pp @@ -197,6 +197,28 @@ include profile::freeipa::base include profile::sssd::client + include nftables::rules::dns + include nftables::rules::http + include nftables::rules::https + include nftables::rules::ldap + include nftables::rules::ssdp + + nftables::rule { 'default_in-kerberos_tcp': + content => 'tcp dport 88 accept comment "Accept kerberos"', + } + nftables::rule { 'default_in-kerberos_udp': + content => 'udp dport 88 accept comment "Accept kerberos"', + } + nftables::rule { 'default_in-kpasswd_tcp': + content => 'tcp dport 464 accept comment "Accept kpasswd"', + } + nftables::rule { 'default_in-kpasswd_udp': + content => 'udp dport 464 accept comment "Accept kpasswd"', + } + nftables::rule { 'default_in-kadmind': + content => 'tcp dport 749 accept comment "Accept kadmind"', + } + file { 'kinit_wrapper': path => '/usr/bin/kinit_wrapper', source => 'puppet:///modules/profile/freeipa/kinit_wrapper', @@ -215,7 +237,7 @@ # https://pagure.io/freeipa/issue/9358 # TODO: remove this patch once FreeIPA >= 4.10 is made available # in RHEL 8. - ensure_packages(['patch'], { ensure => 'present' }) + stdlib::ensure_packages(['patch'], { ensure => 'present' }) $python_version = lookup('os::redhat::python3::version') file { 'freeipa_27e9181bdc.patch': path => "/usr/lib/python${python_version}/site-packages/freeipa_27e9181bdc.patch", @@ -236,7 +258,7 @@ $realm = upcase($ipa_domain) $fqdn = "${facts['networking']['hostname']}.${ipa_domain}" - $reverse_zone = profile::getreversezone() + $reverse_zone = lookup('terraform.network.reverse_zone') $ipaddress = lookup('terraform.self.local_ip') $ipa_server_install_cmd = @("IPASERVERINSTALL"/L) @@ -269,6 +291,10 @@ require => [ Package['ipa-server-dns'], File['/etc/hosts'], + Class['nftables::rules::dns'], + Class['nftables::rules::https'], + Class['nftables::rules::ldap'], + Class['nftables::rules::ssdp'], ], notify => [ Service['systemd-logind'], @@ -454,6 +480,10 @@ ) { include mysql::server + nftables::rule { 'default_in-mokey_tcp': + content => 'tcp dport 12345 accept comment "Accept mokey"', + } + yumrepo { 'mokey-copr-repo': enabled => true, descr => 'Copr repo for mokey owned by cmdntrf', @@ -480,6 +510,8 @@ password => $password, host => 'localhost', grant => ['ALL'], + charset => 'utf8mb4', + collate => 'utf8mb4_unicode_ci', } exec { 'mysql_mokey_schema': @@ -567,8 +599,8 @@ 'password' => $password, 'dbname' => 'mokey', 'port' => $port, - 'auth_key' => seeded_rand_string(64, "${password}+auth_key", 'ABCDEF0123456789'), - 'enc_key' => seeded_rand_string(64, "${password}+enc_key", 'ABCEDF0123456789'), + 'auth_key' => stdlib::seeded_rand_string(64, "${password}+auth_key", 'ABCDEF0123456789'), + 'enc_key' => stdlib::seeded_rand_string(64, "${password}+enc_key", 'ABCEDF0123456789'), 'enable_user_signup' => $enable_user_signup, 'require_verify_admin' => $require_verify_admin, 'email_link_base' => "https://${lookup('terraform.data.domain_name')}/", diff --git a/site/profile/manifests/gpu.pp b/site/profile/manifests/gpu.pp index aa2092a26..4f42d8994 100644 --- a/site/profile/manifests/gpu.pp +++ b/site/profile/manifests/gpu.pp @@ -11,10 +11,10 @@ Optional[String] $lib_symlink_path = undef ) { $restrict_profiling = lookup('profile::gpu::restrict_profiling') - ensure_resource('file', '/etc/nvidia', { 'ensure' => 'directory' }) - ensure_packages(['kernel-devel'], { 'name' => "kernel-devel-${facts['kernelrelease']}" }) - ensure_packages(['kernel-headers'], { 'name' => "kernel-headers-${facts['kernelrelease']}" }) - ensure_packages(['dkms'], { 'require' => [Package['kernel-devel'], Yumrepo['epel']] }) + stdlib::ensure_resource('file', '/etc/nvidia', { 'ensure' => 'directory' }) + stdlib::ensure_packages(['kernel-devel'], { 'name' => "kernel-devel-${facts['kernelrelease']}" }) + stdlib::ensure_packages(['kernel-headers'], { 'name' => "kernel-headers-${facts['kernelrelease']}" }) + stdlib::ensure_packages(['dkms'], { 'require' => [Package['kernel-devel'], Yumrepo['epel']] }) $nvidia_kmod = ['nvidia', 'nvidia_modeset', 'nvidia_drm', 'nvidia_uvm'] selinux::module { 'nvidia-gpu': @@ -245,7 +245,7 @@ # Used by slurm-job-exporter to export GPU metrics # DCGM does not work with GRID VGPU, most of the stats are missing - ensure_packages(['python3', 'python3-pip'], { ensure => 'present' }) + stdlib::ensure_packages(['python3', 'python3-pip'], { ensure => 'present' }) $py3_version = lookup('os::redhat::python3::version') exec { 'pip install nvidia-ml-py': diff --git a/site/profile/manifests/jupyterhub.pp b/site/profile/manifests/jupyterhub.pp index 9208af074..6aec7fd90 100644 --- a/site/profile/manifests/jupyterhub.pp +++ b/site/profile/manifests/jupyterhub.pp @@ -16,6 +16,9 @@ } include profile::slurm::submitter + nftables::rule { 'default_in-jupyterhub_tcp': + content => 'tcp dport 8081 accept comment "Accept jupyterhub"', + } consul::service { 'jupyterhub': port => 8081, tags => ['jupyterhub'], @@ -40,6 +43,9 @@ Class['profile::software_stack'] -> Class['jupyterhub::kernel::venv'] } } + nftables::rule { 'default_in-jupyter_server': + content => 'tcp dport 32768-60999 accept comment "Accept jupyter_server"', + } } class profile::jupyterhub::hub::keytab { diff --git a/site/profile/manifests/mail.pp b/site/profile/manifests/mail.pp index 86e4ee42a..e41c2c2af 100644 --- a/site/profile/manifests/mail.pp +++ b/site/profile/manifests/mail.pp @@ -1,5 +1,5 @@ class profile::mail::server { - ensure_packages(['postfix'], { ensure => 'present' }) + stdlib::ensure_packages(['postfix'], { ensure => 'present' }) service { 'postfix': ensure => running, diff --git a/site/profile/manifests/metrics.pp b/site/profile/manifests/metrics.pp index 57680ace8..c2a9a247a 100644 --- a/site/profile/manifests/metrics.pp +++ b/site/profile/manifests/metrics.pp @@ -5,6 +5,7 @@ class profile::metrics::node_exporter { include profile::consul include prometheus::node_exporter + include nftables::rules::node_exporter consul::service { 'node-exporter': port => 9100, tags => ['node-exporter'], @@ -89,6 +90,8 @@ require => [ Package['prometheus-slurm-exporter'], File['/etc/systemd/system/prometheus-slurm-exporter.service'], + User['slurm'], + Group['slurm'], ], } } diff --git a/site/profile/manifests/nfs.pp b/site/profile/manifests/nfs.pp index d75139f9a..a379b2a01 100644 --- a/site/profile/manifests/nfs.pp +++ b/site/profile/manifests/nfs.pp @@ -48,6 +48,7 @@ Array[String] $no_root_squash_tags = ['mgmt'] ) { include profile::volumes + include nftables::rules::nfs $nfs_domain = lookup('profile::nfs::domain') class { 'nfs': diff --git a/site/profile/manifests/puppetserver.pp b/site/profile/manifests/puppetserver.pp new file mode 100644 index 000000000..bca8f1ba7 --- /dev/null +++ b/site/profile/manifests/puppetserver.pp @@ -0,0 +1,5 @@ +class profile::puppetserver { + tag 'mc_bootstrap' + include profile::firewall + include nftables::rules::puppet +} diff --git a/site/profile/manifests/reverse_proxy.pp b/site/profile/manifests/reverse_proxy.pp index 7d56542a5..fa1a17072 100644 --- a/site/profile/manifests/reverse_proxy.pp +++ b/site/profile/manifests/reverse_proxy.pp @@ -4,6 +4,8 @@ Hash[String, Array[String]] $remote_ips = {}, String $main2sub_redir = 'jupyter', ) { + include profile::firewall + selinux::boolean { 'httpd_can_network_connect': } selinux::module { 'caddy': @@ -11,13 +13,8 @@ source_pp => 'puppet:///modules/profile/reverse_proxy/caddy.pp', } - firewall { '200 httpd public': - chain => 'INPUT', - dport => [80, 443], - proto => 'tcp', - source => '0.0.0.0/0', - action => 'accept', - } + include nftables::rules::http + include nftables::rules::https yumrepo { 'caddy-copr-repo': enabled => true, diff --git a/site/profile/manifests/slurm.pp b/site/profile/manifests/slurm.pp index 2b95673b2..634060410 100644 --- a/site/profile/manifests/slurm.pp +++ b/site/profile/manifests/slurm.pp @@ -167,7 +167,7 @@ # slurm-contribs command "seff" requires Sys/hostname.pm # which is not packaged by default with perl in RHEL >= 9. if versioncmp($facts['os']['release']['major'], '9') >= 0 { - ensure_packages(['perl-Sys-Hostname'], { 'ensure' => 'installed' }) + stdlib::ensure_packages(['perl-Sys-Hostname'], { 'ensure' => 'installed' }) } package { 'slurm-libpmi': @@ -266,6 +266,8 @@ password => $password, host => 'localhost', grant => ['ALL'], + charset => 'utf8mb4', + collate => 'utf8mb4_unicode_ci', } file { '/etc/slurm/slurmdbd.conf': @@ -303,6 +305,10 @@ before => Service['slurmctld'] } + nftables::rule { 'default_in-slurmdbd': + content => "tcp dport ${dbd_port} accept comment \"Accept slurmdbd\"", + } + consul::service { 'slurmdbd': port => $dbd_port, require => Tcp_conn_validator['consul'], @@ -395,7 +401,7 @@ mode => '0755', } - ensure_packages(['python3'], { ensure => 'present' }) + stdlib::ensure_packages(['python3'], { ensure => 'present' }) $autoscale_env_prefix = '/opt/software/slurm/autoscale_env' exec { 'autoscale_slurm_env': @@ -490,6 +496,10 @@ ), } + nftables::rule { 'default_in-slurmctld': + content => 'tcp dport 6817 accept comment "Accept slurmctld"', + } + consul::service { 'slurmctld': port => 6817, require => Tcp_conn_validator['consul'], @@ -541,6 +551,10 @@ ) { contain profile::slurm::base + nftables::rule { 'default_in-slurmd': + content => 'tcp dport 6818 accept comment "Accept slurmd"', + } + package { ['slurm-slurmd', 'slurm-pam_slurm']: ensure => 'installed', require => Package['slurm'], @@ -754,4 +768,7 @@ # controller through Slurm command-line tools. class profile::slurm::submitter { contain profile::slurm::base + nftables::rule { 'default_in-slurm_srun': + content => "tcp dport 32768-60999 accept comment \"Accept srun\"", + } } diff --git a/site/profile/manifests/squid.pp b/site/profile/manifests/squid.pp index a8e1507ec..c39f36940 100644 --- a/site/profile/manifests/squid.pp +++ b/site/profile/manifests/squid.pp @@ -5,6 +5,10 @@ ) { include profile::consul + nftables::rule { 'default_in-squid': + content => 'tcp dport 3128 accept comment "Accept squid"', + } + class { 'squid': } squid::http_port { String($port): } squid::acl { 'SSL_ports': @@ -21,7 +25,7 @@ } squid::acl { 'CLUSTER_NETWORK': type => 'src', - entries => [profile::getcidr()], + entries => [lookup('terraform.network.cidr')], } # How can we have multiple regex entries under the same ACL name? # From Squid documentation: