From 0ea143d8983a0fcac51aff064edd681127f806a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20=C3=81lvaro?= Date: Sat, 16 May 2020 18:15:58 +0200 Subject: [PATCH] feat: Add salt-api support --- Dockerfile | 2 +- README.md | 85 ++++++++++++++++++++++++++++++++++ assets/build/install.sh | 13 ++++-- assets/runtime/env-defaults.sh | 3 ++ assets/runtime/functions.sh | 71 +++++++++++++++++++++++++++- 5 files changed, 166 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8865b5c..32c49b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,7 +57,7 @@ COPY entrypoint.sh /sbin/entrypoint.sh RUN chmod +x /sbin/entrypoint.sh # Shared resources -EXPOSE 4505/tcp 4506/tcp +EXPOSE 4505 4506 8000 RUN mkdir -p ${SALT_DATA_DIR} ${SALT_BASE_DIR} ${SALT_KEYS_DIR} ${SALT_CONFS_DIR} ${SALT_LOGS_DIR} VOLUME [ "${SALT_BASE_DIR}" "${SALT_KEYS_DIR}" "${SALT_CONFS_DIR}" "${SALT_LOGS_DIR}" ] diff --git a/README.md b/README.md index 8740c51..ed02790 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ For other methods to install SaltStack please refer to the [Official SaltStack I - [Custom Recipes](#custom-recipes) - [Minion Keys](#minion-keys) - [Master Signed Keys](#master-signed-keys) + - [Salt API](#salt-api) + - [Salt Pepper](#salt-pepper) - [Host Mapping](#host-mapping) - [Git Fileserver](#git-fileserver) - [GitPython](#gitpython) @@ -132,6 +134,86 @@ docker run --name salt_stack -it --rm \ The newly created keys will appear inside `keys/generated/other_master_sign` directory. +### Salt API + +You can enable `salt-api` service by setting env variable `SALT_API_SERVICE_ENABLED` to `true`. + +A self-signed SSL certificate will be automatically generated and the following configuration +will be added to the master configuration file: + +```yml +rest_cherrypy: + port: 8000 + ssl_crt: /etc/pki/tls/certs/docker-salt-master.crt + ssl_key: /etc/pki/tls/certs/docker-salt-master.key +``` + +The container exposes port `8000` by default, although you can map this port to whatever port you like in +your `docker run` command or in your `docker-compose.yml` file. + +```sh +docker run --name salt_stack --detach \ + --publish 4505:4505 --publish 4506:4506 --publish 8000:8000 \ + --env 'SALT_API_SERVICE_ENABLED=true' \ + --env 'SALT_API_USER_PASS=SuperCool/Password10' + --volume $(pwd)/roots/:/home/salt/data/srv/ \ + --volume $(pwd)/keys/:/home/salt/data/keys/ \ + cdalvaro/saltstack-master:3000.3_1 +``` + +By default, user `salt_api` is created and you can set its password by setting the environment variable +`SALT_API_USER_PASS`. + +You can also change the salt-api _username_ by setting `SALT_API_USER`. +It is possible to disable this user by explicitly setting this variable to an empty string: `SALT_API_USER=''` if you are going to use an `LDAP` server. + +As a security measure, if `SALT_API_USER_PASS` is set to `true` and you don't disable `SALT_API_USER`, +you'll be required to set `SALT_API_USER_PASS`. Otherwise initialization will fail and your Docker image won't work. + +With all that set, you'll be able to provide your _salt-api_ custom configuration by creating the `salt-api.conf` +file inside your `conf` directory: + +```yml +external_auth: + pam: + salt_api: + - .* +``` + +More information is available in the following link: [External Authentication System (eAuth)](https://docs.saltstack.com/en/latest/topics/eauth/index.html#acl-eauth). + +Now you have your saltstack-master docker image ready to accept external authentications and to connect external tools such as [`saltstack/pepper`](https://github.com/saltstack/pepper). + +#### Salt Pepper + +The pepper CLI script allows users to execute Salt commands from computers that are external to computers running the salt-master or salt-minion daemons as though they were running Salt locally + +##### Installation: + +```sh +pip3 install salt-pepper +``` + +##### Configuration + +Then configure pepper by filling your `~/.pepperrc` file with your salt-api credentials: + +```conf +[main] +SALTAPI_URL=https://your.salt-master.hostname:8000/ +SALTAPI_USER=salt_api +SALTAPI_PASS=SuperCool/Password10 +SALTAPI_EAUTH=pam +``` + +##### Usage + +Beging executing salt recipes with `pepper`: + +```sh +pepper '*' test.ping +``` + ### Host Mapping Per default the container is configured to run `salt-master` as user and group `salt` with `uid` and `gid` `1000`. From the host it appears as if the mounted data volumes are owned by the host's user/group `1000` and maybe leading to unfavorable effects. @@ -218,6 +300,9 @@ Below is the list of available options that can be used to customize your SaltSt | `SALT_LOG_ROTATE_FREQUENCY` | Logrotate frequency for salt logs. Available options are 'daily', 'weekly', 'monthly', and 'yearly'. Default: `weekly` | | `SALT_LOG_ROTATE_RETENTION` | Keep x files before deleting old log files. Defaults: `52` | | `SALT_LEVEL_LOGFILE` | The level of messages to send to the log file. One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. Default: `warning` | +| `SALT_API_SERVICE_ENABLED` | Enable `salt-api` service. Default: `false` | +| `SALT_API_USER` | Set username for `salt-api` service. Default: `salt_api` | +| `SALT_API_USER_PASS` | `SALT_API_USER` password. Required if `SALT_API_SERVICE_ENBALED` is `true` and `SALT_API_USER` is not empty. _Unset_ by default | | `SALT_MASTER_SIGN_PUBKEY` | Sign the master auth-replies with a cryptographic signature of the master's public key. Possible values: 'True' or 'False'. Default: `False` | | `SALT_MASTER_USE_PUBKEY_SIGNATURE` | Instead of computing the signature for each auth-reply, use a pre-calculated signature. This option requires `SALT_MASTER_SIGN_PUBKEY` set to 'True'. Possible values: 'True' or 'False'. Default: `True` | | `SALT_MASTER_SIGN_KEY_NAME` | The customizable name of the signing-key-pair without suffix. Default: `master_sign` | diff --git a/assets/build/install.sh b/assets/build/install.sh index 121806d..78a2cba 100755 --- a/assets/build/install.sh +++ b/assets/build/install.sh @@ -15,7 +15,7 @@ DEBIAN_FRONTEND=noninteractive apt-get install --yes --quiet --no-install-recomm # Create salt user echo "Creating ${SALT_USER} user ..." -useradd -d ${SALT_HOME} -ms /bin/bash -U -G root,sudo ${SALT_USER} +useradd -d ${SALT_HOME} -ms /bin/bash -U -G root,sudo,shadow ${SALT_USER} # Set PATH exec_as_salt cat >> ${SALT_HOME}/.profile <2& echo "ERROR: $@") +} + # Map salt user with host user function map_uidgid() { @@ -135,10 +141,10 @@ function setup_ssh_keys() fi } -# This functions cofigures master service +# This function cofigures master service function configure_salt_master() { - echo "Configuring salt-master ..." + echo "Configuring salt-master service ..." # https://docs.saltstack.com/en/latest/ref/configuration/master.html exec_as_salt cp -p ${SALT_RUNTIME_DIR}/config/master.yml ${SALT_ROOT_DIR}/master @@ -162,6 +168,66 @@ function configure_salt_master() SALT_MASTER_USE_PUBKEY_SIGNATURE } +# This function configures salt-api if service is set to be enabled +function configure_salt_api() +{ + [[ ${SALT_API_SERVICE_ENABLED} == true ]] || return 0 + + if [[ -n "${SALT_API_USER}" ]]; then + + if [[ ${SALT_API_USER} == ${SALT_USER} ]]; then + log_error "SALT_API_USER cannot be the same as ${SALT_USER}" + return 1 + fi + + if [[ -z "${SALT_API_USER_PASS}" ]]; then + log_error "SALT_API_USER_PASS env variable must be set to create ${SALT_API_USER} user" + return 2 + fi + + echo "Creating ${SALT_API_USER} user for salt-api ..." + adduser --quiet --disabled-password --gecos "Salt API" ${SALT_API_USER} + echo "${SALT_API_USER}:${SALT_API_USER_PASS}" | chpasswd + unset SALT_API_USER_PASS + fi + + echo "Configuring salt-api service ..." + + CERTS_PATH=/etc/pki + rm -rf ${CERTS_PATH}/tls/certs/* + salt-call --local tls.create_self_signed_cert cacert_path=${CERTS_PATH} CN=docker-salt-master + + cat >> ${SALT_ROOT_DIR}/master < /etc/supervisor/conf.d/salt-api.conf <