# HG changeset patch # User Robert Marshall <rmarshall@gitlab.com> # Date 1707978618 0 # Thu Feb 15 06:30:18 2024 +0000 # Node ID 82723b10e357ef7da0beb7e37bb462af81785865 # Parent 4f7123044f29341b913d7d6c93ae4ab42026121f Consolidate SELinux policy into one module - Create a single versioned SELinux policy module for GitLab similar to other policy module components. - The first iteration of the consolidated policy is opt-in if the user sets `package['selinux_policy_version'] to anything other than nil. Closes https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7453 Closes https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/8235 Changelog: changed Signed-off-by: Robert Marshall <rmarshall@gitlab.com> diff --git a/files/gitlab-config-template/gitlab.rb.template b/files/gitlab-config-template/gitlab.rb.template --- a/files/gitlab-config-template/gitlab.rb.template +++ b/files/gitlab-config-template/gitlab.rb.template @@ -2799,6 +2799,11 @@ # package['generate_default_secrets'] = true ##! Set to false to prevent creating the default `gitlab-secrets.json` file # package['generate_secrets_json_file'] = true + +##! Settings to control SELinux policy +##! Experimental. Set to 1.0 to switch from legacy multiple policy modules to +##! newer single `gitlab` SELinux policy module. +# package['selinux_policy_version'] = nil ################################################################################ ################################################################################ ## Configuration Settings for GitLab EE only ## diff --git a/files/gitlab-cookbooks/gitlab/recipes/selinux.rb b/files/gitlab-cookbooks/gitlab/recipes/selinux.rb --- a/files/gitlab-cookbooks/gitlab/recipes/selinux.rb +++ b/files/gitlab-cookbooks/gitlab/recipes/selinux.rb @@ -17,21 +17,50 @@ if SELinuxDistroHelper.selinux_supported? ssh_keygen_module = 'gitlab-7.2.0-ssh-keygen' - execute "semodule -i /opt/gitlab/embedded/selinux/#{ssh_keygen_module}.pp" do - not_if "getenforce | grep Disabled" - not_if "semodule -l | grep '^#{ssh_keygen_module}\\s'" - end + authorized_keys_module = 'gitlab-10.5.0-ssh-authorized-keys' + gitlab_shell_module = 'gitlab-13.5.0-gitlab-shell' + gitlab_unified_module = 'gitlab' + + if SELinuxHelper.use_unified_policy?(node) + execute "semodule -i /opt/gitlab/embedded/selinux/#{gitlab_unified_module}.pp" do + not_if "getenforce | grep Disabled" + not_if "semodule -l | grep -E '^#{gitlab_unified_module}([[:space:]]|$)'" + end + + execute "semodule -r #{ssh_keygen_module}" do + not_if "getenforce | grep Disabled" + only_if "semodule -l | grep -E '^#{ssh_keygen_module}([[:space:]]|$)'" + end + + execute "semodule -r #{authorized_keys_module}" do + not_if "getenforce | grep Disabled" + only_if "semodule -l | grep -E '^#{authorized_keys_module}([[:space:]]|$)'" + end - authorized_keys_module = 'gitlab-10.5.0-ssh-authorized-keys' - execute "semodule -i /opt/gitlab/embedded/selinux/#{authorized_keys_module}.pp" do - not_if "getenforce | grep Disabled" - not_if "semodule -l | grep '^#{authorized_keys_module}\\s'" - end + execute "semodule -r #{gitlab_shell_module}" do + not_if "getenforce | grep Disabled" + only_if "semodule -l | grep -E '^#{gitlab_shell_module}([[:space:]]|$)'" + end + else + execute "semodule -i /opt/gitlab/embedded/selinux/#{ssh_keygen_module}.pp" do + not_if "getenforce | grep Disabled" + not_if "semodule -l | grep -E '^#{ssh_keygen_module}([[:space:]]|$)'" + end - gitlab_shell_module = 'gitlab-13.5.0-gitlab-shell' - execute "semodule -i /opt/gitlab/embedded/selinux/#{gitlab_shell_module}.pp" do - not_if "getenforce | grep Disabled" - not_if "semodule -l | grep '^#{gitlab_shell_module}\\s'" + execute "semodule -i /opt/gitlab/embedded/selinux/#{authorized_keys_module}.pp" do + not_if "getenforce | grep Disabled" + not_if "semodule -l | grep -E '^#{authorized_keys_module}([[:space:]]|$)'" + end + + execute "semodule -i /opt/gitlab/embedded/selinux/#{gitlab_shell_module}.pp" do + not_if "getenforce | grep Disabled" + not_if "semodule -l | grep -E '^#{gitlab_shell_module}([[:space:]]|$)'" + end + + execute "semodule -r #{gitlab_unified_module}" do + not_if "getenforce | grep Disabled" + only_if "semodule -l | grep -E '^#{gitlab_unified_module}([[:space:]]|$)'" + end end end diff --git a/files/gitlab-cookbooks/package/attributes/default.rb b/files/gitlab-cookbooks/package/attributes/default.rb --- a/files/gitlab-cookbooks/package/attributes/default.rb +++ b/files/gitlab-cookbooks/package/attributes/default.rb @@ -40,3 +40,6 @@ default['runit']['service_dir'] = '/opt/gitlab/service' default['runit']['sv_dir'] = '/opt/gitlab/sv' default['runit']['lsb_init_dir'] = '/opt/gitlab/init' + +# SELinux Policy options to assist with transition to unified policy +default['package']['selinux_policy_version'] = nil diff --git a/files/gitlab-cookbooks/package/libraries/helpers/selinux_helper.rb b/files/gitlab-cookbooks/package/libraries/helpers/selinux_helper.rb --- a/files/gitlab-cookbooks/package/libraries/helpers/selinux_helper.rb +++ b/files/gitlab-cookbooks/package/libraries/helpers/selinux_helper.rb @@ -4,6 +4,12 @@ class << self include ShellOutHelper + def use_unified_policy?(node) + return false if node['package']['selinux_policy_version'].nil? + + true + end + def commands(node) ssh_dir = File.join(node['gitlab']['user']['home'], ".ssh") authorized_keys = node['gitlab']['gitlab_shell']['auth_file'] diff --git a/files/gitlab-selinux/gitlab.te b/files/gitlab-selinux/gitlab.te new file mode 100644 --- /dev/null +++ b/files/gitlab-selinux/gitlab.te @@ -0,0 +1,39 @@ +module gitlab 1.0.0; + +############################ +# External policy components +############################ +require { + type http_cache_port_t; + type httpd_t; + type init_tmp_t; + type ssh_keygen_t; + type sshd_t; + type sshd_t; + type var_log_t; + + attribute file_type; + + class file { open read getattr }; + class sock_file { write read }; + class tcp_socket name_connect; +} + +################################ +# GitLab policy type definitions +################################ +type gitlab_shell_t; + +typeattribute gitlab_shell_t file_type; + +##################### +# Access Vector Rules +##################### +allow ssh_keygen_t init_tmp_t:file open; + +allow sshd_t http_cache_port_t:tcp_socket name_connect; +allow sshd_t var_log_t:file open; +allow sshd_t gitlab_shell_t:file { read open getattr }; +allow sshd_t gitlab_shell_t:sock_file write; + +allow httpd_t gitlab_shell_t:sock_file { read write }; diff --git a/spec/chef_helper.rb b/spec/chef_helper.rb --- a/spec/chef_helper.rb +++ b/spec/chef_helper.rb @@ -50,11 +50,19 @@ end config.before(:each, type: :chef) do + ssh_keygen_module = 'gitlab-7.2.0-ssh-keygen' + authorized_keys_module = 'gitlab-10.5.0-ssh-authorized-keys' + gitlab_shell_module = 'gitlab-13.5.0-gitlab-shell' + gitlab_unified_module = 'gitlab' + stub_command('id -Z').and_return(false) stub_command("grep 'CS:123456:respawn:/opt/gitlab/embedded/bin/runsvdir-start' /etc/inittab").and_return('') stub_command(%r{\(test -f /var/opt/gitlab/gitlab-rails/upgrade-status/db-migrate-\h+-\) && \(cat /var/opt/gitlab/gitlab-rails/upgrade-status/db-migrate-\h+- | grep -Fx 0\)}).and_return(false) stub_command("getenforce | grep Disabled").and_return(true) - stub_command("semodule -l | grep '^#gitlab-7.2.0-ssh-keygen\\s'").and_return(true) + stub_command("semodule -l | grep '^#{ssh_keygen_module}([[:space:]]|$)'").and_return(true) + stub_command("semodule -l | grep '^#{authorized_keys_module}([[:space:]]|$)'").and_return(true) + stub_command("semodule -l | grep '^#{gitlab_shell_module}([[:space:]]|$)'").and_return(true) + stub_command("semodule -l | grep -E '^#{gitlab_unified_module}([[:space:]]|$)'").and_return(true) stub_command(%r{set \-x \&\& \[ \-d "[^"]\" \]}).and_return(false) stub_command(%r{set \-x \&\& \[ "\$\(stat \-\-printf='[^']*' \$\(readlink -f /[^\)]*\)\) }).and_return(false) stub_command('/opt/gitlab/embedded/bin/psql --version').and_return("fake_version")