From 59c4404f7e4e896a69f9c711d7c06149f6e7a6b3 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Fri, 22 Feb 2019 23:20:08 +0000 Subject: [PATCH 01/35] #721: Adds /bin to the search paths for prerequistes of scmi installer. --- CHANGELOG.md | 4 ++++ src/usr/sbin/scmi | 1 + 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9d087d..a882324 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Summary of release changes for Version 2 - CentOS-7 +### 2.5.1 - Unreleased + +- Fixes `scmi` installation error when using the `--manager=systemd` option on Ubuntu hosts. + ### 2.5.0 - 2019-01-28 - Updates `openssl` package to 1.0.2k-16.el7. diff --git a/src/usr/sbin/scmi b/src/usr/sbin/scmi index 8180771..95efe68 100755 --- a/src/usr/sbin/scmi +++ b/src/usr/sbin/scmi @@ -990,6 +990,7 @@ function scmi_manager_type_command_prerequisites () local -a COMMAND_PATHS=( '/usr/local/bin' '/usr/bin' + '/bin' ) local MANAGER_TYPE="${1:-${SCMI_MANAGER_TYPE}}" From 266311fe9a7e0b6d5cbb40d66a318e2000226749 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sat, 23 Feb 2019 09:44:38 +0000 Subject: [PATCH 02/35] #723: Fixes issues with scmi systemd install/uninstall failures. --- CHANGELOG.md | 1 + src/etc/systemd/system/centos-ssh@.service | 5 +++-- src/usr/sbin/scmi | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a882324..02a2657 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Summary of release changes for Version 2 - CentOS-7 ### 2.5.1 - Unreleased - Fixes `scmi` installation error when using the `--manager=systemd` option on Ubuntu hosts. +- Fixes issues with failure to install/uninstall systemd units installed with scmi. ### 2.5.0 - 2019-01-28 diff --git a/src/etc/systemd/system/centos-ssh@.service b/src/etc/systemd/system/centos-ssh@.service index 3cc68d1..cd771be 100644 --- a/src/etc/systemd/system/centos-ssh@.service +++ b/src/etc/systemd/system/centos-ssh@.service @@ -35,6 +35,7 @@ # # To uninstall: # sudo systemctl disable -f {service-unit-instance-name} +# sudo systemctl daemon-reload # sudo systemctl stop {service-unit-instance-name} # sudo rm /etc/systemd/system/{service-unit-template-name} # sudo docker rm -f {service-unit-long-name} @@ -155,10 +156,10 @@ ExecStart=/bin/bash -c \ then \ if /usr/bin/grep -qE \ '^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:)?[1-9][0-9]*$' \ - <<< \"${DOCKER_PORT_MAP_TCP_22}\"; \ + <<< \"${DOCKER_PORT_MAP_TCP_22}\" \ && /usr/bin/grep -qE \ '^.+\.[0-9]+(\.[0-9]+)?$' \ - <<< "${DOCKER_NAME}" + <<< \"${DOCKER_NAME}\"; \ then \ printf -- '--publish %%s%%s:22' \ $(\ diff --git a/src/usr/sbin/scmi b/src/usr/sbin/scmi index 95efe68..aae0dbe 100755 --- a/src/usr/sbin/scmi +++ b/src/usr/sbin/scmi @@ -1701,6 +1701,7 @@ function scmi_systemd_uninstall () then scmi_print_message "sub_step_info" \ "Stopping ${SERVICE_UNIT_INSTANCE_NAME}" + ${systemctl} daemon-reload scmi_run_step \ "${systemctl} stop ${SERVICE_UNIT_INSTANCE_NAME}" fi From d8b61f0324f88633cce67c80a1239a8f0d52636b Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sat, 23 Feb 2019 10:12:44 +0000 Subject: [PATCH 03/35] #717: Removes reference to python-setuptools in README. --- CHANGELOG.md | 1 + README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02a2657..2fa3839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Summary of release changes for Version 2 - CentOS-7 - Fixes `scmi` installation error when using the `--manager=systemd` option on Ubuntu hosts. - Fixes issues with failure to install/uninstall systemd units installed with scmi. +- Removes reference to `python-setuptools` from README as it's no longer installed. ### 2.5.0 - 2019-01-28 diff --git a/README.md b/README.md index 1d4e13b..09013ee 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The latest CentOS-6 / CentOS-7 based releases can be pulled from the `centos-6` The Dockerfile can be used to build a base image that is the bases for several other docker images. -Included in the build are the [SCL](https://www.softwarecollections.org/), [EPEL](http://fedoraproject.org/wiki/EPEL) and [IUS](https://ius.io) repositories. Installed packages include [OpenSSH](http://www.openssh.com/portable.html) secure shell, [Sudo](http://www.courtesan.com/sudo/) and [vim-minimal](http://www.vim.org/) are along with python-setuptools, [supervisor](http://supervisord.org/) and [supervisor-stdout](https://github.com/coderanger/supervisor-stdout). +Included in the build are the [SCL](https://www.softwarecollections.org/), [EPEL](http://fedoraproject.org/wiki/EPEL) and [IUS](https://ius.io) repositories. Installed packages include [OpenSSH](http://www.openssh.com/portable.html) secure shell, [Sudo](http://www.courtesan.com/sudo/) and [vim-minimal](http://www.vim.org/) are along with [supervisor](http://supervisord.org/) and [supervisor-stdout](https://github.com/coderanger/supervisor-stdout). [Supervisor](http://supervisord.org/) is used to start and the sshd daemon when a docker container based on this image is run. To enable simple viewing of stdout for the sshd subprocess, supervisor-stdout is included. This allows you to see output from the supervisord controlled subprocesses with `docker logs {container-name}`. From 30bc0e9d75334af02a5a46f999cb36a5eef23e55 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sat, 23 Feb 2019 11:04:39 +0000 Subject: [PATCH 04/35] #709: Adds improvement to pull logic in systemd unit install template. --- CHANGELOG.md | 1 + .../system/centos-ssh.register@.service | 4 ++-- src/etc/systemd/system/centos-ssh@.service | 24 +++++++------------ 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fa3839..8e7d48e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Summary of release changes for Version 2 - CentOS-7 - Fixes `scmi` installation error when using the `--manager=systemd` option on Ubuntu hosts. - Fixes issues with failure to install/uninstall systemd units installed with scmi. +- Adds improvement to pull logic in systemd unit install template. - Removes reference to `python-setuptools` from README as it's no longer installed. ### 2.5.0 - 2019-01-28 diff --git a/src/etc/systemd/system/centos-ssh.register@.service b/src/etc/systemd/system/centos-ssh.register@.service index 2f975f3..28fe6ec 100644 --- a/src/etc/systemd/system/centos-ssh.register@.service +++ b/src/etc/systemd/system/centos-ssh.register@.service @@ -1,4 +1,4 @@ -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Naming convention: # # centos-ssh@.service = {service-unit-install-template-name} @@ -37,7 +37,7 @@ # sudo systemctl disable -f {service-unit-instance-name} # sudo rm /etc/systemd/system/{service-unit-template-name} # sudo systemctl daemon-reload -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ [Unit] Description=centos-ssh etcd registration // %p@%i diff --git a/src/etc/systemd/system/centos-ssh@.service b/src/etc/systemd/system/centos-ssh@.service index cd771be..1f7c62a 100644 --- a/src/etc/systemd/system/centos-ssh@.service +++ b/src/etc/systemd/system/centos-ssh@.service @@ -1,4 +1,4 @@ -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Naming convention: # # centos-ssh@.service = {service-unit-install-template-name} @@ -39,7 +39,7 @@ # sudo systemctl stop {service-unit-instance-name} # sudo rm /etc/systemd/system/{service-unit-template-name} # sudo docker rm -f {service-unit-long-name} -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ [Unit] Description=centos-ssh // %p@%i @@ -75,20 +75,12 @@ Environment="SSH_USER_SHELL=/bin/bash" # Initialisation: Load image from local storage if available, otherwise pull. ExecStartPre=/bin/bash -c \ - "if [[ -z $( \ - if [[ -n $(/usr/bin/docker images -q \ - ${DOCKER_USER}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} \ - ) ]]; \ - then \ - echo $(/usr/bin/docker images -q \ - ${DOCKER_USER}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} \ - ); \ - else \ - echo $(/usr/bin/docker images -q \ - docker.io/${DOCKER_USER}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} \ - ); \ - fi; \ - ) ]]; \ + "if [[ -z \"$(/usr/bin/docker images -q \ + ${DOCKER_USER}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} \ + )\" ]] \ + && [[ -z \"$(/usr/bin/docker images -q \ + docker.io/${DOCKER_USER}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} \ + )\" ]]; \ then \ if [[ -f ${DOCKER_IMAGE_PACKAGE_PATH}/${DOCKER_USER}/${DOCKER_IMAGE_NAME}.${DOCKER_IMAGE_TAG}.tar.xz ]]; \ then \ From cf2d6b8c93bc129ab238ce4f8ba519c934ff3b0e Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sat, 23 Feb 2019 11:09:11 +0000 Subject: [PATCH 05/35] #709: Adds normalisations for consistency. --- environment.mk | 8 ++++---- src/opt/scmi/environment.sh | 8 ++++---- src/opt/scmi/service-unit.sh | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/environment.mk b/environment.mk index 8bad7cd..a5e04ea 100644 --- a/environment.mk +++ b/environment.mk @@ -1,6 +1,6 @@ -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Constants -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ DOCKER_USER := jdeathe DOCKER_IMAGE_NAME := centos-ssh SHPEC_ROOT := test/shpec @@ -9,9 +9,9 @@ SHPEC_ROOT := test/shpec DOCKER_IMAGE_TAG_PATTERN := ^(latest|centos-[6-7]|((1|2|centos-(6-1|7-2))\.[0-9]+\.[0-9]+))$ DOCKER_IMAGE_RELEASE_TAG_PATTERN := ^(1|2|centos-(6-1|7-2))\.[0-9]+\.[0-9]+$ -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Variables -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Docker image/container settings DOCKER_CONTAINER_OPTS ?= diff --git a/src/opt/scmi/environment.sh b/src/opt/scmi/environment.sh index 1bbe041..2dc69d8 100644 --- a/src/opt/scmi/environment.sh +++ b/src/opt/scmi/environment.sh @@ -1,6 +1,6 @@ -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Constants -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ readonly DOCKER_USER=jdeathe readonly DOCKER_IMAGE_NAME=centos-ssh @@ -8,9 +8,9 @@ readonly DOCKER_IMAGE_NAME=centos-ssh readonly DOCKER_IMAGE_TAG_PATTERN='^(latest|centos-[6-7]|((1|2|centos-(6-1|7-2))\.[0-9]+\.[0-9]+))$' readonly DOCKER_IMAGE_RELEASE_TAG_PATTERN='^(1|2|centos-(6-1|7-2))\.[0-9]+\.[0-9]+$' -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Variables -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Docker image/container settings DOCKER_CONTAINER_OPTS="${DOCKER_CONTAINER_OPTS:-}" diff --git a/src/opt/scmi/service-unit.sh b/src/opt/scmi/service-unit.sh index b7e1d69..824857b 100644 --- a/src/opt/scmi/service-unit.sh +++ b/src/opt/scmi/service-unit.sh @@ -1,6 +1,6 @@ -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Constants -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ readonly SERVICE_UNIT_ENVIRONMENT_KEYS=" DOCKER_CONTAINER_OPTS DOCKER_IMAGE_PACKAGE_PATH @@ -29,7 +29,7 @@ readonly SERVICE_UNIT_REGISTER_ENVIRONMENT_KEYS=" REGISTER_UPDATE_INTERVAL " -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Variables -# ----------------------------------------------------------------------------- -SERVICE_UNIT_INSTALL_TIMEOUT=${SERVICE_UNIT_INSTALL_TIMEOUT:-5} +# ------------------------------------------------------------------------------ +SERVICE_UNIT_INSTALL_TIMEOUT="${SERVICE_UNIT_INSTALL_TIMEOUT:-5}" From f52604a43ac12de5b02a9999f5153ec84c981673 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sat, 23 Feb 2019 11:32:11 +0000 Subject: [PATCH 06/35] #719: Adds docker-compose.yml to .dockerignore. --- .dockerignore | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/.dockerignore b/.dockerignore index f1d19b8..694c48f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,6 +2,7 @@ .gitignore dist test +docker-compose.yml LICENSE README-short.txt *.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e7d48e..afd8b00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Summary of release changes for Version 2 - CentOS-7 - Fixes `scmi` installation error when using the `--manager=systemd` option on Ubuntu hosts. - Fixes issues with failure to install/uninstall systemd units installed with scmi. - Adds improvement to pull logic in systemd unit install template. +- Adds `docker-comose.yml` to `.dockerignore` to reduce size of build context. - Removes reference to `python-setuptools` from README as it's no longer installed. ### 2.5.0 - 2019-01-28 From 08b5f0cc518ed9c73139fb2ae4b620846085d2d2 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sat, 23 Feb 2019 11:42:09 +0000 Subject: [PATCH 07/35] #735 Fixes typo in CHANGELOG. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afd8b00..aa9229f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ Summary of release changes for Version 2 - CentOS-7 - Fixes `scmi` installation error when using the `--manager=systemd` option on Ubuntu hosts. - Fixes issues with failure to install/uninstall systemd units installed with scmi. - Adds improvement to pull logic in systemd unit install template. -- Adds `docker-comose.yml` to `.dockerignore` to reduce size of build context. +- Adds `docker-compose.yml` to `.dockerignore` to reduce size of build context. - Removes reference to `python-setuptools` from README as it's no longer installed. ### 2.5.0 - 2019-01-28 From 91cf974e3c4fd2dcf57596b5e25d73272554a77d Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sat, 23 Feb 2019 15:41:04 +0000 Subject: [PATCH 08/35] #707: Updates Dockerfile to reduce number of layers in final image. --- CHANGELOG.md | 1 + Dockerfile | 30 ++++++++++++------------------ 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa9229f..1630510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Summary of release changes for Version 2 - CentOS-7 ### 2.5.1 - Unreleased +- Updates Dockerfile with combined ADD to reduce layer count in final image. - Fixes `scmi` installation error when using the `--manager=systemd` option on Ubuntu hosts. - Fixes issues with failure to install/uninstall systemd units installed with scmi. - Adds improvement to pull logic in systemd unit install template. diff --git a/Dockerfile b/Dockerfile index 55794a8..c77548f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,13 +2,13 @@ FROM centos:7.5.1804 ARG RELEASE_VERSION="2.5.0" -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # - Import the RPM GPG keys for repositories # - Base install of required packages # - Install supervisord (used to run more than a single process) # - Install supervisor-stdout to allow output of services started by # supervisord to be easily inspected with "docker logs". -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ RUN rpm --rebuilddb \ && rpm --import \ http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7 \ @@ -48,19 +48,13 @@ RUN rpm --rebuilddb \ && rm -rf /{root,tmp,var/cache/{ldconfig,yum}}/* \ && > /etc/sysconfig/i18n -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Copy files into place -# ----------------------------------------------------------------------------- -ADD src/usr/bin \ - /usr/bin/ -ADD src/usr/sbin \ - /usr/sbin/ -ADD src/opt/scmi \ - /opt/scmi/ -ADD src/etc \ - /etc/ +# ------------------------------------------------------------------------------ +ADD src \ + / -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Provisioning # - UTC Timezone # - Networking @@ -68,7 +62,7 @@ ADD src/etc \ # - Enable the wheel sudoers group # - Replace placeholders with values in systemd service unit template # - Set permissions -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ RUN ln -sf \ /usr/share/zoneinfo/UTC \ /etc/localtime \ @@ -94,9 +88,9 @@ RUN ln -sf \ EXPOSE 22 -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Set default environment variables -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ ENV SSH_AUTHORIZED_KEYS="" \ SSH_AUTOSTART_SSHD="true" \ SSH_AUTOSTART_SSHD_BOOTSTRAP="true" \ @@ -114,9 +108,9 @@ ENV SSH_AUTHORIZED_KEYS="" \ SSH_USER_PRIVATE_KEY="" \ SSH_USER_SHELL="/bin/bash" -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ # Set image metadata -# ----------------------------------------------------------------------------- +# ------------------------------------------------------------------------------ LABEL \ maintainer="James Deathe " \ install="docker run \ From 99d44230f869d3586b392ba94cf52e88467910c2 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sat, 23 Feb 2019 16:05:15 +0000 Subject: [PATCH 09/35] #713: Adds updated docker-compose example. --- .dockerignore | 2 ++ .env.example | 16 +++++++++++ CHANGELOG.md | 1 + docker-compose.yml | 67 +++++++++++++++++++++++++++++++++++----------- 4 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 .env.example diff --git a/.dockerignore b/.dockerignore index 694c48f..58065fe 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,5 @@ +.env +.env.example .git .gitignore dist diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..590a183 --- /dev/null +++ b/.env.example @@ -0,0 +1,16 @@ +SSH_AUTHORIZED_KEYS= +SSH_AUTOSTART_SSHD=true +SSH_AUTOSTART_SSHD_BOOTSTRAP=true +SSH_CHROOT_DIRECTORY=%h +SSH_INHERIT_ENVIRONMENT=false +SSH_PASSWORD_AUTHENTICATION=false +SSH_SUDO=ALL=(ALL) ALL +SSH_TIMEZONE=UTC +SSH_USER=app-admin +SSH_USER_FORCE_SFTP=false +SSH_USER_HOME=/home/%u +SSH_USER_ID=500:500 +SSH_USER_PASSWORD= +SSH_USER_PASSWORD_HASHED=false +SSH_USER_PRIVATE_KEY= +SSH_USER_SHELL=/bin/bash \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 1630510..d2d57a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Summary of release changes for Version 2 - CentOS-7 - Fixes issues with failure to install/uninstall systemd units installed with scmi. - Adds improvement to pull logic in systemd unit install template. - Adds `docker-compose.yml` to `.dockerignore` to reduce size of build context. +- Adds docker-compose configuration example. - Removes reference to `python-setuptools` from README as it's no longer installed. ### 2.5.0 - 2019-01-28 diff --git a/docker-compose.yml b/docker-compose.yml index 3336e95..1e62d8c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,52 @@ -# ----------------------------------------------------------------------------- -# Run in background: -# docker-compose up -d -# -# Check status: -# docker-compose ps -# -# View logs of service ssh.1: -# docker-compose logs ssh.1 -# ----------------------------------------------------------------------------- -ssh.1: - image: "jdeathe/centos-ssh:2.5.0" - container_name: "ssh.1" - ports: - - "2020:22" +# ------------------------------------------------------------------------------ +# Ref: https://docs.docker.com/compose/compose-file/ +# +# Setup: +# Copy .env.example to .env and modify values as required. +# docker-compose build +# docker-compose down +# +# Run Default example: +# docker-compose up -d +# +# Check service logs: +# docker-compose logs ssh +# +# Usage: +# docker-compose exec ssh bash +# +# Reset - bring down services + delete volume data: +# docker-compose down -v +# ------------------------------------------------------------------------------ +version: "3.0" +volumes: + config-ssh: + driver: "local" +services: + ssh: + build: + context: "." + dockerfile: "Dockerfile" + environment: + SSH_AUTHORIZED_KEYS: "${SSH_AUTHORIZED_KEYS}" + SSH_AUTOSTART_SSHD: "${SSH_AUTOSTART_SSHD}" + SSH_AUTOSTART_SSHD_BOOTSTRAP: "${SSH_AUTOSTART_SSHD_BOOTSTRAP}" + SSH_CHROOT_DIRECTORY: "${SSH_CHROOT_DIRECTORY}" + SSH_INHERIT_ENVIRONMENT: "${SSH_INHERIT_ENVIRONMENT}" + SSH_PASSWORD_AUTHENTICATION: "${SSH_PASSWORD_AUTHENTICATION}" + SSH_SUDO: "${SSH_SUDO}" + SSH_TIMEZONE: "${SSH_TIMEZONE}" + SSH_USER: "${SSH_USER}" + SSH_USER_FORCE_SFTP: "${SSH_USER_FORCE_SFTP}" + SSH_USER_HOME: "${SSH_USER_HOME}" + SSH_USER_ID: "${SSH_USER_ID}" + SSH_USER_PASSWORD: "${SSH_USER_PASSWORD}" + SSH_USER_PASSWORD_HASHED: "${SSH_USER_PASSWORD_HASHED}" + SSH_USER_PRIVATE_KEY: "${SSH_USER_PRIVATE_KEY}" + SSH_USER_SHELL: "${SSH_USER_SHELL}" + image: "jdeathe/centos-ssh:latest" + ports: + - "22:22" + restart: "always" + volumes: + - "config-ssh:/etc/ssh" From 8d1624b19564a4b961770933dacfc449edeacb11 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sun, 24 Feb 2019 13:56:42 +0000 Subject: [PATCH 10/35] #713: Adds default published port mapping of 2020:22. --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 1e62d8c..76915a6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,7 +46,7 @@ services: SSH_USER_SHELL: "${SSH_USER_SHELL}" image: "jdeathe/centos-ssh:latest" ports: - - "22:22" + - "2020:22" restart: "always" volumes: - "config-ssh:/etc/ssh" From 347b6a97dd0af944148c380f9d369f44d2b99ae5 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sun, 24 Feb 2019 16:52:29 +0000 Subject: [PATCH 11/35] #713: Adds exclusion of .env from version control. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1db27ab..01faf4b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +.env packages dist \ No newline at end of file From d53fb5a9152cd1939bf48ae323d0039794b691ca Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sun, 24 Feb 2019 17:09:34 +0000 Subject: [PATCH 12/35] #713: Adds better usage example. --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 76915a6..a95abaa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,14 +6,14 @@ # docker-compose build # docker-compose down # -# Run Default example: +# Run: # docker-compose up -d # # Check service logs: # docker-compose logs ssh # # Usage: -# docker-compose exec ssh bash +# docker-compose exec ssh sh -c "curl ifconfig.io/all" # # Reset - bring down services + delete volume data: # docker-compose down -v From 7ce82af1980b2efbea2f8f7e479332cd1e5cc4ee Mon Sep 17 00:00:00 2001 From: James Deathe Date: Sun, 24 Feb 2019 23:46:59 +0000 Subject: [PATCH 13/35] #711: Adds logging improvements. --- CHANGELOG.md | 4 + Dockerfile | 9 +- README.md | 6 +- default.mk | 1 + environment.mk | 1 + src/etc/supervisord.conf | 17 +- .../supervisord.d/00-supervisor_stdout.conf | 9 ++ src/etc/supervisord.d/sshd-bootstrap.conf | 14 +- src/etc/supervisord.d/sshd-wrapper.conf | 12 +- src/etc/systemd/system/centos-ssh@.service | 2 + src/opt/scmi/default.sh | 1 + src/opt/scmi/environment.sh | 1 + src/opt/scmi/service-unit.sh | 1 + src/usr/bin/healthcheck | 3 +- src/usr/sbin/sshd-bootstrap | 2 - test/shpec/operation_shpec.sh | 150 +++++++++--------- 16 files changed, 122 insertions(+), 111 deletions(-) create mode 100644 src/etc/supervisord.d/00-supervisor_stdout.conf diff --git a/CHANGELOG.md b/CHANGELOG.md index d2d57a2..d6157cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,13 +6,17 @@ Summary of release changes for Version 2 - CentOS-7 ### 2.5.1 - Unreleased +- Deprecates use of `supervisor_stdout` - the default value of `SSH_AUTOSTART_SUPERVISOR_STDOUT` will be switched to "false" in a future release. - Updates Dockerfile with combined ADD to reduce layer count in final image. - Fixes `scmi` installation error when using the `--manager=systemd` option on Ubuntu hosts. - Fixes issues with failure to install/uninstall systemd units installed with scmi. - Adds improvement to pull logic in systemd unit install template. - Adds `docker-compose.yml` to `.dockerignore` to reduce size of build context. - Adds docker-compose configuration example. +- Adds `SSH_AUTOSTART_SUPERVISOR_STDOUT` to control startup of `supervisor_stdout`. +- Adds drop-in configuration for `supervisor_stdout` in `/etc/supervisord.d/00-supervisor_stdout.conf`. - Removes reference to `python-setuptools` from README as it's no longer installed. +- Removes requirement of `supervisor_stdout` for output of supervisord logs to stdout. ### 2.5.0 - 2019-01-28 diff --git a/Dockerfile b/Dockerfile index c77548f..6287c81 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,8 +51,7 @@ RUN rpm --rebuilddb \ # ------------------------------------------------------------------------------ # Copy files into place # ------------------------------------------------------------------------------ -ADD src \ - / +ADD src / # ------------------------------------------------------------------------------ # Provisioning @@ -91,9 +90,11 @@ EXPOSE 22 # ------------------------------------------------------------------------------ # Set default environment variables # ------------------------------------------------------------------------------ -ENV SSH_AUTHORIZED_KEYS="" \ +ENV \ + SSH_AUTHORIZED_KEYS="" \ SSH_AUTOSTART_SSHD="true" \ SSH_AUTOSTART_SSHD_BOOTSTRAP="true" \ + SSH_AUTOSTART_SUPERVISOR_STDOUT="true" \ SSH_CHROOT_DIRECTORY="%h" \ SSH_INHERIT_ENVIRONMENT="false" \ SSH_PASSWORD_AUTHENTICATION="false" \ @@ -147,4 +148,4 @@ HEALTHCHECK \ --retries=5 \ CMD ["/usr/bin/healthcheck"] -CMD ["/usr/bin/supervisord", "--configuration=/etc/supervisord.conf"] \ No newline at end of file +CMD ["/usr/bin/supervisord", "--configuration=/etc/supervisord.conf"] diff --git a/README.md b/README.md index 09013ee..5fa773e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The Dockerfile can be used to build a base image that is the bases for several o Included in the build are the [SCL](https://www.softwarecollections.org/), [EPEL](http://fedoraproject.org/wiki/EPEL) and [IUS](https://ius.io) repositories. Installed packages include [OpenSSH](http://www.openssh.com/portable.html) secure shell, [Sudo](http://www.courtesan.com/sudo/) and [vim-minimal](http://www.vim.org/) are along with [supervisor](http://supervisord.org/) and [supervisor-stdout](https://github.com/coderanger/supervisor-stdout). -[Supervisor](http://supervisord.org/) is used to start and the sshd daemon when a docker container based on this image is run. To enable simple viewing of stdout for the sshd subprocess, supervisor-stdout is included. This allows you to see output from the supervisord controlled subprocesses with `docker logs {container-name}`. +[Supervisor](http://supervisord.org/) is used to start and the sshd daemon when a docker container based on this image is run. SSH access is by public key authentication and, by default, the [Vagrant](http://www.vagrantup.com/) [insecure private key](https://github.com/mitchellh/vagrant/blob/master/keys/vagrant) is required. @@ -335,6 +335,10 @@ It may be desirable to prevent the startup of the sshd daemon and/or sshd-bootst ... ``` +##### SSH_AUTOSTART_SUPERVISOR_STDOUT + +This image has `supervisor_stdout` installed which can be used to allow a process controlled by supervisord to send output to both a log file and stdout. It is recommended to simply output to stdout in order to reduce the number of running processes to a minimum. Setting `SSH_AUTOSTART_SUPERVISOR_STDOUT` to "false" will prevent the startup of `supervisor_stdout`. Where an image requires this feature for its logging output `SSH_AUTOSTART_SUPERVISOR_STDOUT` should be set to "true". + ##### SSH_CHROOT_DIRECTORY This option is only applicable when `SSH_USER_FORCE_SFTP` is set to `true`. When using the SFTP option the user is jailed into the ChrootDirectory. The value can contain the placeholders `%h` and `%u` which will be replaced with the values of `SSH_USER_HOME` and `SSH_USER` respectively. The default value of `%h` is the best choice in most cases but the user requires a sub-directory in their HOME directory which they have write access to. If no volume is mounted into the path of the SSH user's HOME directory then a directory named `_data` is created automatically. If you need the user to be able to write to their HOME directory then use an alternative value such as `/chroot/%u` so that the user's HOME path, (relative to the ChrootDirectory), becomes `/chroot/app-admin/home/app-admin` by default. diff --git a/default.mk b/default.mk index f974ff6..380e2c7 100644 --- a/default.mk +++ b/default.mk @@ -44,6 +44,7 @@ define DOCKER_CONTAINER_PARAMETERS --env "SSH_AUTHORIZED_KEYS=$(SSH_AUTHORIZED_KEYS)" \ --env "SSH_AUTOSTART_SSHD=$(SSH_AUTOSTART_SSHD)" \ --env "SSH_AUTOSTART_SSHD_BOOTSTRAP=$(SSH_AUTOSTART_SSHD_BOOTSTRAP)" \ +--env "SSH_AUTOSTART_SUPERVISOR_STDOUT=$(SSH_AUTOSTART_SUPERVISOR_STDOUT)" \ --env "SSH_CHROOT_DIRECTORY=$(SSH_CHROOT_DIRECTORY)" \ --env "SSH_INHERIT_ENVIRONMENT=$(SSH_INHERIT_ENVIRONMENT)" \ --env "SSH_PASSWORD_AUTHENTICATION=$(SSH_PASSWORD_AUTHENTICATION)" \ diff --git a/environment.mk b/environment.mk index a5e04ea..9a6c64f 100644 --- a/environment.mk +++ b/environment.mk @@ -35,6 +35,7 @@ STARTUP_TIME ?= 2 SSH_AUTHORIZED_KEYS ?= SSH_AUTOSTART_SSHD ?= true SSH_AUTOSTART_SSHD_BOOTSTRAP ?= true +SSH_AUTOSTART_SUPERVISOR_STDOUT ?= true SSH_CHROOT_DIRECTORY ?= %h SSH_INHERIT_ENVIRONMENT ?= false SSH_PASSWORD_AUTHENTICATION ?= false diff --git a/src/etc/supervisord.conf b/src/etc/supervisord.conf index 6c1f3ea..944c30c 100755 --- a/src/etc/supervisord.conf +++ b/src/etc/supervisord.conf @@ -1,20 +1,13 @@ [supervisord] -logfile = /var/log/supervisor/supervisord.log -logfile_maxbytes = 50MB -logfile_backups = 2 +logfile = /dev/null +logfile_maxbytes = 0 +logfile_backups = 0 loglevel = info -pidfile = /var/run/supervisord.pid minfds = 1024 minprocs = 200 nodaemon = true +pidfile = /var/run/supervisord.pid user = root -[eventlistener:supervisor_stdout] -command = /usr/bin/supervisor_stdout -buffer_size = 100 -events = PROCESS_LOG -result_handler = supervisor_stdout:event_handler -startsecs = 0 - [include] -files = supervisord.d/*.conf supervisord.d/*.ini \ No newline at end of file +files = supervisord.d/*.conf supervisord.d/*.ini diff --git a/src/etc/supervisord.d/00-supervisor_stdout.conf b/src/etc/supervisord.d/00-supervisor_stdout.conf new file mode 100644 index 0000000..98bbcac --- /dev/null +++ b/src/etc/supervisord.d/00-supervisor_stdout.conf @@ -0,0 +1,9 @@ +[eventlistener:supervisor_stdout] +autostart = %(ENV_SSH_AUTOSTART_SUPERVISOR_STDOUT)s +buffer_size = 100 +command = /usr/bin/supervisor_stdout +events = PROCESS_LOG +priority = 1 +result_handler = supervisor_stdout:event_handler +startsecs = 0 +user = root diff --git a/src/etc/supervisord.d/sshd-bootstrap.conf b/src/etc/supervisord.d/sshd-bootstrap.conf index dbb9f54..71f0be0 100644 --- a/src/etc/supervisord.d/sshd-bootstrap.conf +++ b/src/etc/supervisord.d/sshd-bootstrap.conf @@ -1,10 +1,10 @@ [program:sshd-bootstrap] -priority = 5 -command = /usr/sbin/sshd-bootstrap -autostart = %(ENV_SSH_AUTOSTART_SSHD_BOOTSTRAP)s -startsecs = 0 -startretries = 0 autorestart = false +autostart = %(ENV_SSH_AUTOSTART_SSHD_BOOTSTRAP)s +command = /usr/sbin/sshd-bootstrap +priority = 5 redirect_stderr = true -stdout_logfile = /var/log/secure -stdout_events_enabled = true \ No newline at end of file +startretries = 0 +startsecs = 0 +stdout_logfile = /dev/stdout +stdout_logfile_maxbytes = 0 diff --git a/src/etc/supervisord.d/sshd-wrapper.conf b/src/etc/supervisord.d/sshd-wrapper.conf index 6c4c763..b71a51e 100644 --- a/src/etc/supervisord.d/sshd-wrapper.conf +++ b/src/etc/supervisord.d/sshd-wrapper.conf @@ -1,9 +1,9 @@ [program:sshd-wrapper] -priority = 10 -command = /usr/sbin/sshd-wrapper -autostart = %(ENV_SSH_AUTOSTART_SSHD)s -startsecs = 0 autorestart = true +autostart = %(ENV_SSH_AUTOSTART_SSHD)s +command = /usr/sbin/sshd-wrapper +priority = 10 redirect_stderr = true -stdout_logfile = /var/log/secure -stdout_events_enabled = true \ No newline at end of file +startsecs = 0 +stdout_logfile = /dev/stdout +stdout_logfile_maxbytes = 0 diff --git a/src/etc/systemd/system/centos-ssh@.service b/src/etc/systemd/system/centos-ssh@.service index 1f7c62a..e9eab5a 100644 --- a/src/etc/systemd/system/centos-ssh@.service +++ b/src/etc/systemd/system/centos-ssh@.service @@ -59,6 +59,7 @@ Environment="DOCKER_USER=jdeathe" Environment="SSH_AUTHORIZED_KEYS=" Environment="SSH_AUTOSTART_SSHD=true" Environment="SSH_AUTOSTART_SSHD_BOOTSTRAP=true" +Environment="SSH_AUTOSTART_SUPERVISOR_STDOUT=true" Environment="SSH_CHROOT_DIRECTORY=%%h" Environment="SSH_INHERIT_ENVIRONMENT=false" Environment="SSH_PASSWORD_AUTHENTICATION=false" @@ -131,6 +132,7 @@ ExecStart=/bin/bash -c \ --env \"SSH_AUTHORIZED_KEYS=${SSH_AUTHORIZED_KEYS}\" \ --env \"SSH_AUTOSTART_SSHD=${SSH_AUTOSTART_SSHD}\" \ --env \"SSH_AUTOSTART_SSHD_BOOTSTRAP=${SSH_AUTOSTART_SSHD_BOOTSTRAP}\" \ + --env \"SSH_AUTOSTART_SUPERVISOR_STDOUT=${SSH_AUTOSTART_SUPERVISOR_STDOUT}\" \ --env \"SSH_CHROOT_DIRECTORY=${SSH_CHROOT_DIRECTORY}\" \ --env \"SSH_INHERIT_ENVIRONMENT=${SSH_INHERIT_ENVIRONMENT}\" \ --env \"SSH_PASSWORD_AUTHENTICATION=${SSH_PASSWORD_AUTHENTICATION}\" \ diff --git a/src/opt/scmi/default.sh b/src/opt/scmi/default.sh index b0f216a..652b1ce 100644 --- a/src/opt/scmi/default.sh +++ b/src/opt/scmi/default.sh @@ -49,6 +49,7 @@ DOCKER_CONTAINER_PARAMETERS="--name ${DOCKER_NAME} \ --env \"SSH_AUTHORIZED_KEYS=${SSH_AUTHORIZED_KEYS}\" \ --env \"SSH_AUTOSTART_SSHD=${SSH_AUTOSTART_SSHD}\" \ --env \"SSH_AUTOSTART_SSHD_BOOTSTRAP=${SSH_AUTOSTART_SSHD_BOOTSTRAP}\" \ +--env \"SSH_AUTOSTART_SUPERVISOR_STDOUT=${SSH_AUTOSTART_SUPERVISOR_STDOUT}\" \ --env \"SSH_CHROOT_DIRECTORY=${SSH_CHROOT_DIRECTORY}\" \ --env \"SSH_INHERIT_ENVIRONMENT=${SSH_INHERIT_ENVIRONMENT}\" \ --env \"SSH_PASSWORD_AUTHENTICATION=${SSH_PASSWORD_AUTHENTICATION}\" \ diff --git a/src/opt/scmi/environment.sh b/src/opt/scmi/environment.sh index 2dc69d8..ece728d 100644 --- a/src/opt/scmi/environment.sh +++ b/src/opt/scmi/environment.sh @@ -37,6 +37,7 @@ STARTUP_TIME="${STARTUP_TIME:-2}" SSH_AUTHORIZED_KEYS="${SSH_AUTHORIZED_KEYS:-}" SSH_AUTOSTART_SSHD="${SSH_AUTOSTART_SSHD:-true}" SSH_AUTOSTART_SSHD_BOOTSTRAP="${SSH_AUTOSTART_SSHD_BOOTSTRAP:-true}" +SSH_AUTOSTART_SUPERVISOR_STDOUT="${SSH_AUTOSTART_SUPERVISOR_STDOUT:-true}" SSH_CHROOT_DIRECTORY="${SSH_CHROOT_DIRECTORY:-%h}" SSH_INHERIT_ENVIRONMENT="${SSH_INHERIT_ENVIRONMENT:-false}" SSH_PASSWORD_AUTHENTICATION="${SSH_PASSWORD_AUTHENTICATION:-false}" diff --git a/src/opt/scmi/service-unit.sh b/src/opt/scmi/service-unit.sh index 824857b..6e04daf 100644 --- a/src/opt/scmi/service-unit.sh +++ b/src/opt/scmi/service-unit.sh @@ -9,6 +9,7 @@ readonly SERVICE_UNIT_ENVIRONMENT_KEYS=" SSH_AUTHORIZED_KEYS SSH_AUTOSTART_SSHD SSH_AUTOSTART_SSHD_BOOTSTRAP + SSH_AUTOSTART_SUPERVISOR_STDOUT SSH_CHROOT_DIRECTORY SSH_INHERIT_ENVIRONMENT SSH_PASSWORD_AUTHENTICATION diff --git a/src/usr/bin/healthcheck b/src/usr/bin/healthcheck index f018289..e7881c0 100755 --- a/src/usr/bin/healthcheck +++ b/src/usr/bin/healthcheck @@ -33,7 +33,8 @@ fi if [[ ${SSH_AUTOSTART_SSHD} == true ]] then - if ! ps axo command | grep -qE '^/usr/sbin/sshd -D' + if ! ps axo command | grep -qE '^/usr/sbin/sshd -D' \ + || [[ ! -s /var/run/sshd.pid ]] then >&2 printf -- \ '%s\n' \ diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 8ecc256..629d23c 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -1341,8 +1341,6 @@ then EOT - # Attempt to force output flush - sleep 0.1 fi # Release lock file diff --git a/test/shpec/operation_shpec.sh b/test/shpec/operation_shpec.sh index cc3b5ec..eba6e09 100644 --- a/test/shpec/operation_shpec.sh +++ b/test/shpec/operation_shpec.sh @@ -170,9 +170,7 @@ function test_basic_ssh_operations () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -301,9 +299,7 @@ function test_basic_sftp_operations () sftp.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -427,9 +423,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -508,9 +502,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -556,9 +548,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -619,9 +609,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -681,9 +669,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -759,9 +745,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -844,9 +828,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -929,9 +911,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -988,9 +968,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1049,9 +1027,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1111,9 +1087,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1174,9 +1148,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1237,9 +1209,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1301,9 +1271,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1354,9 +1322,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1426,9 +1392,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1498,9 +1462,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1567,9 +1529,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1630,9 +1590,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1744,9 +1702,7 @@ function test_custom_ssh_configuration () ssh.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1782,6 +1738,52 @@ function test_custom_ssh_configuration () ssh.1 \ &> /dev/null + docker run \ + --detach \ + --name ssh.1 \ + --env "SSH_AUTOSTART_SUPERVISOR_STDOUT=true" \ + --publish ${DOCKER_PORT_MAP_TCP_22}:22 \ + jdeathe/centos-ssh:latest \ + &> /dev/null + + sleep ${STARTUP_TIME} + + it "Can enable supervisor_stdout." + docker top ssh.1 \ + | grep -qE '/usr/bin/python /usr/bin/supervisor_stdout' + + assert equal \ + "${?}" \ + "0" + end + + __terminate_container \ + ssh.1 \ + &> /dev/null + + docker run \ + --detach \ + --name ssh.1 \ + --env "SSH_AUTOSTART_SUPERVISOR_STDOUT=false" \ + --publish ${DOCKER_PORT_MAP_TCP_22}:22 \ + jdeathe/centos-ssh:latest \ + &> /dev/null + + sleep ${STARTUP_TIME} + + it "Can disable supervisor_stdout." + docker top ssh.1 \ + | grep -qE '/usr/bin/python /usr/bin/supervisor_stdout' + + assert equal \ + "${?}" \ + "1" + end + + __terminate_container \ + ssh.1 \ + &> /dev/null + docker run \ --detach \ --name ssh.1 \ @@ -1875,9 +1877,7 @@ function test_custom_sftp_configuration () sftp.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -1960,9 +1960,7 @@ function test_custom_sftp_configuration () sftp.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -2040,9 +2038,7 @@ function test_custom_sftp_configuration () sftp.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi @@ -2129,9 +2125,7 @@ function test_custom_sftp_configuration () sftp.1 \ ${STARTUP_TIME} \ "/usr/sbin/sshd " \ - "grep \ - '^Server listening on 0\.0\.0\.0 port 22\.' \ - /var/log/secure" + "[[ -s /var/run/sshd.pid ]]" then exit 1 fi From 1a805e6ce2c1a32e64df81cde87bc0240c1ef744 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Mon, 25 Feb 2019 20:48:31 +0000 Subject: [PATCH 14/35] #743: Adds improved sshd-wrapper script. --- CHANGELOG.md | 1 + src/usr/sbin/sshd-wrapper | 82 +++++++++++++++++++++++++++++---------- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6157cf..55fc316 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Summary of release changes for Version 2 - CentOS-7 - Adds docker-compose configuration example. - Adds `SSH_AUTOSTART_SUPERVISOR_STDOUT` to control startup of `supervisor_stdout`. - Adds drop-in configuration for `supervisor_stdout` in `/etc/supervisord.d/00-supervisor_stdout.conf`. +- Adds improved sshd-wrapper script. - Removes reference to `python-setuptools` from README as it's no longer installed. - Removes requirement of `supervisor_stdout` for output of supervisord logs to stdout. diff --git a/src/usr/sbin/sshd-wrapper b/src/usr/sbin/sshd-wrapper index e723409..f128f8f 100755 --- a/src/usr/sbin/sshd-wrapper +++ b/src/usr/sbin/sshd-wrapper @@ -1,22 +1,64 @@ #!/usr/bin/env bash -readonly BIN="/usr/sbin/sshd" -readonly LOCK_FILE="/var/lock/subsys/sshd-bootstrap" -readonly NICE="/bin/nice" -readonly NICENESS="10" -readonly OPTIONS=" - -D - -e - -u 0 -" - -while true -do - sleep 0.1 - [[ -e ${LOCK_FILE} ]] || break -done - -exec ${NICE} \ - -n ${NICENESS} \ - ${BIN} \ - ${OPTIONS} +set -e + +function __is_valid_ssh_autostart_sshd_bootstrap () +{ + local -r boolean_value='^(true|false)$' + local -r value="${1}" + + if [[ ${value} =~ ${boolean_value} ]] + then + return 0 + fi + + return 1 +} + +function __get_ssh_autostart_sshd_bootstrap () +{ + local -r default_value="${1:-true}" + + local value="${SSH_AUTOSTART_SSHD_BOOTSTRAP}" + + if ! __is_valid_ssh_autostart_sshd_bootstrap "${value}" + then + value="${default_value}" + fi + + printf -- '%s' "${value}" +} + +function main () +{ + local -r autostart_bootstrap="$( + __get_ssh_autostart_sshd_bootstrap + )" + local -r bin="/usr/sbin/sshd" + local -r lock_file="/var/lock/subsys/sshd-bootstrap" + local -r nice="/bin/nice" + local -r niceness="10" + local -r options="-D -e -u 0" + + if [[ ${autostart_bootstrap} == false ]] + then + # block. + sleep infinity + fi + + while true + do + sleep 0.1 + if [[ ! -e ${lock_file} ]] + then + break + fi + done + + exec ${nice} \ + -n ${niceness} \ + ${bin} \ + ${options} +} + +main "${@}" From 6e7fb92c8ee8dd3dc2c28517792d8bebe726ba07 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Mon, 25 Feb 2019 22:05:04 +0000 Subject: [PATCH 15/35] #743: Adds main function to bootstrap script. --- src/usr/sbin/sshd-bootstrap | 777 ++++++++++++++++++------------------ 1 file changed, 390 insertions(+), 387 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 629d23c..f7fb2e3 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -1,22 +1,5 @@ #!/usr/bin/env bash -readonly ENV_EXCLUDE_PATTERN="^([.]*SSH_USER_PASSWORD|_|HOME|HOSTNAME|PATH|PWD|SHLVL|SUPERVISOR_ENABLED|SUPERVISOR_GROUP_NAME|SUPERVISOR_PROCESS_NAME|TERM)=" -readonly LOCK_FILE="/var/lock/subsys/sshd-bootstrap" -readonly PASSWORD_LENGTH=16 -readonly REDACTED_VALUE="********" -readonly TIMER_START="$( - date +%s.%N -)" - -# Create lock file -touch \ - "${LOCK_FILE}" - -# Populate the environment source file -env >> /etc/sshd-bootstrap.env - -source /etc/sshd-bootstrap.conf - function is_sudo_no_password_all () { local -r sudo="${1}" @@ -921,430 +904,450 @@ function set_ssh_user_password () fi } -# Docker ENV inheritance -if [[ ${SSH_INHERIT_ENVIRONMENT} == true ]] \ - && [[ -s /etc/sshd-bootstrap.env ]] -then - grep -Ev "${ENV_EXCLUDE_PATTERN}" \ - /etc/sshd-bootstrap.env \ - > /etc/environment -fi - -OPTS_SSH_USER_HOME="$( - get_ssh_user_home -)" - -if [[ ! -d ${OPTS_SSH_USER_HOME}/.ssh ]] -then - declare -A ENV_VALIDATION_WITH_DEFAULTS=( - [SSH_CHROOT_DIRECTORY]=is_valid_ssh_chroot_directory - [SSH_PASSWORD_AUTHENTICATION]=is_valid_ssh_password_authentication - [SSH_SUDO]=is_valid_ssh_sudo - [SSH_TIMEZONE]=is_valid_ssh_timezone - [SSH_USER]=is_valid_ssh_user - [SSH_USER_FORCE_SFTP]=is_valid_ssh_user_force_sftp - [SSH_USER_HOME]=is_valid_ssh_user_home - [SSH_USER_PASSWORD_HASHED]=is_valid_ssh_user_password_hashed - [SSH_USER_ID]=is_valid_ssh_user_id - [SSH_USER_SHELL]=is_valid_ssh_user_shell - ) - OPTS_SSH_AUTHORIZED_KEYS="$( - get_ssh_authorized_keys - )" - OPTS_SSH_PASSWORD_AUTHENTICATION="$( - get_ssh_password_authentication - )" - OPTS_SSH_SUDO="$( - get_ssh_sudo - )" - OPTS_SSH_TIMEZONE="$( - get_ssh_timezone - )" - OPTS_SSH_USER="$( - get_ssh_user - )" - OPTS_SSH_USER_FORCE_SFTP="$( - get_ssh_user_force_sftp - )" - OPTS_SSH_USER_PASSWORD_HASHED="$( - get_ssh_user_password_hashed - )" - OPTS_SSH_USER_PASSWORD="${SSH_USER_PASSWORD:-"$( - get_password "${PASSWORD_LENGTH}" - )"}" - OPTS_SSH_USER_PRIVATE_KEY="$( - get_ssh_user_private_key - )" - OPTS_SSH_USER_SHELL="$( - get_ssh_user_shell - )" - OPTS_SSH_USER_UID="$( - get_ssh_user_uid +function main () +{ + readonly ENV_EXCLUDE_PATTERN="^([.]*SSH_USER_PASSWORD|_|HOME|HOSTNAME|PATH|PWD|SHLVL|SUPERVISOR_ENABLED|SUPERVISOR_GROUP_NAME|SUPERVISOR_PROCESS_NAME|TERM)=" + readonly LOCK_FILE="/var/lock/subsys/sshd-bootstrap" + readonly PASSWORD_LENGTH=16 + readonly REDACTED_VALUE="********" + readonly TIMER_START="$( + date +%s.%N )" - OPTS_SSH_USER_GID="$( - get_ssh_user_gid + + # Create lock file + touch \ + "${LOCK_FILE}" + + # Populate the environment source file + env >> /etc/sshd-bootstrap.env + + source /etc/sshd-bootstrap.conf + + # Docker ENV inheritance + if [[ ${SSH_INHERIT_ENVIRONMENT} == true ]] \ + && [[ -s /etc/sshd-bootstrap.env ]] + then + grep -Ev "${ENV_EXCLUDE_PATTERN}" \ + /etc/sshd-bootstrap.env \ + > /etc/environment + fi + + OPTS_SSH_USER_HOME="$( + get_ssh_user_home )" - PASSWORD_AUTHENTICATION="no" - if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] + if [[ ! -d ${OPTS_SSH_USER_HOME}/.ssh ]] then - PASSWORD_AUTHENTICATION="yes" - if [[ ${OPTS_SSH_USER} == root ]] + declare -A ENV_VALIDATION_WITH_DEFAULTS=( + [SSH_CHROOT_DIRECTORY]=is_valid_ssh_chroot_directory + [SSH_PASSWORD_AUTHENTICATION]=is_valid_ssh_password_authentication + [SSH_SUDO]=is_valid_ssh_sudo + [SSH_TIMEZONE]=is_valid_ssh_timezone + [SSH_USER]=is_valid_ssh_user + [SSH_USER_FORCE_SFTP]=is_valid_ssh_user_force_sftp + [SSH_USER_HOME]=is_valid_ssh_user_home + [SSH_USER_PASSWORD_HASHED]=is_valid_ssh_user_password_hashed + [SSH_USER_ID]=is_valid_ssh_user_id + [SSH_USER_SHELL]=is_valid_ssh_user_shell + ) + OPTS_SSH_AUTHORIZED_KEYS="$( + get_ssh_authorized_keys + )" + OPTS_SSH_PASSWORD_AUTHENTICATION="$( + get_ssh_password_authentication + )" + OPTS_SSH_SUDO="$( + get_ssh_sudo + )" + OPTS_SSH_TIMEZONE="$( + get_ssh_timezone + )" + OPTS_SSH_USER="$( + get_ssh_user + )" + OPTS_SSH_USER_FORCE_SFTP="$( + get_ssh_user_force_sftp + )" + OPTS_SSH_USER_PASSWORD_HASHED="$( + get_ssh_user_password_hashed + )" + OPTS_SSH_USER_PASSWORD="${SSH_USER_PASSWORD:-"$( + get_password "${PASSWORD_LENGTH}" + )"}" + OPTS_SSH_USER_PRIVATE_KEY="$( + get_ssh_user_private_key + )" + OPTS_SSH_USER_SHELL="$( + get_ssh_user_shell + )" + OPTS_SSH_USER_UID="$( + get_ssh_user_uid + )" + OPTS_SSH_USER_GID="$( + get_ssh_user_gid + )" + + PASSWORD_AUTHENTICATION="no" + if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] + then + PASSWORD_AUTHENTICATION="yes" + if [[ ${OPTS_SSH_USER} == root ]] + then + sed -i \ + -e 's~^\(PasswordAuthentication \)no$~\1yes~g' \ + -e 's~^\(PermitRootLogin \)no$~\1yes~g' \ + /etc/ssh/sshd_config + else + sed -i \ + -e 's~^\(PasswordAuthentication \)no$~\1yes~g' \ + /etc/ssh/sshd_config + fi + elif [[ ${OPTS_SSH_USER} == root ]] then sed -i \ - -e 's~^\(PasswordAuthentication \)no$~\1yes~g' \ - -e 's~^\(PermitRootLogin \)no$~\1yes~g' \ + -e 's~^\(PermitRootLogin \)no$~\1without-password~g' \ /etc/ssh/sshd_config + fi + + if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + then + SSHD_COMMAND="SFTP" + SSH_USER_GROUPS="users" + OPTS_SSH_CHROOT_DIRECTORY="$( + get_ssh_chroot_directory %h + )" else - sed -i \ - -e 's~^\(PasswordAuthentication \)no$~\1yes~g' \ - /etc/ssh/sshd_config + SSHD_COMMAND="SSH" fi - elif [[ ${OPTS_SSH_USER} == root ]] - then - sed -i \ - -e 's~^\(PermitRootLogin \)no$~\1without-password~g' \ - /etc/ssh/sshd_config - fi - if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] - then - SSHD_COMMAND="SFTP" - SSH_USER_GROUPS="users" - OPTS_SSH_CHROOT_DIRECTORY="$( - get_ssh_chroot_directory %h - )" - else - SSHD_COMMAND="SSH" - fi + # Initialise + printf -- \ + 'Initialising %s.\n' \ + "${SSHD_COMMAND}" - # Initialise - printf -- \ - 'Initialising %s.\n' \ - "${SSHD_COMMAND}" + # Warn operator if any supplied environment variable values failed + # validation and have been set to a safe default. + for ENV in "${!ENV_VALIDATION_WITH_DEFAULTS[@]}" + do + if ! ${ENV_VALIDATION_WITH_DEFAULTS[${ENV}]} "${!ENV}" + then + printf -- \ + 'WARNING: Validation failed on %s - setting to default.\n' \ + "${ENV}" + fi + done - # Warn operator if any supplied environment variable values failed - # validation and have been set to a safe default. - for ENV in "${!ENV_VALIDATION_WITH_DEFAULTS[@]}" - do - if ! ${ENV_VALIDATION_WITH_DEFAULTS[${ENV}]} "${!ENV}" + if ! set_ssh_timezone "${OPTS_SSH_TIMEZONE}" then printf -- \ - 'WARNING: Validation failed on %s - setting to default.\n' \ - "${ENV}" + 'ERROR: Could not set timezone - aborting.\n' \ + >&2 + sleep 0.1 + + exit 1 fi - done - if ! set_ssh_timezone "${OPTS_SSH_TIMEZONE}" - then - printf -- \ - 'ERROR: Could not set timezone - aborting.\n' \ - >&2 - sleep 0.1 + $( + generate_ssh_host_keys + ) & + PIDS[0]="${!}" - exit 1 - fi + if [[ ${OPTS_SSH_USER} == root ]] + then + chsh \ + -s "${OPTS_SSH_USER_SHELL}" \ + "${OPTS_SSH_USER}" \ + &> /dev/null + else + # Create base directory for home + if [[ -n ${OPTS_SSH_USER_HOME%/*} ]] \ + && [[ ! -d ${OPTS_SSH_USER_HOME%/*} ]] + then + printf -- \ + 'Creating home base directory.\n' - $( - generate_ssh_host_keys - ) & - PIDS[0]="${!}" + mkdir -pm 755 \ + "${OPTS_SSH_USER_HOME%/*}" + fi - if [[ ${OPTS_SSH_USER} == root ]] - then - chsh \ - -s "${OPTS_SSH_USER_SHELL}" \ - "${OPTS_SSH_USER}" \ - &> /dev/null - else - # Create base directory for home - if [[ -n ${OPTS_SSH_USER_HOME%/*} ]] \ - && [[ ! -d ${OPTS_SSH_USER_HOME%/*} ]] + groupadd \ + -f \ + -g "${OPTS_SSH_USER_GID}" \ + "${OPTS_SSH_USER}" + + useradd \ + -u "${OPTS_SSH_USER_UID}" \ + -g "${OPTS_SSH_USER_GID}" \ + -m \ + -G "${SSH_USER_GROUPS:-users,wheel}" \ + -d "${OPTS_SSH_USER_HOME}" \ + -s "${OPTS_SSH_USER_SHELL}" \ + "${OPTS_SSH_USER}" + + # Set root user password + $( + printf -- \ + '%s:%s\n' \ + "root" \ + "$( + get_password "${PASSWORD_LENGTH}" + )" \ + | chpasswd + ) & + PIDS[1]="${!}" + fi + + if ! set_ssh_user_password "${OPTS_SSH_USER_PASSWORD}" then printf -- \ - 'Creating home base directory.\n' + 'ERROR: Could not set password - aborting.\n' \ + >&2 + sleep 0.1 - mkdir -pm 755 \ - "${OPTS_SSH_USER_HOME%/*}" + exit 1 fi - groupadd \ - -f \ - -g "${OPTS_SSH_USER_GID}" \ - "${OPTS_SSH_USER}" - - useradd \ - -u "${OPTS_SSH_USER_UID}" \ - -g "${OPTS_SSH_USER_GID}" \ - -m \ - -G "${SSH_USER_GROUPS:-users,wheel}" \ - -d "${OPTS_SSH_USER_HOME}" \ - -s "${OPTS_SSH_USER_SHELL}" \ - "${OPTS_SSH_USER}" - - # Set root user password - $( - printf -- \ - '%s:%s\n' \ - "root" \ - "$( - get_password "${PASSWORD_LENGTH}" - )" \ - | chpasswd - ) & - PIDS[1]="${!}" - fi + # SFTP users + if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + then + # Get the ChrootDirectory path. + # %h and %u are replaced with the User's HOME and USERNAME respectively. + SSH_CHROOT_DIRECTORY_PATH="$( + get_ssh_chroot_directory_path "${OPTS_SSH_CHROOT_DIRECTORY}" + )" - if ! set_ssh_user_password "${OPTS_SSH_USER_PASSWORD}" - then - printf -- \ - 'ERROR: Could not set password - aborting.\n' \ - >&2 - sleep 0.1 + if [[ ! -d ${SSH_CHROOT_DIRECTORY_PATH} ]] \ + || [[ ${SSH_CHROOT_DIRECTORY_PATH} != "${OPTS_SSH_USER_HOME}" ]] + then + # ChrootDirectory like /chroot/%u or /home/chroot/%u + printf -v SSH_CHROOT_HOME_DIRECTORY_PATH \ + -- \ + '%s%s' \ + "${SSH_CHROOT_DIRECTORY_PATH}" \ + "${OPTS_SSH_USER_HOME}" + + mkdir -pm 711 \ + "${SSH_CHROOT_DIRECTORY_PATH}" + mkdir -pm 755 \ + "${SSH_CHROOT_HOME_DIRECTORY_PATH}" + else + # ChrootDirectory %h + SSH_CHROOT_HOME_DIRECTORY_PATH="${OPTS_SSH_USER_HOME}" - exit 1 - fi + chmod 750 \ + "${OPTS_SSH_USER_HOME}" + fi - # SFTP users - if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] - then - # Get the ChrootDirectory path. - # %h and %u are replaced with the User's HOME and USERNAME respectively. - SSH_CHROOT_DIRECTORY_PATH="$( - get_ssh_chroot_directory_path "${OPTS_SSH_CHROOT_DIRECTORY}" - )" + # Create a user writeable data directory if no other directories are + # mounted. + if ! grep -q '^d' <<< "$( + ls -l "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/ + )" + then + # Make and set user permissions on new _data directory + mkdir -m 700 \ + "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data + chown -R \ + "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ + "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data + elif [[ -d ${SSH_CHROOT_HOME_DIRECTORY_PATH}/_data ]] + then + # Set user permissions on _data directory in case where it exists + chmod 700 \ + "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data + chown -R \ + "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ + "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data + fi + + # ChrootDirectory must be owned by root user + if [[ ${SSH_CHROOT_DIRECTORY_PATH} != "${OPTS_SSH_USER_HOME}" ]] + then + chown \ + root:root \ + "${SSH_CHROOT_DIRECTORY_PATH}" + chmod 711 \ + "${SSH_CHROOT_DIRECTORY_PATH}" + else + chown \ + root:"${OPTS_SSH_USER}" \ + "${SSH_CHROOT_DIRECTORY_PATH}" + fi + + # Add group specific sshd configuration + tee -a /etc/ssh/sshd_config > /dev/null <<-EOT + # Force SFTP + Match User ${SSH_USER} + AllowTcpForwarding no + X11Forwarding no + ChrootDirectory ${OPTS_SSH_CHROOT_DIRECTORY} + ForceCommand internal-sftp + EOT + else + sed -i \ + -e '/# Force SFTP/,/ForceCommand internal-sftp/ { d; }' \ + /etc/ssh/sshd_config + fi + + # SSH require files + mkdir -m 700 \ + "${OPTS_SSH_USER_HOME}"/.ssh + touch \ + "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys + chown -R \ + "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ + "${OPTS_SSH_USER_HOME}"/.ssh + chmod 600 \ + "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys - if [[ ! -d ${SSH_CHROOT_DIRECTORY_PATH} ]] \ - || [[ ${SSH_CHROOT_DIRECTORY_PATH} != "${OPTS_SSH_USER_HOME}" ]] + # Details output for SSH public key fingerprints + if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] \ + && [[ -z ${SSH_AUTHORIZED_KEYS} ]] then - # ChrootDirectory like /chroot/%u or /home/chroot/%u - printf -v SSH_CHROOT_HOME_DIRECTORY_PATH \ + SSH_KEY_FINGERPRINTS="N/A" + elif ! is_valid_ssh_authorized_keys "${OPTS_SSH_AUTHORIZED_KEYS}" + then + printf -v SSH_KEY_FINGERPRINTS \ -- \ - '%s%s' \ - "${SSH_CHROOT_DIRECTORY_PATH}" \ + '%s\nUnable to populate %s/.ssh/authorized_key' \ + "ERROR: Public key validation failed." \ "${OPTS_SSH_USER_HOME}" - - mkdir -pm 711 \ - "${SSH_CHROOT_DIRECTORY_PATH}" - mkdir -pm 755 \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}" else - # ChrootDirectory %h - SSH_CHROOT_HOME_DIRECTORY_PATH="${OPTS_SSH_USER_HOME}" + printf -- \ + '%s\n' \ + "${OPTS_SSH_AUTHORIZED_KEYS}" \ + > "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys - chmod 750 \ - "${OPTS_SSH_USER_HOME}" + SSH_KEY_FINGERPRINTS="$( + get_ssh_authorized_key_fingerprints + )" fi - # Create a user writeable data directory if no other directories are - # mounted. - if ! grep -q '^d' <<< "$( - ls -l "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/ - )" + # Details output for SSH private key fingerprint + if [[ -z ${OPTS_SSH_USER_PRIVATE_KEY} ]] \ + || [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] then - # Make and set user permissions on new _data directory - mkdir -m 700 \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data - chown -R \ - "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data - elif [[ -d ${SSH_CHROOT_HOME_DIRECTORY_PATH}/_data ]] + SSH_USER_PRIVATE_KEY_FINGERPRINT="N/A" + elif ! is_valid_ssh_key "${OPTS_SSH_USER_PRIVATE_KEY}" then - # Set user permissions on _data directory in case where it exists - chmod 700 \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data - chown -R \ + printf -v SSH_USER_PRIVATE_KEY_FINGERPRINT \ + -- \ + '%s\nUnable to populate %s/.ssh/id_rsa' \ + "ERROR: Private key validation failed." \ + "${OPTS_SSH_USER_HOME}" + else + printf -- \ + '%s\n' \ + "${OPTS_SSH_USER_PRIVATE_KEY}" \ + > "${OPTS_SSH_USER_HOME}"/.ssh/id_rsa + + chown \ "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data + "${OPTS_SSH_USER_HOME}"/.ssh/id_rsa + chmod 600 \ + ${OPTS_SSH_USER_HOME}/.ssh/id_rsa + + SSH_USER_PRIVATE_KEY_FINGERPRINT="$( + get_ssh_key_fingerprint_hash_output \ + "${OPTS_SSH_USER_PRIVATE_KEY}" + )" fi - # ChrootDirectory must be owned by root user - if [[ ${SSH_CHROOT_DIRECTORY_PATH} != "${OPTS_SSH_USER_HOME}" ]] + # Set sudo access for the wheel group only + if [[ ${DEFAULT_SSH_SUDO} != "${OPTS_SSH_SUDO}" ]] then - chown \ - root:root \ - "${SSH_CHROOT_DIRECTORY_PATH}" - chmod 711 \ - "${SSH_CHROOT_DIRECTORY_PATH}" - else - chown \ - root:"${OPTS_SSH_USER}" \ - "${SSH_CHROOT_DIRECTORY_PATH}" + sed -i \ + -e "s~^%wheel\\t.*$~%wheel\\t${OPTS_SSH_SUDO}~g" \ + /etc/sudoers fi - # Add group specific sshd configuration - tee -a /etc/ssh/sshd_config > /dev/null <<-EOT - # Force SFTP - Match User ${SSH_USER} - AllowTcpForwarding no - X11Forwarding no - ChrootDirectory ${OPTS_SSH_CHROOT_DIRECTORY} - ForceCommand internal-sftp - EOT - else - sed -i \ - -e '/# Force SFTP/,/ForceCommand internal-sftp/ { d; }' \ - /etc/ssh/sshd_config - fi + tee -a /etc/sudoers > /dev/null <<-EOT - # SSH require files - mkdir -m 700 \ - "${OPTS_SSH_USER_HOME}"/.ssh - touch \ - "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys - chown -R \ - "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ - "${OPTS_SSH_USER_HOME}"/.ssh - chmod 600 \ - "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys - - # Details output for SSH public key fingerprints - if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] \ - && [[ -z ${SSH_AUTHORIZED_KEYS} ]] - then - SSH_KEY_FINGERPRINTS="N/A" - elif ! is_valid_ssh_authorized_keys "${OPTS_SSH_AUTHORIZED_KEYS}" - then - printf -v SSH_KEY_FINGERPRINTS \ - -- \ - '%s\nUnable to populate %s/.ssh/authorized_key' \ - "ERROR: Public key validation failed." \ - "${OPTS_SSH_USER_HOME}" - else - printf -- \ - '%s\n' \ - "${OPTS_SSH_AUTHORIZED_KEYS}" \ - > "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys - - SSH_KEY_FINGERPRINTS="$( - get_ssh_authorized_key_fingerprints - )" - fi - - # Details output for SSH private key fingerprint - if [[ -z ${OPTS_SSH_USER_PRIVATE_KEY} ]] \ - || [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] - then - SSH_USER_PRIVATE_KEY_FINGERPRINT="N/A" - elif ! is_valid_ssh_key "${OPTS_SSH_USER_PRIVATE_KEY}" - then - printf -v SSH_USER_PRIVATE_KEY_FINGERPRINT \ - -- \ - '%s\nUnable to populate %s/.ssh/id_rsa' \ - "ERROR: Private key validation failed." \ - "${OPTS_SSH_USER_HOME}" - else - printf -- \ - '%s\n' \ - "${OPTS_SSH_USER_PRIVATE_KEY}" \ - > "${OPTS_SSH_USER_HOME}"/.ssh/id_rsa + # ${OPTS_SSH_USER} + Defaults:root secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin + EOT - chown \ - "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ - "${OPTS_SSH_USER_HOME}"/.ssh/id_rsa - chmod 600 \ - ${OPTS_SSH_USER_HOME}/.ssh/id_rsa + # Wait for background processes - Host key generation + wait ${PIDS[0]} - SSH_USER_PRIVATE_KEY_FINGERPRINT="$( - get_ssh_key_fingerprint_hash_output \ - "${OPTS_SSH_USER_PRIVATE_KEY}" + SSH_HOST_KEY_FINGERPRINT_RSA="$( + get_ssh_host_key_fingerprint rsa )" - fi - - # Set sudo access for the wheel group only - if [[ ${DEFAULT_SSH_SUDO} != "${OPTS_SSH_SUDO}" ]] - then - sed -i \ - -e "s~^%wheel\\t.*$~%wheel\\t${OPTS_SSH_SUDO}~g" \ - /etc/sudoers - fi - tee -a /etc/sudoers > /dev/null <<-EOT + # Wait for background processes - Set password for root user + if [[ -n ${PIDS[1]+isset} ]] + then + wait ${PIDS[1]} + fi - # ${OPTS_SSH_USER} - Defaults:root secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin - EOT + # Only show user password if auto-generated and password is required for + # password authentication or sudo. + if [[ -n ${SSH_USER_PASSWORD} ]] + then + OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" + elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ + && [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + then + OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" + elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ + && [[ ${OPTS_SSH_USER} != root ]] \ + && is_sudo_no_password_all "${OPTS_SSH_SUDO}" + then + OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" + elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ + && [[ ${OPTS_SSH_USER} == root ]] + then + OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" + fi - # Wait for background processes - Host key generation - wait ${PIDS[0]} + if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + then + OPTS_SSH_SUDO="N/A" + else + SSH_CHROOT_DIRECTORY_PATH="N/A" + fi - SSH_HOST_KEY_FINGERPRINT_RSA="$( - get_ssh_host_key_fingerprint rsa - )" + TIMER_TOTAL="$( + awk \ + -v timer_end="$( + date +%s.%N + )" \ + -v timer_start="${TIMER_START}" \ + 'BEGIN { print \ + timer_end - timer_start; + }' + )" - # Wait for background processes - Set password for root user - if [[ -n ${PIDS[1]+isset} ]] - then - wait ${PIDS[1]} - fi + cat <<-EOT + + ================================================================================ + ${SSHD_COMMAND} Details + -------------------------------------------------------------------------------- + user : ${OPTS_SSH_USER} + password : ${OPTS_SSH_USER_PASSWORD} + password authentication : ${PASSWORD_AUTHENTICATION} + id : ${OPTS_SSH_USER_UID}:${OPTS_SSH_USER_GID} + home : ${OPTS_SSH_USER_HOME} + chroot path : ${SSH_CHROOT_DIRECTORY_PATH} + shell : ${OPTS_SSH_USER_SHELL} + sudo : ${OPTS_SSH_SUDO} + key fingerprints : + ${SSH_KEY_FINGERPRINTS} + rsa private key fingerprint : + ${SSH_USER_PRIVATE_KEY_FINGERPRINT} + rsa host key fingerprint : + ${SSH_HOST_KEY_FINGERPRINT_RSA} + timezone : ${OPTS_SSH_TIMEZONE} + -------------------------------------------------------------------------------- + ${TIMER_TOTAL} - # Only show user password if auto-generated and password is required for - # password authentication or sudo. - if [[ -n ${SSH_USER_PASSWORD} ]] - then - OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" - elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ - && [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] - then - OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" - elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ - && [[ ${OPTS_SSH_USER} != root ]] \ - && is_sudo_no_password_all "${OPTS_SSH_SUDO}" - then - OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" - elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ - && [[ ${OPTS_SSH_USER} == root ]] - then - OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" - fi + EOT - if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] - then - OPTS_SSH_SUDO="N/A" - else - SSH_CHROOT_DIRECTORY_PATH="N/A" fi - TIMER_TOTAL="$( - awk \ - -v timer_end="$( - date +%s.%N - )" \ - -v timer_start="${TIMER_START}" \ - 'BEGIN { print \ - timer_end - timer_start; - }' - )" + # Release lock file + rm -f \ + "${LOCK_FILE}" +} - cat <<-EOT - - ================================================================================ - ${SSHD_COMMAND} Details - -------------------------------------------------------------------------------- - user : ${OPTS_SSH_USER} - password : ${OPTS_SSH_USER_PASSWORD} - password authentication : ${PASSWORD_AUTHENTICATION} - id : ${OPTS_SSH_USER_UID}:${OPTS_SSH_USER_GID} - home : ${OPTS_SSH_USER_HOME} - chroot path : ${SSH_CHROOT_DIRECTORY_PATH} - shell : ${OPTS_SSH_USER_SHELL} - sudo : ${OPTS_SSH_SUDO} - key fingerprints : - ${SSH_KEY_FINGERPRINTS} - rsa private key fingerprint : - ${SSH_USER_PRIVATE_KEY_FINGERPRINT} - rsa host key fingerprint : - ${SSH_HOST_KEY_FINGERPRINT_RSA} - timezone : ${OPTS_SSH_TIMEZONE} - -------------------------------------------------------------------------------- - ${TIMER_TOTAL} - - EOT - -fi - -# Release lock file -rm -f \ - "${LOCK_FILE}" - -exit 0 +main "${@}" From f2ee0f7a32bae556312e5f078b0ca641626e6cff Mon Sep 17 00:00:00 2001 From: James Deathe Date: Mon, 25 Feb 2019 22:30:29 +0000 Subject: [PATCH 16/35] 743: Removes unnecessary configuration file and imporoves healthcheck script. --- CHANGELOG.md | 3 +- Dockerfile | 2 +- src/etc/sshd-bootstrap.conf | 14 ------ src/usr/bin/healthcheck | 92 +++++++++++++++++++++++++------------ src/usr/sbin/sshd-bootstrap | 2 - 5 files changed, 65 insertions(+), 48 deletions(-) delete mode 100644 src/etc/sshd-bootstrap.conf diff --git a/CHANGELOG.md b/CHANGELOG.md index 55fc316..59ada91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,9 +15,10 @@ Summary of release changes for Version 2 - CentOS-7 - Adds docker-compose configuration example. - Adds `SSH_AUTOSTART_SUPERVISOR_STDOUT` to control startup of `supervisor_stdout`. - Adds drop-in configuration for `supervisor_stdout` in `/etc/supervisord.d/00-supervisor_stdout.conf`. -- Adds improved sshd-wrapper script. +- Adds improved healtchcheck, sshd-wrapper script. - Removes reference to `python-setuptools` from README as it's no longer installed. - Removes requirement of `supervisor_stdout` for output of supervisord logs to stdout. +- Removes unnecessary configuration file `/etc/sshd-bootstrap.conf`. ### 2.5.0 - 2019-01-28 diff --git a/Dockerfile b/Dockerfile index 6287c81..5122e3c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -81,7 +81,7 @@ RUN ln -sf \ -e "s~{{RELEASE_VERSION}}~${RELEASE_VERSION}~g" \ /etc/systemd/system/centos-ssh@.service \ && chmod 644 \ - /etc/{sshd-bootstrap.{conf,env},supervisord.conf,supervisord.d/sshd-{bootstrap,wrapper}.conf} \ + /etc/{sshd-bootstrap.env,supervisord.conf,supervisord.d/sshd-{bootstrap,wrapper}.conf} \ && chmod 700 \ /usr/{bin/healthcheck,sbin/{scmi,sshd-{bootstrap,wrapper}}} diff --git a/src/etc/sshd-bootstrap.conf b/src/etc/sshd-bootstrap.conf deleted file mode 100644 index a4333dd..0000000 --- a/src/etc/sshd-bootstrap.conf +++ /dev/null @@ -1,14 +0,0 @@ -SSH_AUTHORIZED_KEYS="${SSH_AUTHORIZED_KEYS:-}" -SSH_CHROOT_DIRECTORY="${SSH_CHROOT_DIRECTORY:-%h}" -SSH_INHERIT_ENVIRONMENT="${SSH_INHERIT_ENVIRONMENT:-false}" -SSH_PASSWORD_AUTHENTICATION="${SSH_PASSWORD_AUTHENTICATION:-false}" -SSH_SUDO="${SSH_SUDO:-ALL=(ALL) ALL}" -SSH_TIMEZONE="${SSH_TIMEZONE:-UTC}" -SSH_USER="${SSH_USER:-app-admin}" -SSH_USER_FORCE_SFTP="${SSH_USER_FORCE_SFTP:-false}" -SSH_USER_HOME="${SSH_USER_HOME:-/home/%u}" -SSH_USER_ID="${SSH_USER_ID:-500:500}" -SSH_USER_PASSWORD="${SSH_USER_PASSWORD:-}" -SSH_USER_PASSWORD_HASHED="${SSH_USER_PASSWORD_HASHED:-false}" -SSH_USER_PRIVATE_KEY="${SSH_USER_PRIVATE_KEY:-}" -SSH_USER_SHELL="${SSH_USER_SHELL:-/bin/bash}" diff --git a/src/usr/bin/healthcheck b/src/usr/bin/healthcheck index e7881c0..99f164f 100755 --- a/src/usr/bin/healthcheck +++ b/src/usr/bin/healthcheck @@ -2,45 +2,77 @@ set -e -source /etc/sshd-bootstrap.conf - -if ! ps axo command | grep -qE '^/usr/bin/python /usr/bin/supervisord' -then - >&2 printf -- \ - '%s\n' \ - "supervisord not running." - exit 1 -fi - -if [[ ${SSH_AUTOSTART_SSHD_BOOTSTRAP} == true ]] -then - if [[ -e /var/lock/subsys/sshd-bootstrap ]] +function __is_valid_ssh_user () +{ + local -r safe_user='^[a-z_][a-z0-9_-]{0,29}[$a-z0-9_]?$' + local -r user="${1}" + + if [[ ${user} =~ ${safe_user} ]] then - >&2 printf -- \ - '%s\n' \ - "sshd-bootstrap in progress." - exit 1 + return 0 fi - if ! grep -qE "^# ${SSH_USER}" /etc/sudoers + return 1 +} + +function __get_ssh_user () +{ + local -r default_value="${1:-app-admin}" + + local value="${SSH_USER}" + + if ! __is_valid_ssh_user "${value}" then - >&2 printf -- \ - '%s\n' \ - "sshd-bootstrap incomplete." - exit 1 + value="${default_value}" fi -fi -if [[ ${SSH_AUTOSTART_SSHD} == true ]] -then - if ! ps axo command | grep -qE '^/usr/sbin/sshd -D' \ - || [[ ! -s /var/run/sshd.pid ]] + printf -- '%s' "${value}" +} + +function main () +{ + local -r user="$( + __get_ssh_user + )" + + if ! ps axo command | grep -qE '^/usr/bin/python /usr/bin/supervisord' then >&2 printf -- \ '%s\n' \ - "sshd not running." + "supervisord not running." exit 1 fi -fi -exit 0 + if [[ ${SSH_AUTOSTART_SSHD_BOOTSTRAP} == true ]] + then + if [[ -e /var/lock/subsys/sshd-bootstrap ]] + then + >&2 printf -- \ + '%s\n' \ + "sshd-bootstrap in progress." + exit 1 + fi + + if ! grep -qE "^# ${user}" /etc/sudoers + then + >&2 printf -- \ + '%s\n' \ + "sshd-bootstrap incomplete." + exit 1 + fi + fi + + if [[ ${SSH_AUTOSTART_SSHD} == true ]] + then + if ! ps axo command | grep -qE '^/usr/sbin/sshd -D' \ + || [[ ! -s /var/run/sshd.pid ]] + then + >&2 printf -- \ + '%s\n' \ + "sshd not running." + exit 1 + fi + fi +} + +main "${@}" diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index f7fb2e3..54520d2 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -921,8 +921,6 @@ function main () # Populate the environment source file env >> /etc/sshd-bootstrap.env - source /etc/sshd-bootstrap.conf - # Docker ENV inheritance if [[ ${SSH_INHERIT_ENVIRONMENT} == true ]] \ && [[ -s /etc/sshd-bootstrap.env ]] From ff260585a308c82439d0cff8f049ef0276410502 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Mon, 25 Feb 2019 22:52:06 +0000 Subject: [PATCH 17/35] #743: Normalise setting of empty string value if variable is unset. --- src/usr/sbin/scmi | 26 +++++++++++++------------- src/usr/sbin/sshd-bootstrap | 34 +++++++++++++++++----------------- test/health_status | 12 ++++++------ test/shpec/operation_shpec.sh | 12 ++++++------ 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/usr/sbin/scmi b/src/usr/sbin/scmi index aae0dbe..34c8d4a 100755 --- a/src/usr/sbin/scmi +++ b/src/usr/sbin/scmi @@ -48,7 +48,7 @@ function scmi () break ;; -c) - if [[ -z ${2:-} ]] + if [[ -z ${2} ]] then scmi_print_message "error" \ "Empty option value (${1})" @@ -92,7 +92,7 @@ function scmi () shift 1 ;; -m) - if [[ ! ${2:-} =~ ${SCMI_MANAGER_TYPE_PATTERN} ]] + if [[ ! ${2} =~ ${SCMI_MANAGER_TYPE_PATTERN} ]] then scmi_print_message "error" \ "Invalid option value (${1})" @@ -152,7 +152,7 @@ function scmi () shift 1 ;; -t) - if [[ -z ${2:-} ]] + if [[ -z ${2} ]] then scmi_print_message "error" \ "Empty option value (${1})" @@ -334,8 +334,8 @@ function scmi () function scmi_cleanup_background_task () { - local PID="${1:-}" - local PID_CHILD="${2:-}" + local PID="${1}" + local PID_CHILD="${2}" if [[ -n ${PID} ]] then @@ -967,7 +967,7 @@ function scmi_info () # Require a docker name of the form described with SCMI_NAME_FORMAT function scmi_is_valid_managed_docker_name () { - local NAME="${1:-}" + local NAME="${1}" local NAME_PATTERN='^[a-zA-Z0-9][a-zA-Z0-9_.-]*\.[0-9][0-9]*(\.[0-9][0-9]*)?$' if [[ -z ${NAME} ]] @@ -1071,9 +1071,9 @@ function scmi_print_message () local COLOUR_RESET='\033[0m' local CHARACTER_STEP='--->' local FORMAT='%s\n' - local MESSAGE="${2:-}" + local MESSAGE="${2}" local PREFIX="" - local TYPE="${1:-}" + local TYPE="${1}" local TYPE_PATTERN_ERROR='^(error|error_info|step_error|sub_step_error)$' # Allow for uncolourised output @@ -1205,7 +1205,7 @@ function scmi_restart_option_error () function scmi_run_step () { - local COMMAND="${1:-}" + local COMMAND="${1}" local COMMAND_OUTPUT if [[ -n ${COMMAND} ]] @@ -1228,7 +1228,7 @@ function scmi_run_step () function scmi_systemd_get_template_unit_file_drop_in_content () { local KEYS - local SOURCE_UNIT_FILE_NAME="${1:-}" + local SOURCE_UNIT_FILE_NAME="${1}" local UNIT_SERVICE local VALUE @@ -1360,7 +1360,7 @@ function scmi_systemd_get_template_unit_file_drop_in_path () function scmi_systemd_get_template_unit_file_name () { - local SOURCE_UNIT_FILE_NAME="${1:-}" + local SOURCE_UNIT_FILE_NAME="${1}" local TEMPLATE_UNIT_NAME case "${SOURCE_UNIT_FILE_NAME}" in @@ -1379,7 +1379,7 @@ function scmi_systemd_get_template_unit_file_name () function scmi_systemd_get_unit_file_install_path () { - local UNIT_FILE="${1:-}" + local UNIT_FILE="${1}" printf -- \ '%s/etc/systemd/system/%s' \ @@ -1389,7 +1389,7 @@ function scmi_systemd_get_unit_file_install_path () function scmi_systemd_get_unit_file_path () { - local UNIT_FILE="${1:-}" + local UNIT_FILE="${1}" local UNIT_FILE_PATH="" local TEMPLATE_PATHS=" . diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 54520d2..e5ca5de 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -42,7 +42,7 @@ function is_valid_ssh_authorized_keys () function is_valid_ssh_chroot_directory () { - local -r chroot_directory="${1:-}" + local -r chroot_directory="${1}" local -r safe_directory='^(%h|\/(?!\/|bin|dev|etc|lib|lib64|lost+found|media|proc|root|sbin|srv|sys|tmp|usr).+)$' if grep -qoP "${safe_directory}" <<< "${chroot_directory}" @@ -92,7 +92,7 @@ function is_valid_ssh_sudo () local -r temp_path="$( mktemp -u )" - local -r sudo_cmd="${1:-}" + local -r sudo_cmd="${1}" trap \ "rm -f \"${temp_path}\"" \ @@ -160,7 +160,7 @@ function is_valid_ssh_user_force_sftp () function is_valid_ssh_user_home () { - local -r home_directory="${1:-}" + local -r home_directory="${1}" local -r user_directory='^\/(?!\/|bin|dev|etc|lib|lib64|lost+found|media|proc|root|sbin|srv|sys|tmp|usr).+$' local -r root_directory='^/root$' local -r user="${2:-"$( @@ -278,7 +278,7 @@ function get_ssh_authorized_keys () get_ssh_password_authentication )" - local value="${SSH_AUTHORIZED_KEYS:-}" + local value="${SSH_AUTHORIZED_KEYS}" if [[ -n ${value} ]] \ && [[ ${value} =~ ${pattern_base64} ]] @@ -337,7 +337,7 @@ function get_ssh_chroot_directory () { local -r default_value="${1:-%h}" - local value="${SSH_CHROOT_DIRECTORY:-}" + local value="${SSH_CHROOT_DIRECTORY}" if [[ -z ${value} ]] \ || ! is_valid_ssh_chroot_directory "${value}" @@ -415,7 +415,7 @@ function get_ssh_host_key_fingerprint () function get_ssh_key_fingerprint () { - local -r ssh_key="${1:-}" + local -r ssh_key="${1}" local -r ssh_key_file="$( mktemp )" @@ -495,7 +495,7 @@ function get_ssh_password_authentication () { local -r default_value="${1:-false}" - local value="${SSH_PASSWORD_AUTHENTICATION:-}" + local value="${SSH_PASSWORD_AUTHENTICATION}" if [[ -z ${value} ]] \ || ! is_valid_ssh_password_authentication "${value}" @@ -510,7 +510,7 @@ function get_ssh_sudo () { local -r default_value="${1:-"ALL=(ALL) ALL"}" - local value="${SSH_SUDO:-}" + local value="${SSH_SUDO}" if [[ -z ${value} ]] \ || ! is_valid_ssh_sudo "${value}" @@ -525,7 +525,7 @@ function get_ssh_timezone () { local -r default_value="${1:-UTC}" - local value="${SSH_TIMEZONE:-}" + local value="${SSH_TIMEZONE}" if [[ -z ${value} ]] \ || ! is_valid_ssh_timezone "${value}" @@ -540,7 +540,7 @@ function get_ssh_user () { local -r default_value="${1:-app-admin}" - local value="${SSH_USER:-}" + local value="${SSH_USER}" if [[ -z ${value} ]] \ || ! is_valid_ssh_user "${value}" @@ -555,7 +555,7 @@ function get_ssh_user_password_hashed () { local -r default_value="${1:-false}" - local value="${SSH_USER_PASSWORD_HASHED:-}" + local value="${SSH_USER_PASSWORD_HASHED}" if [[ -z ${value} ]] \ || ! is_valid_ssh_user_password_hashed "${value}" @@ -571,7 +571,7 @@ function get_ssh_user_private_key () local -r default_value="" local -r pattern_base64='^[A-Za-z0-9/+=]*$' - local value="${SSH_USER_PRIVATE_KEY:-}" + local value="${SSH_USER_PRIVATE_KEY}" if [[ -n ${value} ]] \ && [[ ${value} =~ ${pattern_base64} ]] @@ -592,7 +592,7 @@ function get_ssh_user_force_sftp () { local -r default_value="${1:-false}" - local value="${SSH_USER_FORCE_SFTP:-}" + local value="${SSH_USER_FORCE_SFTP}" if [[ -z ${value} ]] \ || ! is_valid_ssh_user_force_sftp "${value}" @@ -629,7 +629,7 @@ function get_ssh_user_home () get_ssh_user )"}" - local value="${SSH_USER_HOME:-}" + local value="${SSH_USER_HOME}" if [[ -z ${value} ]] \ || ! is_valid_ssh_user_home "${value}" @@ -656,7 +656,7 @@ function get_ssh_user_id () get_ssh_user )"}" - local value="${SSH_USER_ID:-}" + local value="${SSH_USER_ID}" if [[ -z ${value} ]] \ || ! is_valid_ssh_user_id "${value}" @@ -679,7 +679,7 @@ function get_ssh_user_shell () get_ssh_user_force_sftp )" - local value="${SSH_USER_SHELL:-}" + local value="${SSH_USER_SHELL}" if [[ -z ${value} ]] \ || ! is_valid_ssh_user_shell "${value}" @@ -767,7 +767,7 @@ function generate_ssh_host_keys () { local -r replace="${1:-false}" - local version="${2:-}" + local version="${2}" if [[ -z ${version} ]] \ && [[ -e /etc/redhat-release ]] diff --git a/test/health_status b/test/health_status index c26a7b9..aa2c1f6 100755 --- a/test/health_status +++ b/test/health_status @@ -2,7 +2,7 @@ function __cleanup () { - local -r fifo_path="${1:-}" + local -r fifo_path="${1}" local -r pid="${2:-0}" if [[ -p ${fifo_path} ]] @@ -29,7 +29,7 @@ function __print_status () local colour_negative='\033[1;31m' local colour_positive='\033[1;32m' local colour_reset='\033[0m' - local type="${1:-}" + local type="${1}" local message="${2:-${type}}" if [[ ${option_quiet} == true ]] @@ -129,11 +129,11 @@ function health_status () shift 1 ;; -c) - if [[ -z ${2:-} ]] + if [[ -z ${2} ]] then __usage fi - container="${2:-}" + container="${2}" shift 2 ;; --container=*) @@ -149,11 +149,11 @@ function health_status () shift 1 ;; -t) - if [[ -z ${2:-} ]] + if [[ -z ${2} ]] then __usage fi - timeout="${2:-}" + timeout="${2}" shift 2 ;; --timeout=*) diff --git a/test/shpec/operation_shpec.sh b/test/shpec/operation_shpec.sh index eba6e09..56ecf5b 100644 --- a/test/shpec/operation_shpec.sh +++ b/test/shpec/operation_shpec.sh @@ -22,8 +22,8 @@ function __destroy () function __get_container_port () { - local container="${1:-}" - local port="${2:-}" + local container="${1}" + local port="${2}" local value="" value="$( @@ -44,13 +44,13 @@ function __get_container_port () # ready_test - Command used to test if the service is ready. function __is_container_ready () { - local container="${1:-}" + local container="${1}" local counter=$( awk \ -v seconds="${2:-10}" \ 'BEGIN { print 10 * seconds; }' ) - local process_pattern="${3:-}" + local process_pattern="${3}" local ready_test="${4:-true}" until (( counter == 0 )); do @@ -85,8 +85,8 @@ function __setup () # Match a string with an Extended Regular Expression pattern. function __shpec_matcher_egrep () { - local pattern="${2:-}" - local string="${1:-}" + local pattern="${2}" + local string="${1}" printf -- \ '%s' \ From bdfba1c236b4e01df214e5210b9a3c7801c05de4 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Mon, 25 Feb 2019 23:05:44 +0000 Subject: [PATCH 18/35] #743: Adds prefix to all subfunctions in bootstrap script. --- src/usr/sbin/sshd-bootstrap | 234 ++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index e5ca5de..63ba3d8 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -1,6 +1,6 @@ #!/usr/bin/env bash -function is_sudo_no_password_all () +function __is_sudo_no_password_all () { local -r sudo="${1}" local -r pattern=' ?NOPASSWD:ALL$' @@ -13,7 +13,7 @@ function is_sudo_no_password_all () return 1 } -function is_valid_ssh_authorized_keys () +function __is_valid_ssh_authorized_keys () { local -r authorized_keys="${1}" local -r invalid_key_pattern='is not a public key file.$' @@ -30,7 +30,7 @@ function is_valid_ssh_authorized_keys () do if [[ -n ${ssh_key} ]] \ && [[ $( - get_ssh_key_fingerprint "${ssh_key}" + __get_ssh_key_fingerprint "${ssh_key}" ) =~ ${invalid_key_pattern} ]] then return 1 @@ -40,7 +40,7 @@ function is_valid_ssh_authorized_keys () return 0 } -function is_valid_ssh_chroot_directory () +function __is_valid_ssh_chroot_directory () { local -r chroot_directory="${1}" local -r safe_directory='^(%h|\/(?!\/|bin|dev|etc|lib|lib64|lost+found|media|proc|root|sbin|srv|sys|tmp|usr).+)$' @@ -53,7 +53,7 @@ function is_valid_ssh_chroot_directory () return 1 } -function is_valid_ssh_key () +function __is_valid_ssh_key () { local -r public_key="${1}" local -r invalid_key_pattern='is not a public key file.$' @@ -65,7 +65,7 @@ function is_valid_ssh_key () if [[ -n ${public_key} ]] \ && [[ $( - get_ssh_key_fingerprint "${public_key}" + __get_ssh_key_fingerprint "${public_key}" ) =~ ${invalid_key_pattern} ]] then return 1 @@ -74,7 +74,7 @@ function is_valid_ssh_key () return 0 } -function is_valid_ssh_password_authentication () +function __is_valid_ssh_password_authentication () { local -r boolean_value='^(true|false)$' local -r value="${1}" @@ -87,7 +87,7 @@ function is_valid_ssh_password_authentication () return 1 } -function is_valid_ssh_sudo () +function __is_valid_ssh_sudo () { local -r temp_path="$( mktemp -u @@ -115,7 +115,7 @@ function is_valid_ssh_sudo () return 1 } -function is_valid_ssh_timezone () +function __is_valid_ssh_timezone () { local -r zone="${1}" @@ -132,7 +132,7 @@ function is_valid_ssh_timezone () return 1 } -function is_valid_ssh_user () +function __is_valid_ssh_user () { local -r safe_user='^[a-z_][a-z0-9_-]{0,29}[$a-z0-9_]?$' local -r user="${1}" @@ -145,7 +145,7 @@ function is_valid_ssh_user () return 1 } -function is_valid_ssh_user_force_sftp () +function __is_valid_ssh_user_force_sftp () { local -r boolean_value='^(true|false)$' local -r value="${1}" @@ -158,13 +158,13 @@ function is_valid_ssh_user_force_sftp () return 1 } -function is_valid_ssh_user_home () +function __is_valid_ssh_user_home () { local -r home_directory="${1}" local -r user_directory='^\/(?!\/|bin|dev|etc|lib|lib64|lost+found|media|proc|root|sbin|srv|sys|tmp|usr).+$' local -r root_directory='^/root$' local -r user="${2:-"$( - get_ssh_user + __get_ssh_user )"}" local safe_directory="${user_directory}" @@ -182,13 +182,13 @@ function is_valid_ssh_user_home () return 1 } -function is_valid_ssh_user_id () +function __is_valid_ssh_user_id () { local -r id="${1}" local -r user_id_pattern='^[1-9][0-9]*:[1-9][0-9]*$' local -r root_id_pattern='^0:0$' local -r user="${2:-"$( - get_ssh_user + __get_ssh_user )"}" local id_pattern="${user_id_pattern}" @@ -206,7 +206,7 @@ function is_valid_ssh_user_id () return 1 } -function is_valid_ssh_user_password_hash () +function __is_valid_ssh_user_password_hash () { local -r password_hash="${1}" local -r sha_512_pattern='^\$6\$[a-zA-Z0-9./]{0,16}\$[a-zA-Z0-9./]{86}$' @@ -219,7 +219,7 @@ function is_valid_ssh_user_password_hash () return 1 } -function is_valid_ssh_user_password_hashed () +function __is_valid_ssh_user_password_hashed () { local -r boolean_value='^(true|false)$' local -r value="${1}" @@ -232,7 +232,7 @@ function is_valid_ssh_user_password_hashed () return 1 } -function is_valid_ssh_user_shell () +function __is_valid_ssh_user_shell () { local -r shell="${1}" local -r valid_shells="$( @@ -257,7 +257,7 @@ function is_valid_ssh_user_shell () return 1 } -function get_password () +function __get_password () { local -r password_length="${1:-16}" @@ -270,12 +270,12 @@ function get_password () printf -- '%s' "${password}" } -function get_ssh_authorized_keys () +function __get_ssh_authorized_keys () { local -r default_value="ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key" local -r pattern_base64='^[A-Za-z0-9/+=]*$' local -r password_authentication="$( - get_ssh_password_authentication + __get_ssh_password_authentication )" local value="${SSH_AUTHORIZED_KEYS}" @@ -303,10 +303,10 @@ function get_ssh_authorized_keys () printf -- '%s' "${value}" } -function get_ssh_authorized_key_fingerprints () +function __get_ssh_authorized_key_fingerprints () { local -r authorized_keys="${1:-"$( - get_ssh_authorized_keys + __get_ssh_authorized_keys )"}" local ssh_key @@ -317,14 +317,14 @@ function get_ssh_authorized_key_fingerprints () then while read -r ssh_key || [[ -n ${ssh_key} ]] do - if is_valid_ssh_key "${ssh_key}" + if __is_valid_ssh_key "${ssh_key}" then printf -v value \ -- \ '%s%s\n' \ "${value}" \ "$( - get_ssh_key_fingerprint_hash_output "${ssh_key}" + __get_ssh_key_fingerprint_hash_output "${ssh_key}" )" fi done <<< "${authorized_keys}" @@ -333,14 +333,14 @@ function get_ssh_authorized_key_fingerprints () printf -- '%s' "${value}" } -function get_ssh_chroot_directory () +function __get_ssh_chroot_directory () { local -r default_value="${1:-%h}" local value="${SSH_CHROOT_DIRECTORY}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_chroot_directory "${value}" + || ! __is_valid_ssh_chroot_directory "${value}" then value="${default_value}" fi @@ -348,22 +348,22 @@ function get_ssh_chroot_directory () printf -- '%s' "${value}" } -function get_ssh_chroot_directory_path () +function __get_ssh_chroot_directory_path () { local -r default_chroot_directory="%h" local -r user="$( - get_ssh_user + __get_ssh_user )" local -r home="$( - get_ssh_user_home + __get_ssh_user_home )" local chroot_directory="${1:-"$( - get_ssh_chroot_directory + __get_ssh_chroot_directory )"}" local value - if ! is_valid_ssh_chroot_directory "${chroot_directory}" + if ! __is_valid_ssh_chroot_directory "${chroot_directory}" then chroot_directory="${default_chroot_directory}" fi @@ -377,7 +377,7 @@ function get_ssh_chroot_directory_path () printf -- '%s' "${value}" } -function get_ssh_host_key_fingerprint () +function __get_ssh_host_key_fingerprint () { local -r type="${1:-rsa}" @@ -390,9 +390,9 @@ function get_ssh_host_key_fingerprint () public_key_path=/etc/ssh/ssh_host_"${type}"_key.pub ssh_key="$(< "${public_key_path}")" - if is_valid_ssh_key "${ssh_key}" + if __is_valid_ssh_key "${ssh_key}" then - get_ssh_key_fingerprint_hash_output "${ssh_key}" + __get_ssh_key_fingerprint_hash_output "${ssh_key}" else printf -- \ 'ERROR: invalid host key\n' \ @@ -413,7 +413,7 @@ function get_ssh_host_key_fingerprint () esac } -function get_ssh_key_fingerprint () +function __get_ssh_key_fingerprint () { local -r ssh_key="${1}" local -r ssh_key_file="$( @@ -459,20 +459,20 @@ function get_ssh_key_fingerprint () printf -- '%s' "${fingerprint}" } -function get_ssh_key_fingerprint_hash_output () +function __get_ssh_key_fingerprint_hash_output () { local -r ssh_key="${1}" local -r insecure_fingerprint='dd:3b:b8:2e:85:04:06:e9:ab:ff:a8:0a:c0:04:6e:d6' local value - if is_valid_ssh_key "${ssh_key}" + if __is_valid_ssh_key "${ssh_key}" then printf -v value \ -- \ '%s' \ "$( - get_ssh_key_fingerprint "${ssh_key}" \ + __get_ssh_key_fingerprint "${ssh_key}" \ | awk '{ print $2; }' )" @@ -491,14 +491,14 @@ function get_ssh_key_fingerprint_hash_output () printf -- '%s' "${value}" } -function get_ssh_password_authentication () +function __get_ssh_password_authentication () { local -r default_value="${1:-false}" local value="${SSH_PASSWORD_AUTHENTICATION}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_password_authentication "${value}" + || ! __is_valid_ssh_password_authentication "${value}" then value="${default_value}" fi @@ -506,14 +506,14 @@ function get_ssh_password_authentication () printf -- '%s' "${value}" } -function get_ssh_sudo () +function __get_ssh_sudo () { local -r default_value="${1:-"ALL=(ALL) ALL"}" local value="${SSH_SUDO}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_sudo "${value}" + || ! __is_valid_ssh_sudo "${value}" then value="${default_value}" fi @@ -521,14 +521,14 @@ function get_ssh_sudo () printf -- '%s' "${value}" } -function get_ssh_timezone () +function __get_ssh_timezone () { local -r default_value="${1:-UTC}" local value="${SSH_TIMEZONE}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_timezone "${value}" + || ! __is_valid_ssh_timezone "${value}" then value="${default_value}" fi @@ -536,14 +536,14 @@ function get_ssh_timezone () printf -- '%s' "${value}" } -function get_ssh_user () +function __get_ssh_user () { local -r default_value="${1:-app-admin}" local value="${SSH_USER}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_user "${value}" + || ! __is_valid_ssh_user "${value}" then value="${default_value}" fi @@ -551,14 +551,14 @@ function get_ssh_user () printf -- '%s' "${value}" } -function get_ssh_user_password_hashed () +function __get_ssh_user_password_hashed () { local -r default_value="${1:-false}" local value="${SSH_USER_PASSWORD_HASHED}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_user_password_hashed "${value}" + || ! __is_valid_ssh_user_password_hashed "${value}" then value="${default_value}" fi @@ -566,7 +566,7 @@ function get_ssh_user_password_hashed () printf -- '%s' "${value}" } -function get_ssh_user_private_key () +function __get_ssh_user_private_key () { local -r default_value="" local -r pattern_base64='^[A-Za-z0-9/+=]*$' @@ -588,14 +588,14 @@ function get_ssh_user_private_key () printf -- '%s' "${value}" } -function get_ssh_user_force_sftp () +function __get_ssh_user_force_sftp () { local -r default_value="${1:-false}" local value="${SSH_USER_FORCE_SFTP}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_user_force_sftp "${value}" + || ! __is_valid_ssh_user_force_sftp "${value}" then value="${default_value}" fi @@ -603,11 +603,11 @@ function get_ssh_user_force_sftp () printf -- '%s' "${value}" } -function get_ssh_user_gid () +function __get_ssh_user_gid () { local -r default_value="${1:-500}" local -r id="$( - get_ssh_user_id + __get_ssh_user_id )" local -r id_pattern='^([0-9]{1,}):([0-9]{1,})$' @@ -621,18 +621,18 @@ function get_ssh_user_gid () printf -- '%d' "${value}" } -function get_ssh_user_home () +function __get_ssh_user_home () { local -r default_value="${1:-/home/%u}" local -r root_value="/root" local -r user="${2:-"$( - get_ssh_user + __get_ssh_user )"}" local value="${SSH_USER_HOME}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_user_home "${value}" + || ! __is_valid_ssh_user_home "${value}" then if [[ ${user} == root ]] then @@ -648,18 +648,18 @@ function get_ssh_user_home () printf -- '%s' "${value}" } -function get_ssh_user_id () +function __get_ssh_user_id () { local -r default_value="${1:-500:500}" local -r root_value="0:0" local -r user="${2:-"$( - get_ssh_user + __get_ssh_user )"}" local value="${SSH_USER_ID}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_user_id "${value}" + || ! __is_valid_ssh_user_id "${value}" then if [[ ${user} == root ]] then @@ -672,17 +672,17 @@ function get_ssh_user_id () printf -- '%s' "${value}" } -function get_ssh_user_shell () +function __get_ssh_user_shell () { local -r default_value="${1:-/bin/bash}" local -r force_sftp="$( - get_ssh_user_force_sftp + __get_ssh_user_force_sftp )" local value="${SSH_USER_SHELL}" if [[ -z ${value} ]] \ - || ! is_valid_ssh_user_shell "${value}" + || ! __is_valid_ssh_user_shell "${value}" then value="${default_value}" fi @@ -696,11 +696,11 @@ function get_ssh_user_shell () printf -- '%s' "${value}" } -function get_ssh_user_uid () +function __get_ssh_user_uid () { local -r default_value="${1:-500}" local -r id="$( - get_ssh_user_id + __get_ssh_user_id )" local -r id_pattern='^([0-9]{1,}):([0-9]{1,})$' @@ -714,7 +714,7 @@ function get_ssh_user_uid () printf -- '%d' "${value}" } -function generate_ssh_host_key () +function __generate_ssh_host_key () { local -r replace="${1:-false}" local -r type="${2:-rsa}" @@ -763,7 +763,7 @@ function generate_ssh_host_key () esac } -function generate_ssh_host_keys () +function __generate_ssh_host_keys () { local -r replace="${1:-false}" @@ -788,16 +788,16 @@ function generate_ssh_host_keys () case "${version}" in 6) - generate_ssh_host_key "${replace}" rsa1 - generate_ssh_host_key "${replace}" rsa - generate_ssh_host_key "${replace}" dsa + __generate_ssh_host_key "${replace}" rsa1 + __generate_ssh_host_key "${replace}" rsa + __generate_ssh_host_key "${replace}" dsa ;; 7) - generate_ssh_host_key "${replace}" rsa1 - generate_ssh_host_key "${replace}" rsa - generate_ssh_host_key "${replace}" dsa - generate_ssh_host_key "${replace}" ecdsa - generate_ssh_host_key "${replace}" ed25519 + __generate_ssh_host_key "${replace}" rsa1 + __generate_ssh_host_key "${replace}" rsa + __generate_ssh_host_key "${replace}" dsa + __generate_ssh_host_key "${replace}" ecdsa + __generate_ssh_host_key "${replace}" ed25519 ;; *) printf -- \ @@ -807,11 +807,11 @@ function generate_ssh_host_keys () esac } -function set_ssh_timezone () +function __set_ssh_timezone () { local -r zone="${1:-UTC}" - if ! is_valid_ssh_timezone "${zone}" + if ! __is_valid_ssh_timezone "${zone}" then printf -- \ 'ERROR: Unknown time zone: %s\n' \ @@ -836,13 +836,13 @@ function set_ssh_timezone () fi } -function set_ssh_user_password () +function __set_ssh_user_password () { local -r password_hashed="${2:-"$( - get_ssh_user_password_hashed + __get_ssh_user_password_hashed )"}" local -r user="${3:-"$( - get_ssh_user + __get_ssh_user )"}" local password="${1:-${SSH_USER_PASSWORD}}" @@ -854,7 +854,7 @@ function set_ssh_user_password () password="$(< "${password}")" fi - if ! is_valid_ssh_user "${user}" + if ! __is_valid_ssh_user "${user}" then printf -- \ 'ERROR: Invalid user\n' \ @@ -865,7 +865,7 @@ function set_ssh_user_password () else if [[ ${password_hashed} == true ]] then - if ! is_valid_ssh_user_password_hash "${password}" + if ! __is_valid_ssh_user_password_hash "${password}" then printf -- \ 'ERROR: Invalid password - requires SHA-512 hash\n' \ @@ -931,58 +931,58 @@ function main () fi OPTS_SSH_USER_HOME="$( - get_ssh_user_home + __get_ssh_user_home )" if [[ ! -d ${OPTS_SSH_USER_HOME}/.ssh ]] then declare -A ENV_VALIDATION_WITH_DEFAULTS=( - [SSH_CHROOT_DIRECTORY]=is_valid_ssh_chroot_directory - [SSH_PASSWORD_AUTHENTICATION]=is_valid_ssh_password_authentication - [SSH_SUDO]=is_valid_ssh_sudo - [SSH_TIMEZONE]=is_valid_ssh_timezone - [SSH_USER]=is_valid_ssh_user - [SSH_USER_FORCE_SFTP]=is_valid_ssh_user_force_sftp - [SSH_USER_HOME]=is_valid_ssh_user_home - [SSH_USER_PASSWORD_HASHED]=is_valid_ssh_user_password_hashed - [SSH_USER_ID]=is_valid_ssh_user_id - [SSH_USER_SHELL]=is_valid_ssh_user_shell + [SSH_CHROOT_DIRECTORY]=__is_valid_ssh_chroot_directory + [SSH_PASSWORD_AUTHENTICATION]=__is_valid_ssh_password_authentication + [SSH_SUDO]=__is_valid_ssh_sudo + [SSH_TIMEZONE]=__is_valid_ssh_timezone + [SSH_USER]=__is_valid_ssh_user + [SSH_USER_FORCE_SFTP]=__is_valid_ssh_user_force_sftp + [SSH_USER_HOME]=__is_valid_ssh_user_home + [SSH_USER_PASSWORD_HASHED]=__is_valid_ssh_user_password_hashed + [SSH_USER_ID]=__is_valid_ssh_user_id + [SSH_USER_SHELL]=__is_valid_ssh_user_shell ) OPTS_SSH_AUTHORIZED_KEYS="$( - get_ssh_authorized_keys + __get_ssh_authorized_keys )" OPTS_SSH_PASSWORD_AUTHENTICATION="$( - get_ssh_password_authentication + __get_ssh_password_authentication )" OPTS_SSH_SUDO="$( - get_ssh_sudo + __get_ssh_sudo )" OPTS_SSH_TIMEZONE="$( - get_ssh_timezone + __get_ssh_timezone )" OPTS_SSH_USER="$( - get_ssh_user + __get_ssh_user )" OPTS_SSH_USER_FORCE_SFTP="$( - get_ssh_user_force_sftp + __get_ssh_user_force_sftp )" OPTS_SSH_USER_PASSWORD_HASHED="$( - get_ssh_user_password_hashed + __get_ssh_user_password_hashed )" OPTS_SSH_USER_PASSWORD="${SSH_USER_PASSWORD:-"$( - get_password "${PASSWORD_LENGTH}" + __get_password "${PASSWORD_LENGTH}" )"}" OPTS_SSH_USER_PRIVATE_KEY="$( - get_ssh_user_private_key + __get_ssh_user_private_key )" OPTS_SSH_USER_SHELL="$( - get_ssh_user_shell + __get_ssh_user_shell )" OPTS_SSH_USER_UID="$( - get_ssh_user_uid + __get_ssh_user_uid )" OPTS_SSH_USER_GID="$( - get_ssh_user_gid + __get_ssh_user_gid )" PASSWORD_AUTHENTICATION="no" @@ -1012,7 +1012,7 @@ function main () SSHD_COMMAND="SFTP" SSH_USER_GROUPS="users" OPTS_SSH_CHROOT_DIRECTORY="$( - get_ssh_chroot_directory %h + __get_ssh_chroot_directory %h )" else SSHD_COMMAND="SSH" @@ -1035,7 +1035,7 @@ function main () fi done - if ! set_ssh_timezone "${OPTS_SSH_TIMEZONE}" + if ! __set_ssh_timezone "${OPTS_SSH_TIMEZONE}" then printf -- \ 'ERROR: Could not set timezone - aborting.\n' \ @@ -1046,7 +1046,7 @@ function main () fi $( - generate_ssh_host_keys + __generate_ssh_host_keys ) & PIDS[0]="${!}" @@ -1088,14 +1088,14 @@ function main () '%s:%s\n' \ "root" \ "$( - get_password "${PASSWORD_LENGTH}" + __get_password "${PASSWORD_LENGTH}" )" \ | chpasswd ) & PIDS[1]="${!}" fi - if ! set_ssh_user_password "${OPTS_SSH_USER_PASSWORD}" + if ! __set_ssh_user_password "${OPTS_SSH_USER_PASSWORD}" then printf -- \ 'ERROR: Could not set password - aborting.\n' \ @@ -1111,7 +1111,7 @@ function main () # Get the ChrootDirectory path. # %h and %u are replaced with the User's HOME and USERNAME respectively. SSH_CHROOT_DIRECTORY_PATH="$( - get_ssh_chroot_directory_path "${OPTS_SSH_CHROOT_DIRECTORY}" + __get_ssh_chroot_directory_path "${OPTS_SSH_CHROOT_DIRECTORY}" )" if [[ ! -d ${SSH_CHROOT_DIRECTORY_PATH} ]] \ @@ -1203,7 +1203,7 @@ function main () && [[ -z ${SSH_AUTHORIZED_KEYS} ]] then SSH_KEY_FINGERPRINTS="N/A" - elif ! is_valid_ssh_authorized_keys "${OPTS_SSH_AUTHORIZED_KEYS}" + elif ! __is_valid_ssh_authorized_keys "${OPTS_SSH_AUTHORIZED_KEYS}" then printf -v SSH_KEY_FINGERPRINTS \ -- \ @@ -1217,7 +1217,7 @@ function main () > "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys SSH_KEY_FINGERPRINTS="$( - get_ssh_authorized_key_fingerprints + __get_ssh_authorized_key_fingerprints )" fi @@ -1226,7 +1226,7 @@ function main () || [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] then SSH_USER_PRIVATE_KEY_FINGERPRINT="N/A" - elif ! is_valid_ssh_key "${OPTS_SSH_USER_PRIVATE_KEY}" + elif ! __is_valid_ssh_key "${OPTS_SSH_USER_PRIVATE_KEY}" then printf -v SSH_USER_PRIVATE_KEY_FINGERPRINT \ -- \ @@ -1246,7 +1246,7 @@ function main () ${OPTS_SSH_USER_HOME}/.ssh/id_rsa SSH_USER_PRIVATE_KEY_FINGERPRINT="$( - get_ssh_key_fingerprint_hash_output \ + __get_ssh_key_fingerprint_hash_output \ "${OPTS_SSH_USER_PRIVATE_KEY}" )" fi @@ -1269,7 +1269,7 @@ function main () wait ${PIDS[0]} SSH_HOST_KEY_FINGERPRINT_RSA="$( - get_ssh_host_key_fingerprint rsa + __get_ssh_host_key_fingerprint rsa )" # Wait for background processes - Set password for root user @@ -1289,7 +1289,7 @@ function main () OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ && [[ ${OPTS_SSH_USER} != root ]] \ - && is_sudo_no_password_all "${OPTS_SSH_SUDO}" + && __is_sudo_no_password_all "${OPTS_SSH_SUDO}" then OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ From 391f24b985e6ecbfd245a962ec01b04e712b198d Mon Sep 17 00:00:00 2001 From: James Deathe Date: Mon, 25 Feb 2019 23:27:31 +0000 Subject: [PATCH 19/35] #743: Replaces global constants with local scoped constants. --- src/usr/sbin/sshd-bootstrap | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 63ba3d8..87f7804 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -906,17 +906,17 @@ function __set_ssh_user_password () function main () { - readonly ENV_EXCLUDE_PATTERN="^([.]*SSH_USER_PASSWORD|_|HOME|HOSTNAME|PATH|PWD|SHLVL|SUPERVISOR_ENABLED|SUPERVISOR_GROUP_NAME|SUPERVISOR_PROCESS_NAME|TERM)=" - readonly LOCK_FILE="/var/lock/subsys/sshd-bootstrap" - readonly PASSWORD_LENGTH=16 - readonly REDACTED_VALUE="********" - readonly TIMER_START="$( + local -r env_exclude_pattern="^([.]*SSH_USER_PASSWORD|_|HOME|HOSTNAME|PATH|PWD|SHLVL|SUPERVISOR_ENABLED|SUPERVISOR_GROUP_NAME|SUPERVISOR_PROCESS_NAME|TERM)=" + local -r lock_file="/var/lock/subsys/sshd-bootstrap" + local -r password_length=16 + local -r redacted_value="********" + local -r timer_start="$( date +%s.%N )" # Create lock file touch \ - "${LOCK_FILE}" + "${lock_file}" # Populate the environment source file env >> /etc/sshd-bootstrap.env @@ -925,7 +925,7 @@ function main () if [[ ${SSH_INHERIT_ENVIRONMENT} == true ]] \ && [[ -s /etc/sshd-bootstrap.env ]] then - grep -Ev "${ENV_EXCLUDE_PATTERN}" \ + grep -Ev "${env_exclude_pattern}" \ /etc/sshd-bootstrap.env \ > /etc/environment fi @@ -970,7 +970,7 @@ function main () __get_ssh_user_password_hashed )" OPTS_SSH_USER_PASSWORD="${SSH_USER_PASSWORD:-"$( - __get_password "${PASSWORD_LENGTH}" + __get_password "${password_length}" )"}" OPTS_SSH_USER_PRIVATE_KEY="$( __get_ssh_user_private_key @@ -1088,7 +1088,7 @@ function main () '%s:%s\n' \ "root" \ "$( - __get_password "${PASSWORD_LENGTH}" + __get_password "${password_length}" )" \ | chpasswd ) & @@ -1282,20 +1282,20 @@ function main () # password authentication or sudo. if [[ -n ${SSH_USER_PASSWORD} ]] then - OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" + OPTS_SSH_USER_PASSWORD="${redacted_value}" elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ && [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] then - OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" + OPTS_SSH_USER_PASSWORD="${redacted_value}" elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ && [[ ${OPTS_SSH_USER} != root ]] \ && __is_sudo_no_password_all "${OPTS_SSH_SUDO}" then - OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" + OPTS_SSH_USER_PASSWORD="${redacted_value}" elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ && [[ ${OPTS_SSH_USER} == root ]] then - OPTS_SSH_USER_PASSWORD="${REDACTED_VALUE}" + OPTS_SSH_USER_PASSWORD="${redacted_value}" fi if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] @@ -1310,7 +1310,7 @@ function main () -v timer_end="$( date +%s.%N )" \ - -v timer_start="${TIMER_START}" \ + -v timer_start="${timer_start}" \ 'BEGIN { print \ timer_end - timer_start; }' @@ -1345,7 +1345,7 @@ function main () # Release lock file rm -f \ - "${LOCK_FILE}" + "${lock_file}" } main "${@}" From 6663fe995bfb10bf4db185e261d8234bd3bff118 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Tue, 26 Feb 2019 00:51:43 +0000 Subject: [PATCH 20/35] #743: Adds lowercased local scope variables. --- src/usr/sbin/sshd-bootstrap | 137 +++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 64 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 87f7804..559ff4a 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -914,6 +914,30 @@ function main () date +%s.%N )" + local env + local -A env_validation_with_defaults=( + [SSH_CHROOT_DIRECTORY]=__is_valid_ssh_chroot_directory + [SSH_PASSWORD_AUTHENTICATION]=__is_valid_ssh_password_authentication + [SSH_SUDO]=__is_valid_ssh_sudo + [SSH_TIMEZONE]=__is_valid_ssh_timezone + [SSH_USER]=__is_valid_ssh_user + [SSH_USER_FORCE_SFTP]=__is_valid_ssh_user_force_sftp + [SSH_USER_HOME]=__is_valid_ssh_user_home + [SSH_USER_PASSWORD_HASHED]=__is_valid_ssh_user_password_hashed + [SSH_USER_ID]=__is_valid_ssh_user_id + [SSH_USER_SHELL]=__is_valid_ssh_user_shell + ) + local password_authentication="no" + local -a pids + local sshd_command="SSH" + local ssh_chroot_directory_path + local ssh_chroot_home_directory_path + local ssh_host_key_fingerprint_rsa + local ssh_key_fingerprints + local ssh_user_groups="users,wheel" + local ssh_user_private_key_fingerprint + local timer_total + # Create lock file touch \ "${lock_file}" @@ -936,18 +960,6 @@ function main () if [[ ! -d ${OPTS_SSH_USER_HOME}/.ssh ]] then - declare -A ENV_VALIDATION_WITH_DEFAULTS=( - [SSH_CHROOT_DIRECTORY]=__is_valid_ssh_chroot_directory - [SSH_PASSWORD_AUTHENTICATION]=__is_valid_ssh_password_authentication - [SSH_SUDO]=__is_valid_ssh_sudo - [SSH_TIMEZONE]=__is_valid_ssh_timezone - [SSH_USER]=__is_valid_ssh_user - [SSH_USER_FORCE_SFTP]=__is_valid_ssh_user_force_sftp - [SSH_USER_HOME]=__is_valid_ssh_user_home - [SSH_USER_PASSWORD_HASHED]=__is_valid_ssh_user_password_hashed - [SSH_USER_ID]=__is_valid_ssh_user_id - [SSH_USER_SHELL]=__is_valid_ssh_user_shell - ) OPTS_SSH_AUTHORIZED_KEYS="$( __get_ssh_authorized_keys )" @@ -985,10 +997,9 @@ function main () __get_ssh_user_gid )" - PASSWORD_AUTHENTICATION="no" if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] then - PASSWORD_AUTHENTICATION="yes" + password_authentication="yes" if [[ ${OPTS_SSH_USER} == root ]] then sed -i \ @@ -1009,29 +1020,27 @@ function main () if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] then - SSHD_COMMAND="SFTP" - SSH_USER_GROUPS="users" + sshd_command="SFTP" + ssh_user_groups="users" OPTS_SSH_CHROOT_DIRECTORY="$( __get_ssh_chroot_directory %h )" - else - SSHD_COMMAND="SSH" fi # Initialise printf -- \ 'Initialising %s.\n' \ - "${SSHD_COMMAND}" + "${sshd_command}" # Warn operator if any supplied environment variable values failed # validation and have been set to a safe default. - for ENV in "${!ENV_VALIDATION_WITH_DEFAULTS[@]}" + for env in "${!env_validation_with_defaults[@]}" do - if ! ${ENV_VALIDATION_WITH_DEFAULTS[${ENV}]} "${!ENV}" + if ! ${env_validation_with_defaults[${env}]} "${!env}" then printf -- \ 'WARNING: Validation failed on %s - setting to default.\n' \ - "${ENV}" + "${env}" fi done @@ -1048,7 +1057,7 @@ function main () $( __generate_ssh_host_keys ) & - PIDS[0]="${!}" + pids[0]="${!}" if [[ ${OPTS_SSH_USER} == root ]] then @@ -1077,7 +1086,7 @@ function main () -u "${OPTS_SSH_USER_UID}" \ -g "${OPTS_SSH_USER_GID}" \ -m \ - -G "${SSH_USER_GROUPS:-users,wheel}" \ + -G "${ssh_user_groups}" \ -d "${OPTS_SSH_USER_HOME}" \ -s "${OPTS_SSH_USER_SHELL}" \ "${OPTS_SSH_USER}" @@ -1092,7 +1101,7 @@ function main () )" \ | chpasswd ) & - PIDS[1]="${!}" + pids[1]="${!}" fi if ! __set_ssh_user_password "${OPTS_SSH_USER_PASSWORD}" @@ -1110,27 +1119,27 @@ function main () then # Get the ChrootDirectory path. # %h and %u are replaced with the User's HOME and USERNAME respectively. - SSH_CHROOT_DIRECTORY_PATH="$( + ssh_chroot_directory_path="$( __get_ssh_chroot_directory_path "${OPTS_SSH_CHROOT_DIRECTORY}" )" - if [[ ! -d ${SSH_CHROOT_DIRECTORY_PATH} ]] \ - || [[ ${SSH_CHROOT_DIRECTORY_PATH} != "${OPTS_SSH_USER_HOME}" ]] + if [[ ! -d ${ssh_chroot_directory_path} ]] \ + || [[ ${ssh_chroot_directory_path} != "${OPTS_SSH_USER_HOME}" ]] then # ChrootDirectory like /chroot/%u or /home/chroot/%u - printf -v SSH_CHROOT_HOME_DIRECTORY_PATH \ + printf -v ssh_chroot_home_directory_path \ -- \ '%s%s' \ - "${SSH_CHROOT_DIRECTORY_PATH}" \ + "${ssh_chroot_directory_path}" \ "${OPTS_SSH_USER_HOME}" mkdir -pm 711 \ - "${SSH_CHROOT_DIRECTORY_PATH}" + "${ssh_chroot_directory_path}" mkdir -pm 755 \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}" + "${ssh_chroot_home_directory_path}" else # ChrootDirectory %h - SSH_CHROOT_HOME_DIRECTORY_PATH="${OPTS_SSH_USER_HOME}" + ssh_chroot_home_directory_path="${OPTS_SSH_USER_HOME}" chmod 750 \ "${OPTS_SSH_USER_HOME}" @@ -1139,43 +1148,43 @@ function main () # Create a user writeable data directory if no other directories are # mounted. if ! grep -q '^d' <<< "$( - ls -l "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/ + ls -l "${ssh_chroot_home_directory_path}"/ )" then # Make and set user permissions on new _data directory mkdir -m 700 \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data + "${ssh_chroot_home_directory_path}"/_data chown -R \ "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data - elif [[ -d ${SSH_CHROOT_HOME_DIRECTORY_PATH}/_data ]] + "${ssh_chroot_home_directory_path}"/_data + elif [[ -d ${ssh_chroot_home_directory_path}/_data ]] then # Set user permissions on _data directory in case where it exists chmod 700 \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data + "${ssh_chroot_home_directory_path}"/_data chown -R \ "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ - "${SSH_CHROOT_HOME_DIRECTORY_PATH}"/_data + "${ssh_chroot_home_directory_path}"/_data fi # ChrootDirectory must be owned by root user - if [[ ${SSH_CHROOT_DIRECTORY_PATH} != "${OPTS_SSH_USER_HOME}" ]] + if [[ ${ssh_chroot_directory_path} != "${OPTS_SSH_USER_HOME}" ]] then chown \ root:root \ - "${SSH_CHROOT_DIRECTORY_PATH}" + "${ssh_chroot_directory_path}" chmod 711 \ - "${SSH_CHROOT_DIRECTORY_PATH}" + "${ssh_chroot_directory_path}" else chown \ root:"${OPTS_SSH_USER}" \ - "${SSH_CHROOT_DIRECTORY_PATH}" + "${ssh_chroot_directory_path}" fi - # Add group specific sshd configuration + # Add user specific sshd configuration tee -a /etc/ssh/sshd_config > /dev/null <<-EOT # Force SFTP - Match User ${SSH_USER} + Match User ${OPTS_SSH_USER} AllowTcpForwarding no X11Forwarding no ChrootDirectory ${OPTS_SSH_CHROOT_DIRECTORY} @@ -1202,10 +1211,10 @@ function main () if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] \ && [[ -z ${SSH_AUTHORIZED_KEYS} ]] then - SSH_KEY_FINGERPRINTS="N/A" + ssh_key_fingerprints="N/A" elif ! __is_valid_ssh_authorized_keys "${OPTS_SSH_AUTHORIZED_KEYS}" then - printf -v SSH_KEY_FINGERPRINTS \ + printf -v ssh_key_fingerprints \ -- \ '%s\nUnable to populate %s/.ssh/authorized_key' \ "ERROR: Public key validation failed." \ @@ -1216,7 +1225,7 @@ function main () "${OPTS_SSH_AUTHORIZED_KEYS}" \ > "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys - SSH_KEY_FINGERPRINTS="$( + ssh_key_fingerprints="$( __get_ssh_authorized_key_fingerprints )" fi @@ -1225,10 +1234,10 @@ function main () if [[ -z ${OPTS_SSH_USER_PRIVATE_KEY} ]] \ || [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] then - SSH_USER_PRIVATE_KEY_FINGERPRINT="N/A" + ssh_user_private_key_fingerprint="N/A" elif ! __is_valid_ssh_key "${OPTS_SSH_USER_PRIVATE_KEY}" then - printf -v SSH_USER_PRIVATE_KEY_FINGERPRINT \ + printf -v ssh_user_private_key_fingerprint \ -- \ '%s\nUnable to populate %s/.ssh/id_rsa' \ "ERROR: Private key validation failed." \ @@ -1245,7 +1254,7 @@ function main () chmod 600 \ ${OPTS_SSH_USER_HOME}/.ssh/id_rsa - SSH_USER_PRIVATE_KEY_FINGERPRINT="$( + ssh_user_private_key_fingerprint="$( __get_ssh_key_fingerprint_hash_output \ "${OPTS_SSH_USER_PRIVATE_KEY}" )" @@ -1266,16 +1275,16 @@ function main () EOT # Wait for background processes - Host key generation - wait ${PIDS[0]} + wait ${pids[0]} - SSH_HOST_KEY_FINGERPRINT_RSA="$( + ssh_host_key_fingerprint_rsa="$( __get_ssh_host_key_fingerprint rsa )" # Wait for background processes - Set password for root user - if [[ -n ${PIDS[1]+isset} ]] + if [[ -n ${pids[1]+isset} ]] then - wait ${PIDS[1]} + wait ${pids[1]} fi # Only show user password if auto-generated and password is required for @@ -1302,10 +1311,10 @@ function main () then OPTS_SSH_SUDO="N/A" else - SSH_CHROOT_DIRECTORY_PATH="N/A" + ssh_chroot_directory_path="N/A" fi - TIMER_TOTAL="$( + timer_total="$( awk \ -v timer_end="$( date +%s.%N @@ -1319,25 +1328,25 @@ function main () cat <<-EOT ================================================================================ - ${SSHD_COMMAND} Details + ${sshd_command} Details -------------------------------------------------------------------------------- user : ${OPTS_SSH_USER} password : ${OPTS_SSH_USER_PASSWORD} - password authentication : ${PASSWORD_AUTHENTICATION} + password authentication : ${password_authentication} id : ${OPTS_SSH_USER_UID}:${OPTS_SSH_USER_GID} home : ${OPTS_SSH_USER_HOME} - chroot path : ${SSH_CHROOT_DIRECTORY_PATH} + chroot path : ${ssh_chroot_directory_path} shell : ${OPTS_SSH_USER_SHELL} sudo : ${OPTS_SSH_SUDO} key fingerprints : - ${SSH_KEY_FINGERPRINTS} + ${ssh_key_fingerprints} rsa private key fingerprint : - ${SSH_USER_PRIVATE_KEY_FINGERPRINT} + ${ssh_user_private_key_fingerprint} rsa host key fingerprint : - ${SSH_HOST_KEY_FINGERPRINT_RSA} + ${ssh_host_key_fingerprint_rsa} timezone : ${OPTS_SSH_TIMEZONE} -------------------------------------------------------------------------------- - ${TIMER_TOTAL} + ${timer_total} EOT From 830b166aa70fbabbf1a4d76555281479f0717ce7 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Tue, 26 Feb 2019 00:55:49 +0000 Subject: [PATCH 21/35] #743: Adds sshd-bootstrap to changelog. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59ada91..8bb82c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ Summary of release changes for Version 2 - CentOS-7 - Adds docker-compose configuration example. - Adds `SSH_AUTOSTART_SUPERVISOR_STDOUT` to control startup of `supervisor_stdout`. - Adds drop-in configuration for `supervisor_stdout` in `/etc/supervisord.d/00-supervisor_stdout.conf`. -- Adds improved healtchcheck, sshd-wrapper script. +- Adds improved `healtchcheck`, `sshd-bootstrap` and `sshd-wrapper` scripts. - Removes reference to `python-setuptools` from README as it's no longer installed. - Removes requirement of `supervisor_stdout` for output of supervisord logs to stdout. - Removes unnecessary configuration file `/etc/sshd-bootstrap.conf`. From ada17af166362cc71d53d3b4a7232e291befc4e6 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 14:50:34 +0000 Subject: [PATCH 22/35] #743: Adds validation/getter for SSH_INHERIT_ENVIRONMENT. --- src/usr/sbin/sshd-bootstrap | 119 ++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 45 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 559ff4a..319a923 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -53,6 +53,19 @@ function __is_valid_ssh_chroot_directory () return 1 } +function __is_valid_ssh_inherit_environment () +{ + local -r boolean_value='^(true|false)$' + local -r value="${1}" + + if [[ ${value} =~ ${boolean_value} ]] + then + return 0 + fi + + return 1 +} + function __is_valid_ssh_key () { local -r public_key="${1}" @@ -377,6 +390,21 @@ function __get_ssh_chroot_directory_path () printf -- '%s' "${value}" } +function __get_ssh_inherit_environment () +{ + local -r default_value="${1:-false}" + + local value="${SSH_INHERIT_ENVIRONMENT}" + + if [[ -z ${value} ]] \ + || ! __is_valid_ssh_inherit_environment "${value}" + then + value="${default_value}" + fi + + printf -- '%s' "${value}" +} + function __get_ssh_host_key_fingerprint () { local -r type="${1:-rsa}" @@ -945,57 +973,58 @@ function main () # Populate the environment source file env >> /etc/sshd-bootstrap.env - # Docker ENV inheritance - if [[ ${SSH_INHERIT_ENVIRONMENT} == true ]] \ - && [[ -s /etc/sshd-bootstrap.env ]] - then - grep -Ev "${env_exclude_pattern}" \ - /etc/sshd-bootstrap.env \ - > /etc/environment - fi - + OPTS_SSH_AUTHORIZED_KEYS="$( + __get_ssh_authorized_keys + )" + OPTS_SSH_INHERIT_ENVIRONMENT="$( + __get_ssh_inherit_environment + )" + OPTS_SSH_PASSWORD_AUTHENTICATION="$( + __get_ssh_password_authentication + )" + OPTS_SSH_SUDO="$( + __get_ssh_sudo + )" + OPTS_SSH_TIMEZONE="$( + __get_ssh_timezone + )" + OPTS_SSH_USER="$( + __get_ssh_user + )" + OPTS_SSH_USER_FORCE_SFTP="$( + __get_ssh_user_force_sftp + )" OPTS_SSH_USER_HOME="$( __get_ssh_user_home )" + OPTS_SSH_USER_PASSWORD_HASHED="$( + __get_ssh_user_password_hashed + )" + OPTS_SSH_USER_PASSWORD="${SSH_USER_PASSWORD:-"$( + __get_password "${password_length}" + )"}" + OPTS_SSH_USER_PRIVATE_KEY="$( + __get_ssh_user_private_key + )" + OPTS_SSH_USER_SHELL="$( + __get_ssh_user_shell + )" + OPTS_SSH_USER_UID="$( + __get_ssh_user_uid + )" + OPTS_SSH_USER_GID="$( + __get_ssh_user_gid + )" if [[ ! -d ${OPTS_SSH_USER_HOME}/.ssh ]] then - OPTS_SSH_AUTHORIZED_KEYS="$( - __get_ssh_authorized_keys - )" - OPTS_SSH_PASSWORD_AUTHENTICATION="$( - __get_ssh_password_authentication - )" - OPTS_SSH_SUDO="$( - __get_ssh_sudo - )" - OPTS_SSH_TIMEZONE="$( - __get_ssh_timezone - )" - OPTS_SSH_USER="$( - __get_ssh_user - )" - OPTS_SSH_USER_FORCE_SFTP="$( - __get_ssh_user_force_sftp - )" - OPTS_SSH_USER_PASSWORD_HASHED="$( - __get_ssh_user_password_hashed - )" - OPTS_SSH_USER_PASSWORD="${SSH_USER_PASSWORD:-"$( - __get_password "${password_length}" - )"}" - OPTS_SSH_USER_PRIVATE_KEY="$( - __get_ssh_user_private_key - )" - OPTS_SSH_USER_SHELL="$( - __get_ssh_user_shell - )" - OPTS_SSH_USER_UID="$( - __get_ssh_user_uid - )" - OPTS_SSH_USER_GID="$( - __get_ssh_user_gid - )" + if [[ ${OPTS_SSH_INHERIT_ENVIRONMENT} == true ]] \ + && [[ -s /etc/sshd-bootstrap.env ]] + then + grep -Ev "${env_exclude_pattern}" \ + /etc/sshd-bootstrap.env \ + > /etc/environment + fi if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] then From 5f096378d2ad3c4937869ad611860297463479e1 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 15:25:59 +0000 Subject: [PATCH 23/35] #743: Removes unnecessary population of file and lowercases all local variables. --- Dockerfile | 2 +- src/etc/sshd-bootstrap.env | 0 src/usr/sbin/sshd-bootstrap | 207 +++++++++++++++++++----------------- 3 files changed, 110 insertions(+), 99 deletions(-) delete mode 100644 src/etc/sshd-bootstrap.env diff --git a/Dockerfile b/Dockerfile index 5122e3c..e626f56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -81,7 +81,7 @@ RUN ln -sf \ -e "s~{{RELEASE_VERSION}}~${RELEASE_VERSION}~g" \ /etc/systemd/system/centos-ssh@.service \ && chmod 644 \ - /etc/{sshd-bootstrap.env,supervisord.conf,supervisord.d/sshd-{bootstrap,wrapper}.conf} \ + /etc/{supervisord.conf,supervisord.d/sshd-{bootstrap,wrapper}.conf} \ && chmod 700 \ /usr/{bin/healthcheck,sbin/{scmi,sshd-{bootstrap,wrapper}}} diff --git a/src/etc/sshd-bootstrap.env b/src/etc/sshd-bootstrap.env deleted file mode 100644 index e69de29..0000000 diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 319a923..0591316 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -957,79 +957,90 @@ function main () ) local password_authentication="no" local -a pids - local sshd_command="SSH" + local ssh_authorized_keys + local ssh_chroot_directory local ssh_chroot_directory_path local ssh_chroot_home_directory_path local ssh_host_key_fingerprint_rsa + local ssh_inherit_environment local ssh_key_fingerprints + local ssh_password_authentication + local ssh_sudo + local ssh_timezone + local ssh_user + local ssh_user_force_sftp local ssh_user_groups="users,wheel" + local ssh_user_gid + local ssh_user_home + local ssh_user_password + local ssh_user_password_hashed + local ssh_user_private_key local ssh_user_private_key_fingerprint + local ssh_user_shell + local ssh_user_uid + local sshd_command="SSH" local timer_total # Create lock file touch \ "${lock_file}" - # Populate the environment source file - env >> /etc/sshd-bootstrap.env - - OPTS_SSH_AUTHORIZED_KEYS="$( + ssh_authorized_keys="$( __get_ssh_authorized_keys )" - OPTS_SSH_INHERIT_ENVIRONMENT="$( + ssh_inherit_environment="$( __get_ssh_inherit_environment )" - OPTS_SSH_PASSWORD_AUTHENTICATION="$( + ssh_password_authentication="$( __get_ssh_password_authentication )" - OPTS_SSH_SUDO="$( + ssh_sudo="$( __get_ssh_sudo )" - OPTS_SSH_TIMEZONE="$( + ssh_timezone="$( __get_ssh_timezone )" - OPTS_SSH_USER="$( + ssh_user="$( __get_ssh_user )" - OPTS_SSH_USER_FORCE_SFTP="$( + ssh_user_force_sftp="$( __get_ssh_user_force_sftp )" - OPTS_SSH_USER_HOME="$( + ssh_user_home="$( __get_ssh_user_home )" - OPTS_SSH_USER_PASSWORD_HASHED="$( + ssh_user_password_hashed="$( __get_ssh_user_password_hashed )" - OPTS_SSH_USER_PASSWORD="${SSH_USER_PASSWORD:-"$( + ssh_user_password="${SSH_USER_PASSWORD:-"$( __get_password "${password_length}" )"}" - OPTS_SSH_USER_PRIVATE_KEY="$( + ssh_user_private_key="$( __get_ssh_user_private_key )" - OPTS_SSH_USER_SHELL="$( + ssh_user_shell="$( __get_ssh_user_shell )" - OPTS_SSH_USER_UID="$( + ssh_user_uid="$( __get_ssh_user_uid )" - OPTS_SSH_USER_GID="$( + ssh_user_gid="$( __get_ssh_user_gid )" - if [[ ! -d ${OPTS_SSH_USER_HOME}/.ssh ]] + if [[ ! -d ${ssh_user_home}/.ssh ]] then - if [[ ${OPTS_SSH_INHERIT_ENVIRONMENT} == true ]] \ - && [[ -s /etc/sshd-bootstrap.env ]] + if [[ ${ssh_inherit_environment} == true ]] then - grep -Ev "${env_exclude_pattern}" \ - /etc/sshd-bootstrap.env \ + env \ + | grep -Ev "${env_exclude_pattern}" \ > /etc/environment fi - if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] + if [[ ${ssh_password_authentication} == true ]] then password_authentication="yes" - if [[ ${OPTS_SSH_USER} == root ]] + if [[ ${ssh_user} == root ]] then sed -i \ -e 's~^\(PasswordAuthentication \)no$~\1yes~g' \ @@ -1040,18 +1051,18 @@ function main () -e 's~^\(PasswordAuthentication \)no$~\1yes~g' \ /etc/ssh/sshd_config fi - elif [[ ${OPTS_SSH_USER} == root ]] + elif [[ ${ssh_user} == root ]] then sed -i \ -e 's~^\(PermitRootLogin \)no$~\1without-password~g' \ /etc/ssh/sshd_config fi - if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + if [[ ${ssh_user_force_sftp} == true ]] then sshd_command="SFTP" ssh_user_groups="users" - OPTS_SSH_CHROOT_DIRECTORY="$( + ssh_chroot_directory="$( __get_ssh_chroot_directory %h )" fi @@ -1073,7 +1084,7 @@ function main () fi done - if ! __set_ssh_timezone "${OPTS_SSH_TIMEZONE}" + if ! __set_ssh_timezone "${ssh_timezone}" then printf -- \ 'ERROR: Could not set timezone - aborting.\n' \ @@ -1088,37 +1099,37 @@ function main () ) & pids[0]="${!}" - if [[ ${OPTS_SSH_USER} == root ]] + if [[ ${ssh_user} == root ]] then chsh \ - -s "${OPTS_SSH_USER_SHELL}" \ - "${OPTS_SSH_USER}" \ + -s "${ssh_user_shell}" \ + "${ssh_user}" \ &> /dev/null else # Create base directory for home - if [[ -n ${OPTS_SSH_USER_HOME%/*} ]] \ - && [[ ! -d ${OPTS_SSH_USER_HOME%/*} ]] + if [[ -n ${ssh_user_home%/*} ]] \ + && [[ ! -d ${ssh_user_home%/*} ]] then printf -- \ 'Creating home base directory.\n' mkdir -pm 755 \ - "${OPTS_SSH_USER_HOME%/*}" + "${ssh_user_home%/*}" fi groupadd \ -f \ - -g "${OPTS_SSH_USER_GID}" \ - "${OPTS_SSH_USER}" + -g "${ssh_user_gid}" \ + "${ssh_user}" useradd \ - -u "${OPTS_SSH_USER_UID}" \ - -g "${OPTS_SSH_USER_GID}" \ + -u "${ssh_user_uid}" \ + -g "${ssh_user_gid}" \ -m \ -G "${ssh_user_groups}" \ - -d "${OPTS_SSH_USER_HOME}" \ - -s "${OPTS_SSH_USER_SHELL}" \ - "${OPTS_SSH_USER}" + -d "${ssh_user_home}" \ + -s "${ssh_user_shell}" \ + "${ssh_user}" # Set root user password $( @@ -1133,7 +1144,7 @@ function main () pids[1]="${!}" fi - if ! __set_ssh_user_password "${OPTS_SSH_USER_PASSWORD}" + if ! __set_ssh_user_password "${ssh_user_password}" then printf -- \ 'ERROR: Could not set password - aborting.\n' \ @@ -1144,23 +1155,23 @@ function main () fi # SFTP users - if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + if [[ ${ssh_user_force_sftp} == true ]] then # Get the ChrootDirectory path. # %h and %u are replaced with the User's HOME and USERNAME respectively. ssh_chroot_directory_path="$( - __get_ssh_chroot_directory_path "${OPTS_SSH_CHROOT_DIRECTORY}" + __get_ssh_chroot_directory_path "${ssh_chroot_directory}" )" if [[ ! -d ${ssh_chroot_directory_path} ]] \ - || [[ ${ssh_chroot_directory_path} != "${OPTS_SSH_USER_HOME}" ]] + || [[ ${ssh_chroot_directory_path} != "${ssh_user_home}" ]] then # ChrootDirectory like /chroot/%u or /home/chroot/%u printf -v ssh_chroot_home_directory_path \ -- \ '%s%s' \ "${ssh_chroot_directory_path}" \ - "${OPTS_SSH_USER_HOME}" + "${ssh_user_home}" mkdir -pm 711 \ "${ssh_chroot_directory_path}" @@ -1168,10 +1179,10 @@ function main () "${ssh_chroot_home_directory_path}" else # ChrootDirectory %h - ssh_chroot_home_directory_path="${OPTS_SSH_USER_HOME}" + ssh_chroot_home_directory_path="${ssh_user_home}" chmod 750 \ - "${OPTS_SSH_USER_HOME}" + "${ssh_user_home}" fi # Create a user writeable data directory if no other directories are @@ -1184,7 +1195,7 @@ function main () mkdir -m 700 \ "${ssh_chroot_home_directory_path}"/_data chown -R \ - "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ + "${ssh_user}":"${ssh_user}" \ "${ssh_chroot_home_directory_path}"/_data elif [[ -d ${ssh_chroot_home_directory_path}/_data ]] then @@ -1192,12 +1203,12 @@ function main () chmod 700 \ "${ssh_chroot_home_directory_path}"/_data chown -R \ - "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ + "${ssh_user}":"${ssh_user}" \ "${ssh_chroot_home_directory_path}"/_data fi # ChrootDirectory must be owned by root user - if [[ ${ssh_chroot_directory_path} != "${OPTS_SSH_USER_HOME}" ]] + if [[ ${ssh_chroot_directory_path} != "${ssh_user_home}" ]] then chown \ root:root \ @@ -1206,17 +1217,17 @@ function main () "${ssh_chroot_directory_path}" else chown \ - root:"${OPTS_SSH_USER}" \ + root:"${ssh_user}" \ "${ssh_chroot_directory_path}" fi # Add user specific sshd configuration tee -a /etc/ssh/sshd_config > /dev/null <<-EOT # Force SFTP - Match User ${OPTS_SSH_USER} + Match User ${ssh_user} AllowTcpForwarding no X11Forwarding no - ChrootDirectory ${OPTS_SSH_CHROOT_DIRECTORY} + ChrootDirectory ${ssh_chroot_directory} ForceCommand internal-sftp EOT else @@ -1227,32 +1238,32 @@ function main () # SSH require files mkdir -m 700 \ - "${OPTS_SSH_USER_HOME}"/.ssh + "${ssh_user_home}"/.ssh touch \ - "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys + "${ssh_user_home}"/.ssh/authorized_keys chown -R \ - "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ - "${OPTS_SSH_USER_HOME}"/.ssh + "${ssh_user}":"${ssh_user}" \ + "${ssh_user_home}"/.ssh chmod 600 \ - "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys + "${ssh_user_home}"/.ssh/authorized_keys # Details output for SSH public key fingerprints - if [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == true ]] \ + if [[ ${ssh_password_authentication} == true ]] \ && [[ -z ${SSH_AUTHORIZED_KEYS} ]] then ssh_key_fingerprints="N/A" - elif ! __is_valid_ssh_authorized_keys "${OPTS_SSH_AUTHORIZED_KEYS}" + elif ! __is_valid_ssh_authorized_keys "${ssh_authorized_keys}" then printf -v ssh_key_fingerprints \ -- \ '%s\nUnable to populate %s/.ssh/authorized_key' \ "ERROR: Public key validation failed." \ - "${OPTS_SSH_USER_HOME}" + "${ssh_user_home}" else printf -- \ '%s\n' \ - "${OPTS_SSH_AUTHORIZED_KEYS}" \ - > "${OPTS_SSH_USER_HOME}"/.ssh/authorized_keys + "${ssh_authorized_keys}" \ + > "${ssh_user_home}"/.ssh/authorized_keys ssh_key_fingerprints="$( __get_ssh_authorized_key_fingerprints @@ -1260,46 +1271,46 @@ function main () fi # Details output for SSH private key fingerprint - if [[ -z ${OPTS_SSH_USER_PRIVATE_KEY} ]] \ - || [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + if [[ -z ${ssh_user_private_key} ]] \ + || [[ ${ssh_user_force_sftp} == true ]] then ssh_user_private_key_fingerprint="N/A" - elif ! __is_valid_ssh_key "${OPTS_SSH_USER_PRIVATE_KEY}" + elif ! __is_valid_ssh_key "${ssh_user_private_key}" then printf -v ssh_user_private_key_fingerprint \ -- \ '%s\nUnable to populate %s/.ssh/id_rsa' \ "ERROR: Private key validation failed." \ - "${OPTS_SSH_USER_HOME}" + "${ssh_user_home}" else printf -- \ '%s\n' \ - "${OPTS_SSH_USER_PRIVATE_KEY}" \ - > "${OPTS_SSH_USER_HOME}"/.ssh/id_rsa + "${ssh_user_private_key}" \ + > "${ssh_user_home}"/.ssh/id_rsa chown \ - "${OPTS_SSH_USER}":"${OPTS_SSH_USER}" \ - "${OPTS_SSH_USER_HOME}"/.ssh/id_rsa + "${ssh_user}":"${ssh_user}" \ + "${ssh_user_home}"/.ssh/id_rsa chmod 600 \ - ${OPTS_SSH_USER_HOME}/.ssh/id_rsa + ${ssh_user_home}/.ssh/id_rsa ssh_user_private_key_fingerprint="$( __get_ssh_key_fingerprint_hash_output \ - "${OPTS_SSH_USER_PRIVATE_KEY}" + "${ssh_user_private_key}" )" fi # Set sudo access for the wheel group only - if [[ ${DEFAULT_SSH_SUDO} != "${OPTS_SSH_SUDO}" ]] + if [[ ${DEFAULT_SSH_SUDO} != "${ssh_sudo}" ]] then sed -i \ - -e "s~^%wheel\\t.*$~%wheel\\t${OPTS_SSH_SUDO}~g" \ + -e "s~^%wheel\\t.*$~%wheel\\t${ssh_sudo}~g" \ /etc/sudoers fi tee -a /etc/sudoers > /dev/null <<-EOT - # ${OPTS_SSH_USER} + # ${ssh_user} Defaults:root secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin EOT @@ -1320,25 +1331,25 @@ function main () # password authentication or sudo. if [[ -n ${SSH_USER_PASSWORD} ]] then - OPTS_SSH_USER_PASSWORD="${redacted_value}" - elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ - && [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + ssh_user_password="${redacted_value}" + elif [[ ${ssh_password_authentication} == false ]] \ + && [[ ${ssh_user_force_sftp} == true ]] then - OPTS_SSH_USER_PASSWORD="${redacted_value}" - elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ - && [[ ${OPTS_SSH_USER} != root ]] \ - && __is_sudo_no_password_all "${OPTS_SSH_SUDO}" + ssh_user_password="${redacted_value}" + elif [[ ${ssh_password_authentication} == false ]] \ + && [[ ${ssh_user} != root ]] \ + && __is_sudo_no_password_all "${ssh_sudo}" then - OPTS_SSH_USER_PASSWORD="${redacted_value}" - elif [[ ${OPTS_SSH_PASSWORD_AUTHENTICATION} == false ]] \ - && [[ ${OPTS_SSH_USER} == root ]] + ssh_user_password="${redacted_value}" + elif [[ ${ssh_password_authentication} == false ]] \ + && [[ ${ssh_user} == root ]] then - OPTS_SSH_USER_PASSWORD="${redacted_value}" + ssh_user_password="${redacted_value}" fi - if [[ ${OPTS_SSH_USER_FORCE_SFTP} == true ]] + if [[ ${ssh_user_force_sftp} == true ]] then - OPTS_SSH_SUDO="N/A" + ssh_sudo="N/A" else ssh_chroot_directory_path="N/A" fi @@ -1359,21 +1370,21 @@ function main () ================================================================================ ${sshd_command} Details -------------------------------------------------------------------------------- - user : ${OPTS_SSH_USER} - password : ${OPTS_SSH_USER_PASSWORD} + user : ${ssh_user} + password : ${ssh_user_password} password authentication : ${password_authentication} - id : ${OPTS_SSH_USER_UID}:${OPTS_SSH_USER_GID} - home : ${OPTS_SSH_USER_HOME} + id : ${ssh_user_uid}:${ssh_user_gid} + home : ${ssh_user_home} chroot path : ${ssh_chroot_directory_path} - shell : ${OPTS_SSH_USER_SHELL} - sudo : ${OPTS_SSH_SUDO} + shell : ${ssh_user_shell} + sudo : ${ssh_sudo} key fingerprints : ${ssh_key_fingerprints} rsa private key fingerprint : ${ssh_user_private_key_fingerprint} rsa host key fingerprint : ${ssh_host_key_fingerprint_rsa} - timezone : ${OPTS_SSH_TIMEZONE} + timezone : ${ssh_timezone} -------------------------------------------------------------------------------- ${timer_total} From 53424ad82bf5910d240f4667ea81a82f988171de Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 16:03:32 +0000 Subject: [PATCH 24/35] #743: Removes check against unset variable. --- src/usr/sbin/sshd-bootstrap | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 0591316..d85b689 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -1300,13 +1300,10 @@ function main () )" fi - # Set sudo access for the wheel group only - if [[ ${DEFAULT_SSH_SUDO} != "${ssh_sudo}" ]] - then - sed -i \ - -e "s~^%wheel\\t.*$~%wheel\\t${ssh_sudo}~g" \ - /etc/sudoers - fi + # Set sudo access for the wheel group + sed -i \ + -e "s~^%wheel\\t.*$~%wheel\\t${ssh_sudo}~g" \ + /etc/sudoers tee -a /etc/sudoers > /dev/null <<-EOT From e52bae06862383734a303b88b3d5428d0770ae0f Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 16:06:12 +0000 Subject: [PATCH 25/35] #743: Adds changelong entry advising removal of .env file. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bb82c6..255fc3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Summary of release changes for Version 2 - CentOS-7 - Removes reference to `python-setuptools` from README as it's no longer installed. - Removes requirement of `supervisor_stdout` for output of supervisord logs to stdout. - Removes unnecessary configuration file `/etc/sshd-bootstrap.conf`. +- Removes unnecessary environment file `/etc/sshd-bootstrap.env`. ### 2.5.0 - 2019-01-28 From 8c3a0fca8ca92f69fb51f9604c09e29e072ae183 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 16:14:12 +0000 Subject: [PATCH 26/35] #743: Reverts back to population variable values only if required. --- src/usr/sbin/sshd-bootstrap | 79 +++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index d85b689..2022b22 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -985,51 +985,52 @@ function main () touch \ "${lock_file}" - ssh_authorized_keys="$( - __get_ssh_authorized_keys - )" - ssh_inherit_environment="$( - __get_ssh_inherit_environment - )" - ssh_password_authentication="$( - __get_ssh_password_authentication - )" - ssh_sudo="$( - __get_ssh_sudo - )" - ssh_timezone="$( - __get_ssh_timezone - )" - ssh_user="$( - __get_ssh_user - )" - ssh_user_force_sftp="$( - __get_ssh_user_force_sftp - )" ssh_user_home="$( __get_ssh_user_home )" - ssh_user_password_hashed="$( - __get_ssh_user_password_hashed - )" - ssh_user_password="${SSH_USER_PASSWORD:-"$( - __get_password "${password_length}" - )"}" - ssh_user_private_key="$( - __get_ssh_user_private_key - )" - ssh_user_shell="$( - __get_ssh_user_shell - )" - ssh_user_uid="$( - __get_ssh_user_uid - )" - ssh_user_gid="$( - __get_ssh_user_gid - )" if [[ ! -d ${ssh_user_home}/.ssh ]] then + ssh_authorized_keys="$( + __get_ssh_authorized_keys + )" + ssh_inherit_environment="$( + __get_ssh_inherit_environment + )" + ssh_password_authentication="$( + __get_ssh_password_authentication + )" + ssh_sudo="$( + __get_ssh_sudo + )" + ssh_timezone="$( + __get_ssh_timezone + )" + ssh_user="$( + __get_ssh_user + )" + ssh_user_force_sftp="$( + __get_ssh_user_force_sftp + )" + ssh_user_password_hashed="$( + __get_ssh_user_password_hashed + )" + ssh_user_password="${SSH_USER_PASSWORD:-"$( + __get_password "${password_length}" + )"}" + ssh_user_private_key="$( + __get_ssh_user_private_key + )" + ssh_user_shell="$( + __get_ssh_user_shell + )" + ssh_user_uid="$( + __get_ssh_user_uid + )" + ssh_user_gid="$( + __get_ssh_user_gid + )" + if [[ ${ssh_inherit_environment} == true ]] then env \ From c27a48fd298aecb97ebffd20b423eb31a5e76a87 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 16:36:04 +0000 Subject: [PATCH 27/35] #743: Removes bootstrap init message and move all SFTP logic together. --- README.md | 3 +-- src/usr/sbin/sshd-bootstrap | 34 ++++++++++------------------------ 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 5fa773e..bbe9332 100644 --- a/README.md +++ b/README.md @@ -265,8 +265,7 @@ The output of the logs will show the auto-generated password for the user specif 2019-01-17 18:56:10,089 INFO success: supervisor_stdout entered RUNNING state, process has stayed up for > than 0 seconds (startsecs) 2019-01-17 18:56:10,089 INFO success: sshd-bootstrap entered RUNNING state, process has stayed up for > than 0 seconds (startsecs) 2019-01-17 18:56:10,089 INFO success: sshd-wrapper entered RUNNING state, process has stayed up for > than 0 seconds (startsecs) -sshd-bootstrap stdout | Initialising SSH. -sshd-bootstrap stdout | + ================================================================================ SSH Details -------------------------------------------------------------------------------- diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 2022b22..09ea557 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -1059,20 +1059,6 @@ function main () /etc/ssh/sshd_config fi - if [[ ${ssh_user_force_sftp} == true ]] - then - sshd_command="SFTP" - ssh_user_groups="users" - ssh_chroot_directory="$( - __get_ssh_chroot_directory %h - )" - fi - - # Initialise - printf -- \ - 'Initialising %s.\n' \ - "${sshd_command}" - # Warn operator if any supplied environment variable values failed # validation and have been set to a safe default. for env in "${!env_validation_with_defaults[@]}" @@ -1155,11 +1141,17 @@ function main () exit 1 fi - # SFTP users if [[ ${ssh_user_force_sftp} == true ]] then - # Get the ChrootDirectory path. - # %h and %u are replaced with the User's HOME and USERNAME respectively. + sshd_command="SFTP" + ssh_sudo="N/A" + ssh_user_groups="users" + ssh_chroot_directory="$( + __get_ssh_chroot_directory %h + )" + + # Get the ChrootDirectory path. %h and %u are replaced with the + # HOME and USERNAME values respectively. ssh_chroot_directory_path="$( __get_ssh_chroot_directory_path "${ssh_chroot_directory}" )" @@ -1232,6 +1224,7 @@ function main () ForceCommand internal-sftp EOT else + ssh_chroot_directory_path="N/A" sed -i \ -e '/# Force SFTP/,/ForceCommand internal-sftp/ { d; }' \ /etc/ssh/sshd_config @@ -1345,13 +1338,6 @@ function main () ssh_user_password="${redacted_value}" fi - if [[ ${ssh_user_force_sftp} == true ]] - then - ssh_sudo="N/A" - else - ssh_chroot_directory_path="N/A" - fi - timer_total="$( awk \ -v timer_end="$( From 0810ce9574d3ed6f885175497c968b23ff1bec19 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 16:45:54 +0000 Subject: [PATCH 28/35] #743: Removes unnecessary message from output. --- src/usr/sbin/sshd-bootstrap | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 09ea557..462e081 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -1097,9 +1097,6 @@ function main () if [[ -n ${ssh_user_home%/*} ]] \ && [[ ! -d ${ssh_user_home%/*} ]] then - printf -- \ - 'Creating home base directory.\n' - mkdir -pm 755 \ "${ssh_user_home%/*}" fi From f20b3ca73d3361093ea924bde3e7f6607ad8abec Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 16:50:58 +0000 Subject: [PATCH 29/35] #743: Assign default value of chroot directory at start. --- src/usr/sbin/sshd-bootstrap | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 462e081..fb12395 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -959,7 +959,7 @@ function main () local -a pids local ssh_authorized_keys local ssh_chroot_directory - local ssh_chroot_directory_path + local ssh_chroot_directory_path="N/A" local ssh_chroot_home_directory_path local ssh_host_key_fingerprint_rsa local ssh_inherit_environment @@ -1221,7 +1221,6 @@ function main () ForceCommand internal-sftp EOT else - ssh_chroot_directory_path="N/A" sed -i \ -e '/# Force SFTP/,/ForceCommand internal-sftp/ { d; }' \ /etc/ssh/sshd_config From 680dfb15dab28212e25c7d2e166c53e12158e1aa Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 17:22:25 +0000 Subject: [PATCH 30/35] #743: Adds --verbose option to bootstrap script to allow details output to be hidden/minimal. --- src/etc/supervisord.d/sshd-bootstrap.conf | 2 +- src/usr/sbin/sshd-bootstrap | 160 ++++++++++++++-------- 2 files changed, 104 insertions(+), 58 deletions(-) diff --git a/src/etc/supervisord.d/sshd-bootstrap.conf b/src/etc/supervisord.d/sshd-bootstrap.conf index 71f0be0..b254f0a 100644 --- a/src/etc/supervisord.d/sshd-bootstrap.conf +++ b/src/etc/supervisord.d/sshd-bootstrap.conf @@ -1,7 +1,7 @@ [program:sshd-bootstrap] autorestart = false autostart = %(ENV_SSH_AUTOSTART_SSHD_BOOTSTRAP)s -command = /usr/sbin/sshd-bootstrap +command = /usr/sbin/sshd-bootstrap --verbose priority = 5 redirect_stderr = true startretries = 0 diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index fb12395..72fe8c7 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -981,10 +981,21 @@ function main () local sshd_command="SSH" local timer_total - # Create lock file + # Create lock touch \ "${lock_file}" + # Parse options + while [[ "${#}" -gt 0 ]] + do + case "${1}" in + -v|--verbose) + verbose=true + shift 1 + ;; + esac + done + ssh_user_home="$( __get_ssh_user_home )" @@ -1241,37 +1252,52 @@ function main () if [[ ${ssh_password_authentication} == true ]] \ && [[ -z ${SSH_AUTHORIZED_KEYS} ]] then - ssh_key_fingerprints="N/A" + if [[ ${verbose} == true ]] + then + ssh_key_fingerprints="N/A" + fi elif ! __is_valid_ssh_authorized_keys "${ssh_authorized_keys}" then - printf -v ssh_key_fingerprints \ - -- \ - '%s\nUnable to populate %s/.ssh/authorized_key' \ - "ERROR: Public key validation failed." \ - "${ssh_user_home}" + if [[ ${verbose} == true ]] + then + printf -v ssh_key_fingerprints \ + -- \ + '%s\nUnable to populate %s/.ssh/authorized_key' \ + "ERROR: Public key validation failed." \ + "${ssh_user_home}" + fi else printf -- \ '%s\n' \ "${ssh_authorized_keys}" \ > "${ssh_user_home}"/.ssh/authorized_keys - ssh_key_fingerprints="$( - __get_ssh_authorized_key_fingerprints - )" + if [[ ${verbose} == true ]] + then + ssh_key_fingerprints="$( + __get_ssh_authorized_key_fingerprints + )" + fi fi # Details output for SSH private key fingerprint if [[ -z ${ssh_user_private_key} ]] \ || [[ ${ssh_user_force_sftp} == true ]] then - ssh_user_private_key_fingerprint="N/A" + if [[ ${verbose} == true ]] + then + ssh_user_private_key_fingerprint="N/A" + fi elif ! __is_valid_ssh_key "${ssh_user_private_key}" then - printf -v ssh_user_private_key_fingerprint \ - -- \ - '%s\nUnable to populate %s/.ssh/id_rsa' \ - "ERROR: Private key validation failed." \ - "${ssh_user_home}" + if [[ ${verbose} == true ]] + then + printf -v ssh_user_private_key_fingerprint \ + -- \ + '%s\nUnable to populate %s/.ssh/id_rsa' \ + "ERROR: Private key validation failed." \ + "${ssh_user_home}" + fi else printf -- \ '%s\n' \ @@ -1284,10 +1310,13 @@ function main () chmod 600 \ ${ssh_user_home}/.ssh/id_rsa - ssh_user_private_key_fingerprint="$( - __get_ssh_key_fingerprint_hash_output \ - "${ssh_user_private_key}" - )" + if [[ ${verbose} == true ]] + then + ssh_user_private_key_fingerprint="$( + __get_ssh_key_fingerprint_hash_output \ + "${ssh_user_private_key}" + )" + fi fi # Set sudo access for the wheel group @@ -1304,9 +1333,12 @@ function main () # Wait for background processes - Host key generation wait ${pids[0]} - ssh_host_key_fingerprint_rsa="$( - __get_ssh_host_key_fingerprint rsa - )" + if [[ ${verbose} == true ]] + then + ssh_host_key_fingerprint_rsa="$( + __get_ssh_host_key_fingerprint rsa + )" + fi # Wait for background processes - Set password for root user if [[ -n ${pids[1]+isset} ]] @@ -1334,45 +1366,59 @@ function main () ssh_user_password="${redacted_value}" fi - timer_total="$( - awk \ - -v timer_end="$( - date +%s.%N - )" \ - -v timer_start="${timer_start}" \ - 'BEGIN { print \ - timer_end - timer_start; - }' - )" + if [[ ${verbose} == true ]] + then + timer_total="$( + awk \ + -v timer_end="$( + date +%s.%N + )" \ + -v timer_start="${timer_start}" \ + 'BEGIN { print \ + timer_end - timer_start; + }' + )" - cat <<-EOT - - ================================================================================ - ${sshd_command} Details - -------------------------------------------------------------------------------- - user : ${ssh_user} - password : ${ssh_user_password} - password authentication : ${password_authentication} - id : ${ssh_user_uid}:${ssh_user_gid} - home : ${ssh_user_home} - chroot path : ${ssh_chroot_directory_path} - shell : ${ssh_user_shell} - sudo : ${ssh_sudo} - key fingerprints : - ${ssh_key_fingerprints} - rsa private key fingerprint : - ${ssh_user_private_key_fingerprint} - rsa host key fingerprint : - ${ssh_host_key_fingerprint_rsa} - timezone : ${ssh_timezone} - -------------------------------------------------------------------------------- - ${timer_total} + cat <<-EOT + + ================================================================================ + ${sshd_command} Details + -------------------------------------------------------------------------------- + user : ${ssh_user} + password : ${ssh_user_password} + password authentication : ${password_authentication} + id : ${ssh_user_uid}:${ssh_user_gid} + home : ${ssh_user_home} + chroot path : ${ssh_chroot_directory_path} + shell : ${ssh_user_shell} + sudo : ${ssh_sudo} + key fingerprints : + ${ssh_key_fingerprints} + rsa private key fingerprint : + ${ssh_user_private_key_fingerprint} + rsa host key fingerprint : + ${ssh_host_key_fingerprint_rsa} + timezone : ${ssh_timezone} + -------------------------------------------------------------------------------- + ${timer_total} - EOT + EOT + elif [[ ${ssh_user_password} != "${redacted_value}" ]] + then + # Mininal ouput when required + cat <<-EOT + + ================================================================================ + ${sshd_command} Details + -------------------------------------------------------------------------------- + password : ${ssh_user_password} + -------------------------------------------------------------------------------- + EOT + fi fi - # Release lock file + # Release lock rm -f \ "${lock_file}" } From d011b4f4416202a659dbb31bcc3e87c42e7f1fc4 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 17:26:14 +0000 Subject: [PATCH 31/35] #743: Removes validation warnings if running in non-verbose mode. --- src/usr/sbin/sshd-bootstrap | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 72fe8c7..18df1ec 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -1072,15 +1072,18 @@ function main () # Warn operator if any supplied environment variable values failed # validation and have been set to a safe default. - for env in "${!env_validation_with_defaults[@]}" - do - if ! ${env_validation_with_defaults[${env}]} "${!env}" - then - printf -- \ - 'WARNING: Validation failed on %s - setting to default.\n' \ - "${env}" - fi - done + if [[ ${verbose} == true ]] + then + for env in "${!env_validation_with_defaults[@]}" + do + if ! ${env_validation_with_defaults[${env}]} "${!env}" + then + printf -- \ + 'WARNING: Validation failed on %s - setting to default.\n' \ + "${env}" + fi + done + fi if ! __set_ssh_timezone "${ssh_timezone}" then From 5000ddaf5558c8461f6e3382c61300824014b221 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 22:25:26 +0000 Subject: [PATCH 32/35] #743: Moves all validation logic into validation functions. --- src/usr/sbin/sshd-bootstrap | 48 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 18df1ec..8ccbbaa 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -45,6 +45,11 @@ function __is_valid_ssh_chroot_directory () local -r chroot_directory="${1}" local -r safe_directory='^(%h|\/(?!\/|bin|dev|etc|lib|lib64|lost+found|media|proc|root|sbin|srv|sys|tmp|usr).+)$' + if [[ -z ${chroot_directory} ]] + then + return 1 + fi + if grep -qoP "${safe_directory}" <<< "${chroot_directory}" then return 0 @@ -107,6 +112,11 @@ function __is_valid_ssh_sudo () )" local -r sudo_cmd="${1}" + if [[ -z ${sudo_cmd} ]] + then + return 1 + fi + trap \ "rm -f \"${temp_path}\"" \ EXIT INT RETURN TERM @@ -182,6 +192,11 @@ function __is_valid_ssh_user_home () local safe_directory="${user_directory}" + if [[ -z ${home_directory} ]] + then + return 1 + fi + if [[ ${user} == root ]] then safe_directory="${root_directory}" @@ -352,8 +367,7 @@ function __get_ssh_chroot_directory () local value="${SSH_CHROOT_DIRECTORY}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_chroot_directory "${value}" + if ! __is_valid_ssh_chroot_directory "${value}" then value="${default_value}" fi @@ -396,8 +410,7 @@ function __get_ssh_inherit_environment () local value="${SSH_INHERIT_ENVIRONMENT}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_inherit_environment "${value}" + if ! __is_valid_ssh_inherit_environment "${value}" then value="${default_value}" fi @@ -525,8 +538,7 @@ function __get_ssh_password_authentication () local value="${SSH_PASSWORD_AUTHENTICATION}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_password_authentication "${value}" + if ! __is_valid_ssh_password_authentication "${value}" then value="${default_value}" fi @@ -540,8 +552,7 @@ function __get_ssh_sudo () local value="${SSH_SUDO}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_sudo "${value}" + if ! __is_valid_ssh_sudo "${value}" then value="${default_value}" fi @@ -555,8 +566,7 @@ function __get_ssh_timezone () local value="${SSH_TIMEZONE}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_timezone "${value}" + if ! __is_valid_ssh_timezone "${value}" then value="${default_value}" fi @@ -570,8 +580,7 @@ function __get_ssh_user () local value="${SSH_USER}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_user "${value}" + if ! __is_valid_ssh_user "${value}" then value="${default_value}" fi @@ -585,8 +594,7 @@ function __get_ssh_user_password_hashed () local value="${SSH_USER_PASSWORD_HASHED}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_user_password_hashed "${value}" + if ! __is_valid_ssh_user_password_hashed "${value}" then value="${default_value}" fi @@ -622,8 +630,7 @@ function __get_ssh_user_force_sftp () local value="${SSH_USER_FORCE_SFTP}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_user_force_sftp "${value}" + if ! __is_valid_ssh_user_force_sftp "${value}" then value="${default_value}" fi @@ -659,8 +666,7 @@ function __get_ssh_user_home () local value="${SSH_USER_HOME}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_user_home "${value}" + if ! __is_valid_ssh_user_home "${value}" then if [[ ${user} == root ]] then @@ -686,8 +692,7 @@ function __get_ssh_user_id () local value="${SSH_USER_ID}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_user_id "${value}" + if ! __is_valid_ssh_user_id "${value}" then if [[ ${user} == root ]] then @@ -709,8 +714,7 @@ function __get_ssh_user_shell () local value="${SSH_USER_SHELL}" - if [[ -z ${value} ]] \ - || ! __is_valid_ssh_user_shell "${value}" + if ! __is_valid_ssh_user_shell "${value}" then value="${default_value}" fi From 68c11601b0bd4067329a834e2faf0907da9b1970 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 23:21:28 +0000 Subject: [PATCH 33/35] #743: Removes overide of default value with same default value, quotes path variable, tidies up comments. --- src/usr/sbin/sshd-bootstrap | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/usr/sbin/sshd-bootstrap b/src/usr/sbin/sshd-bootstrap index 8ccbbaa..583b01a 100755 --- a/src/usr/sbin/sshd-bootstrap +++ b/src/usr/sbin/sshd-bootstrap @@ -1056,6 +1056,7 @@ function main () if [[ ${ssh_password_authentication} == true ]] then password_authentication="yes" + if [[ ${ssh_user} == root ]] then sed -i \ @@ -1162,11 +1163,8 @@ function main () ssh_sudo="N/A" ssh_user_groups="users" ssh_chroot_directory="$( - __get_ssh_chroot_directory %h + __get_ssh_chroot_directory )" - - # Get the ChrootDirectory path. %h and %u are replaced with the - # HOME and USERNAME values respectively. ssh_chroot_directory_path="$( __get_ssh_chroot_directory_path "${ssh_chroot_directory}" )" @@ -1180,7 +1178,6 @@ function main () '%s%s' \ "${ssh_chroot_directory_path}" \ "${ssh_user_home}" - mkdir -pm 711 \ "${ssh_chroot_directory_path}" mkdir -pm 755 \ @@ -1188,13 +1185,12 @@ function main () else # ChrootDirectory %h ssh_chroot_home_directory_path="${ssh_user_home}" - chmod 750 \ - "${ssh_user_home}" + "${ssh_chroot_home_directory_path}" fi - # Create a user writeable data directory if no other directories are - # mounted. + # Create a user writeable data directory if no other directories + # are mounted. if ! grep -q '^d' <<< "$( ls -l "${ssh_chroot_home_directory_path}"/ )" @@ -1207,7 +1203,7 @@ function main () "${ssh_chroot_home_directory_path}"/_data elif [[ -d ${ssh_chroot_home_directory_path}/_data ]] then - # Set user permissions on _data directory in case where it exists + # Set user permissions on _data directory where it exists chmod 700 \ "${ssh_chroot_home_directory_path}"/_data chown -R \ @@ -1310,12 +1306,11 @@ function main () '%s\n' \ "${ssh_user_private_key}" \ > "${ssh_user_home}"/.ssh/id_rsa - chown \ "${ssh_user}":"${ssh_user}" \ "${ssh_user_home}"/.ssh/id_rsa chmod 600 \ - ${ssh_user_home}/.ssh/id_rsa + "${ssh_user_home}"/.ssh/id_rsa if [[ ${verbose} == true ]] then @@ -1353,8 +1348,8 @@ function main () wait ${pids[1]} fi - # Only show user password if auto-generated and password is required for - # password authentication or sudo. + # Only show user password if auto-generated and password is required + # for password authentication or sudo. if [[ -n ${SSH_USER_PASSWORD} ]] then ssh_user_password="${redacted_value}" From 9575a1882b9a5ef143e76db3ff1f8304e8dcd019 Mon Sep 17 00:00:00 2001 From: James Deathe Date: Wed, 27 Feb 2019 23:42:21 +0000 Subject: [PATCH 34/35] #743: Adds changelog entry for addition of SSH_INHERIT_ENVIRONMENT validation. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 255fc3f..5950cb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Summary of release changes for Version 2 - CentOS-7 - Adds `SSH_AUTOSTART_SUPERVISOR_STDOUT` to control startup of `supervisor_stdout`. - Adds drop-in configuration for `supervisor_stdout` in `/etc/supervisord.d/00-supervisor_stdout.conf`. - Adds improved `healtchcheck`, `sshd-bootstrap` and `sshd-wrapper` scripts. +- Adds validation of `SSH_INHERIT_ENVIRONMENT` values. - Removes reference to `python-setuptools` from README as it's no longer installed. - Removes requirement of `supervisor_stdout` for output of supervisord logs to stdout. - Removes unnecessary configuration file `/etc/sshd-bootstrap.conf`. From d980cf1484a4e5f430c03318496a52665a22afad Mon Sep 17 00:00:00 2001 From: James Deathe Date: Thu, 28 Feb 2019 00:13:14 +0000 Subject: [PATCH 35/35] Release changes for 1.10.1/2.5.1. --- CHANGELOG.md | 2 +- Dockerfile | 2 +- README.md | 40 ++++++++++++++++++++-------------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5950cb4..4d415e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ Summary of release changes for Version 2 - CentOS-7 -### 2.5.1 - Unreleased +### 2.5.1 - 2019-02-28 - Deprecates use of `supervisor_stdout` - the default value of `SSH_AUTOSTART_SUPERVISOR_STDOUT` will be switched to "false" in a future release. - Updates Dockerfile with combined ADD to reduce layer count in final image. diff --git a/Dockerfile b/Dockerfile index e626f56..995f25f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM centos:7.5.1804 -ARG RELEASE_VERSION="2.5.0" +ARG RELEASE_VERSION="2.5.1" # ------------------------------------------------------------------------------ # - Import the RPM GPG keys for repositories diff --git a/README.md b/README.md index bbe9332..adc168d 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ Includes public key authentication, Automated password generation and supports c ## Overview & links -The latest CentOS-6 / CentOS-7 based releases can be pulled from the `centos-6` / `centos-7` Docker tags respectively. For production use it is recommended to select a specific release tag - the convention is `centos-6-1.10.0` OR `1.10.0` for the [1.10.0](https://github.com/jdeathe/centos-ssh/tree/1.10.0) release tag and `centos-7-2.5.0` OR `2.5.0` for the [2.5.0](https://github.com/jdeathe/centos-ssh/tree/2.5.0) release tag. +The latest CentOS-6 / CentOS-7 based releases can be pulled from the `centos-6` / `centos-7` Docker tags respectively. For production use it is recommended to select a specific release tag - the convention is `centos-6-1.10.1` OR `1.10.1` for the [1.10.1](https://github.com/jdeathe/centos-ssh/tree/1.10.1) release tag and `centos-7-2.5.1` OR `2.5.1` for the [2.5.1](https://github.com/jdeathe/centos-ssh/tree/2.5.1) release tag. ### Tags and respective `Dockerfile` links -- `centos-7`,`centos-7-2.5.0`,`2.5.0` [(centos-7/Dockerfile)](https://github.com/jdeathe/centos-ssh/blob/centos-7/Dockerfile) -- `centos-6`,`centos-6-1.10.0`,`1.10.0` [(centos-6/Dockerfile)](https://github.com/jdeathe/centos-ssh/blob/centos-6/Dockerfile) +- `centos-7`,`centos-7-2.5.1`,`2.5.1` [(centos-7/Dockerfile)](https://github.com/jdeathe/centos-ssh/blob/centos-7/Dockerfile) +- `centos-6`,`centos-6-1.10.1`,`1.10.1` [(centos-6/Dockerfile)](https://github.com/jdeathe/centos-ssh/blob/centos-6/Dockerfile) The Dockerfile can be used to build a base image that is the bases for several other docker images. @@ -42,7 +42,7 @@ Run up an SSH container named 'ssh.1' from the docker image 'jdeathe/centos-ssh' $ docker run -d \ --name ssh.1 \ -p 2020:22 \ - jdeathe/centos-ssh:2.5.0 + jdeathe/centos-ssh:2.5.1 ``` Check the logs for the password (required for sudo). @@ -76,7 +76,7 @@ $ docker run -d \ --name sftp.1 \ -p 2021:22 \ -e SSH_USER_FORCE_SFTP=true \ - jdeathe/centos-ssh:2.5.0 + jdeathe/centos-ssh:2.5.1 ``` Connect using the `sftp` command line client with the [insecure private key](https://github.com/mitchellh/vagrant/blob/master/keys/vagrant). @@ -106,10 +106,10 @@ $ docker run \ --rm \ --privileged \ --volume /:/media/root \ - jdeathe/centos-ssh:2.5.0 \ + jdeathe/centos-ssh:2.5.1 \ /usr/sbin/scmi install \ --chroot=/media/root \ - --tag=2.5.0 \ + --tag=2.5.1 \ --name=ssh.1 \ --setopt="--volume {{NAME}}.config-ssh:/etc/ssh" ``` @@ -123,10 +123,10 @@ $ docker run \ --rm \ --privileged \ --volume /:/media/root \ - jdeathe/centos-ssh:2.5.0 \ + jdeathe/centos-ssh:2.5.1 \ /usr/sbin/scmi uninstall \ --chroot=/media/root \ - --tag=2.5.0 \ + --tag=2.5.1 \ --name=ssh.1 \ --setopt="--volume {{NAME}}.config-ssh:/etc/ssh" ``` @@ -140,10 +140,10 @@ $ docker run \ --rm \ --privileged \ --volume /:/media/root \ - jdeathe/centos-ssh:2.5.0 \ + jdeathe/centos-ssh:2.5.1 \ /usr/sbin/scmi install \ --chroot=/media/root \ - --tag=2.5.0 \ + --tag=2.5.1 \ --name=ssh.1 \ --manager=systemd \ --register \ @@ -159,7 +159,7 @@ Since release tags `1.7.2` / `2.1.2` the install template has been added to the _NOTE:_ A prerequisite of the following examples is that the image has been pulled (or loaded from the release package). ``` -$ docker pull jdeathe/centos-ssh:2.5.0 +$ docker pull jdeathe/centos-ssh:2.5.1 ``` To see detailed information about the image run `scmi` with the `--info` option. To see all available `scmi` options run with the `--help` option. @@ -168,7 +168,7 @@ To see detailed information about the image run `scmi` with the `--info` option. $ eval "sudo -E $( docker inspect \ -f "{{.ContainerConfig.Labels.install}}" \ - jdeathe/centos-ssh:2.5.0 + jdeathe/centos-ssh:2.5.1 ) --info" ``` @@ -178,7 +178,7 @@ To perform an installation using the docker name `ssh.2` simply use the `--name` $ eval "sudo -E $( docker inspect \ -f "{{.ContainerConfig.Labels.install}}" \ - jdeathe/centos-ssh:2.5.0 + jdeathe/centos-ssh:2.5.1 ) --name=ssh.2" ``` @@ -188,7 +188,7 @@ To uninstall use the *same command* that was used to install but with the `unins $ eval "sudo -E $( docker inspect \ -f "{{.ContainerConfig.Labels.uninstall}}" \ - jdeathe/centos-ssh:2.5.0 + jdeathe/centos-ssh:2.5.1 ) --name=ssh.2" ``` @@ -201,7 +201,7 @@ To see detailed information about the image run `scmi` with the `--info` option. ``` $ sudo -E atomic install \ -n ssh.3 \ - jdeathe/centos-ssh:2.5.0 \ + jdeathe/centos-ssh:2.5.1 \ --info ``` @@ -210,14 +210,14 @@ To perform an installation using the docker name `ssh.3` simply use the `-n` opt ``` $ sudo -E atomic install \ -n ssh.3 \ - jdeathe/centos-ssh:2.5.0 + jdeathe/centos-ssh:2.5.1 ``` Alternatively, you could use the `scmi` options `--name` or `-n` for naming the container. ``` $ sudo -E atomic install \ - jdeathe/centos-ssh:2.5.0 \ + jdeathe/centos-ssh:2.5.1 \ --name ssh.3 ``` @@ -226,7 +226,7 @@ To uninstall use the *same command* that was used to install but with the `unins ``` $ sudo -E atomic uninstall \ -n ssh.3 \ - jdeathe/centos-ssh:2.5.0 + jdeathe/centos-ssh:2.5.1 ``` #### Using environment variables @@ -242,7 +242,7 @@ $ docker stop ssh.1 \ --name ssh.1 \ -p :22 \ --env "SSH_USER=centos" \ - jdeathe/centos-ssh:2.5.0 + jdeathe/centos-ssh:2.5.1 ``` To identify the `SSH_USER` user's sudoer password, inspect the container's logs as follows: