From 35117969cb2750fb955d8e5de5a98a86712f06cd Mon Sep 17 00:00:00 2001 From: Stan Hu <stanhu@gmail.com> Date: Wed, 31 May 2023 10:32:06 -0700 Subject: [PATCH] Support Puma key_password_command for SSL key decryption This commit adds support for `puma['ssl_key_password_command']` to make it possible to store encrypted SSL keys on disk. This requires Puma v6.3.0 (https://github.com/puma/puma/pull/3133) to work: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122200. Relates to https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7799 Changelog: added --- files/gitlab-config-template/gitlab.rb.template | 1 + .../gitlab/attributes/default.rb | 1 + files/gitlab-cookbooks/gitlab/recipes/puma.rb | 2 ++ .../gitlab/resources/puma_config.rb | 1 + .../gitlab/templates/default/puma.rb.erb | 3 +++ spec/chef/cookbooks/gitlab/recipes/puma_spec.rb | 16 +++++++++++++--- 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/files/gitlab-config-template/gitlab.rb.template b/files/gitlab-config-template/gitlab.rb.template index 58e8b1ed35..a6f18e3659 100644 --- a/files/gitlab-config-template/gitlab.rb.template +++ b/files/gitlab-config-template/gitlab.rb.template @@ -1083,6 +1083,7 @@ external_url 'GENERATED_EXTERNAL_URL' # puma['ssl_certificate_key'] = nil # puma['ssl_client_certificate'] = nil # puma['ssl_cipher_filter'] = nil +# puma['ssl_key_password_command'] = nil # puma['ssl_verify_mode'] = 'none' # puma['pidfile'] = '/opt/gitlab/var/puma/puma.pid' diff --git a/files/gitlab-cookbooks/gitlab/attributes/default.rb b/files/gitlab-cookbooks/gitlab/attributes/default.rb index 719a7192a2..832d27a47f 100644 --- a/files/gitlab-cookbooks/gitlab/attributes/default.rb +++ b/files/gitlab-cookbooks/gitlab/attributes/default.rb @@ -569,6 +569,7 @@ default['gitlab']['puma']['ssl_certificate'] = nil default['gitlab']['puma']['ssl_certificate_key'] = nil default['gitlab']['puma']['ssl_client_certificate'] = nil default['gitlab']['puma']['ssl_cipher_filter'] = nil +default['gitlab']['puma']['ssl_key_password_command'] = nil default['gitlab']['puma']['ssl_verify_mode'] = 'none' default['gitlab']['puma']['prometheus_scrape_scheme'] = 'http' default['gitlab']['puma']['prometheus_scrape_tls_server_name'] = nil diff --git a/files/gitlab-cookbooks/gitlab/recipes/puma.rb b/files/gitlab-cookbooks/gitlab/recipes/puma.rb index f2daefc987..f60b9abb17 100644 --- a/files/gitlab-cookbooks/gitlab/recipes/puma.rb +++ b/files/gitlab-cookbooks/gitlab/recipes/puma.rb @@ -38,6 +38,7 @@ puma_listen_ssl_host = node['gitlab'][svc]['ssl_listen'] puma_ssl_port = node['gitlab'][svc]['ssl_port'] puma_ssl_cert = node['gitlab'][svc]['ssl_certificate'] puma_ssl_key = node['gitlab'][svc]['ssl_certificate_key'] +puma_ssl_key_password_command = node['gitlab'][svc]['ssl_key_password_command'] puma_ssl_client_cert = node['gitlab'][svc]['ssl_client_certificate'] puma_ssl_cipher_filter = node['gitlab'][svc]['ssl_cipher_filter'] puma_ssl_verify_mode = node['gitlab'][svc]['ssl_verify_mode'] @@ -85,6 +86,7 @@ puma_config puma_rb do ssl_certificate_key puma_ssl_key ssl_cipher_filter puma_ssl_cipher_filter ssl_client_certificate puma_ssl_client_cert + ssl_key_password_command puma_ssl_key_password_command ssl_verify_mode puma_ssl_verify_mode worker_timeout node['gitlab'][svc]['worker_timeout'] per_worker_max_memory_mb node['gitlab'][svc]['per_worker_max_memory_mb'] diff --git a/files/gitlab-cookbooks/gitlab/resources/puma_config.rb b/files/gitlab-cookbooks/gitlab/resources/puma_config.rb index 36d92ef506..879e10a8d6 100644 --- a/files/gitlab-cookbooks/gitlab/resources/puma_config.rb +++ b/files/gitlab-cookbooks/gitlab/resources/puma_config.rb @@ -16,6 +16,7 @@ property :ssl_certificate, [String, nil], default: nil property :ssl_certificate_key, [String, nil], default: nil property :ssl_client_certificate, [String, nil], default: nil property :ssl_cipher_filter, [String, nil], default: nil +property :ssl_key_password_command, [String, nil], default: nil property :ssl_verify_mode, String, default: 'none' property :working_directory, [String, nil], default: nil property :worker_timeout, Integer, default: 60 diff --git a/files/gitlab-cookbooks/gitlab/templates/default/puma.rb.erb b/files/gitlab-cookbooks/gitlab/templates/default/puma.rb.erb index b9b4436f43..ad5ff412ab 100644 --- a/files/gitlab-cookbooks/gitlab/templates/default/puma.rb.erb +++ b/files/gitlab-cookbooks/gitlab/templates/default/puma.rb.erb @@ -50,6 +50,9 @@ ssl_bind '<%= @ssl_listen_host %>', <%= @ssl_port %>, { <%- if @ssl_certificate_key %> key: '<%= @ssl_certificate_key %>', <%- end %> + <%- if @ssl_key_password_command %> + key_password_command: '<%= @ssl_key_password_command %>', + <%- end %> <%- if @ssl_client_certificate %> ca: '<%= @ssl_client_certificate %>', <%- end %> diff --git a/spec/chef/cookbooks/gitlab/recipes/puma_spec.rb b/spec/chef/cookbooks/gitlab/recipes/puma_spec.rb index 2299449c8b..8d9b58386b 100644 --- a/spec/chef/cookbooks/gitlab/recipes/puma_spec.rb +++ b/spec/chef/cookbooks/gitlab/recipes/puma_spec.rb @@ -137,7 +137,8 @@ RSpec.describe 'gitlab::puma with Ubuntu 16.04' do ssl_listen: '192.168.0.1', ssl_port: 9999, ssl_certificate: '/tmp/test.crt', - ssl_certificate_key: '/tmp/test.key' + ssl_certificate_key: '/tmp/test.key', + ssl_key_password_command: 'echo mypassword' } } end @@ -149,6 +150,9 @@ RSpec.describe 'gitlab::puma with Ubuntu 16.04' do it 'renders the puma.rb file' do expect(chef_run).to create_puma_config('/var/opt/gitlab/gitlab-rails/etc/puma.rb').with( + ssl_certificate: '/tmp/test.crt', + ssl_certificate_key: '/tmp/test.key', + ssl_key_password_command: 'echo mypassword', ssl_listen_host: '192.168.0.1', ssl_port: 9999, listen_socket: '/tmp/puma.socket', @@ -159,7 +163,7 @@ RSpec.describe 'gitlab::puma with Ubuntu 16.04' do ) expect(chef_run).to render_file('/var/opt/gitlab/gitlab-rails/etc/puma.rb').with_content { |content| - expect(content).to match(/ssl_bind '192.168.0.1', 9999, {\n cert: '\/tmp\/test.crt',\n key: '\/tmp\/test.key',\n verify_mode: 'none'\n}/m) + expect(content).to match(/ssl_bind '192.168.0.1', 9999, {\n cert: '\/tmp\/test.crt',\n key: '\/tmp\/test.key',\n key_password_command: 'echo mypassword',\n verify_mode: 'none'\n}/m) } end @@ -186,13 +190,17 @@ RSpec.describe 'gitlab::puma with Ubuntu 16.04' do ssl_listen: '192.168.0.1', ssl_port: 9999, ssl_certificate: '/tmp/test.crt', - ssl_certificate_key: '/tmp/test.key' + ssl_certificate_key: '/tmp/test.key', + ssl_key_password_command: nil } } end it 'omits the UNIX socket and TCP binds from the Puma config' do expect(chef_run).to create_puma_config('/var/opt/gitlab/gitlab-rails/etc/puma.rb').with( + ssl_certificate: '/tmp/test.crt', + ssl_certificate_key: '/tmp/test.key', + ssl_key_password_command: nil, ssl_listen_host: '192.168.0.1', ssl_port: 9999, listen_socket: '', @@ -218,6 +226,7 @@ RSpec.describe 'gitlab::puma with Ubuntu 16.04' do base_params.tap do |config| config[:puma][:ssl_client_certificate] = client_cert config[:puma][:ssl_cipher_filter] = filter + config[:puma][:ssl_key_password_command] = nil config[:puma][:ssl_verify_mode] = 'peer' end end @@ -228,6 +237,7 @@ RSpec.describe 'gitlab::puma with Ubuntu 16.04' do ssl_port: 9999, listen_socket: '/tmp/puma.socket', listen_tcp: '10.0.0.1:9000', + ssl_client_certificate: client_cert, ssl_cipher_filter: filter, worker_processes: 4, min_threads: 5, -- GitLab