From db988f281315fcbaeb0c32dc26c39890da977466 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Javier=20B=C3=A9rtoli?= Date: Fri, 25 Feb 2022 13:40:15 -0300 Subject: [PATCH] 18791: allow single-host-single-hostname to manage LE certs MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Arvados-DCO-1.1-Signed-off-by: Javier Bértoli --- tools/salt-install/Vagrantfile | 12 +- .../single_hostname/pillars/arvados.sls | 2 +- .../pillars/nginx_api_configuration.sls | 2 +- .../nginx_controller_configuration.sls | 10 +- .../pillars/nginx_keepproxy_configuration.sls | 20 +++- .../pillars/nginx_keepweb_configuration.sls | 8 +- .../pillars/nginx_webshell_configuration.sls | 8 +- .../pillars/nginx_websocket_configuration.sls | 8 +- .../nginx_workbench2_configuration.sls | 8 +- .../pillars/nginx_workbench_configuration.sls | 8 +- .../single_hostname/states/custom_certs.sls | 33 ++++++ .../single_hostname/states/snakeoil_certs.sls | 105 ++++++++++-------- .../local.params.example.multiple_hosts | 4 +- ...ams.example.single_host_multiple_hostnames | 2 +- ...params.example.single_host_single_hostname | 13 ++- tools/salt-install/provision.sh | 99 +++++++++++------ 16 files changed, 231 insertions(+), 111 deletions(-) create mode 100644 tools/salt-install/config_examples/single_host/single_hostname/states/custom_certs.sls diff --git a/tools/salt-install/Vagrantfile b/tools/salt-install/Vagrantfile index f5759c482d..27f1591c8f 100644 --- a/tools/salt-install/Vagrantfile +++ b/tools/salt-install/Vagrantfile @@ -37,9 +37,9 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| s#domain_fixme_or_this_wont_work#local#g; s#CONTROLLER_EXT_SSL_PORT=443#CONTROLLER_EXT_SSL_PORT=8443#g; s#RELEASE=\"production\"#RELEASE=\"development\"#g; - s/# VERSION=.*$/VERSION=\"latest\"/g; - s/#\ BRANCH=\"main\"/\ BRANCH=\"main\"/g' \ + s/# VERSION=.*$/VERSION=\"latest\"/g;' \ /vagrant/local.params.example.single_host_multiple_hostnames > /tmp/local.params.single_host_multiple_hostnames" + # s/#\ BRANCH=\"main\"/\ BRANCH=\"main\"/g;' \ arv.vm.provision "shell", path: "provision.sh", @@ -54,7 +54,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # A single_host single_hostname example config.vm.define "arvados-sh-sn" do |arv| - arv.vm.box = "bento/debian-10" + arv.vm.box = "bento/debian-11" arv.vm.hostname = "zeppo" # CPU/RAM config.vm.provider :virtualbox do |v| @@ -80,15 +80,15 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| arv.vm.provision "shell", inline: "cp -vr /vagrant/config_examples/single_host/single_hostname /home/vagrant/local_config_dir; cp -vr /vagrant/tests /home/vagrant/tests; - sed 's#HOSTNAME_EXT=\"\"#HOSTNAME_EXT=\"zeppo.local\"#g; + sed 's#HOSTNAME_EXT=\"hostname_ext_fixme_or_this_wont_work\"#HOSTNAME_EXT=\"zeppo.local\"#g; s#cluster_fixme_or_this_wont_work#zeppo#g; - s/#\ BRANCH=\"main\"/\ BRANCH=\"main\"/g; s#domain_fixme_or_this_wont_work#local#g;' \ /vagrant/local.params.example.single_host_single_hostname > /tmp/local.params.single_host_single_hostname" + # s/#\ BRANCH=\"main\"/\ BRANCH=\"main\"/g; arv.vm.provision "shell", path: "provision.sh", args: [ - # "--debug", + "--debug", "--config /tmp/local.params.single_host_single_hostname", "--test", "--vagrant" diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/arvados.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/arvados.sls index eb59062857..334edb946b 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/arvados.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/arvados.sls @@ -68,6 +68,7 @@ arvados: password: "__DATABASE_PASSWORD__" user: __CLUSTER___arvados encoding: en_US.utf8 + client_encoding: UTF8 tls: # certificate: '' @@ -80,7 +81,6 @@ arvados: system_root: __SYSTEM_ROOT_TOKEN__ management: __MANAGEMENT_TOKEN__ anonymous_user: __ANONYMOUS_USER_TOKEN__ - rails_secret: YDLxHf4GqqmLXYAMgndrAmFEdqgC0sBqX7TEjMN2rw9D6EVwgx ### KEYS secrets: diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_api_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_api_configuration.sls index 2c9a10cb52..ac3ba99f16 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_api_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_api_configuration.sls @@ -13,7 +13,7 @@ nginx: ### SITES servers: managed: - arvados_api: + arvados_api.conf: enabled: true overwrite: true config: diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_controller_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_controller_configuration.sls index dc0200b5ef..08aba90494 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_controller_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_controller_configuration.sls @@ -20,7 +20,7 @@ nginx: servers: managed: ### DEFAULT - arvados_controller_default: + arvados_controller_default.conf: enabled: true overwrite: true config: @@ -33,9 +33,11 @@ nginx: - location /: - return: '301 https://$host$request_uri' - arvados_controller_ssl: + arvados_controller_ssl.conf: enabled: true overwrite: true + requires: + __CERT_REQUIRES__ config: - server: - server_name: __HOSTNAME_EXT__ @@ -52,7 +54,9 @@ nginx: - proxy_set_header: 'X-Real-IP $remote_addr' - proxy_set_header: 'X-Forwarded-For $proxy_add_x_forwarded_for' - proxy_set_header: 'X-External-Client $external_client' - - include: 'snippets/arvados-snakeoil.conf' + - include: snippets/ssl_hardening_default.conf + - ssl_certificate: __CERT_PEM__ + - ssl_certificate_key: __CERT_KEY__ - access_log: /var/log/nginx/__CLUSTER__.__DOMAIN__.access.log combined - error_log: /var/log/nginx/__CLUSTER__.__DOMAIN__.error.log - client_max_body_size: 128m diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_keepproxy_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_keepproxy_configuration.sls index 5a4f249210..11f6e85695 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_keepproxy_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_keepproxy_configuration.sls @@ -15,9 +15,23 @@ nginx: servers: managed: - arvados_keepproxy_ssl: + ### DEFAULT + arvados_keepproxy_default.conf: enabled: true overwrite: true + config: + - server: + - server_name: keep.__CLUSTER__.__DOMAIN__ + - listen: + - 80 + - location /: + - return: '301 https://$host$request_uri' + + arvados_keepproxy_ssl.conf: + enabled: true + overwrite: true + requires: + __CERT_REQUIRES__ config: - server: - server_name: __HOSTNAME_EXT__ @@ -38,6 +52,8 @@ nginx: - client_max_body_size: 64M - proxy_http_version: '1.1' - proxy_request_buffering: 'off' - - include: 'snippets/arvados-snakeoil.conf' + - include: snippets/ssl_hardening_default.conf + - ssl_certificate: __CERT_PEM__ + - ssl_certificate_key: __CERT_KEY__ - access_log: /var/log/nginx/keepproxy.__CLUSTER__.__DOMAIN__.access.log combined - error_log: /var/log/nginx/keepproxy.__CLUSTER__.__DOMAIN__.error.log diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_keepweb_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_keepweb_configuration.sls index 702dd68f6c..1082b5357d 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_keepweb_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_keepweb_configuration.sls @@ -16,9 +16,11 @@ nginx: servers: managed: ### COLLECTIONS / DOWNLOAD - arvados_collections_download_ssl: + arvados_collections_download_ssl.conf: enabled: true overwrite: true + requires: + __CERT_REQUIRES__ config: - server: - server_name: __HOSTNAME_EXT__ @@ -38,6 +40,8 @@ nginx: - client_max_body_size: 0 - proxy_http_version: '1.1' - proxy_request_buffering: 'off' - - include: 'snippets/arvados-snakeoil.conf' + - include: snippets/ssl_hardening_default.conf + - ssl_certificate: __CERT_PEM__ + - ssl_certificate_key: __CERT_KEY__ - access_log: /var/log/nginx/keepweb.__CLUSTER__.__DOMAIN__.access.log combined - error_log: /var/log/nginx/keepweb.__CLUSTER__.__DOMAIN__.error.log diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_webshell_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_webshell_configuration.sls index e7d96d2b9d..67013f93c2 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_webshell_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_webshell_configuration.sls @@ -17,9 +17,11 @@ nginx: ### SITES servers: managed: - arvados_webshell_ssl: + arvados_webshell_ssl.conf: enabled: true overwrite: true + requires: + __CERT_REQUIRES__ config: - server: - server_name: __HOSTNAME_EXT__ @@ -55,7 +57,9 @@ nginx: - add_header: "'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'" - add_header: "'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'" - - include: 'snippets/arvados-snakeoil.conf' + - include: snippets/ssl_hardening_default.conf + - ssl_certificate: __CERT_PEM__ + - ssl_certificate_key: __CERT_KEY__ - access_log: /var/log/nginx/webshell.__CLUSTER__.__DOMAIN__.access.log combined - error_log: /var/log/nginx/webshell.__CLUSTER__.__DOMAIN__.error.log diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_websocket_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_websocket_configuration.sls index 96074256f7..e772072174 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_websocket_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_websocket_configuration.sls @@ -15,9 +15,11 @@ nginx: servers: managed: - arvados_websocket_ssl: + arvados_websocket_ssl.conf: enabled: true overwrite: true + requires: + __CERT_REQUIRES__ config: - server: - server_name: __HOSTNAME_EXT__ @@ -39,6 +41,8 @@ nginx: - client_max_body_size: 64M - proxy_http_version: '1.1' - proxy_request_buffering: 'off' - - include: 'snippets/arvados-snakeoil.conf' + - include: snippets/ssl_hardening_default.conf + - ssl_certificate: __CERT_PEM__ + - ssl_certificate_key: __CERT_KEY__ - access_log: /var/log/nginx/ws.__CLUSTER__.__DOMAIN__.access.log combined - error_log: /var/log/nginx/ws.__CLUSTER__.__DOMAIN__.error.log diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench2_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench2_configuration.sls index 462443c1fa..8e4b9b4aa1 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench2_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench2_configuration.sls @@ -13,9 +13,11 @@ nginx: ### SITES servers: managed: - arvados_workbench2_ssl: + arvados_workbench2_ssl.conf: enabled: true overwrite: true + requires: + __CERT_REQUIRES__ config: - server: - server_name: __HOSTNAME_EXT__ @@ -29,6 +31,8 @@ nginx: - return: 503 - location /config.json: - return: {{ "200 '" ~ '{"API_HOST":"__HOSTNAME_EXT__:__CONTROLLER_EXT_SSL_PORT__"}' ~ "'" }} - - include: 'snippets/arvados-snakeoil.conf' + - include: snippets/ssl_hardening_default.conf + - ssl_certificate: __CERT_PEM__ + - ssl_certificate_key: __CERT_KEY__ - access_log: /var/log/nginx/workbench2.__CLUSTER__.__DOMAIN__.access.log combined - error_log: /var/log/nginx/workbench2.__CLUSTER__.__DOMAIN__.error.log diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench_configuration.sls index 7bf095de3a..3477c02750 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench_configuration.sls @@ -22,9 +22,11 @@ nginx: ### SITES servers: managed: - arvados_workbench_ssl: + arvados_workbench_ssl.conf: enabled: true overwrite: true + requires: + __CERT_REQUIRES__ config: - server: - server_name: __HOSTNAME_EXT__ @@ -40,7 +42,9 @@ nginx: - proxy_set_header: 'Host $http_host' - proxy_set_header: 'X-Real-IP $remote_addr' - proxy_set_header: 'X-Forwarded-For $proxy_add_x_forwarded_for' - - include: 'snippets/arvados-snakeoil.conf' + - include: snippets/ssl_hardening_default.conf + - ssl_certificate: __CERT_PEM__ + - ssl_certificate_key: __CERT_KEY__ - access_log: /var/log/nginx/workbench.__CLUSTER__.__DOMAIN__.access.log combined - error_log: /var/log/nginx/workbench.__CLUSTER__.__DOMAIN__.error.log diff --git a/tools/salt-install/config_examples/single_host/single_hostname/states/custom_certs.sls b/tools/salt-install/config_examples/single_host/single_hostname/states/custom_certs.sls new file mode 100644 index 0000000000..3b2be59f36 --- /dev/null +++ b/tools/salt-install/config_examples/single_host/single_hostname/states/custom_certs.sls @@ -0,0 +1,33 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +{%- set orig_cert_dir = salt['pillar.get']('extra_custom_certs_dir', '/srv/salt/certs') %} +{%- set dest_cert_dir = '/etc/nginx/ssl' %} +{%- set certs = salt['pillar.get']('extra_custom_certs', []) %} + +{% if certs %} +extra_custom_certs_file_directory_certs_dir: + file.directory: + - name: /etc/nginx/ssl + - require: + - pkg: nginx_install + + {%- for cert in certs %} + {%- set cert_file = 'arvados-' ~ cert ~ '.pem' %} + {#- set csr_file = 'arvados-' ~ cert ~ '.csr' #} + {%- set key_file = 'arvados-' ~ cert ~ '.key' %} + {% for c in [cert_file, key_file] %} +extra_custom_certs_file_copy_{{ c }}: + file.copy: + - name: {{ dest_cert_dir }}/{{ c }} + - source: {{ orig_cert_dir }}/{{ c }} + - force: true + - user: root + - group: root + - unless: cmp {{ dest_cert_dir }}/{{ c }} {{ orig_cert_dir }}/{{ c }} + - require: + - file: extra_custom_certs_file_directory_certs_dir + {%- endfor %} + {%- endfor %} +{%- endif %} diff --git a/tools/salt-install/config_examples/single_host/single_hostname/states/snakeoil_certs.sls b/tools/salt-install/config_examples/single_host/single_hostname/states/snakeoil_certs.sls index c5883b2e70..e97da23864 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/states/snakeoil_certs.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/states/snakeoil_certs.sls @@ -2,11 +2,16 @@ # # SPDX-License-Identifier: Apache-2.0 +# WARNING: This file is only used for testing purposes, and should not be used +# in a production environment + {%- set curr_tpldir = tpldir %} {%- set tpldir = 'arvados' %} {%- from "arvados/map.jinja" import arvados with context %} {%- set tpldir = curr_tpldir %} +{%- set orig_cert_dir = salt['pillar.get']('extra_custom_certs_dir', '/srv/salt/certs') %} + include: - nginx.passenger - nginx.config @@ -16,31 +21,49 @@ include: # we'll keep it simple here. {%- set arvados_ca_cert_file = '/etc/ssl/private/arvados-snakeoil-ca.pem' %} {%- set arvados_ca_key_file = '/etc/ssl/private/arvados-snakeoil-ca.key' %} -{%- set arvados_cert_file = '/etc/ssl/private/arvados-snakeoil-cert.pem' %} -{%- set arvados_csr_file = '/etc/ssl/private/arvados-snakeoil-cert.csr' %} -{%- set arvados_key_file = '/etc/ssl/private/arvados-snakeoil-cert.key' %} {%- if grains.get('os_family') == 'Debian' %} {%- set arvados_ca_cert_dest = '/usr/local/share/ca-certificates/arvados-snakeoil-ca.crt' %} {%- set update_ca_cert = '/usr/sbin/update-ca-certificates' %} {%- set openssl_conf = '/etc/ssl/openssl.cnf' %} + +extra_snakeoil_certs_ssl_cert_pkg_installed: + pkg.installed: + - name: ssl-cert + - require_in: + - sls: postgres + {%- else %} {%- set arvados_ca_cert_dest = '/etc/pki/ca-trust/source/anchors/arvados-snakeoil-ca.pem' %} {%- set update_ca_cert = '/usr/bin/update-ca-trust' %} {%- set openssl_conf = '/etc/pki/tls/openssl.cnf' %} + {%- endif %} -arvados_test_salt_states_examples_single_host_snakeoil_certs_dependencies_pkg_installed: +extra_snakeoil_certs_dependencies_pkg_installed: pkg.installed: - pkgs: - openssl - ca-certificates -arvados_test_salt_states_examples_single_host_snakeoil_certs_arvados_snake_oil_ca_cmd_run: +# Remove the RANDFILE parameter in openssl.cnf as it makes openssl fail in Ubuntu 18.04 +# Saving and restoring the rng state is not necessary anymore in the openssl 1.1.1 +# random generator, cf +# https://github.com/openssl/openssl/issues/7754 +# +extra_snakeoil_certs_file_comment_etc_openssl_conf: + file.comment: + - name: /etc/ssl/openssl.cnf + - regex: ^RANDFILE.* + - onlyif: grep -q ^RANDFILE /etc/ssl/openssl.cnf + - require_in: + - cmd: extra_snakeoil_certs_arvados_snakeoil_ca_cmd_run + +extra_snakeoil_certs_arvados_snakeoil_ca_cmd_run: # Taken from https://github.com/arvados/arvados/blob/master/tools/arvbox/lib/arvbox/docker/service/certificate/run cmd.run: - name: | - # These dirs are not to CentOS-ish, but this is a helper script + # These dirs are not too CentOS-ish, but this is a helper script # and they should be enough mkdir -p /etc/ssl/certs/ /etc/ssl/private/ && \ openssl req \ @@ -61,64 +84,56 @@ arvados_test_salt_states_examples_single_host_snakeoil_certs_arvados_snake_oil_c - test -f {{ arvados_ca_cert_file }} - openssl verify -CAfile {{ arvados_ca_cert_file }} {{ arvados_ca_cert_file }} - require: - - pkg: arvados_test_salt_states_examples_single_host_snakeoil_certs_dependencies_pkg_installed + - pkg: extra_snakeoil_certs_dependencies_pkg_installed + +{%- set arvados_cert_file = orig_cert_dir ~ '/arvados-__HOSTNAME_EXT__.pem' %} +{%- set arvados_csr_file = orig_cert_dir ~ '/arvadoos-__HOSTNAME_EXT__.csr' %} +{%- set arvados_key_file = orig_cert_dir ~ '/arvados-__HOSTNAME_EXT__.key' %} -arvados_test_salt_states_examples_single_host_snakeoil_certs_arvados_snake_oil_cert_cmd_run: +extra_snakeoil_certs_arvados_snakeoil_cert___HOSTNAME_EXT___cmd_run: cmd.run: - name: | - cat > /tmp/openssl.cnf <<-CNF + cat > /tmp/__HOSTNAME_EXT__.openssl.cnf <<-CNF [req] default_bits = 2048 prompt = no default_md = sha256 - req_extensions = rext distinguished_name = dn + req_extensions = rext + [rext] + subjectAltName = @alt_names [dn] C = CC ST = Some State L = Some Location - O = Arvados Formula - OU = arvados-formula + O = Arvados Provision Example Single Host / Single Hostname + OU = arvados-provision-example-single_host_single_hostname CN = {{ arvados.cluster.name }}.{{ arvados.cluster.domain }} emailAddress = admin@{{ arvados.cluster.name }}.{{ arvados.cluster.domain }} - [rext] - subjectAltName = @alt_names [alt_names] {%- for entry in grains.get('ipv4') %} IP.{{ loop.index }} = {{ entry }} {%- endfor %} - {%- for entry in [ - 'keep', - 'collections', - 'download', - 'keepweb', - 'ws', - 'workbench', - 'workbench2', - ] - %} - DNS.{{ loop.index }} = {{ entry }} - {%- endfor %} - DNS.8 = {{ arvados.cluster.name }}.{{ arvados.cluster.domain }} - DNS.9 = '__HOSTNAME_EXT__' - DNS.10 = '__IP_INT__' + DNS.1 = {{ arvados.cluster.name }}.{{ arvados.cluster.domain }} + DNS.2 = '__HOSTNAME_EXT__' + DNS.3 = '__HOSTNAME_INT__' CNF # The req openssl req \ - -config /tmp/openssl.cnf \ + -config /tmp/__HOSTNAME_EXT__.openssl.cnf \ -new \ -nodes \ -sha256 \ -out {{ arvados_csr_file }} \ - -keyout {{ arvados_key_file }} > /tmp/snake_oil_certs.output 2>&1 && \ + -keyout {{ arvados_key_file }} > /tmp/snake_oil_certs.__HOSTNAME_EXT__.output 2>&1 && \ # The cert openssl x509 \ -req \ -days 365 \ -in {{ arvados_csr_file }} \ -out {{ arvados_cert_file }} \ - -extfile /tmp/openssl.cnf \ + -extfile /tmp/__HOSTNAME_EXT__.openssl.cnf \ -extensions rext \ -CA {{ arvados_ca_cert_file }} \ -CAkey {{ arvados_ca_key_file }} \ @@ -129,27 +144,19 @@ arvados_test_salt_states_examples_single_host_snakeoil_certs_arvados_snake_oil_c - test -f {{ arvados_key_file }} - openssl verify -CAfile {{ arvados_ca_cert_file }} {{ arvados_cert_file }} - require: - - pkg: arvados_test_salt_states_examples_single_host_snakeoil_certs_dependencies_pkg_installed - - cmd: arvados_test_salt_states_examples_single_host_snakeoil_certs_arvados_snake_oil_ca_cmd_run - # We need this before we can add the nginx's snippet - - require_in: - - file: nginx_snippet_arvados-snakeoil.conf - -{%- if grains.get('os_family') == 'Debian' %} -arvados_test_salt_states_examples_single_host_snakeoil_certs_ssl_cert_pkg_installed: - pkg.installed: - - name: ssl-cert + - pkg: extra_snakeoil_certs_dependencies_pkg_installed + - cmd: extra_snakeoil_certs_arvados_snakeoil_ca_cmd_run - require_in: - - sls: postgres + - file: extra_custom_certs_file_copy_arvados-__HOSTNAME_EXT__.pem + - file: extra_custom_certs_file_copy_arvados-__HOSTNAME_EXT__.key -arvados_test_salt_states_examples_single_host_snakeoil_certs_certs_permissions_cmd_run: + {%- if grains.get('os_family') == 'Debian' %} +extra_snakeoil_certs_certs_permissions___HOSTNAME_EXT___cmd_run: file.managed: - name: {{ arvados_key_file }} - owner: root - group: ssl-cert - require: - - cmd: arvados_test_salt_states_examples_single_host_snakeoil_certs_arvados_snake_oil_cert_cmd_run - - pkg: arvados_test_salt_states_examples_single_host_snakeoil_certs_ssl_cert_pkg_installed - - require_in: - - file: nginx_snippet_arvados-snakeoil.conf -{%- endif %} + - cmd: extra_snakeoil_certs_arvados_snakeoil_cert___HOSTNAME_EXT___cmd_run + - pkg: extra_snakeoil_certs_ssl_cert_pkg_installed + {%- endif %} diff --git a/tools/salt-install/local.params.example.multiple_hosts b/tools/salt-install/local.params.example.multiple_hosts index cf960df70b..221e7b35eb 100644 --- a/tools/salt-install/local.params.example.multiple_hosts +++ b/tools/salt-install/local.params.example.multiple_hosts @@ -65,7 +65,7 @@ DATABASE_PASSWORD=please_set_this_to_some_secure_value # # See https://doc.arvados.org/intall/salt-multi-host.html for more information. SSL_MODE="lets-encrypt" -USE_LETSENCRYPT_IAM_USER="yes" +USE_LETSENCRYPT_ROUTE53="yes" # For collections, we need to obtain a wildcard certificate for # '*.collections..'. This is only possible through a DNS-01 challenge. # For that reason, you'll need to provide AWS credentials with permissions to manage @@ -120,7 +120,7 @@ RELEASE="production" # Formulas versions # ARVADOS_TAG="2.2.0" # POSTGRES_TAG="v0.43.0" -# NGINX_TAG="temp-fix-missing-statements-in-pillar" +# NGINX_TAG="v2.8.0" # DOCKER_TAG="v2.0.7" # LOCALE_TAG="v0.3.4" # LETSENCRYPT_TAG="v2.1.0" diff --git a/tools/salt-install/local.params.example.single_host_multiple_hostnames b/tools/salt-install/local.params.example.single_host_multiple_hostnames index 0fca600eff..a77cb24575 100644 --- a/tools/salt-install/local.params.example.single_host_multiple_hostnames +++ b/tools/salt-install/local.params.example.single_host_multiple_hostnames @@ -92,7 +92,7 @@ RELEASE="production" # Formulas versions # ARVADOS_TAG="2.2.0" # POSTGRES_TAG="v0.43.0" -# NGINX_TAG="temp-fix-missing-statements-in-pillar" +# NGINX_TAG="v2.8.0" # DOCKER_TAG="v2.0.7" # LOCALE_TAG="v0.3.4" # LETSENCRYPT_TAG="v2.1.0" diff --git a/tools/salt-install/local.params.example.single_host_single_hostname b/tools/salt-install/local.params.example.single_host_single_hostname index c07cc55ea8..c126c219fa 100644 --- a/tools/salt-install/local.params.example.single_host_single_hostname +++ b/tools/salt-install/local.params.example.single_host_single_hostname @@ -15,8 +15,7 @@ DOMAIN="domain_fixme_or_this_wont_work" # to access all the instances. Not used in the other examples. # When using virtualization (ie AWS), this should be # the EXTERNAL/PUBLIC hostname for the instance. -# If empty, ${CLUSTER}.${DOMAIN} will be used -HOSTNAME_EXT="" +HOSTNAME_EXT="hostname_ext_fixme_or_this_wont_work" # The internal hostname for the host. In the example files, only used in the # single_host/single_hostname example IP_INT="127.0.1.1" @@ -56,6 +55,14 @@ DATABASE_PASSWORD=please_set_this_to_some_secure_value # See https://doc.arvados.org/intall/salt-single-host.html#certificates for more information. SSL_MODE="self-signed" +# If you want to use letsencrypt, set SSL_MODE="lets-encrypt" +# A single certificate for the external hostname of the host will be retrieved, using +# "standalone" mode of LE. + +# If you going to provide your own certificates for Arvados, the provision script can +# help you deploy them. In order to do that, you need to set `SSL_MODE=bring-your-own` above, +# and copy the required certificates under the directory specified in the next line. +# The certs will be copied from this directory by the provision script. # The directory to check for the config files (pillars, states) you want to use. # There are a few examples under 'config_examples'. # CONFIG_DIR="local_config_dir" @@ -79,7 +86,7 @@ RELEASE="production" # Formulas versions # ARVADOS_TAG="2.2.0" # POSTGRES_TAG="v0.43.0" -# NGINX_TAG="temp-fix-missing-statements-in-pillar" +# NGINX_TAG="v2.8.0" # DOCKER_TAG="v2.0.7" # LOCALE_TAG="v0.3.4" # LETSENCRYPT_TAG="v2.1.0" diff --git a/tools/salt-install/provision.sh b/tools/salt-install/provision.sh index df3b95e0cc..7a49acda44 100755 --- a/tools/salt-install/provision.sh +++ b/tools/salt-install/provision.sh @@ -168,7 +168,6 @@ CLUSTER="" DOMAIN="" # Hostnames/IPs used for single-host deploys -HOSTNAME_EXT="" IP_INT="127.0.1.1" # Initial user setup @@ -186,6 +185,7 @@ WORKBENCH1_EXT_SSL_PORT=443 WORKBENCH2_EXT_SSL_PORT=3001 SSL_MODE="self-signed" +USE_LETSENCRYPT_ROUTE53="no" CUSTOM_CERTS_DIR="${SCRIPT_DIR}/certs" ## These are ARVADOS-related parameters @@ -205,7 +205,7 @@ VERSION="latest" # Other formula versions we depend on POSTGRES_TAG="v0.43.0" -NGINX_TAG="temp-fix-missing-statements-in-pillar" +NGINX_TAG="v2.8.0" DOCKER_TAG="v2.0.7" LOCALE_TAG="v0.3.4" LETSENCRYPT_TAG="v2.1.0" @@ -254,7 +254,13 @@ if ! grep -qE '^[[:alnum:]]{5}$' <<<${CLUSTER} ; then fi # Only used in single_host/single_name deploys -if [ "x${HOSTNAME_EXT}" = "x" ] ; then +if [ ! -z "${HOSTNAME_EXT}" ] ; then + # We need to add some extra control vars to manage a single certificate vs. multiple + USE_SINGLE_HOSTNAME="yes" +else + USE_SINGLE_HOSTNAME="no" + # We set this variable, anyway, so sed lines do not fail and we don't need to add more + # conditionals HOSTNAME_EXT="${CLUSTER}.${DOMAIN}" fi @@ -313,18 +319,23 @@ rm -rf ${F_DIR}/* || exit 1 git clone --quiet https://github.com/saltstack-formulas/docker-formula.git ${F_DIR}/docker ( cd docker && git checkout --quiet tags/"${DOCKER_TAG}" -b "${DOCKER_TAG}" ) +echo "...locale" git clone --quiet https://github.com/saltstack-formulas/locale-formula.git ${F_DIR}/locale ( cd locale && git checkout --quiet tags/"${LOCALE_TAG}" -b "${LOCALE_TAG}" ) -git clone --quiet https://github.com/netmanagers/nginx-formula.git ${F_DIR}/nginx +echo "...nginx" +git clone --quiet https://github.com/saltstack-formulas/nginx-formula.git ${F_DIR}/nginx ( cd nginx && git checkout --quiet tags/"${NGINX_TAG}" -b "${NGINX_TAG}" ) +echo "...postgres" git clone --quiet https://github.com/saltstack-formulas/postgres-formula.git ${F_DIR}/postgres ( cd postgres && git checkout --quiet tags/"${POSTGRES_TAG}" -b "${POSTGRES_TAG}" ) +echo "...letsencrypt" git clone --quiet https://github.com/saltstack-formulas/letsencrypt-formula.git ${F_DIR}/letsencrypt ( cd letsencrypt && git checkout --quiet tags/"${LETSENCRYPT_TAG}" -b "${LETSENCRYPT_TAG}" ) +echo "...arvados" git clone --quiet https://git.arvados.org/arvados-formula.git ${F_DIR}/arvados # If we want to try a specific branch of the formula @@ -479,11 +490,12 @@ EOFPSLS # States, extra states if [ -d "${F_DIR}"/extra/extra ]; then SKIP_SNAKE_OIL="snakeoil_certs" + if [[ "$DEV_MODE" = "yes" || "${SSL_MODE}" == "self-signed" ]] ; then # In dev mode, we create some snake oil certs that we'll # use as CUSTOM_CERTS, so we don't skip the states file. # Same when using self-signed certificates. - SKIP_SNAKE_OIL="dont_snakeoil_certs" + SKIP_SNAKE_OIL="dont_add_snakeoil_certs" fi for f in $(ls "${F_DIR}"/extra/extra/*.sls | grep -v ${SKIP_SNAKE_OIL}); do echo " - extra.$(basename ${f} | sed 's/.sls$//g')" >> ${S_DIR}/top.sls @@ -501,7 +513,7 @@ if [ -z "${ROLES}" ]; then echo " - nginx.passenger" >> ${S_DIR}/top.sls # Currently, only available on config_examples/multi_host/aws if [ "${SSL_MODE}" = "lets-encrypt" ]; then - if [ "${USE_LETSENCRYPT_IAM_USER}" != "yes" ]; then + if [ "${USE_LETSENCRYPT_ROUTE53}" = "yes" ]; then grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - extra.aws_credentials" >> ${S_DIR}/top.sls fi grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls @@ -519,7 +531,6 @@ if [ -z "${ROLES}" ]; then echo " - postgres" >> ${S_DIR}/top.sls echo " - docker.software" >> ${S_DIR}/top.sls echo " - arvados" >> ${S_DIR}/top.sls - echo " - extra.dns" >> ${S_DIR}/top.sls # Pillars echo " - docker" >> ${P_DIR}/top.sls @@ -534,36 +545,52 @@ if [ -z "${ROLES}" ]; then echo " - nginx_workbench_configuration" >> ${P_DIR}/top.sls echo " - postgresql" >> ${P_DIR}/top.sls - # Currently, only available on config_examples/multi_host/aws if [ "${SSL_MODE}" = "lets-encrypt" ]; then - if [ "${USE_LETSENCRYPT_IAM_USER}" != "yes" ]; then + if [ "${USE_LETSENCRYPT_ROUTE53}" = "yes" ]; then grep -q "aws_credentials" ${P_DIR}/top.sls || echo " - aws_credentials" >> ${P_DIR}/top.sls fi - grep -q "letsencrypt" ${P_DIR}/top.sls || echo " - letsencrypt" >> ${P_DIR}/top.sls + grep -q "letsencrypt" ${P_DIR}/top.sls || echo " - letsencrypt" >> ${P_DIR}/top.sls # As the pillar differ whether we use LE or custom certs, we need to do a final edition on them - for c in controller websocket workbench workbench2 webshell download collections keepproxy; do - sed -i "s/__CERT_REQUIRES__/cmd: create-initial-cert-${c}.${CLUSTER}.${DOMAIN}*/g; - s#__CERT_PEM__#/etc/letsencrypt/live/${c}.${CLUSTER}.${DOMAIN}/fullchain.pem#g; - s#__CERT_KEY__#/etc/letsencrypt/live/${c}.${CLUSTER}.${DOMAIN}/privkey.pem#g" \ + for c in controller websocket workbench workbench2 webshell keepweb keepproxy; do + if [ "${USE_SINGLE_HOSTNAME}" = "yes" ]; then + # Are we in a single-host-single-hostname env? + CERT_NAME=${HOSTNAME_EXT} + else + # We are in a single-host-multiple-hostnames env + CERT_NAME=${c}.${CLUSTER}.${DOMAIN} + fi + + sed -i "s/__CERT_REQUIRES__/cmd: create-initial-cert-${CERT_NAME}*/g; + s#__CERT_PEM__#/etc/letsencrypt/live/${CERT_NAME}/fullchain.pem#g; + s#__CERT_KEY__#/etc/letsencrypt/live/${CERT_NAME}/privkey.pem#g" \ ${P_DIR}/nginx_${c}_configuration.sls done - elif [ "${SSL_MODE}" = "bring-your-own" ]; then - # Use custom "bring-your-own" certs (either dev mode or prod) - grep -q "custom_certs" ${S_DIR}/top.sls || echo " - extra.custom_certs" >> ${S_DIR}/top.sls + else + # Use custom certs (either dev mode or prod) grep -q "extra_custom_certs" ${P_DIR}/top.sls || echo " - extra_custom_certs" >> ${P_DIR}/top.sls # And add the certs in the custom_certs pillar echo "extra_custom_certs_dir: /srv/salt/certs" > ${P_DIR}/extra_custom_certs.sls echo "extra_custom_certs:" >> ${P_DIR}/extra_custom_certs.sls - for c in controller websocket workbench workbench2 webshell download collections keepproxy; do - copy_custom_cert ${CUSTOM_CERTS_DIR} $c - grep -q ${c} ${P_DIR}/extra_custom_certs.sls || echo " - ${c}" >> ${P_DIR}/extra_custom_certs.sls - - # As the pillar differ whether we use LE or custom certs, we need to do a final edition on them - sed -i "s/__CERT_REQUIRES__/file: extra_custom_certs_file_copy_arvados-${c}.pem/g; - s#__CERT_PEM__#/etc/nginx/ssl/arvados-${c}.pem#g; - s#__CERT_KEY__#/etc/nginx/ssl/arvados-${c}.key#g" \ + # Are we in a single-host-single-hostname env? + if [ "${USE_SINGLE_HOSTNAME}" = "yes" ]; then + # Are we in a single-host-single-hostname env? + CERT_NAME=${HOSTNAME_EXT} + else + # We are in a multiple-hostnames env + CERT_NAME=${c} + fi + for c in controller websocket workbench workbench2 webshell keepweb keepproxy; do + if [ "${SSL_MODE}" = "bring-your-own" ]; then + copy_custom_cert ${CUSTOM_CERTS_DIR} $c + fi + grep -q ${CERT_NAME} ${P_DIR}/extra_custom_certs.sls || echo " - ${CERT_NAME}" >> ${P_DIR}/extra_custom_certs.sls + + # As the pillar differs whether we use LE or custom certs, we need to do a final edition on them + sed -i "s/__CERT_REQUIRES__/file: extra_custom_certs_file_copy_arvados-${CERT_NAME}.pem/g; + s#__CERT_PEM__#/etc/nginx/ssl/arvados-${CERT_NAME}.pem#g; + s#__CERT_KEY__#/etc/nginx/ssl/arvados-${CERT_NAME}.key#g" \ ${P_DIR}/nginx_${c}_configuration.sls done fi @@ -571,7 +598,7 @@ else # If we add individual roles, make sure we add the repo first echo " - arvados.repo" >> ${S_DIR}/top.sls # We add the extra_custom_certs state - grep -q "extra_custom_certs" ${S_DIR}/top.sls || echo " - extra.custom_certs" >> ${S_DIR}/top.sls + grep -q "extra.custom_certs" ${S_DIR}/top.sls || echo " - extra.custom_certs" >> ${S_DIR}/top.sls # And we add the basic part for the certs pillar if [ "${SSL_MODE}" != "lets-encrypt" ]; then @@ -598,13 +625,15 @@ else ### after it. So we add this here as we are, after all, sharing the host for api and controller # Currently, only available on config_examples/multi_host/aws if [ "${SSL_MODE}" = "lets-encrypt" ]; then - if [ "${USE_LETSENCRYPT_IAM_USER}" != "yes" ]; then + if [ "${USE_LETSENCRYPT_ROUTE53}" = "yes" ]; then grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - aws_credentials" >> ${S_DIR}/top.sls fi grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls else # Use custom certs - copy_custom_cert ${CUSTOM_CERTS_DIR} controller + if [ "${SSL_MODE}" = "bring-your-own" ]; then + copy_custom_cert ${CUSTOM_CERTS_DIR} controller + fi grep -q controller ${P_DIR}/extra_custom_certs.sls || echo " - controller" >> ${P_DIR}/extra_custom_certs.sls fi grep -q "arvados.${R}" ${S_DIR}/top.sls || echo " - arvados.${R}" >> ${S_DIR}/top.sls @@ -619,17 +648,21 @@ else grep -q "nginx.passenger" ${S_DIR}/top.sls || echo " - nginx.passenger" >> ${S_DIR}/top.sls # Currently, only available on config_examples/multi_host/aws if [ "${SSL_MODE}" = "lets-encrypt" ]; then - if [ "x${USE_LETSENCRYPT_IAM_USER}" != "xyes" ]; then + if [ "x${USE_LETSENCRYPT_ROUTE53}" = "xyes" ]; then grep -q "aws_credentials" ${S_DIR}/top.sls || echo " - aws_credentials" >> ${S_DIR}/top.sls fi grep -q "letsencrypt" ${S_DIR}/top.sls || echo " - letsencrypt" >> ${S_DIR}/top.sls else # Use custom certs, special case for keepweb if [ ${R} = "keepweb" ]; then - copy_custom_cert ${CUSTOM_CERTS_DIR} download - copy_custom_cert ${CUSTOM_CERTS_DIR} collections + if [ "${SSL_MODE}" = "bring-your-own" ]; then + copy_custom_cert ${CUSTOM_CERTS_DIR} download + copy_custom_cert ${CUSTOM_CERTS_DIR} collections + fi else - copy_custom_cert ${CUSTOM_CERTS_DIR} ${R} + if [ "${SSL_MODE}" = "bring-your-own" ]; then + copy_custom_cert ${CUSTOM_CERTS_DIR} ${R} + fi fi fi # webshell role is just a nginx vhost, so it has no state @@ -647,7 +680,7 @@ else # Currently, only available on config_examples/multi_host/aws if [ "${SSL_MODE}" = "lets-encrypt" ]; then - if [ "${USE_LETSENCRYPT_IAM_USER}" != "yes" ]; then + if [ "${USE_LETSENCRYPT_ROUTE53}" = "yes" ]; then grep -q "aws_credentials" ${P_DIR}/top.sls || echo " - aws_credentials" >> ${P_DIR}/top.sls fi grep -q "letsencrypt" ${P_DIR}/top.sls || echo " - letsencrypt" >> ${P_DIR}/top.sls -- 2.30.2