diff --git a/site-cookbooks/sockethub/recipes/proxy.rb b/site-cookbooks/sockethub/recipes/proxy.rb index b707693..29c753c 100644 --- a/site-cookbooks/sockethub/recipes/proxy.rb +++ b/site-cookbooks/sockethub/recipes/proxy.rb @@ -26,8 +26,41 @@ include_recipe 'sockethub::_firewall' include_recipe 'kosmos-nginx' +include_recipe "kosmos-base::letsencrypt" + server_name = node['sockethub']['nginx']['server_name'] +nginx_post_hook = <<-EOF +#!/usr/bin/env bash + +set -e + +systemctl reload nginx +EOF + +file "/etc/letsencrypt/renewal-hooks/post/nginx" do + content nginx_post_hook + mode 0755 + owner "root" + group "root" +end + +gandi_api_data_bag_item = data_bag_item('credentials', 'gandi_api_5apps') + +template "/root/gandi_dns_certbot_hook.sh" do + variables gandi_api_key: gandi_api_data_bag_item["key"] + mode 0770 +end + +# Generate a Let's Encrypt cert (only if no cert has been generated before). +# The systemd timer will take care of renewing +execute "letsencrypt cert for sockethub" do + command "certbot certonly --manual --preferred-challenges dns --manual-public-ip-logging-ok --agree-tos --manual-auth-hook \"/root/gandi_dns_certbot_hook.sh auth\" --manual-cleanup-hook \"/root/gandi_dns_certbot_hook.sh cleanup\" --deploy-hook \"/etc/letsencrypt/renewal-hooks/post/nginx\" --email ops@kosmos.org -d #{server_name} -n" + not_if do + File.exist?("/etc/letsencrypt/live/#{server_name}/fullchain.pem") + end +end + template "#{node['nginx']['dir']}/sites-available/#{server_name}" do source 'nginx_conf_sockethub.erb' owner 'www-data' @@ -40,13 +73,7 @@ template "#{node['nginx']['dir']}/sites-available/#{server_name}" do notifies :reload, 'service[nginx]', :delayed end -# Legacy vhost -nginx_site "sockethub" do - action :disable -end - nginx_site server_name do action :enable end -nginx_certbot_site server_name diff --git a/site-cookbooks/sockethub/templates/gandi_dns_certbot_hook.sh.erb b/site-cookbooks/sockethub/templates/gandi_dns_certbot_hook.sh.erb new file mode 100755 index 0000000..d0ed9dc --- /dev/null +++ b/site-cookbooks/sockethub/templates/gandi_dns_certbot_hook.sh.erb @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# + +set -euf -o pipefail + +# ************** USAGE ************** +# +# Example usage (with this hook file saved in /root/): +# +# sudo su - +# certbot certonly --manual --preferred-challenges dns --manual-public-ip-logging-ok --agree-tos -d "5apps.com" -d muc.5apps.com -d "xmpp.5apps.com" \ +# --manual-auth-hook "/root/letsencrypt_hook.sh auth" --manual-cleanup-hook "/root/letsencrypt_hook.sh cleanup" +# +# This hook requires configuration, continue reading. +# +# ************** CONFIGURATION ************** +# +# GANDI_API_KEY: Your Gandi Live API key +# +# PROVIDER_UPDATE_DELAY: +# How many seconds to wait after updating your DNS records. This may be required, +# depending on how slow your DNS host is to begin serving new DNS records after updating +# them via the API. 30 seconds is a safe default, but some providers can be very slow +# (e.g. Linode). +# +# Defaults to 30 seconds. +# +GANDI_API_KEY="<%= @gandi_api_key %>" +PROVIDER_UPDATE_DELAY=30 + +regex='.*\.(.*\..*)' +if [[ $CERTBOT_DOMAIN =~ $regex ]] +then + DOMAIN="${BASH_REMATCH[1]}" +else + DOMAIN="${CERTBOT_DOMAIN}" +fi + +# To be invoked via Certbot's --manual-auth-hook +function auth { + curl -s -D- -H "Content-Type: application/json" \ + -H "X-Api-Key: ${GANDI_API_KEY}" \ + -d "{\"rrset_name\": \"_acme-challenge.${CERTBOT_DOMAIN}.\", + \"rrset_type\": \"TXT\", + \"rrset_ttl\": 3600, + \"rrset_values\": [\"${CERTBOT_VALIDATION}\"]}" \ + "https://dns.api.gandi.net/api/v5/domains/${DOMAIN}/records" + + + sleep ${PROVIDER_UPDATE_DELAY} +} + +# To be invoked via Certbot's --manual-cleanup-hook +function cleanup { + curl -s -X DELETE -H "Content-Type: application/json" \ + -H "X-Api-Key: ${GANDI_API_KEY}" \ + https://dns.api.gandi.net/api/v5/domains/${DOMAIN}/records/_acme-challenge.${CERTBOT_DOMAIN}./TXT +} + +HANDLER=$1; shift; +if [ -n "$(type -t $HANDLER)" ] && [ "$(type -t $HANDLER)" = function ]; then + $HANDLER "$@" +fi