# HG changeset patch # User Ian Baum <ibaum@gitlab.com> # Date 1518626913 0 # Wed Feb 14 16:48:33 2018 +0000 # Node ID c6afc63063776c876d0c0836ee9cc18a422e0ec4 # Parent 5541b5ea03314823da9da65449c6474089052d70 Add le renew diff --git a/doc/settings/ssl.md b/doc/settings/ssl.md --- a/doc/settings/ssl.md +++ b/doc/settings/ssl.md @@ -59,9 +59,19 @@ ### Renewing -By default, when `gitlab-ctl reconfigure` is run, if the certificate is within 30 days of expiring, it will automatically be renewed. +There are two commands that can be used to renew your Let's Encrypt certificates. + +1. `gitlab-ctl reconfigure` +1. `gitlab-ctl renew-le-certs` + +Both commands require root privileges and will only perform a request to Let's Encrypt if the certificates are close to expiration date. Please consider [LE rate limits](https://letsencrypt.org/docs/rate-limits/) if you get an error during renewal. -Both tools will only perform a request to Let's Encrypt if the certificates are near expiration, so you don't need to be concerned about hitting any [rate limits](https://letsencrypt.org/docs/rate-limits/). +It is recommended to setup a scheduled task to run `gitlab-ctl le-renew-certs` to ensure your Let's Encrypt certificates stay up to date automatically. + +An example cron entry to check daily +```sh +0 0 * * * /opt/gitlab/bin/gitlab-ctl le-renew-certs > /dev/null +``` ## Troubleshooting diff --git a/files/gitlab-cookbooks/gitlab/recipes/letsencrypt_renew.rb b/files/gitlab-cookbooks/gitlab/recipes/letsencrypt_renew.rb new file mode 100644 --- /dev/null +++ b/files/gitlab-cookbooks/gitlab/recipes/letsencrypt_renew.rb @@ -0,0 +1,21 @@ +# +# Copyright:: Copyright (c) 2018 GitLab Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +include_recipe 'gitlab::config' + +if node['gitlab']['nginx']['enable'] && node['letsencrypt']['enable'] + include_recipe 'letsencrypt::enable' +end diff --git a/files/gitlab-cookbooks/renew-letsencrypt.json b/files/gitlab-cookbooks/renew-letsencrypt.json new file mode 100644 --- /dev/null +++ b/files/gitlab-cookbooks/renew-letsencrypt.json @@ -0,0 +1,5 @@ +{ + "run_list": [ + "recipe[gitlab::letsencrypt_renew]" + ] +} diff --git a/files/gitlab-ctl-commands/letsencrypt.rb b/files/gitlab-ctl-commands/letsencrypt.rb new file mode 100644 --- /dev/null +++ b/files/gitlab-ctl-commands/letsencrypt.rb @@ -0,0 +1,23 @@ +# +# Copyright:: Copyright (c) 2018 GitLab Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "#{base_path}/embedded/service/omnibus-ctl/lib/gitlab_ctl" + +add_command_under_category('renew-le-certs', "Let's Encrypt", "Renew the existing Let's Encrypt certificates", 2) do + status = GitlabCtl::Util.chef_run('solo.rb', 'renew-letsencrypt.json') + $stdout.puts status.stdout + $stderr.puts Rainbow("There was an error renewing Let's Encrypt certificates, please checkout the output").red if status.error? +end diff --git a/files/gitlab-ctl-commands/lib/gitlab_ctl/util.rb b/files/gitlab-ctl-commands/lib/gitlab_ctl/util.rb --- a/files/gitlab-ctl-commands/lib/gitlab_ctl/util.rb +++ b/files/gitlab-ctl-commands/lib/gitlab_ctl/util.rb @@ -69,6 +69,11 @@ def userinfo(username) Etc.getpwnam(username) end + + def chef_run(config, attribs) + cookbook_path = "/opt/gitlab/embedded/cookbooks" + run_command("/opt/gitlab/embedded/bin/chef-client -z -c #{cookbook_path}/#{config} -j #{cookbook_path}/#{attribs}") + end end end end diff --git a/spec/chef/recipes/letsencrypt_spec.rb b/spec/chef/recipes/letsencrypt_spec.rb --- a/spec/chef/recipes/letsencrypt_spec.rb +++ b/spec/chef/recipes/letsencrypt_spec.rb @@ -99,19 +99,19 @@ end # This should work standalone for renewal purposes -describe 'letsencrypt::enable' do +describe 'letsencrypt::renew' do let(:chef_run) do - ChefSpec::SoloRunner.new do |node| - node.normal['gitlab']['external-url'] = 'https://standalone.fakehost.com' - node.normal['gitlab']['nginx']['log_directory'] = '/fake/dir' - node.normal['gitlab']['nginx']['ssl_certificate'] = '/fake/path/cert.crt' - node.normal['gitlab']['nginx']['ssl_certificate_key'] = '/fake/path/cert.key' - node.normal['gitlab']['logging'] = {} - end.converge('letsencrypt::enable') + ChefSpec::SoloRunner.converge('gitlab::letsencrypt_renew') end before do allow(Gitlab).to receive(:[]).and_call_original + stub_gitlab_rb( + external_url: 'https://standalone.fakehost.com', + letsencrypt: { + enable: true + } + ) end it 'executes letsencrypt_certificate' do