20035: Adds pillars & states to retrieve the password from AWS secrets manager.
authorLucas Di Pentima <lucas.dipentima@curii.com>
Tue, 7 Feb 2023 19:13:18 +0000 (16:13 -0300)
committerLucas Di Pentima <lucas.dipentima@curii.com>
Fri, 10 Feb 2023 18:22:11 +0000 (15:22 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>

tools/salt-install/config_examples/multi_host/aws/pillars/ssl_key_encrypted.sls [new file with mode: 0644]
tools/salt-install/config_examples/multi_host/aws/states/ssl_key_encrypted.sls [new file with mode: 0644]
tools/salt-install/provision.sh

diff --git a/tools/salt-install/config_examples/multi_host/aws/pillars/ssl_key_encrypted.sls b/tools/salt-install/config_examples/multi_host/aws/pillars/ssl_key_encrypted.sls
new file mode 100644 (file)
index 0000000..afec37c
--- /dev/null
@@ -0,0 +1,10 @@
+---
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+ssl_key_encrypted:
+  enabled: __SSL_KEY_ENCRYPTED__
+  aws_secret_name: __SSL_KEY_AWS_SECRET_NAME__
+  ssl_password_file: /etc/nginx/ssl/ssl_key_password.txt
+  ssl_password_connector_script: /usr/local/sbin/password_secret_connector.sh
diff --git a/tools/salt-install/config_examples/multi_host/aws/states/ssl_key_encrypted.sls b/tools/salt-install/config_examples/multi_host/aws/states/ssl_key_encrypted.sls
new file mode 100644 (file)
index 0000000..5bc08f0
--- /dev/null
@@ -0,0 +1,70 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+{%- set ssl_key_encrypted = pillar.get('ssl_key_encrypted', {'enabled': False}) %}
+
+{%- if ssl_key_encrypted.enabled %}
+
+extra_ssl_key_encrypted_password_fifo_file:
+  file.mknod:
+    - ntype: p
+    - name: {{ ssl_key_encrypted.ssl_password_file }}
+    - user: root
+    - group: root
+    - mode: '0600'
+
+extra_ssl_key_encrypted_required_pkgs:
+  pkg.installed:
+    - name: jq
+
+extra_ssl_key_encrypted_password_retrieval_script:
+  file.managed:
+    - name: {{ ssl_key_encrypted.ssl_password_connector_script }}
+    - user: root
+    - group: root
+    - mode: '0750'
+    - require:
+      - pkg: extra_ssl_key_encrypted_required_pkgs
+      - file: extra_ssl_key_encrypted_password_fifo_file
+    - contents: |
+        #!/bin/bash
+
+        while [ true ]; do
+          # AWS_SHARED_CREDENTIALS_FILE is set to an non-existant path to avoid awscli
+          # loading invalid credentials on nodes who use ~/.aws/credentials for other
+          # purposes (e.g.: the dispatcher credentials)
+          # Access to the secrets manager is given by using an instance profile.
+          AWS_SHARED_CREDENTIALS_FILE=~/nonexistant aws secretsmanager get-secret-value --secret-id {{ ssl_key_encrypted.aws_secret_name }} --region us-east-1 | jq -r .SecretString > {{ ssl_key_encrypted.ssl_password_file }}
+          sleep 1
+        done
+
+extra_ssl_key_encrypted_password_retrieval_service_unit:
+  file.managed:
+    - name: /etc/systemd/system/password_secret_connector.service
+    - user: root
+    - group: root
+    - mode: '0644'
+    - require:
+      - file: extra_ssl_key_encrypted_password_retrieval_script
+    - contents: |
+        [Unit]
+        Description=Arvados SSL private key password retrieval service
+        After=network.target
+        AssertPathExists={{ ssl_key_encrypted.ssl_password_file }}
+        [Service]
+        ExecStart=/bin/bash {{ ssl_key_encrypted.ssl_password_connector_script }}
+        [Install]
+        WantedBy=multi-user.target
+
+extra_ssl_key_encrypted_password_retrieval_service:
+  service.running:
+    - name: password_secret_connector
+    - enable: true
+    - require:
+      - file: extra_ssl_key_encrypted_password_retrieval_service_unit
+    - watch:
+      - file: extra_ssl_key_encrypted_password_retrieval_service_unit
+      - file: extra_ssl_key_encrypted_password_retrieval_script
+
+{%- endif %}
\ No newline at end of file
index 435c56d0591e2828cba65d4b529590b40d7495bc..7a60363d696306fa1073e66ce2dc39a9ccda8808 100755 (executable)
@@ -438,7 +438,9 @@ for f in $(ls "${SOURCE_PILLARS_DIR}"/*); do
        s#__WORKBENCH1_INT_IP__#${WORKBENCH1_INT_IP}#g;
        s#__WORKBENCH2_INT_IP__#${WORKBENCH2_INT_IP}#g;
        s#__DATABASE_INT_IP__#${DATABASE_INT_IP}#g;
-       s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g" \
+       s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g;
+       s#__SSL_KEY_ENCRYPTED__#${SSL_KEY_ENCRYPTED}#g;
+       s#__SSL_KEY_AWS_SECRET_NAME__#${SSL_KEY_AWS_SECRET_NAME}#g" \
   "${f}" > "${P_DIR}"/$(basename "${f}")
 done
 
@@ -509,7 +511,9 @@ if [ -d "${SOURCE_STATES_DIR}" ]; then
          s#__WEBSOCKET_EXT_SSL_PORT__#${WEBSOCKET_EXT_SSL_PORT}#g;
          s#__WORKBENCH1_EXT_SSL_PORT__#${WORKBENCH1_EXT_SSL_PORT}#g;
          s#__WORKBENCH2_EXT_SSL_PORT__#${WORKBENCH2_EXT_SSL_PORT}#g;
-         s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g" \
+         s#__WORKBENCH_SECRET_KEY__#${WORKBENCH_SECRET_KEY}#g;
+         s#__SSL_KEY_ENCRYPTED__#${SSL_KEY_ENCRYPTED}#g;
+         s#__SSL_KEY_AWS_SECRET_NAME__#${SSL_KEY_AWS_SECRET_NAME}#g" \
     "${f}" > "${F_DIR}/extra/extra"/$(basename "${f}")
   done
 fi
@@ -561,7 +565,7 @@ if [ -z "${ROLES}" ]; 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
+    grep -q "letsencrypt" ${S_DIR}/top.sls || echo "    - letsencrypt" >> ${S_DIR}/top.sls
   else
     mkdir -p /srv/salt/certs
     chmod 700 /srv/salt/certs
@@ -570,7 +574,10 @@ if [ -z "${ROLES}" ]; then
       cp -rv ${CUSTOM_CERTS_DIR}/* /srv/salt/certs/
       chmod 600 /srv/salt/certs/*
       # We add the custom_certs state
-      grep -q "custom_certs"    ${S_DIR}/top.sls || echo "    - extra.custom_certs" >> ${S_DIR}/top.sls
+      grep -q "custom_certs" ${S_DIR}/top.sls || echo "    - extra.custom_certs" >> ${S_DIR}/top.sls
+      if [ "${SSL_KEY_ENCRYPTED}" = "yes" ]; then
+        grep -q "ssl_key_encrypted" ${S_DIR}/top.sls || echo "    - extra.ssl_key_encrypted" >> ${S_DIR}/top.sls
+      fi
     fi
     # In self-signed mode, the certificate files will be created and put in the
     # destination directory by the snakeoil_certs.sls state file
@@ -667,6 +674,9 @@ else
   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
+  if [ "${SSL_KEY_ENCRYPTED}" = "yes" ]; then
+    grep -q "ssl_key_encrypted" ${S_DIR}/top.sls || echo "    - extra.ssl_key_encrypted" >> ${S_DIR}/top.sls
+  fi
 
   # And we add the basic part for the certs pillar
   if [ "${SSL_MODE}" != "lets-encrypt" ]; then
@@ -789,6 +799,7 @@ else
             ${P_DIR}/nginx_${R}_configuration.sls
           fi
         else
+          grep -q "ssl_key_encrypted" ${P_DIR}/top.sls || echo "    - ssl_key_encrypted" >> ${P_DIR}/top.sls
           # As the pillar differ whether we use LE or custom certs, we need to do a final edition on them
           # Special case for keepweb
           if [ ${R} = "keepweb" ]; then