Skip to content
Snippets Groups Projects
Commit 11a062b7 authored by Robert Marshall's avatar Robert Marshall
Browse files

Update fcontexts after workhorse configured


- Run the SELinux helper after GitLab Workhorse and other files are
  created ensuring their file contexts are restored
- Place GitLab Workhorse socket files into a sockets directory allowing
  the SELinux file context to be inherited on service restarts
- Add a GitLab Workhorse helper to ensure that new UNIX sockets for
  Workhorse always inherit the proper SELinux file context

Signed-off-by: default avatarRobert Marshall <rmarshall@gitlab.com>
parent af2534eb
No related branches found
No related tags found
No related merge requests found
Showing
with 85 additions and 27 deletions
Loading
Loading
@@ -780,7 +780,7 @@ gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = nil
# gitlab_workhorse['ha'] = false
# gitlab_workhorse['listen_network'] = "unix"
# gitlab_workhorse['listen_umask'] = 000
# gitlab_workhorse['listen_addr'] = "/var/opt/gitlab/gitlab-workhorse/socket"
# gitlab_workhorse['listen_addr'] = "/var/opt/gitlab/gitlab-workhorse/sockets/socket"
# gitlab_workhorse['auth_backend'] = "http://localhost:8080"
 
##! the empty string is the default in gitlab-workhorse option parser
Loading
Loading
Loading
Loading
@@ -609,7 +609,7 @@ default['gitlab']['gitlab-workhorse']['enable'] = false
default['gitlab']['gitlab-workhorse']['ha'] = false
default['gitlab']['gitlab-workhorse']['listen_network'] = "unix"
default['gitlab']['gitlab-workhorse']['listen_umask'] = 000
default['gitlab']['gitlab-workhorse']['listen_addr'] = "/var/opt/gitlab/gitlab-workhorse/socket"
default['gitlab']['gitlab-workhorse']['listen_addr'] = "/var/opt/gitlab/gitlab-workhorse/sockets/socket"
default['gitlab']['gitlab-workhorse']['auth_backend'] = "http://localhost:8080"
default['gitlab']['gitlab-workhorse']['auth_socket'] = nil
default['gitlab']['gitlab-workhorse']['cable_backend'] = "http://localhost:8280"
Loading
Loading
require_relative 'base_helper'
class GitlabWorkhorseHelper < BaseHelper
attr_reader :node
def socket_file_name
return unless unix_socket?
File.basename(node['gitlab']['gitlab-workhorse']['listen_addr'])
end
def sockets_directory
return unless unix_socket?
path = File.dirname(node['gitlab']['gitlab-workhorse']['listen_addr'])
return path if File.basename(path) == 'sockets'
File.join(path, 'sockets')
end
def unix_socket?
node['gitlab']['gitlab-workhorse']['listen_network'] == "unix"
end
def socket_file_path
return File.join(sockets_directory, socket_file_name) if unix_socket?
node['gitlab']['gitlab-workhorse']['listen_addr']
end
end
Loading
Loading
@@ -15,6 +15,8 @@
# limitations under the License.
#
 
workhorse_helper = GitlabWorkhorseHelper.new(node)
# If nginx is disabled we will use workhorse for the healthcheck
if node['gitlab']['nginx']['enable']
listen_https = node['gitlab']['nginx']['listen_https']
Loading
Loading
@@ -27,7 +29,7 @@ else
# Always use http for workhorse
schema = 'http'
use_socket = node['gitlab']['gitlab-workhorse']['listen_network'] == "unix"
host = use_socket ? 'localhost' : node['gitlab']['gitlab-workhorse']['listen_addr']
host = use_socket ? 'localhost' : workhorse_helper.socket_file_path
end
 
template "/opt/gitlab/etc/gitlab-healthcheck-rc" do
Loading
Loading
@@ -36,7 +38,7 @@ template "/opt/gitlab/etc/gitlab-healthcheck-rc" do
variables(
{
use_socket: use_socket,
socket_path: use_socket ? node['gitlab']['gitlab-workhorse']['listen_addr'] : '',
socket_path: use_socket ? workhorse_helper.socket_file_path : '',
url: "#{schema}://#{host}#{Gitlab['gitlab_rails']['gitlab_relative_url']}/help"
}
)
Loading
Loading
Loading
Loading
@@ -339,6 +339,7 @@ templatesymlink "Create a gitlab_shell_secret and create a symlink to Rails root
sensitive true
variables(secret_token: node['gitlab']['gitlab-shell']['secret_token'])
dependent_services.each { |svc| notifies :restart, svc }
notifies :run, 'bash[Set proper security context on ssh files for selinux]', :delayed if SELinuxHelper.enabled?
end
 
gitlab_pages_services = dependent_services
Loading
Loading
Loading
Loading
@@ -16,6 +16,7 @@
##
#
account_helper = AccountHelper.new(node)
workhorse_helper = GitlabWorkhorseHelper.new(node)
 
git_user = account_helper.gitlab_user
git_group = account_helper.gitlab_group
Loading
Loading
@@ -72,6 +73,7 @@ templatesymlink "Create a config.yml and create a symlink to Rails root" do
custom_hooks_dir: node['gitlab']['gitlab-shell']['custom_hooks_dir'],
migration: node['gitlab']['gitlab-shell']['migration'],
})
notifies :run, 'bash[Set proper security context on ssh files for selinux]', :delayed if SELinuxHelper.enabled?
end
 
link File.join(gitlab_shell_dir, ".gitlab_shell_secret") do
Loading
Loading
@@ -83,4 +85,5 @@ file authorized_keys do
group git_group
mode '600'
action :create_if_missing
notifies :run, 'bash[Set proper security context on ssh files for selinux]', :delayed if SELinuxHelper.enabled?
end
Loading
Loading
@@ -16,11 +16,13 @@
#
account_helper = AccountHelper.new(node)
redis_helper = RedisHelper.new(node)
workhorse_helper = GitlabWorkhorseHelper.new(node)
 
working_dir = node['gitlab']['gitlab-workhorse']['dir']
log_directory = node['gitlab']['gitlab-workhorse']['log_directory']
gitlab_workhorse_static_etc_dir = "/opt/gitlab/etc/gitlab-workhorse"
workhorse_env_dir = node['gitlab']['gitlab-workhorse']['env_directory']
gitlab_workhorse_socket_dir = workhorse_helper.sockets_directory
 
directory working_dir do
owner account_helper.gitlab_user
Loading
Loading
@@ -29,6 +31,15 @@ directory working_dir do
recursive true
end
 
if workhorse_helper.unix_socket?
directory gitlab_workhorse_socket_dir do
owner account_helper.gitlab_user
group account_helper.web_server_group
mode '0750'
recursive true
end
end
directory log_directory do
owner account_helper.gitlab_user
mode '0700'
Loading
Loading
@@ -83,4 +94,5 @@ template config_file_path do
mode "0640"
variables(object_store: object_store, object_store_provider: object_store_provider, redis_url: redis_url, password: redis_password, sentinels: redis_sentinels, sentinel_master: redis_sentinel_master, master_password: redis_sentinel_master_password)
notifies :restart, "runit_service[gitlab-workhorse]"
notifies :run, 'bash[Set proper security context on ssh files for selinux]', :delayed if SELinuxHelper.enabled?
end
Loading
Loading
@@ -38,7 +38,8 @@ end
# If SELinux is enabled, make sure that OpenSSH thinks the .ssh directory and authorized_keys file of the
# git_user is valid.
bash "Set proper security context on ssh files for selinux" do
code SELinuxHelper.commands(node)
code lazy { SELinuxHelper.commands(node) }
only_if "id -Z"
not_if { !node['gitlab']['gitlab-rails']['enable'] }
action :nothing
end
Loading
Loading
@@ -77,7 +77,7 @@ http {
<% end -%>
 
upstream gitlab-workhorse {
server <%= "unix:" if node['gitlab']['gitlab-workhorse']['listen_network'] == "unix" %><%= node['gitlab']['gitlab-workhorse']['listen_addr'] %>;
server <%= "unix:" if node['gitlab']['gitlab-workhorse']['listen_network'] == "unix" %><%= GitlabWorkhorseHelper.new(node).socket_file_path %>;
}
 
<% if @gitlab_http_config %>
Loading
Loading
Loading
Loading
@@ -14,7 +14,7 @@ exec chpst -e /opt/gitlab/etc/gitlab-workhorse/env -P \
/opt/gitlab/embedded/bin/gitlab-workhorse \
-listenNetwork <%= node['gitlab']['gitlab-workhorse']['listen_network'] %> \
-listenUmask <%= node['gitlab']['gitlab-workhorse']['listen_umask'] %> \
-listenAddr <%= node['gitlab']['gitlab-workhorse']['listen_addr'] %> \
-listenAddr <%= GitlabWorkhorseHelper.new(node).socket_file_path %> \
-authBackend <%= node['gitlab']['gitlab-workhorse']['auth_backend'] %><%= node['gitlab']['gitlab-workhorse']['relative_url'] %> \
<% if node['gitlab']['gitlab-workhorse']['auth_socket'] %>
-authSocket <%= node['gitlab']['gitlab-workhorse']['auth_socket'] %> \
Loading
Loading
require_relative '../helpers/shell_out_helper'
class SELinuxHelper
class << self
include ShellOutHelper
def commands(node)
workhorse_helper = GitlabWorkhorseHelper.new(node)
ssh_dir = File.join(node['gitlab']['user']['home'], ".ssh")
authorized_keys = node['gitlab']['gitlab-shell']['auth_file']
gitlab_shell_var_dir = node['gitlab']['gitlab-shell']['dir']
Loading
Loading
@@ -8,30 +14,29 @@ class SELinuxHelper
gitlab_rails_dir = node['gitlab']['gitlab-rails']['dir']
gitlab_rails_etc_dir = File.join(gitlab_rails_dir, "etc")
gitlab_shell_secret_file = File.join(gitlab_rails_etc_dir, 'gitlab_shell_secret')
gitlab_workhorse_sock = node['gitlab']['gitlab-workhorse']['listen_addr']
 
# If SELinux is enabled, make sure that OpenSSH thinks the .ssh directory and authorized_keys file of the
# git_user is valid.
selinux_code = []
if File.exist?(ssh_dir)
selinux_code << "semanage fcontext -a -t gitlab_shell_t '#{ssh_dir}(/.*)?'"
selinux_code << "restorecon -R -v '#{ssh_dir}'"
end
selinux_code << "semanage fcontext -a -t gitlab_shell_t '#{ssh_dir}(/.*)?'"
selinux_code << "restorecon -R -v '#{ssh_dir}'" if File.exist?(ssh_dir)
[
authorized_keys,
gitlab_shell_config_file,
gitlab_shell_secret_file,
gitlab_workhorse_sock
workhorse_helper.sockets_directory
].each do |file|
selinux_code << "semanage fcontext -a -t gitlab_shell_t '#{file}'"
next unless File.exist?(file)
 
selinux_code << "semanage fcontext -a -t gitlab_shell_t '#{file}'"
selinux_code << "restorecon -v '#{file}'"
end
 
selinux_code.join("\n")
end
def enabled?
success?('id -Z')
end
end
end
Loading
Loading
@@ -46,7 +46,7 @@ RSpec.describe 'gitlab::gitlab-healthcheck' do
expect(chef_run).to render_file("/opt/gitlab/etc/gitlab-healthcheck-rc")
.with_content(%r{url='http://localhost/help'})
expect(chef_run).to render_file("/opt/gitlab/etc/gitlab-healthcheck-rc")
.with_content(%r{flags='--unix-socket /var/opt/gitlab/gitlab-workhorse/socket'})
.with_content(%r{flags='--unix-socket /var/opt/gitlab/gitlab-workhorse/sockets/socket'})
end
 
it 'correctly renders healthcheck-rc file using workhorse on a port' do
Loading
Loading
Loading
Loading
@@ -49,7 +49,7 @@ RSpec.describe 'gitlab::gitlab-shell' do
log_format: "json",
custom_hooks_dir: nil,
migration: { enabled: true, features: [] },
gitlab_url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsocket',
gitlab_url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsockets%2Fsocket',
gitlab_relative_path: ''
)
)
Loading
Loading
@@ -181,7 +181,7 @@ RSpec.describe 'gitlab::gitlab-shell' do
it 'create config file with provided values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
gitlab_url: 'http+unix://%2Ffake%2Fworkhorse%2Fsocket',
gitlab_url: 'http+unix://%2Ffake%2Fworkhorse%2Fsockets%2Fsocket',
gitlab_relative_path: ''
)
)
Loading
Loading
@@ -217,7 +217,7 @@ RSpec.describe 'gitlab::gitlab-shell' do
it 'create config file with provided values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
gitlab_url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsocket',
gitlab_url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsockets%2Fsocket',
gitlab_relative_path: '/gitlab'
)
)
Loading
Loading
Loading
Loading
@@ -2,28 +2,32 @@ require 'chef_helper'
 
RSpec.describe 'gitlab::gitlab-selinux' do
let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(templatesymlink storage_directory)).converge('gitlab::default') }
let(:templatesymlink) { chef_run.templatesymlink('Create a config.yml and create a symlink to Rails root') }
 
before do
allow(Gitlab).to receive(:[]).and_call_original
stub_default_should_notify?(true)
end
 
context 'when NOT running on selinux' do
before { stub_command('id -Z').and_return(false) }
before do
allow_any_instance_of(ShellOutHelper).to receive(:success?).with('id -Z').and_return(false)
end
 
it 'should not run the semanage bash command' do
expect(chef_run).not_to run_bash('Set proper security context on ssh files for selinux')
expect(templatesymlink).to_not notify('bash[Set proper security context on ssh files for selinux]').delayed
end
end
 
context 'when running on selinux' do
before do
stub_command('id -Z').and_return('')
allow_any_instance_of(ShellOutHelper).to receive(:success?).with('id -Z').and_return(true)
allow(File).to receive(:exist?).and_call_original
allow(File).to receive(:exist?).with('/var/opt/gitlab/.ssh').and_return(true)
allow(File).to receive(:exist?).with('/var/opt/gitlab/.ssh/authorized_keys').and_return(true)
allow(File).to receive(:exist?).with('/var/opt/gitlab/gitlab-rails/etc/gitlab_shell_secret').and_return(true)
allow(File).to receive(:exist?).with('/var/opt/gitlab/gitlab-shell/config.yml').and_return(true)
allow(File).to receive(:exist?).with('/var/opt/gitlab/gitlab-workhorse/socket').and_return(true)
allow(File).to receive(:exist?).with('/var/opt/gitlab/gitlab-workhorse/sockets').and_return(true)
end
 
let(:bash_block) { chef_run.bash('Set proper security context on ssh files for selinux') }
Loading
Loading
@@ -33,7 +37,7 @@ RSpec.describe 'gitlab::gitlab-selinux' do
end
 
it 'should run the semanage bash command' do
expect(chef_run).to run_bash('Set proper security context on ssh files for selinux')
expect(templatesymlink).to notify('bash[Set proper security context on ssh files for selinux]').delayed
end
 
it 'sets the security context of gitlab-shell files' do
Loading
Loading
@@ -42,7 +46,7 @@ RSpec.describe 'gitlab::gitlab-selinux' do
/var/opt/gitlab/.ssh/authorized_keys
/var/opt/gitlab/gitlab-shell/config.yml
/var/opt/gitlab/gitlab-rails/etc/gitlab_shell_secret
/var/opt/gitlab/gitlab-workhorse/socket)
/var/opt/gitlab/gitlab-workhorse/sockets)
managed_files = files.map { |file| semanage_fcontext(file) }
 
expect(lines).to include(*managed_files)
Loading
Loading
@@ -50,7 +54,7 @@ RSpec.describe 'gitlab::gitlab-selinux' do
expect(lines).to include("restorecon -v '/var/opt/gitlab/.ssh/authorized_keys'")
expect(lines).to include("restorecon -v '/var/opt/gitlab/gitlab-shell/config.yml'")
expect(lines).to include("restorecon -v '/var/opt/gitlab/gitlab-rails/etc/gitlab_shell_secret'")
expect(lines).to include("restorecon -v '/var/opt/gitlab/gitlab-workhorse/socket'")
expect(lines).to include("restorecon -v '/var/opt/gitlab/gitlab-workhorse/sockets'")
end
 
context 'when gitlab-rails is disabled' do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment