From e83ea269ae832c15b92afc0e9f9b700068721a83 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 9 Jul 2020 15:07:39 +0200 Subject: [PATCH 01/24] Changed: initial revamp with passbolt debian package --- Dockerfile | 89 +++++++--------------------------------- bin/docker-entrypoint.sh | 22 +++++----- docker-compose.yml | 2 +- 3 files changed, 26 insertions(+), 87 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5797e7a..b39e323 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,84 +1,23 @@ -FROM php:7.3.16-fpm +FROM debian:buster-slim LABEL maintainer="Passbolt SA " -ARG PASSBOLT_VERSION="2.12.1" -ARG PASSBOLT_URL="https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz" -ARG PASSBOLT_CURL_HEADERS="" +ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D +ENV PASSBOLT_PKG=passbolt-ce-server -ARG PHP_EXTENSIONS="gd \ - intl \ - pdo_mysql \ - opcache \ - xsl" - -ARG PECL_PASSBOLT_EXTENSIONS="gnupg \ - redis \ - mcrypt" - -ARG PASSBOLT_DEV_PACKAGES="libgpgme11-dev \ - libpng-dev \ - libjpeg62-turbo-dev \ - libicu-dev \ - libxslt1-dev \ - libmcrypt-dev \ - unzip" - -ARG PASSBOLT_BASE_PACKAGES="nginx \ - gnupg \ - libgpgme11 \ - libmcrypt4 \ - mariadb-client \ - supervisor \ - cron" - -ENV PECL_BASE_URL="https://pecl.php.net/get" -ENV PHP_EXT_DIR="/usr/src/php/ext" - -WORKDIR /var/www/passbolt RUN apt-get update \ - && apt-get -y install --no-install-recommends \ - $PASSBOLT_DEV_PACKAGES \ - $PASSBOLT_BASE_PACKAGES \ - && mkdir /home/www-data \ - && chown -R www-data:www-data /home/www-data \ - && usermod -d /home/www-data www-data \ - && docker-php-source extract \ - && for i in $PECL_PASSBOLT_EXTENSIONS; do \ - mkdir $PHP_EXT_DIR/$i; \ - curl -sSL $PECL_BASE_URL/$i | tar zxf - -C $PHP_EXT_DIR/$i --strip-components 1; \ - done \ - && docker-php-ext-configure gd --with-jpeg-dir=/usr/include/ \ - && docker-php-ext-install -j4 $PHP_EXTENSIONS $PECL_PASSBOLT_EXTENSIONS \ - && docker-php-ext-enable $PHP_EXTENSIONS $PECL_PASSBOLT_EXTENSIONS \ - && docker-php-source delete \ - && EXPECTED_SIGNATURE=$(curl -s https://composer.github.io/installer.sig) \ - && curl -o composer-setup.php https://getcomposer.org/installer \ - && ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');") \ - && if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]; then \ - >&2 echo 'ERROR: Invalid installer signature'; \ - rm composer-setup.php; \ - exit 1; \ - fi \ - && php composer-setup.php \ - && mv composer.phar /usr/local/bin/composer \ - && rm composer-setup.php \ - && curl -sSL -H "$PASSBOLT_CURL_HEADERS" "$PASSBOLT_URL" | tar zxf - -C . --strip-components 1 \ - && composer install -n --no-dev --optimize-autoloader \ - && chown -R www-data:www-data . \ - && chmod 775 $(find /var/www/passbolt/tmp -type d) \ - && chmod 664 $(find /var/www/passbolt/tmp -type f) \ - && chmod 775 $(find /var/www/passbolt/webroot/img/public -type d) \ - && chmod 664 $(find /var/www/passbolt/webroot/img/public -type f) \ - && rm /etc/nginx/sites-enabled/default \ - && apt-get purge -y --auto-remove $PASSBOLT_DEV_PACKAGES \ - && rm -rf /var/lib/apt/lists/* \ - && rm /usr/local/bin/composer \ - && echo 'php_flag[expose_php] = off' > /usr/local/etc/php-fpm.d/expose.conf \ - && sed -i 's/# server_tokens/server_tokens/' /etc/nginx/nginx.conf \ - && mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + && DEBIAN_FRONTEND=non-interactive apt-get -y install \ + ca-certificates \ + gnupg \ + && apt-key adv --keyserver keys.gnupg.net --recv-keys $PASSBOLT_PKG_KEY \ + && echo "deb https://download.passbolt.com/ce/debian buster stable" > /etc/apt/sources.list.d/passbolt.list \ + && apt-get update \ + && DEBIAN_FRONTEND=non-interactive apt-get -y install --no-install-recommends \ + nginx \ + $PASSBOLT_PKG \ + supervisor + -COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ COPY bin/docker-entrypoint.sh /docker-entrypoint.sh COPY scripts/wait-for.sh /usr/bin/wait-for.sh diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 7bcef9c..e402318 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -8,7 +8,7 @@ gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-/var/www/passbolt/config/gpg/s ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' -export GNUPGHOME="/home/www-data/.gnupg" +export GNUPGHOME="/var/lib/passbolt/.gnupg" entropy_check() { local entropy_avail @@ -42,7 +42,7 @@ gpg_gen_key() { entropy_check - su -c "gpg --batch --no-tty --gen-key < $gpg_private_key" -ls /bin/bash www-data - su -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --armor --export-secret-keys $key_email > $gpg_private_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --armor --export $key_email > $gpg_public_key" -ls /bin/bash www-data } gpg_import_key() { - su -c "gpg --batch --import $gpg_public_key" -ls /bin/bash www-data - su -c "gpg --batch --import $gpg_private_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --batch --import $gpg_public_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --batch --import $gpg_private_key" -ls /bin/bash www-data } gen_ssl_cert() { @@ -70,18 +70,18 @@ gen_ssl_cert() { } install() { - local app_config="/var/www/passbolt/config/app.php" + local app_config="/etc/passbolt/app.php" if [ ! -f "$app_config" ]; then - su -c 'cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php' -s /bin/bash www-data + su -c "cp $app_config/app.default.php $app_config/app.php" -s /bin/bash www-data fi - if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f '/var/www/passbolt/config/passbolt.php' ]; then - gpg_auto_fingerprint="$(su -c "gpg --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" + if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$app_config/passbolt.php" ]; then + gpg_auto_fingerprint="$(su -c "gpg --homedir $GNUPGHOME --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint fi - su -c '/var/www/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data || su -c '/var/www/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data && echo "Enjoy! ☮" + su -c '/usr/share/php/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data || su -c '/usr/share/php/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data && echo "Enjoy! ☮" } email_cron_job() { diff --git a/docker-compose.yml b/docker-compose.yml index b735821..bf8c74f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: - "127.0.0.1:3306:3306" passbolt: - image: passbolt/passbolt:2.12.0-debian + image: localpassbolt tty: true depends_on: - db From b5c3c6e18f7ca77324d07798bc40c3c4df568b10 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 23 Jul 2020 12:08:26 +0200 Subject: [PATCH 02/24] Changed: non-root feature --- Dockerfile | 30 ++++++++++++++++++++++++- bin/docker-entrypoint.sh | 47 ++++++++++++++------------------------- conf/supervisor/cron.conf | 8 ------- conf/supervisor/php.conf | 2 +- docker-compose.yml | 4 ++-- env/passbolt.env | 2 +- 6 files changed, 50 insertions(+), 43 deletions(-) delete mode 100644 conf/supervisor/cron.conf diff --git a/Dockerfile b/Dockerfile index b39e323..2738a80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ LABEL maintainer="Passbolt SA " ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D ENV PASSBOLT_PKG=passbolt-ce-server +ENV GNUPGHOME=/var/lib/passbolt/.gnupg RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ @@ -17,11 +18,38 @@ RUN apt-get update \ $PASSBOLT_PKG \ supervisor +RUN sed -i 's,listen 80;,listen 8080;,' /etc/nginx/sites-enabled/nginx-passbolt.conf \ + && rm /etc/nginx/sites-enabled/default \ + && sed -i '/user www-data;/d' /etc/nginx/nginx.conf \ + && sed -i 's,/run/nginx.pid,/tmp/nginx.pid,' /etc/nginx/nginx.conf \ + && sed -i "/^http {/a \ proxy_temp_path /tmp/proxy_temp;\n client_body_temp_path /tmp/client_temp;\n fastcgi_temp_path /tmp/fastcgi_temp;\n uwsgi_temp_path /tmp/uwsgi_temp;\n scgi_temp_path /tmp/scgi_temp;\n" /etc/nginx/nginx.conf \ + && sed -i 's,listen = /run/php/php7.3-fpm.sock,listen = 127.0.0.1:9000,' /etc/php/7.3/fpm/pool.d/www.conf \ + && sed -i 's,unix:/run/php/php7.3-fpm.sock,127.0.0.1:9000,' /etc/nginx/sites-enabled/nginx-passbolt.conf \ + && sed -i 's,pid = /run/php/php7.3-fpm.pid,pid = /tmp/php7.3-fpm.pid,' /etc/php/7.3/fpm/php-fpm.conf \ + && sed -i 's,/var/run/supervisor.sock,/tmp/supervisor.sock,' /etc/supervisor/supervisord.conf \ +# nginx user must own the cache and etc directory to write cache and tweak the nginx config + #&& chown -R www-data:0 /var/cache/nginx \ + #&& chmod -R g+w /var/cache/nginx \ + && chown -R www-data:0 /etc/nginx \ + && chmod -R g+w /etc/nginx \ + && mkdir /etc/passbolt/certs \ + && chown www-data:0 /etc/passbolt/certs \ + && chown www-data:0 /var/log/supervisor \ + && chown -R www-data:0 /var/log/nginx \ + && ln -sf /dev/stdout /var/log/nginx/passbolt-access.log \ + && ln -sf /dev/stderr /var/log/nginx/passbolt-error.log \ + && ln -sf /dev/stderr /var/log/passbolt/error.log \ + && ln -sf /dev/stderr /var/log/php7.3-fpm.log \ + && chown -R www-data:0 /var/log/supervisor \ + && touch /var/www/.profile \ + && chown www-data:www-data /var/www/.profile COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ COPY bin/docker-entrypoint.sh /docker-entrypoint.sh COPY scripts/wait-for.sh /usr/bin/wait-for.sh -EXPOSE 80 443 +EXPOSE 8080 4443 + +USER www-data CMD ["/docker-entrypoint.sh"] diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index e402318..59c44c9 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -2,13 +2,14 @@ set -euo pipefail -gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-/var/www/passbolt/config/gpg/serverkey_private.asc}" -gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-/var/www/passbolt/config/gpg/serverkey.asc}" +passbolt_base='/usr/share/php/passbolt' +passbolt_config="/etc/passbolt" -ssl_key='/etc/ssl/certs/certificate.key' -ssl_cert='/etc/ssl/certs/certificate.crt' +gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-$passbolt_config/gpg/serverkey_private.asc}" +gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-$passbolt_config/gpg/serverkey.asc}" -export GNUPGHOME="/var/lib/passbolt/.gnupg" +ssl_key="$passbolt_config/certs/certificate.key" +ssl_cert="$passbolt_config/certs/certificate.crt" entropy_check() { local entropy_avail @@ -42,7 +43,7 @@ gpg_gen_key() { entropy_check - su -c "gpg --homedir $GNUPGHOME --batch --no-tty --gen-key < $gpg_private_key" -ls /bin/bash www-data - su -c "gpg --homedir $GNUPGHOME --armor --export $key_email > $gpg_public_key" -ls /bin/bash www-data + gpg --armor --export-secret-keys "$key_email" > "$gpg_private_key" + gpg --armor --export "$key_email" > "$gpg_public_key" } gpg_import_key() { - su -c "gpg --homedir $GNUPGHOME --batch --import $gpg_public_key" -ls /bin/bash www-data - su -c "gpg --homedir $GNUPGHOME --batch --import $gpg_private_key" -ls /bin/bash www-data + gpg --batch --import "$gpg_public_key" + gpg --batch --import "$gpg_private_key" } gen_ssl_cert() { openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ -subj '/C=FR/ST=Denial/L=Springfield/O=Dis/CN=www.passbolt.local' \ - -keyout $ssl_key -out $ssl_cert + -keyout "$ssl_key" -out "$ssl_cert" } install() { - local app_config="/etc/passbolt/app.php" - - if [ ! -f "$app_config" ]; then - su -c "cp $app_config/app.default.php $app_config/app.php" -s /bin/bash www-data - fi - - if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$app_config/passbolt.php" ]; then - gpg_auto_fingerprint="$(su -c "gpg --homedir $GNUPGHOME --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" + if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$passbolt_config/passbolt.php" ]; then + gpg_auto_fingerprint="$(gpg --list-keys --with-colons "${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com}" |grep fpr |head -1| cut -f10 -d:)" export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint + declare -p | grep PASSBOLT_GPG_SERVER_KEY_FINGERPRINT > ~/.profile fi - su -c '/usr/share/php/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data || su -c '/usr/share/php/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data && echo "Enjoy! ☮" + "$passbolt_base/bin/cake" passbolt install --no-admin || "$passbolt_base/bin/cake" passbolt migrate && echo "Enjoy! ☮" } -email_cron_job() { - cron_task='/etc/cron.d/passbolt_email' - declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /etc/environment - if [ ! -f "$cron_task" ]; then - echo "* * * * * su -c \"source /etc/environment ; /var/www/passbolt/bin/cake EmailQueue.sender\" -s /bin/bash www-data >> /var/log/cron.log 2>&1" >> $cron_task - crontab /etc/cron.d/passbolt_email - fi -} if [ ! -f "$gpg_private_key" ] && [ ! -L "$gpg_private_key" ] || \ [ ! -f "$gpg_public_key" ] && [ ! -L "$gpg_public_key" ]; then @@ -107,6 +95,5 @@ if [ ! -f "$ssl_key" ] && [ ! -L "$ssl_key" ] && \ fi install -email_cron_job exec /usr/bin/supervisord -n diff --git a/conf/supervisor/cron.conf b/conf/supervisor/cron.conf deleted file mode 100644 index 5b6291f..0000000 --- a/conf/supervisor/cron.conf +++ /dev/null @@ -1,8 +0,0 @@ -[program:cron] -command=cron -f -l -autostart=true -priority=20 -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 -stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=0 diff --git a/conf/supervisor/php.conf b/conf/supervisor/php.conf index c008c6b..a98b80c 100644 --- a/conf/supervisor/php.conf +++ b/conf/supervisor/php.conf @@ -1,5 +1,5 @@ [program:php-fpm] -command=php-fpm -F +command=php-fpm7.3 -F autostart=true priority=5 stdout_logfile=/dev/stdout diff --git a/docker-compose.yml b/docker-compose.yml index bf8c74f..e438d62 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,8 +23,8 @@ services: - /run command: ["/usr/bin/wait-for.sh", "-t", "0", "db:3306", "--", "/docker-entrypoint.sh"] ports: - - 80:80 - - 443:443 + - 80:8080 + - 443:4443 volumes: database_volume: diff --git a/env/passbolt.env b/env/passbolt.env index 1f0ec57..2b38655 100644 --- a/env/passbolt.env +++ b/env/passbolt.env @@ -1,5 +1,5 @@ # URL -APP_FULL_BASE_URL=https://passbolt.local +APP_FULL_BASE_URL=http://passbolt.local # Database settings DATASOURCES_DEFAULT_HOST=db From 6635960f401ed352cef33eb73d3440012249a3c2 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Thu, 23 Jul 2020 17:48:34 +0200 Subject: [PATCH 03/24] Changed: fix SSL nginx configs * variable renaming on entrypoint * php version --- Dockerfile | 12 ++++++++++-- bin/docker-entrypoint.sh | 12 ++++++------ conf/supervisor/php.conf | 2 +- docker-compose.yml | 6 ++---- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index b39e323..439b202 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ LABEL maintainer="Passbolt SA " ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D ENV PASSBOLT_PKG=passbolt-ce-server +ENV PHP_VERSION=7.3 RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ @@ -15,8 +16,15 @@ RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install --no-install-recommends \ nginx \ $PASSBOLT_PKG \ - supervisor - + supervisor \ + && rm /etc/nginx/sites-enabled/default \ + && mkdir /run/php \ + && cp /usr/share/passbolt/examples/nginx-passbolt-ssl.conf /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,;clear_env = no,clear_env = no,' /etc/php/$PHP_VERSION/fpm/pool.d/www.conf \ + && sed -i 's,# include __PASSBOLT_SSL__,include /etc/nginx/snippets/passbolt-ssl.conf;,' /etc/nginx/sites-enabled/nginx-passbolt.conf \ + && sed -i 's,ssl on;,listen 443 ssl;,' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,__CERT_PATH__,/etc/ssl/certs/certificate.crt;,' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,__KEY_PATH__,/etc/ssl/certs/certificate.key;,' /etc/nginx/snippets/passbolt-ssl.conf COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ COPY bin/docker-entrypoint.sh /docker-entrypoint.sh diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index e402318..15e2f36 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -2,8 +2,9 @@ set -euo pipefail -gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-/var/www/passbolt/config/gpg/serverkey_private.asc}" -gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-/var/www/passbolt/config/gpg/serverkey.asc}" +passbolt_config="/etc/passbolt" +gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-$passbolt_config/gpg/serverkey_private.asc}" +gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-$passbolt_config/gpg/serverkey.asc}" ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' @@ -70,13 +71,12 @@ gen_ssl_cert() { } install() { - local app_config="/etc/passbolt/app.php" - if [ ! -f "$app_config" ]; then - su -c "cp $app_config/app.default.php $app_config/app.php" -s /bin/bash www-data + if [ ! -f "$passbolt_config/app.php" ]; then + su -c "cp $passbolt_config/app.default.php $passbolt_config/app.php" -s /bin/bash www-data fi - if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$app_config/passbolt.php" ]; then + if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$passbolt_config/passbolt.php" ]; then gpg_auto_fingerprint="$(su -c "gpg --homedir $GNUPGHOME --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint fi diff --git a/conf/supervisor/php.conf b/conf/supervisor/php.conf index c008c6b..a98b80c 100644 --- a/conf/supervisor/php.conf +++ b/conf/supervisor/php.conf @@ -1,5 +1,5 @@ [program:php-fpm] -command=php-fpm -F +command=php-fpm7.3 -F autostart=true priority=5 stdout_logfile=/dev/stdout diff --git a/docker-compose.yml b/docker-compose.yml index bf8c74f..868cce8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,10 +17,8 @@ services: env_file: - env/passbolt.env volumes: - - gpg_volume:/var/www/passbolt/config/gpg - - images_volume:/var/www/passbolt/webroot/img/public - tmpfs: - - /run + - gpg_volume:/var/lib/passbolt/.gnupg + - images_volume:/usr/share/php/passbolt/webroot/img/public command: ["/usr/bin/wait-for.sh", "-t", "0", "db:3306", "--", "/docker-entrypoint.sh"] ports: - 80:80 From 169780b30e9b5aad9647c3d6379f2d99ba155677 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Fri, 24 Jul 2020 09:27:15 +0200 Subject: [PATCH 04/24] Deleted: passbolt.conf --- conf/passbolt.conf | 76 ---------------------------------------------- 1 file changed, 76 deletions(-) delete mode 100644 conf/passbolt.conf diff --git a/conf/passbolt.conf b/conf/passbolt.conf deleted file mode 100644 index 7b3f453..0000000 --- a/conf/passbolt.conf +++ /dev/null @@ -1,76 +0,0 @@ -server { - listen 80; - - client_body_buffer_size 100K; - client_header_buffer_size 1K; - client_max_body_size 5M; - - client_body_timeout 10; - client_header_timeout 10; - keepalive_timeout 5 5; - send_timeout 10; - - root /var/www/passbolt/webroot; - index index.php; - error_log /dev/stdout info; - access_log /dev/stdout; - - location / { - try_files $uri $uri/ /index.php?$args; - } - - location ~ \.php$ { - try_files $uri =404; - include fastcgi_params; - fastcgi_pass 127.0.0.1:9000; - fastcgi_index index.php; - fastcgi_intercept_errors on; - fastcgi_split_path_info ^(.+\.php)(.+)$; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param SERVER_NAME $http_host; - fastcgi_param PHP_VALUE "upload_max_filesize=5M \n post_max_size=5M"; - } - -} - -server { - listen 443; - - client_body_buffer_size 100K; - client_header_buffer_size 1K; - client_max_body_size 5M; - - client_body_timeout 10; - client_header_timeout 10; - keepalive_timeout 5 5; - send_timeout 10; - - ssl on; - ssl_certificate /etc/ssl/certs/certificate.crt; - ssl_certificate_key /etc/ssl/certs/certificate.key; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; - ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:@STRENGTH"; - ssl_session_tickets off; - - root /var/www/passbolt/webroot; - index index.php; - error_log /dev/stdout info; - access_log /dev/stdout; - - location / { - try_files $uri $uri/ /index.php?$args; - } - - location ~ \.php$ { - try_files $uri =404; - include fastcgi_params; - fastcgi_pass 127.0.0.1:9000; - fastcgi_index index.php; - fastcgi_intercept_errors on; - fastcgi_split_path_info ^(.+\.php)(.+)$; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param SERVER_NAME $http_host; - fastcgi_param PHP_VALUE "upload_max_filesize=5M \n post_max_size=5M"; - } -} From e6f915ebe4675be005a7c6eb4393284582b36602 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 18 Jan 2021 18:44:15 +0100 Subject: [PATCH 05/24] Changed: Dockerfile build args to customize debian repo. --- Dockerfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 439b202..38fe0aa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,12 +6,16 @@ ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D ENV PASSBOLT_PKG=passbolt-ce-server ENV PHP_VERSION=7.3 +ARG PASSBOLT_REPO_URL="https://download.passbolt.com/ce/debian" +ARG PASSBOLT_DISTRO="buster" +ARG PASSBOLT_COMPONENT="stable" + RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ ca-certificates \ gnupg \ && apt-key adv --keyserver keys.gnupg.net --recv-keys $PASSBOLT_PKG_KEY \ - && echo "deb https://download.passbolt.com/ce/debian buster stable" > /etc/apt/sources.list.d/passbolt.list \ + && echo "deb $PASSBOLT_REPO_URL $PASSBOLT_DISTRO $PASSBOLT_COMPONENT" > /etc/apt/sources.list.d/passbolt.list \ && apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install --no-install-recommends \ nginx \ From 027b170d7a49af08cc6aca1c4daecd9f0a1e0d4e Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 25 Jan 2021 15:50:21 +0100 Subject: [PATCH 06/24] Changed: move Dockerfiles to dev and debian directories. --- Dockerfile => debian/Dockerfile | 0 dev/Dockerfile | 88 +++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) rename Dockerfile => debian/Dockerfile (100%) create mode 100644 dev/Dockerfile diff --git a/Dockerfile b/debian/Dockerfile similarity index 100% rename from Dockerfile rename to debian/Dockerfile diff --git a/dev/Dockerfile b/dev/Dockerfile new file mode 100644 index 0000000..5797e7a --- /dev/null +++ b/dev/Dockerfile @@ -0,0 +1,88 @@ +FROM php:7.3.16-fpm + +LABEL maintainer="Passbolt SA " + +ARG PASSBOLT_VERSION="2.12.1" +ARG PASSBOLT_URL="https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz" +ARG PASSBOLT_CURL_HEADERS="" + +ARG PHP_EXTENSIONS="gd \ + intl \ + pdo_mysql \ + opcache \ + xsl" + +ARG PECL_PASSBOLT_EXTENSIONS="gnupg \ + redis \ + mcrypt" + +ARG PASSBOLT_DEV_PACKAGES="libgpgme11-dev \ + libpng-dev \ + libjpeg62-turbo-dev \ + libicu-dev \ + libxslt1-dev \ + libmcrypt-dev \ + unzip" + +ARG PASSBOLT_BASE_PACKAGES="nginx \ + gnupg \ + libgpgme11 \ + libmcrypt4 \ + mariadb-client \ + supervisor \ + cron" + +ENV PECL_BASE_URL="https://pecl.php.net/get" +ENV PHP_EXT_DIR="/usr/src/php/ext" + +WORKDIR /var/www/passbolt +RUN apt-get update \ + && apt-get -y install --no-install-recommends \ + $PASSBOLT_DEV_PACKAGES \ + $PASSBOLT_BASE_PACKAGES \ + && mkdir /home/www-data \ + && chown -R www-data:www-data /home/www-data \ + && usermod -d /home/www-data www-data \ + && docker-php-source extract \ + && for i in $PECL_PASSBOLT_EXTENSIONS; do \ + mkdir $PHP_EXT_DIR/$i; \ + curl -sSL $PECL_BASE_URL/$i | tar zxf - -C $PHP_EXT_DIR/$i --strip-components 1; \ + done \ + && docker-php-ext-configure gd --with-jpeg-dir=/usr/include/ \ + && docker-php-ext-install -j4 $PHP_EXTENSIONS $PECL_PASSBOLT_EXTENSIONS \ + && docker-php-ext-enable $PHP_EXTENSIONS $PECL_PASSBOLT_EXTENSIONS \ + && docker-php-source delete \ + && EXPECTED_SIGNATURE=$(curl -s https://composer.github.io/installer.sig) \ + && curl -o composer-setup.php https://getcomposer.org/installer \ + && ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');") \ + && if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]; then \ + >&2 echo 'ERROR: Invalid installer signature'; \ + rm composer-setup.php; \ + exit 1; \ + fi \ + && php composer-setup.php \ + && mv composer.phar /usr/local/bin/composer \ + && rm composer-setup.php \ + && curl -sSL -H "$PASSBOLT_CURL_HEADERS" "$PASSBOLT_URL" | tar zxf - -C . --strip-components 1 \ + && composer install -n --no-dev --optimize-autoloader \ + && chown -R www-data:www-data . \ + && chmod 775 $(find /var/www/passbolt/tmp -type d) \ + && chmod 664 $(find /var/www/passbolt/tmp -type f) \ + && chmod 775 $(find /var/www/passbolt/webroot/img/public -type d) \ + && chmod 664 $(find /var/www/passbolt/webroot/img/public -type f) \ + && rm /etc/nginx/sites-enabled/default \ + && apt-get purge -y --auto-remove $PASSBOLT_DEV_PACKAGES \ + && rm -rf /var/lib/apt/lists/* \ + && rm /usr/local/bin/composer \ + && echo 'php_flag[expose_php] = off' > /usr/local/etc/php-fpm.d/expose.conf \ + && sed -i 's/# server_tokens/server_tokens/' /etc/nginx/nginx.conf \ + && mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf +COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ +COPY bin/docker-entrypoint.sh /docker-entrypoint.sh +COPY scripts/wait-for.sh /usr/bin/wait-for.sh + +EXPOSE 80 443 + +CMD ["/docker-entrypoint.sh"] From 08e090abc55789c0f547d609e809b9256851b90c Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 25 Jan 2021 18:24:12 +0100 Subject: [PATCH 07/24] Changed: entrypoint.sh shows warning messagge when detects deprecated paths. --- bin/docker-entrypoint.sh | 49 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 15e2f36..872c290 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -euo pipefail +set -eo pipefail passbolt_config="/etc/passbolt" gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-$passbolt_config/gpg/serverkey_private.asc}" @@ -9,6 +9,8 @@ gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-$passbolt_config/gpg/serverkey ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' +deprecation_message="" + export GNUPGHOME="/var/lib/passbolt/.gnupg" entropy_check() { @@ -93,8 +95,47 @@ email_cron_job() { fi } -if [ ! -f "$gpg_private_key" ] && [ ! -L "$gpg_private_key" ] || \ - [ ! -f "$gpg_public_key" ] && [ ! -L "$gpg_public_key" ]; then +create_deprecation_message() { + deprecation_message+="\033[33;5;7mWARNING: $1 is deprecated, point your docker volume to $2\033[0m\n" +} + +check_deprecated_paths() { + declare -A deprecated_paths + local deprecated_avatar_path="/var/www/passbolt/webroot/img/public/Avatar" + local avatar_path="/usr/share/php/passbolt/webroot/img/public/Avatar" + local deprecated_subscription_path="/var/www/passbolt/webroot/img/public/Avatar" + local subscription_path="/etc/passbolt/license" + deprecated_paths=( + ['/var/www/passbolt/config/gpg/serverkey.asc']='/etc/passbolt/gpg/serverkey.asc' + ['/var/www/passbolt/config/gpg/serverkey_private.asc']='/etc/passbolt/gpg/serverkey_private.asc' + ) + + if [ -z "$PASSBOLT_GPG_SERVER_KEY_PUBLIC" ] || [ -z "$PASSBOLT_GPG_SERVER_KEY_PRIVATE" ]; then + for path in "${!deprecated_paths[@]}" + do + echo "VOLTA" + if [ -f "$path" ] && [ ! -f "${deprecated_paths[$path]}" ]; then + ln -s "$path" "${deprecated_paths[$path]}" + create_deprecation_message "$path" "${deprecated_paths[$path]}" + fi + done + fi + + if [ -d "$deprecated_avatar_path" ] && [ ! -d "$avatar_path" ]; then + ln -s "$deprecated_avatar_path" "$avatar_path" + create_deprecation_message "$deprecated_avatar_path" "$avatar_path" + fi + + if [ -f "$deprecated_subscription_path" ] && [ ! -f "$subscription_path" ]; then + ln -s "$deprecated_subscription_path" "$subscription_path" + create_deprecation_message "$deprecated_subscription_path" "$subscription_path" + fi +} + +check_deprecated_paths + +if [ ! -f "$gpg_private_key" ] || \ + [ ! -f "$gpg_public_key" ]; then gpg_gen_key gpg_import_key else @@ -109,4 +150,6 @@ fi install email_cron_job +echo -e "$deprecation_message" + exec /usr/bin/supervisord -n From bd19c1a15b0463fe862273dd972f5ee6394601d3 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 25 Jan 2021 18:51:08 +0100 Subject: [PATCH 08/24] Added: nightly pipeline. --- .gitlab-ci.yml | 13 +++++ .gitlab-ci/Jobs/build_image.yml | 30 +++++++++++ .gitlab-ci/Jobs/container_security_scan.yml | 59 +++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100644 .gitlab-ci/Jobs/build_image.yml create mode 100644 .gitlab-ci/Jobs/container_security_scan.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..716a2a5 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,13 @@ +image: alpine:latest + +variables: + DOCKER_DRIVER: overlay2 + DOCKER_HOST: tcp://localhost:2375/ + +stages: + - build + - test + +include: + - local: '/.gitlab-ci/Jobs/build_image.yml' + - local: '/.gitlab-ci/Jobs/container_security_scan.yml' diff --git a/.gitlab-ci/Jobs/build_image.yml b/.gitlab-ci/Jobs/build_image.yml new file mode 100644 index 0000000..6af2da0 --- /dev/null +++ b/.gitlab-ci/Jobs/build_image.yml @@ -0,0 +1,30 @@ +.passbolt-prerelease: + stage: build + image: + name: gcr.io/kaniko-project/executor:debug + entrypoint: [""] + script: + - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json + - | + echo "********************************************" + echo "Build details" + echo "============================================" + echo "Flavour ${PASSBOLT_FLAVOUR:-local}" + echo "Commit ${UPSTREAM_COMMIT_SHA:-latest}" + echo "********************************************" + - | + /kaniko/executor --context $CI_PROJECT_DIR \ + --build-arg PASSBOLT_PKG="passbolt-$PASSBOLT_FLAVOUR-server" \ + --build-arg PASSBOLT_REPO_URL="https://download.passbolt.com/$PASSBOLT_FLAVOUR/debian" \ + --build-arg PASSBOLT_COMPONENT="$COMPONENT" \ + --dockerfile $CI_PROJECT_DIR/debian/Dockerfile \ + --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-$(date +%s) + +prerelease-pro: + extends: .passbolt-prerelease + variables: + PASSBOLT_URL: "https://gitlab.com/api/v4/projects/$UPSTREAM_PROJECT_ID/repository/archive.tar.gz?sha=$UPSTREAM_COMMIT_SHA" + PASSBOLT_CURL_HEADERS: "PRIVATE-TOKEN: $PRIVATE_TOKEN" + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_BRANCH == "develop"' + when: on_success diff --git a/.gitlab-ci/Jobs/container_security_scan.yml b/.gitlab-ci/Jobs/container_security_scan.yml new file mode 100644 index 0000000..00afead --- /dev/null +++ b/.gitlab-ci/Jobs/container_security_scan.yml @@ -0,0 +1,59 @@ +# Read more about this feature here: https://docs.gitlab.com/ee/user/project/merge_requests/container_scanning.html + +container_scanning: + stage: test + image: docker:stable + variables: + DOCKER_DRIVER: overlay2 + # Defining two new variables based on GitLab's CI/CD predefined variables + # https://docs.gitlab.com/ee/ci/variables/#predefined-environment-variables + CI_APPLICATION_REPOSITORY: $CI_REGISTRY_IMAGE + # Prior to this, you need to have the Container Registry running for your project and setup a build job + # with at least the following steps: + # + # docker build -t $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG . + # docker push $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA + # + # Container Scanning deals with Docker images only so no need to import the project's Git repository: + GIT_STRATEGY: none + # Services and containers running in the same Kubernetes pod are all sharing the same localhost address + # https://docs.gitlab.com/runner/executors/kubernetes.html + DOCKER_SERVICE: localhost + DOCKER_HOST: tcp://${DOCKER_SERVICE}:2375/ + # https://hub.docker.com/r/arminc/clair-local-scan/tags + CLAIR_LOCAL_SCAN_VERSION: v2.0.8_fe9b059d930314b54c78f75afe265955faf4fdc1 + allow_failure: true + services: + - docker:18-dind + script: + - export CI_APPLICATION_TAG=${PASSBOLT_FLAVOUR:-local}-${UPSTREAM_COMMIT_SHA:-latest} + - echo "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" + - if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then { export DOCKER_SERVICE="localhost" ; export DOCKER_HOST="tcp://${DOCKER_SERVICE}:2375" ; } fi + - | + if [[ -n "$CI_REGISTRY_USER" ]]; then + echo "Logging to GitLab Container Registry with CI credentials..." + docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" + echo "" + fi + - docker run -d --name db arminc/clair-db:latest + - docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:${CLAIR_LOCAL_SCAN_VERSION} + - apk add -U wget ca-certificates + - docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} + - wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64 + - mv clair-scanner_linux_amd64 clair-scanner + - chmod +x clair-scanner + - touch clair-whitelist.yml + - retries=0 + - echo "Waiting for clair daemon to start" + - while( ! wget -T 10 -q -O /dev/null http://${DOCKER_SERVICE}:6060/v1/namespaces ) ; do sleep 1 ; echo -n "." ; if [ $retries -eq 10 ] ; then echo " Timeout, aborting." ; exit 1 ; fi ; retries=$(($retries+1)) ; done + - ./clair-scanner -c http://${DOCKER_SERVICE}:6060 --ip $(hostname -i) -r gl-container-scanning-report.json -l clair.log -w clair-whitelist.yml -t Medium ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true + artifacts: + reports: + container_scanning: gl-container-scanning-report.json + dependencies: [] + only: + refs: + - branches + except: + variables: + - $CONTAINER_SCANNING_DISABLED From 8cedbaa67998c57ca79875325f4d07bc67cf2777 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 25 Jan 2021 17:55:23 +0000 Subject: [PATCH 09/24] Changed: fix SSL nginx configs * variable renaming on entrypoint * php version --- .gitlab-ci.yml | 13 ++++ .gitlab-ci/Jobs/build_image.yml | 30 ++++++++ .gitlab-ci/Jobs/container_security_scan.yml | 59 ++++++++++++++++ bin/docker-entrypoint.sh | 77 ++++++++++++++++----- conf/supervisor/php.conf | 2 +- debian/Dockerfile | 39 +++++++++++ Dockerfile => dev/Dockerfile | 0 docker-compose.yml | 8 +-- 8 files changed, 205 insertions(+), 23 deletions(-) create mode 100644 .gitlab-ci.yml create mode 100644 .gitlab-ci/Jobs/build_image.yml create mode 100644 .gitlab-ci/Jobs/container_security_scan.yml create mode 100644 debian/Dockerfile rename Dockerfile => dev/Dockerfile (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..716a2a5 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,13 @@ +image: alpine:latest + +variables: + DOCKER_DRIVER: overlay2 + DOCKER_HOST: tcp://localhost:2375/ + +stages: + - build + - test + +include: + - local: '/.gitlab-ci/Jobs/build_image.yml' + - local: '/.gitlab-ci/Jobs/container_security_scan.yml' diff --git a/.gitlab-ci/Jobs/build_image.yml b/.gitlab-ci/Jobs/build_image.yml new file mode 100644 index 0000000..6af2da0 --- /dev/null +++ b/.gitlab-ci/Jobs/build_image.yml @@ -0,0 +1,30 @@ +.passbolt-prerelease: + stage: build + image: + name: gcr.io/kaniko-project/executor:debug + entrypoint: [""] + script: + - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json + - | + echo "********************************************" + echo "Build details" + echo "============================================" + echo "Flavour ${PASSBOLT_FLAVOUR:-local}" + echo "Commit ${UPSTREAM_COMMIT_SHA:-latest}" + echo "********************************************" + - | + /kaniko/executor --context $CI_PROJECT_DIR \ + --build-arg PASSBOLT_PKG="passbolt-$PASSBOLT_FLAVOUR-server" \ + --build-arg PASSBOLT_REPO_URL="https://download.passbolt.com/$PASSBOLT_FLAVOUR/debian" \ + --build-arg PASSBOLT_COMPONENT="$COMPONENT" \ + --dockerfile $CI_PROJECT_DIR/debian/Dockerfile \ + --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-$(date +%s) + +prerelease-pro: + extends: .passbolt-prerelease + variables: + PASSBOLT_URL: "https://gitlab.com/api/v4/projects/$UPSTREAM_PROJECT_ID/repository/archive.tar.gz?sha=$UPSTREAM_COMMIT_SHA" + PASSBOLT_CURL_HEADERS: "PRIVATE-TOKEN: $PRIVATE_TOKEN" + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_BRANCH == "develop"' + when: on_success diff --git a/.gitlab-ci/Jobs/container_security_scan.yml b/.gitlab-ci/Jobs/container_security_scan.yml new file mode 100644 index 0000000..00afead --- /dev/null +++ b/.gitlab-ci/Jobs/container_security_scan.yml @@ -0,0 +1,59 @@ +# Read more about this feature here: https://docs.gitlab.com/ee/user/project/merge_requests/container_scanning.html + +container_scanning: + stage: test + image: docker:stable + variables: + DOCKER_DRIVER: overlay2 + # Defining two new variables based on GitLab's CI/CD predefined variables + # https://docs.gitlab.com/ee/ci/variables/#predefined-environment-variables + CI_APPLICATION_REPOSITORY: $CI_REGISTRY_IMAGE + # Prior to this, you need to have the Container Registry running for your project and setup a build job + # with at least the following steps: + # + # docker build -t $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG . + # docker push $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA + # + # Container Scanning deals with Docker images only so no need to import the project's Git repository: + GIT_STRATEGY: none + # Services and containers running in the same Kubernetes pod are all sharing the same localhost address + # https://docs.gitlab.com/runner/executors/kubernetes.html + DOCKER_SERVICE: localhost + DOCKER_HOST: tcp://${DOCKER_SERVICE}:2375/ + # https://hub.docker.com/r/arminc/clair-local-scan/tags + CLAIR_LOCAL_SCAN_VERSION: v2.0.8_fe9b059d930314b54c78f75afe265955faf4fdc1 + allow_failure: true + services: + - docker:18-dind + script: + - export CI_APPLICATION_TAG=${PASSBOLT_FLAVOUR:-local}-${UPSTREAM_COMMIT_SHA:-latest} + - echo "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" + - if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then { export DOCKER_SERVICE="localhost" ; export DOCKER_HOST="tcp://${DOCKER_SERVICE}:2375" ; } fi + - | + if [[ -n "$CI_REGISTRY_USER" ]]; then + echo "Logging to GitLab Container Registry with CI credentials..." + docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" + echo "" + fi + - docker run -d --name db arminc/clair-db:latest + - docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:${CLAIR_LOCAL_SCAN_VERSION} + - apk add -U wget ca-certificates + - docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} + - wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64 + - mv clair-scanner_linux_amd64 clair-scanner + - chmod +x clair-scanner + - touch clair-whitelist.yml + - retries=0 + - echo "Waiting for clair daemon to start" + - while( ! wget -T 10 -q -O /dev/null http://${DOCKER_SERVICE}:6060/v1/namespaces ) ; do sleep 1 ; echo -n "." ; if [ $retries -eq 10 ] ; then echo " Timeout, aborting." ; exit 1 ; fi ; retries=$(($retries+1)) ; done + - ./clair-scanner -c http://${DOCKER_SERVICE}:6060 --ip $(hostname -i) -r gl-container-scanning-report.json -l clair.log -w clair-whitelist.yml -t Medium ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true + artifacts: + reports: + container_scanning: gl-container-scanning-report.json + dependencies: [] + only: + refs: + - branches + except: + variables: + - $CONTAINER_SCANNING_DISABLED diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 7bcef9c..872c290 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -1,14 +1,17 @@ #!/usr/bin/env bash -set -euo pipefail +set -eo pipefail -gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-/var/www/passbolt/config/gpg/serverkey_private.asc}" -gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-/var/www/passbolt/config/gpg/serverkey.asc}" +passbolt_config="/etc/passbolt" +gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-$passbolt_config/gpg/serverkey_private.asc}" +gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-$passbolt_config/gpg/serverkey.asc}" ssl_key='/etc/ssl/certs/certificate.key' ssl_cert='/etc/ssl/certs/certificate.crt' -export GNUPGHOME="/home/www-data/.gnupg" +deprecation_message="" + +export GNUPGHOME="/var/lib/passbolt/.gnupg" entropy_check() { local entropy_avail @@ -42,7 +45,7 @@ gpg_gen_key() { entropy_check - su -c "gpg --batch --no-tty --gen-key < $gpg_private_key" -ls /bin/bash www-data - su -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --armor --export-secret-keys $key_email > $gpg_private_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --armor --export $key_email > $gpg_public_key" -ls /bin/bash www-data } gpg_import_key() { - su -c "gpg --batch --import $gpg_public_key" -ls /bin/bash www-data - su -c "gpg --batch --import $gpg_private_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --batch --import $gpg_public_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --batch --import $gpg_private_key" -ls /bin/bash www-data } gen_ssl_cert() { @@ -70,18 +73,17 @@ gen_ssl_cert() { } install() { - local app_config="/var/www/passbolt/config/app.php" - if [ ! -f "$app_config" ]; then - su -c 'cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php' -s /bin/bash www-data + if [ ! -f "$passbolt_config/app.php" ]; then + su -c "cp $passbolt_config/app.default.php $passbolt_config/app.php" -s /bin/bash www-data fi - if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f '/var/www/passbolt/config/passbolt.php' ]; then - gpg_auto_fingerprint="$(su -c "gpg --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" + if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$passbolt_config/passbolt.php" ]; then + gpg_auto_fingerprint="$(su -c "gpg --homedir $GNUPGHOME --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint fi - su -c '/var/www/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data || su -c '/var/www/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data && echo "Enjoy! ☮" + su -c '/usr/share/php/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data || su -c '/usr/share/php/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data && echo "Enjoy! ☮" } email_cron_job() { @@ -93,8 +95,47 @@ email_cron_job() { fi } -if [ ! -f "$gpg_private_key" ] && [ ! -L "$gpg_private_key" ] || \ - [ ! -f "$gpg_public_key" ] && [ ! -L "$gpg_public_key" ]; then +create_deprecation_message() { + deprecation_message+="\033[33;5;7mWARNING: $1 is deprecated, point your docker volume to $2\033[0m\n" +} + +check_deprecated_paths() { + declare -A deprecated_paths + local deprecated_avatar_path="/var/www/passbolt/webroot/img/public/Avatar" + local avatar_path="/usr/share/php/passbolt/webroot/img/public/Avatar" + local deprecated_subscription_path="/var/www/passbolt/webroot/img/public/Avatar" + local subscription_path="/etc/passbolt/license" + deprecated_paths=( + ['/var/www/passbolt/config/gpg/serverkey.asc']='/etc/passbolt/gpg/serverkey.asc' + ['/var/www/passbolt/config/gpg/serverkey_private.asc']='/etc/passbolt/gpg/serverkey_private.asc' + ) + + if [ -z "$PASSBOLT_GPG_SERVER_KEY_PUBLIC" ] || [ -z "$PASSBOLT_GPG_SERVER_KEY_PRIVATE" ]; then + for path in "${!deprecated_paths[@]}" + do + echo "VOLTA" + if [ -f "$path" ] && [ ! -f "${deprecated_paths[$path]}" ]; then + ln -s "$path" "${deprecated_paths[$path]}" + create_deprecation_message "$path" "${deprecated_paths[$path]}" + fi + done + fi + + if [ -d "$deprecated_avatar_path" ] && [ ! -d "$avatar_path" ]; then + ln -s "$deprecated_avatar_path" "$avatar_path" + create_deprecation_message "$deprecated_avatar_path" "$avatar_path" + fi + + if [ -f "$deprecated_subscription_path" ] && [ ! -f "$subscription_path" ]; then + ln -s "$deprecated_subscription_path" "$subscription_path" + create_deprecation_message "$deprecated_subscription_path" "$subscription_path" + fi +} + +check_deprecated_paths + +if [ ! -f "$gpg_private_key" ] || \ + [ ! -f "$gpg_public_key" ]; then gpg_gen_key gpg_import_key else @@ -109,4 +150,6 @@ fi install email_cron_job +echo -e "$deprecation_message" + exec /usr/bin/supervisord -n diff --git a/conf/supervisor/php.conf b/conf/supervisor/php.conf index c008c6b..a98b80c 100644 --- a/conf/supervisor/php.conf +++ b/conf/supervisor/php.conf @@ -1,5 +1,5 @@ [program:php-fpm] -command=php-fpm -F +command=php-fpm7.3 -F autostart=true priority=5 stdout_logfile=/dev/stdout diff --git a/debian/Dockerfile b/debian/Dockerfile new file mode 100644 index 0000000..38fe0aa --- /dev/null +++ b/debian/Dockerfile @@ -0,0 +1,39 @@ +FROM debian:buster-slim + +LABEL maintainer="Passbolt SA " + +ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D +ENV PASSBOLT_PKG=passbolt-ce-server +ENV PHP_VERSION=7.3 + +ARG PASSBOLT_REPO_URL="https://download.passbolt.com/ce/debian" +ARG PASSBOLT_DISTRO="buster" +ARG PASSBOLT_COMPONENT="stable" + +RUN apt-get update \ + && DEBIAN_FRONTEND=non-interactive apt-get -y install \ + ca-certificates \ + gnupg \ + && apt-key adv --keyserver keys.gnupg.net --recv-keys $PASSBOLT_PKG_KEY \ + && echo "deb $PASSBOLT_REPO_URL $PASSBOLT_DISTRO $PASSBOLT_COMPONENT" > /etc/apt/sources.list.d/passbolt.list \ + && apt-get update \ + && DEBIAN_FRONTEND=non-interactive apt-get -y install --no-install-recommends \ + nginx \ + $PASSBOLT_PKG \ + supervisor \ + && rm /etc/nginx/sites-enabled/default \ + && mkdir /run/php \ + && cp /usr/share/passbolt/examples/nginx-passbolt-ssl.conf /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,;clear_env = no,clear_env = no,' /etc/php/$PHP_VERSION/fpm/pool.d/www.conf \ + && sed -i 's,# include __PASSBOLT_SSL__,include /etc/nginx/snippets/passbolt-ssl.conf;,' /etc/nginx/sites-enabled/nginx-passbolt.conf \ + && sed -i 's,ssl on;,listen 443 ssl;,' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,__CERT_PATH__,/etc/ssl/certs/certificate.crt;,' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,__KEY_PATH__,/etc/ssl/certs/certificate.key;,' /etc/nginx/snippets/passbolt-ssl.conf + +COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ +COPY bin/docker-entrypoint.sh /docker-entrypoint.sh +COPY scripts/wait-for.sh /usr/bin/wait-for.sh + +EXPOSE 80 443 + +CMD ["/docker-entrypoint.sh"] diff --git a/Dockerfile b/dev/Dockerfile similarity index 100% rename from Dockerfile rename to dev/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index b735821..868cce8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,17 +10,15 @@ services: - "127.0.0.1:3306:3306" passbolt: - image: passbolt/passbolt:2.12.0-debian + image: localpassbolt tty: true depends_on: - db env_file: - env/passbolt.env volumes: - - gpg_volume:/var/www/passbolt/config/gpg - - images_volume:/var/www/passbolt/webroot/img/public - tmpfs: - - /run + - gpg_volume:/var/lib/passbolt/.gnupg + - images_volume:/usr/share/php/passbolt/webroot/img/public command: ["/usr/bin/wait-for.sh", "-t", "0", "db:3306", "--", "/docker-entrypoint.sh"] ports: - 80:80 From b07c57c010bde58f425f6fbd466ca9ba971ba43a Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 25 Jan 2021 19:03:00 +0100 Subject: [PATCH 10/24] Changed: fix job names and build args. --- .gitlab-ci/Jobs/build_image.yml | 6 +++--- debian/Dockerfile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci/Jobs/build_image.yml b/.gitlab-ci/Jobs/build_image.yml index 6af2da0..b86594b 100644 --- a/.gitlab-ci/Jobs/build_image.yml +++ b/.gitlab-ci/Jobs/build_image.yml @@ -1,4 +1,4 @@ -.passbolt-prerelease: +.passbolt-build: stage: build image: name: gcr.io/kaniko-project/executor:debug @@ -20,8 +20,8 @@ --dockerfile $CI_PROJECT_DIR/debian/Dockerfile \ --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-$(date +%s) -prerelease-pro: - extends: .passbolt-prerelease +docker-build-pro: + extends: .passbolt-build variables: PASSBOLT_URL: "https://gitlab.com/api/v4/projects/$UPSTREAM_PROJECT_ID/repository/archive.tar.gz?sha=$UPSTREAM_COMMIT_SHA" PASSBOLT_CURL_HEADERS: "PRIVATE-TOKEN: $PRIVATE_TOKEN" diff --git a/debian/Dockerfile b/debian/Dockerfile index 38fe0aa..65640ab 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -3,9 +3,9 @@ FROM debian:buster-slim LABEL maintainer="Passbolt SA " ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D -ENV PASSBOLT_PKG=passbolt-ce-server ENV PHP_VERSION=7.3 +ARG PASSBOLT_PKG=passbolt-ce-server ARG PASSBOLT_REPO_URL="https://download.passbolt.com/ce/debian" ARG PASSBOLT_DISTRO="buster" ARG PASSBOLT_COMPONENT="stable" From 33565520252a9736a3c4eefc62f7338245a2f498 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 25 Jan 2021 19:11:08 +0100 Subject: [PATCH 11/24] Changed: renamed build jobs --- .gitlab-ci/Jobs/build_image.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci/Jobs/build_image.yml b/.gitlab-ci/Jobs/build_image.yml index 6af2da0..ae8688c 100644 --- a/.gitlab-ci/Jobs/build_image.yml +++ b/.gitlab-ci/Jobs/build_image.yml @@ -1,4 +1,4 @@ -.passbolt-prerelease: +.build: stage: build image: name: gcr.io/kaniko-project/executor:debug @@ -20,8 +20,8 @@ --dockerfile $CI_PROJECT_DIR/debian/Dockerfile \ --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-$(date +%s) -prerelease-pro: - extends: .passbolt-prerelease +build-docker: + extends: .build variables: PASSBOLT_URL: "https://gitlab.com/api/v4/projects/$UPSTREAM_PROJECT_ID/repository/archive.tar.gz?sha=$UPSTREAM_COMMIT_SHA" PASSBOLT_CURL_HEADERS: "PRIVATE-TOKEN: $PRIVATE_TOKEN" From f622dd571b345b33cc4b6a130c2ba1b03e9b47c5 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Mon, 25 Jan 2021 19:12:20 +0100 Subject: [PATCH 12/24] Changed: PASSBOLT_PKG is not an ARG --- debian/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/Dockerfile b/debian/Dockerfile index 38fe0aa..9b3488c 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -3,12 +3,12 @@ FROM debian:buster-slim LABEL maintainer="Passbolt SA " ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D -ENV PASSBOLT_PKG=passbolt-ce-server ENV PHP_VERSION=7.3 ARG PASSBOLT_REPO_URL="https://download.passbolt.com/ce/debian" ARG PASSBOLT_DISTRO="buster" ARG PASSBOLT_COMPONENT="stable" +ARG PASSBOLT_PKG=passbolt-ce-server RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ From 7e6c359cc74839bb95d0730e3714c2533133f1af Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 25 Jan 2021 19:23:44 +0100 Subject: [PATCH 13/24] Changed: add latest tag. --- .gitlab-ci/Jobs/build_image.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci/Jobs/build_image.yml b/.gitlab-ci/Jobs/build_image.yml index ae8688c..7843eef 100644 --- a/.gitlab-ci/Jobs/build_image.yml +++ b/.gitlab-ci/Jobs/build_image.yml @@ -18,7 +18,8 @@ --build-arg PASSBOLT_REPO_URL="https://download.passbolt.com/$PASSBOLT_FLAVOUR/debian" \ --build-arg PASSBOLT_COMPONENT="$COMPONENT" \ --dockerfile $CI_PROJECT_DIR/debian/Dockerfile \ - --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-$(date +%s) + --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-$(date +%s) \ + --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-latest build-docker: extends: .build From 5a8fd286befbd08658dce46102982b163ce61f3c Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 26 Jan 2021 15:44:53 +0100 Subject: [PATCH 14/24] Changed: removed tmpfs mount and point persistence volumes to correct dirs in docker-compose --- docker-compose-pro.yml | 8 +++----- docker-compose.yml | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docker-compose-pro.yml b/docker-compose-pro.yml index df6fb61..db95a2a 100644 --- a/docker-compose-pro.yml +++ b/docker-compose-pro.yml @@ -17,11 +17,9 @@ services: env_file: - env/passbolt.env volumes: - - gpg_volume:/var/www/passbolt/config/gpg - - images_volume:/var/www/passbolt/webroot/img/public - - ./license:/var/www/passbolt/config/license - tmpfs: - - /run + - gpg_volume:/etc/passbolt/gpg + - images_volume:/usr/share/php/passbolt/webroot/img/public + - ./license:/etc/passbolt/license command: ["/usr/bin/wait-for.sh", "-t", "0", "db:3306", "--", "/docker-entrypoint.sh"] ports: - 80:80 diff --git a/docker-compose.yml b/docker-compose.yml index 868cce8..9ee0a07 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,7 +17,7 @@ services: env_file: - env/passbolt.env volumes: - - gpg_volume:/var/lib/passbolt/.gnupg + - gpg_volume:/etc/passbolt/gpg - images_volume:/usr/share/php/passbolt/webroot/img/public command: ["/usr/bin/wait-for.sh", "-t", "0", "db:3306", "--", "/docker-entrypoint.sh"] ports: From f20a465feebf9f6e8103bbcd71fd6bf6aa1dcbdb Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 26 Jan 2021 16:32:30 +0100 Subject: [PATCH 15/24] Changed: workdir is /usr/share/php/passbolt --- debian/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/Dockerfile b/debian/Dockerfile index 9b3488c..b4ab00c 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -36,4 +36,6 @@ COPY scripts/wait-for.sh /usr/bin/wait-for.sh EXPOSE 80 443 +WORKDIR /usr/share/php/passbolt + CMD ["/docker-entrypoint.sh"] From 5db86deb9601b135a6e5e3a161c3e9fe706d41df Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 26 Jan 2021 16:33:04 +0100 Subject: [PATCH 16/24] Changed: removed references to localpassbolt --- docker-compose-pro.yml | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose-pro.yml b/docker-compose-pro.yml index db95a2a..d714c57 100644 --- a/docker-compose-pro.yml +++ b/docker-compose-pro.yml @@ -10,7 +10,7 @@ services: - "127.0.0.1:3306:3306" passbolt: - image: passbolt/passbolt:2.12.0-pro-debian + image: passbolt/passbolt:3.0.0-pro-debian tty: true depends_on: - db diff --git a/docker-compose.yml b/docker-compose.yml index 9ee0a07..1a68c1a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: - "127.0.0.1:3306:3306" passbolt: - image: localpassbolt + image: passbolt/passbolt:3.0.0-debian tty: true depends_on: - db From c0e5e25417b5397c4d467cc7bd3b82bdeeb8b9dd Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 26 Jan 2021 18:11:27 +0100 Subject: [PATCH 17/24] Changed: cleanup entrypoint --- bin/docker-entrypoint.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/docker-entrypoint.sh b/bin/docker-entrypoint.sh index 872c290..b2c7d30 100755 --- a/bin/docker-entrypoint.sh +++ b/bin/docker-entrypoint.sh @@ -113,7 +113,6 @@ check_deprecated_paths() { if [ -z "$PASSBOLT_GPG_SERVER_KEY_PUBLIC" ] || [ -z "$PASSBOLT_GPG_SERVER_KEY_PRIVATE" ]; then for path in "${!deprecated_paths[@]}" do - echo "VOLTA" if [ -f "$path" ] && [ ! -f "${deprecated_paths[$path]}" ]; then ln -s "$path" "${deprecated_paths[$path]}" create_deprecation_message "$path" "${deprecated_paths[$path]}" From ddc34aff48a1162dd07a94df4ea42cac00dc5a8b Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Fri, 12 Feb 2021 12:53:41 +0100 Subject: [PATCH 18/24] Changed: adapt sed command to new passbolt-ssl snippet configuration --- Dockerfile | 3 ++- env/passbolt.env | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index c1733a9..6bb71d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,7 +26,8 @@ RUN sed -i 's,listen 80;,listen 8080;,' /etc/nginx/sites-enabled/nginx-passbolt. && cp /usr/share/passbolt/examples/nginx-passbolt-ssl.conf /etc/nginx/snippets/passbolt-ssl.conf \ && sed -i 's,;clear_env = no,clear_env = no,' /etc/php/$PHP_VERSION/fpm/pool.d/www.conf \ && sed -i 's,# include __PASSBOLT_SSL__,include /etc/nginx/snippets/passbolt-ssl.conf;,' /etc/nginx/sites-enabled/nginx-passbolt.conf \ - && sed -i 's,ssl on;,listen 4443 ssl;,' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,listen \[\:\:\]\:443 ssl http2;,listen \[\:\:\]\:4443 ssl http2;,' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i '/listen \[\:\:\]\:4443 ssl http2;/a listen 4443 ssl http2;' /etc/nginx/snippets/passbolt-ssl.conf \ && sed -i 's,__CERT_PATH__,/etc/passbolt/certs/certificate.crt;,' /etc/nginx/snippets/passbolt-ssl.conf \ && sed -i 's,__KEY_PATH__,/etc/passbolt/certs/certificate.key;,' /etc/nginx/snippets/passbolt-ssl.conf \ && sed -i '/user www-data;/d' /etc/nginx/nginx.conf \ diff --git a/env/passbolt.env b/env/passbolt.env index 2b38655..1f0ec57 100644 --- a/env/passbolt.env +++ b/env/passbolt.env @@ -1,5 +1,5 @@ # URL -APP_FULL_BASE_URL=http://passbolt.local +APP_FULL_BASE_URL=https://passbolt.local # Database settings DATASOURCES_DEFAULT_HOST=db From 7e8fd580b5fff4dabf3a1b673e8b5fcbb765ee54 Mon Sep 17 00:00:00 2001 From: Diego Lendoiro Date: Tue, 16 Feb 2021 19:03:33 +0100 Subject: [PATCH 19/24] Changed: reorganized repository, fixed cron issues --- conf/passbolt.conf | 76 ++++++++++++ conf/supervisor/cron.conf | 8 ++ debian/Dockerfile | 48 ++++++++ Dockerfile => debian/Dockerfile.rootless | 18 ++- debian/bin/docker-entrypoint.sh | 141 +++++++++++++++++++++++ debian/conf | 1 + debian/scripts | 1 + dev/Dockerfile | 91 +++++++++++++++ {bin => dev/bin}/docker-entrypoint.sh | 39 ++++--- dev/conf | 1 + dev/scripts | 1 + 11 files changed, 401 insertions(+), 24 deletions(-) create mode 100644 conf/passbolt.conf create mode 100644 conf/supervisor/cron.conf create mode 100644 debian/Dockerfile rename Dockerfile => debian/Dockerfile.rootless (83%) create mode 100755 debian/bin/docker-entrypoint.sh create mode 120000 debian/conf create mode 120000 debian/scripts create mode 100644 dev/Dockerfile rename {bin => dev/bin}/docker-entrypoint.sh (61%) create mode 120000 dev/conf create mode 120000 dev/scripts diff --git a/conf/passbolt.conf b/conf/passbolt.conf new file mode 100644 index 0000000..7b3f453 --- /dev/null +++ b/conf/passbolt.conf @@ -0,0 +1,76 @@ +server { + listen 80; + + client_body_buffer_size 100K; + client_header_buffer_size 1K; + client_max_body_size 5M; + + client_body_timeout 10; + client_header_timeout 10; + keepalive_timeout 5 5; + send_timeout 10; + + root /var/www/passbolt/webroot; + index index.php; + error_log /dev/stdout info; + access_log /dev/stdout; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + try_files $uri =404; + include fastcgi_params; + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + fastcgi_intercept_errors on; + fastcgi_split_path_info ^(.+\.php)(.+)$; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SERVER_NAME $http_host; + fastcgi_param PHP_VALUE "upload_max_filesize=5M \n post_max_size=5M"; + } + +} + +server { + listen 443; + + client_body_buffer_size 100K; + client_header_buffer_size 1K; + client_max_body_size 5M; + + client_body_timeout 10; + client_header_timeout 10; + keepalive_timeout 5 5; + send_timeout 10; + + ssl on; + ssl_certificate /etc/ssl/certs/certificate.crt; + ssl_certificate_key /etc/ssl/certs/certificate.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4:@STRENGTH"; + ssl_session_tickets off; + + root /var/www/passbolt/webroot; + index index.php; + error_log /dev/stdout info; + access_log /dev/stdout; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + try_files $uri =404; + include fastcgi_params; + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + fastcgi_intercept_errors on; + fastcgi_split_path_info ^(.+\.php)(.+)$; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SERVER_NAME $http_host; + fastcgi_param PHP_VALUE "upload_max_filesize=5M \n post_max_size=5M"; + } +} diff --git a/conf/supervisor/cron.conf b/conf/supervisor/cron.conf new file mode 100644 index 0000000..07bce67 --- /dev/null +++ b/conf/supervisor/cron.conf @@ -0,0 +1,8 @@ +[program:cron] +command=/bin/bash -c "declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /etc/environment; cron -f -l" +autostart=true +priority=20 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/debian/Dockerfile b/debian/Dockerfile new file mode 100644 index 0000000..337959c --- /dev/null +++ b/debian/Dockerfile @@ -0,0 +1,48 @@ +FROM debian:buster-slim + +LABEL maintainer="Passbolt SA " + +ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D +ENV PHP_VERSION=7.3 +ENV GNUPGHOME=/var/lib/passbolt/.gnupg + +ARG PASSBOLT_REPO_URL="https://download.passbolt.com/ce/debian" +ARG PASSBOLT_DISTRO="buster" +ARG PASSBOLT_COMPONENT="stable" +ARG PASSBOLT_PKG=passbolt-ce-server + +RUN apt-get update \ + && DEBIAN_FRONTEND=non-interactive apt-get -y install \ + ca-certificates \ + gnupg \ + && apt-key adv --keyserver keys.gnupg.net --recv-keys $PASSBOLT_PKG_KEY \ + && echo "deb $PASSBOLT_REPO_URL $PASSBOLT_DISTRO $PASSBOLT_COMPONENT" > /etc/apt/sources.list.d/passbolt.list \ + && apt-get update \ + && DEBIAN_FRONTEND=non-interactive apt-get -y install --no-install-recommends \ + nginx \ + $PASSBOLT_PKG \ + supervisor \ + && rm /etc/nginx/sites-enabled/default \ + && mkdir /run/php \ + && cp /usr/share/passbolt/examples/nginx-passbolt-ssl.conf /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,;clear_env = no,clear_env = no,' /etc/php/$PHP_VERSION/fpm/pool.d/www.conf \ + && sed -i 's,# include __PASSBOLT_SSL__,include /etc/nginx/snippets/passbolt-ssl.conf;,' /etc/nginx/sites-enabled/nginx-passbolt.conf \ + && sed -i '/listen \[\:\:\]\:443 ssl http2;/a listen 443 ssl http2;' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,__CERT_PATH__,/etc/ssl/certs/certificate.crt;,' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,__KEY_PATH__,/etc/ssl/certs/certificate.key;,' /etc/nginx/snippets/passbolt-ssl.conf \ + && sed -i 's,www-data.*$,www-data exec /bin/bash -c ". /etc/environment \&\& $PASSBOLT_BASE_DIR/bin/cron",' /etc/cron.d/$PASSBOLT_PKG \ + && ln -sf /dev/stdout /var/log/nginx/passbolt-access.log \ + && ln -sf /dev/stderr /var/log/nginx/passbolt-error.log \ + && ln -sf /dev/stderr /var/log/passbolt/error.log \ + && ln -sf /dev/stderr /var/log/php7.3-fpm.log \ + && crontab /etc/cron.d/$PASSBOLT_PKG + +COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ +COPY debian/bin/docker-entrypoint.sh /docker-entrypoint.sh +COPY scripts/wait-for.sh /usr/bin/wait-for.sh + +EXPOSE 80 443 + +WORKDIR /usr/share/php/passbolt + +CMD ["/docker-entrypoint.sh"] diff --git a/Dockerfile b/debian/Dockerfile.rootless similarity index 83% rename from Dockerfile rename to debian/Dockerfile.rootless index 6bb71d0..9a1fd7a 100644 --- a/Dockerfile +++ b/debian/Dockerfile.rootless @@ -3,23 +3,25 @@ FROM debian:buster-slim LABEL maintainer="Passbolt SA " ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D -ENV PASSBOLT_PKG=passbolt-ce-server ENV PHP_VERSION=7.3 ENV GNUPGHOME=/var/lib/passbolt/.gnupg +ARG PASSBOLT_REPO_URL="https://download.passbolt.com/ce/debian" +ARG PASSBOLT_DISTRO="buster" +ARG PASSBOLT_COMPONENT="stable" +ARG PASSBOLT_PKG=passbolt-ce-server RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ ca-certificates \ gnupg \ && apt-key adv --keyserver keys.gnupg.net --recv-keys $PASSBOLT_PKG_KEY \ - && echo "deb https://download.passbolt.com/ce/debian buster stable" > /etc/apt/sources.list.d/passbolt.list \ + && echo "deb $PASSBOLT_REPO_URL $PASSBOLT_DISTRO $PASSBOLT_COMPONENT" > /etc/apt/sources.list.d/passbolt.list \ && apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install --no-install-recommends \ nginx \ $PASSBOLT_PKG \ - supervisor \ - php-apcu + supervisor RUN sed -i 's,listen 80;,listen 8080;,' /etc/nginx/sites-enabled/nginx-passbolt.conf \ && rm /etc/nginx/sites-enabled/default \ @@ -52,14 +54,18 @@ RUN sed -i 's,listen 80;,listen 8080;,' /etc/nginx/sites-enabled/nginx-passbolt. && ln -sf /dev/stderr /var/log/php7.3-fpm.log \ && chown -R www-data:0 /var/log/supervisor \ && touch /var/www/.profile \ - && chown www-data:www-data /var/www/.profile + && chown www-data:www-data /var/www/.profile \ + && sed -i 's,www-data.*$,www-data exec /bin/bash -c ". /etc/environment \&\& $PASSBOLT_BASE_DIR/bin/cron",' /etc/cron.d/$PASSBOLT_PKG \ + && crontab /etc/cron.d/$PASSBOLT_PKG COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ -COPY bin/docker-entrypoint.sh /docker-entrypoint.sh +COPY debian/bin/docker-entrypoint.sh /docker-entrypoint.sh COPY scripts/wait-for.sh /usr/bin/wait-for.sh EXPOSE 8080 4443 +WORKDIR /usr/share/php/passbolt + USER www-data CMD ["/docker-entrypoint.sh"] diff --git a/debian/bin/docker-entrypoint.sh b/debian/bin/docker-entrypoint.sh new file mode 100755 index 0000000..5c1f803 --- /dev/null +++ b/debian/bin/docker-entrypoint.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash + +set -eo pipefail + +passbolt_config="/etc/passbolt" +gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-$passbolt_config/gpg/serverkey_private.asc}" +gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-$passbolt_config/gpg/serverkey.asc}" + +ssl_key='/etc/ssl/certs/certificate.key' +ssl_cert='/etc/ssl/certs/certificate.crt' + +deprecation_message="" + +entropy_check() { + local entropy_avail + + entropy_avail=$(cat /proc/sys/kernel/random/entropy_avail) + + if [ "$entropy_avail" -lt 2000 ]; then + + cat < $gpg_private_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --armor --export $key_email > $gpg_public_key" -ls /bin/bash www-data +} + +gpg_import_key() { + su -c "gpg --homedir $GNUPGHOME --batch --import $gpg_public_key" -ls /bin/bash www-data + su -c "gpg --homedir $GNUPGHOME --batch --import $gpg_private_key" -ls /bin/bash www-data +} + +gen_ssl_cert() { + openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ + -subj '/C=FR/ST=Denial/L=Springfield/O=Dis/CN=www.passbolt.local' \ + -keyout $ssl_key -out $ssl_cert +} + +install() { + if [ ! -f "$passbolt_config/app.php" ]; then + su -c "cp $passbolt_config/app.default.php $passbolt_config/app.php" -s /bin/bash www-data + fi + + if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$passbolt_config/passbolt.php" ]; then + gpg_auto_fingerprint="$(su -c "gpg --homedir $GNUPGHOME --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" + export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint + fi + + su -c '/usr/share/php/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data || su -c '/usr/share/php/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data && echo "Enjoy! ☮" +} + +create_deprecation_message() { + deprecation_message+="\033[33;5;7mWARNING: $1 is deprecated, point your docker volume to $2\033[0m\n" +} + +check_deprecated_paths() { + declare -A deprecated_paths + local deprecated_avatar_path="/var/www/passbolt/webroot/img/public/Avatar" + local avatar_path="/usr/share/php/passbolt/webroot/img/public/Avatar" + local deprecated_subscription_path="/var/www/passbolt/webroot/img/public/Avatar" + local subscription_path="/etc/passbolt/license" + deprecated_paths=( + ['/var/www/passbolt/config/gpg/serverkey.asc']='/etc/passbolt/gpg/serverkey.asc' + ['/var/www/passbolt/config/gpg/serverkey_private.asc']='/etc/passbolt/gpg/serverkey_private.asc' + ) + + if [ -z "$PASSBOLT_GPG_SERVER_KEY_PUBLIC" ] || [ -z "$PASSBOLT_GPG_SERVER_KEY_PRIVATE" ]; then + for path in "${!deprecated_paths[@]}" + do + if [ -f "$path" ] && [ ! -f "${deprecated_paths[$path]}" ]; then + ln -s "$path" "${deprecated_paths[$path]}" + create_deprecation_message "$path" "${deprecated_paths[$path]}" + fi + done + fi + + if [ -d "$deprecated_avatar_path" ] && [ ! -d "$avatar_path" ]; then + ln -s "$deprecated_avatar_path" "$avatar_path" + create_deprecation_message "$deprecated_avatar_path" "$avatar_path" + fi + + if [ -f "$deprecated_subscription_path" ] && [ ! -f "$subscription_path" ]; then + ln -s "$deprecated_subscription_path" "$subscription_path" + create_deprecation_message "$deprecated_subscription_path" "$subscription_path" + fi +} + +check_deprecated_paths + +if [ ! -f "$gpg_private_key" ] || \ + [ ! -f "$gpg_public_key" ]; then + gpg_gen_key + gpg_import_key +else + gpg_import_key +fi + +if [ ! -f "$ssl_key" ] && [ ! -L "$ssl_key" ] && \ + [ ! -f "$ssl_cert" ] && [ ! -L "$ssl_cert" ]; then + gen_ssl_cert +fi + +install + +echo -e "$deprecation_message" + +exec /usr/bin/supervisord -n diff --git a/debian/conf b/debian/conf new file mode 120000 index 0000000..59f0502 --- /dev/null +++ b/debian/conf @@ -0,0 +1 @@ +../conf \ No newline at end of file diff --git a/debian/scripts b/debian/scripts new file mode 120000 index 0000000..a339954 --- /dev/null +++ b/debian/scripts @@ -0,0 +1 @@ +../scripts \ No newline at end of file diff --git a/dev/Dockerfile b/dev/Dockerfile new file mode 100644 index 0000000..f631edf --- /dev/null +++ b/dev/Dockerfile @@ -0,0 +1,91 @@ +FROM php:7.3.24-fpm + +LABEL maintainer="Passbolt SA " + +ARG PASSBOLT_VERSION="2.13.5" +ARG PASSBOLT_URL="https://github.com/passbolt/passbolt_api/archive/v${PASSBOLT_VERSION}.tar.gz" +ARG PASSBOLT_CURL_HEADERS="" + +ARG PHP_EXTENSIONS="gd \ + intl \ + pdo_mysql \ + opcache \ + xsl" + +ARG PECL_PASSBOLT_EXTENSIONS="gnupg \ + redis \ + mcrypt" + +ARG PASSBOLT_DEV_PACKAGES="libgpgme11-dev \ + libpng-dev \ + libjpeg62-turbo-dev \ + libicu-dev \ + libxslt1-dev \ + libmcrypt-dev \ + unzip" + +ARG PASSBOLT_BASE_PACKAGES="nginx \ + gnupg \ + libgpgme11 \ + libmcrypt4 \ + mariadb-client \ + supervisor \ + cron" + +ENV PECL_BASE_URL="https://pecl.php.net/get" +ENV PHP_EXT_DIR="/usr/src/php/ext" + +WORKDIR /var/www/passbolt +RUN apt-get update \ + && apt-get -y install --no-install-recommends \ + $PASSBOLT_DEV_PACKAGES \ + $PASSBOLT_BASE_PACKAGES \ + && mkdir /home/www-data \ + && chown -R www-data:www-data /home/www-data \ + && usermod -d /home/www-data www-data \ + && docker-php-source extract \ + && for i in $PECL_PASSBOLT_EXTENSIONS; do \ + mkdir $PHP_EXT_DIR/$i; \ + curl -sSL $PECL_BASE_URL/$i | tar zxf - -C $PHP_EXT_DIR/$i --strip-components 1; \ + done \ + && docker-php-ext-configure gd --with-jpeg-dir=/usr/include/ \ + && docker-php-ext-install -j4 $PHP_EXTENSIONS $PECL_PASSBOLT_EXTENSIONS \ + && docker-php-ext-enable $PHP_EXTENSIONS $PECL_PASSBOLT_EXTENSIONS \ + && docker-php-source delete \ + && EXPECTED_SIGNATURE=$(curl -s https://composer.github.io/installer.sig) \ + && curl -o composer-setup.php https://getcomposer.org/installer \ + && ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');") \ + && if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]; then \ + >&2 echo 'ERROR: Invalid installer signature'; \ + rm composer-setup.php; \ + exit 1; \ + fi \ + && php composer-setup.php --1 \ + && mv composer.phar /usr/local/bin/composer \ + && rm composer-setup.php \ + && curl -sSL -H "$PASSBOLT_CURL_HEADERS" "$PASSBOLT_URL" | tar zxf - -C . --strip-components 1 \ + && composer install -n --no-dev --optimize-autoloader \ + && chown -R www-data:www-data . \ + && chmod 775 $(find /var/www/passbolt/tmp -type d) \ + && chmod 664 $(find /var/www/passbolt/tmp -type f) \ + && chmod 775 $(find /var/www/passbolt/webroot/img/public -type d) \ + && chmod 664 $(find /var/www/passbolt/webroot/img/public -type f) \ + && rm /etc/nginx/sites-enabled/default \ + && apt-get purge -y --auto-remove $PASSBOLT_DEV_PACKAGES \ + && rm -rf /var/lib/apt/lists/* \ + && rm /usr/local/bin/composer \ + && echo 'php_flag[expose_php] = off' > /usr/local/etc/php-fpm.d/expose.conf \ + && sed -i 's/# server_tokens/server_tokens/' /etc/nginx/nginx.conf \ + && mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \ + && echo "* * * * * su -c \"source /etc/environment ; /var/www/passbolt/bin/cake EmailQueue.sender\" -s /bin/bash www-data >> /var/log/cron.log 2>&1" >> /etc/cron.d/passbolt_email \ + && crontab /etc/cron.d/passbolt_email \ + && ln -s $(which php-fpm){,7.3} + +COPY conf/passbolt.conf /etc/nginx/conf.d/default.conf +COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ +COPY dev/bin/docker-entrypoint.sh /docker-entrypoint.sh +COPY scripts/wait-for.sh /usr/bin/wait-for.sh + +EXPOSE 80 443 + +CMD ["/docker-entrypoint.sh"] diff --git a/bin/docker-entrypoint.sh b/dev/bin/docker-entrypoint.sh similarity index 61% rename from bin/docker-entrypoint.sh rename to dev/bin/docker-entrypoint.sh index c095df4..09784b4 100755 --- a/bin/docker-entrypoint.sh +++ b/dev/bin/docker-entrypoint.sh @@ -2,15 +2,13 @@ set -euo pipefail -passbolt_config="/etc/passbolt" -passbolt_base="/usr/share/php/passbolt" -gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-$passbolt_config/gpg/serverkey_private.asc}" -gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-$passbolt_config/gpg/serverkey.asc}" +gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-/var/www/passbolt/config/gpg/serverkey_private.asc}" +gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-/var/www/passbolt/config/gpg/serverkey.asc}" -ssl_key="$passbolt_config/certs/certificate.key" -ssl_cert="$passbolt_config/certs/certificate.crt" +ssl_key='/etc/ssl/certs/certificate.key' +ssl_cert='/etc/ssl/certs/certificate.crt' -export GNUPGHOME="/var/lib/passbolt/.gnupg" +export GNUPGHOME="/home/www-data/.gnupg" entropy_check() { local entropy_avail @@ -44,7 +42,7 @@ gpg_gen_key() { entropy_check - gpg --batch --no-tty --gen-key < "$gpg_private_key" - gpg --armor --export "$key_email" > "$gpg_public_key" + su -c "gpg --armor --export-secret-keys $key_email > $gpg_private_key" -ls /bin/bash www-data + su -c "gpg --armor --export $key_email > $gpg_public_key" -ls /bin/bash www-data } gpg_import_key() { - gpg --batch --import "$gpg_public_key" - gpg --batch --import "$gpg_private_key" + su -c "gpg --batch --import $gpg_public_key" -ls /bin/bash www-data + su -c "gpg --batch --import $gpg_private_key" -ls /bin/bash www-data } gen_ssl_cert() { openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ -subj '/C=FR/ST=Denial/L=Springfield/O=Dis/CN=www.passbolt.local' \ - -keyout "$ssl_key" -out "$ssl_cert" + -keyout $ssl_key -out $ssl_cert } install() { - if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$passbolt_config/passbolt.php" ]; then - gpg_auto_fingerprint="$(gpg --homedir $GNUPGHOME --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:)" + local app_config="/var/www/passbolt/config/app.php" + + if [ ! -f "$app_config" ]; then + su -c 'cp /var/www/passbolt/config/app.default.php /var/www/passbolt/config/app.php' -s /bin/bash www-data + fi + + if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f '/var/www/passbolt/config/passbolt.php' ]; then + gpg_auto_fingerprint="$(su -c "gpg --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:" -ls /bin/bash www-data)" export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint fi - $passbolt_base/bin/cake passbolt install --no-admin || $passbolt_base/bin/cake passbolt migrate && echo "Enjoy! ☮" + su -c '/var/www/passbolt/bin/cake passbolt install --no-admin' -s /bin/bash www-data || su -c '/var/www/passbolt/bin/cake passbolt migrate' -s /bin/bash www-data && echo "Enjoy! ☮" } - if [ ! -f "$gpg_private_key" ] && [ ! -L "$gpg_private_key" ] || \ [ ! -f "$gpg_public_key" ] && [ ! -L "$gpg_public_key" ]; then gpg_gen_key diff --git a/dev/conf b/dev/conf new file mode 120000 index 0000000..59f0502 --- /dev/null +++ b/dev/conf @@ -0,0 +1 @@ +../conf \ No newline at end of file diff --git a/dev/scripts b/dev/scripts new file mode 120000 index 0000000..a339954 --- /dev/null +++ b/dev/scripts @@ -0,0 +1 @@ +../scripts \ No newline at end of file From 22a3d945b9a48d40ba25825d76dbd91aec56734e Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Tue, 16 Feb 2021 19:24:10 +0100 Subject: [PATCH 20/24] Added: rootless image build --- .gitlab-ci/Jobs/build_image.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci/Jobs/build_image.yml b/.gitlab-ci/Jobs/build_image.yml index 7843eef..9d669c2 100644 --- a/.gitlab-ci/Jobs/build_image.yml +++ b/.gitlab-ci/Jobs/build_image.yml @@ -17,15 +17,24 @@ --build-arg PASSBOLT_PKG="passbolt-$PASSBOLT_FLAVOUR-server" \ --build-arg PASSBOLT_REPO_URL="https://download.passbolt.com/$PASSBOLT_FLAVOUR/debian" \ --build-arg PASSBOLT_COMPONENT="$COMPONENT" \ - --dockerfile $CI_PROJECT_DIR/debian/Dockerfile \ - --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-$(date +%s) \ - --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-latest + --dockerfile $CI_PROJECT_DIR/$DOCKERFILE_PATH \ + --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-${DOCKER_TAG}-$(date +%s) \ + --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-${DOCKER_TAG}-latest build-docker: extends: .build variables: - PASSBOLT_URL: "https://gitlab.com/api/v4/projects/$UPSTREAM_PROJECT_ID/repository/archive.tar.gz?sha=$UPSTREAM_COMMIT_SHA" - PASSBOLT_CURL_HEADERS: "PRIVATE-TOKEN: $PRIVATE_TOKEN" + DOCKERFILE_PATH: "debian/Dockerfile" + DOCKER_TAG: "root" rules: - - if: '$CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_BRANCH == "develop"' + - if: '$CI_PIPELINE_SOURCE == "schedule" || $CI_COMMIT_BRANCH == "develop"' + when: on_success + +build-rootless: + extends: .build + variables: + DOCKERFILE_PATH: "debian/Dockerfile.rootless" + DOCKER_TAG: "rootless" + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule" || $CI_COMMIT_BRANCH == "develop"' when: on_success From 94ddf46ff55d5363e41c220b6692a3b2acf365cc Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Tue, 16 Feb 2021 19:28:30 +0100 Subject: [PATCH 21/24] Changed: add CE and pro builds --- .gitlab-ci/Jobs/build_image.yml | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci/Jobs/build_image.yml b/.gitlab-ci/Jobs/build_image.yml index 9d669c2..0c5f156 100644 --- a/.gitlab-ci/Jobs/build_image.yml +++ b/.gitlab-ci/Jobs/build_image.yml @@ -3,6 +3,8 @@ image: name: gcr.io/kaniko-project/executor:debug entrypoint: [""] + variables: + COMPONENT: "testing" script: - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - | @@ -21,20 +23,42 @@ --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-${DOCKER_TAG}-$(date +%s) \ --destination $CI_REGISTRY_IMAGE:${PASSBOLT_FLAVOUR:-local}-${DOCKER_TAG}-latest -build-docker: +build-docker-ce: extends: .build variables: DOCKERFILE_PATH: "debian/Dockerfile" DOCKER_TAG: "root" + PASSBOLT_FLAVOUR: "ce" rules: - if: '$CI_PIPELINE_SOURCE == "schedule" || $CI_COMMIT_BRANCH == "develop"' when: on_success -build-rootless: +build-rootless-ce: extends: .build variables: DOCKERFILE_PATH: "debian/Dockerfile.rootless" DOCKER_TAG: "rootless" + PASSBOLT_FLAVOUR: "ce" + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule" || $CI_COMMIT_BRANCH == "develop"' + when: on_success + +build-docker-pro: + extends: .build + variables: + DOCKERFILE_PATH: "debian/Dockerfile" + DOCKER_TAG: "root" + PASSBOLT_FLAVOUR: "pro" + rules: + - if: '$CI_PIPELINE_SOURCE == "schedule" || $CI_COMMIT_BRANCH == "develop"' + when: on_success + +build-rootless-pro: + extends: .build + variables: + DOCKERFILE_PATH: "debian/Dockerfile.rootless" + DOCKER_TAG: "rootless" + PASSBOLT_FLAVOUR: "pro" rules: - if: '$CI_PIPELINE_SOURCE == "schedule" || $CI_COMMIT_BRANCH == "develop"' when: on_success From 4e366a9888cfc259caa291341dcd6917cee0bed6 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Tue, 16 Feb 2021 19:46:49 +0100 Subject: [PATCH 22/24] Changed: fix image tag --- .gitlab-ci/Jobs/container_security_scan.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci/Jobs/container_security_scan.yml b/.gitlab-ci/Jobs/container_security_scan.yml index 00afead..df4c583 100644 --- a/.gitlab-ci/Jobs/container_security_scan.yml +++ b/.gitlab-ci/Jobs/container_security_scan.yml @@ -20,13 +20,15 @@ container_scanning: # https://docs.gitlab.com/runner/executors/kubernetes.html DOCKER_SERVICE: localhost DOCKER_HOST: tcp://${DOCKER_SERVICE}:2375/ + DOCKER_TAG: rootless # https://hub.docker.com/r/arminc/clair-local-scan/tags CLAIR_LOCAL_SCAN_VERSION: v2.0.8_fe9b059d930314b54c78f75afe265955faf4fdc1 + PASSBOLT_FLAVOUR: pro allow_failure: true services: - docker:18-dind script: - - export CI_APPLICATION_TAG=${PASSBOLT_FLAVOUR:-local}-${UPSTREAM_COMMIT_SHA:-latest} + - export CI_APPLICATION_TAG=${PASSBOLT_FLAVOUR:-local}-${DOCKER_TAG}-latest - echo "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" - if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then { export DOCKER_SERVICE="localhost" ; export DOCKER_HOST="tcp://${DOCKER_SERVICE}:2375" ; } fi - | From 4cbb992c47f3524ae91852bcec47c6eb996e8d2d Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Date: Mon, 22 Feb 2021 15:04:46 +0000 Subject: [PATCH 23/24] Fix docker tests --- .gitignore | 2 + Gemfile.lock | 47 ++++++++++--------- debian/Dockerfile | 7 +-- spec/docker_image/image_spec.rb | 39 +++++---------- spec/docker_runtime/runtime_spec.rb | 32 ++----------- .../runtime_no_envs_spec.rb | 34 ++------------ 6 files changed, 50 insertions(+), 111 deletions(-) diff --git a/.gitignore b/.gitignore index 21f1ca3..4285565 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ conf/*.key src .ruby-version + +.bundle diff --git a/Gemfile.lock b/Gemfile.lock index 73aff83..4d786f6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,45 +1,45 @@ GEM remote: https://rubygems.org/ specs: - coderay (1.1.2) - diff-lcs (1.3) - docker-api (1.34.2) + coderay (1.1.3) + diff-lcs (1.4.4) + docker-api (2.0.0) excon (>= 0.47.0) multi_json - excon (0.73.0) + excon (0.79.0) method_source (1.0.0) - multi_json (1.14.1) - net-scp (2.0.0) - net-ssh (>= 2.6.5, < 6.0.0) - net-ssh (5.2.0) + multi_json (1.15.0) + net-scp (3.0.0) + net-ssh (>= 2.6.5, < 7.0.0) + net-ssh (6.1.0) net-telnet (0.1.1) - pry (0.13.1) + pry (0.14.0) coderay (~> 1.1) method_source (~> 1.0) - rake (13.0.1) - rspec (3.9.0) - rspec-core (~> 3.9.0) - rspec-expectations (~> 3.9.0) - rspec-mocks (~> 3.9.0) - rspec-core (3.9.1) - rspec-support (~> 3.9.1) - rspec-expectations (3.9.1) + rake (13.0.3) + rspec (3.10.0) + rspec-core (~> 3.10.0) + rspec-expectations (~> 3.10.0) + rspec-mocks (~> 3.10.0) + rspec-core (3.10.1) + rspec-support (~> 3.10.0) + rspec-expectations (3.10.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) + rspec-support (~> 3.10.0) rspec-its (1.3.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.9.1) + rspec-mocks (3.10.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-support (3.9.2) + rspec-support (~> 3.10.0) + rspec-support (3.10.2) serverspec (2.41.5) multi_json rspec (~> 3.0) rspec-its specinfra (~> 2.72) sfl (2.3) - specinfra (2.82.15) + specinfra (2.82.23) net-scp net-ssh (>= 2.7) net-telnet (= 0.1.1) @@ -47,6 +47,7 @@ GEM PLATFORMS ruby + x86_64-linux DEPENDENCIES docker-api @@ -55,4 +56,4 @@ DEPENDENCIES serverspec BUNDLED WITH - 1.17.2 + 2.2.6 diff --git a/debian/Dockerfile b/debian/Dockerfile index 26c3fba..d398861 100644 --- a/debian/Dockerfile +++ b/debian/Dockerfile @@ -11,11 +11,6 @@ ARG PASSBOLT_DISTRO="buster" ARG PASSBOLT_COMPONENT="stable" ARG PASSBOLT_PKG=passbolt-ce-server -ARG PASSBOLT_REPO_URL="https://download.passbolt.com/ce/debian" -ARG PASSBOLT_DISTRO="buster" -ARG PASSBOLT_COMPONENT="stable" -ARG PASSBOLT_PKG=passbolt-ce-server - RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ ca-certificates \ @@ -27,6 +22,7 @@ RUN apt-get update \ nginx \ $PASSBOLT_PKG \ supervisor \ + curl \ && rm /etc/nginx/sites-enabled/default \ && mkdir /run/php \ && cp /usr/share/passbolt/examples/nginx-passbolt-ssl.conf /etc/nginx/snippets/passbolt-ssl.conf \ @@ -36,6 +32,7 @@ RUN apt-get update \ && sed -i 's,__CERT_PATH__,/etc/ssl/certs/certificate.crt;,' /etc/nginx/snippets/passbolt-ssl.conf \ && sed -i 's,__KEY_PATH__,/etc/ssl/certs/certificate.key;,' /etc/nginx/snippets/passbolt-ssl.conf \ && sed -i 's,www-data.*$,www-data exec /bin/bash -c ". /etc/environment \&\& $PASSBOLT_BASE_DIR/bin/cron",' /etc/cron.d/$PASSBOLT_PKG \ + && sed -i 's/# server_tokens/server_tokens/' /etc/nginx/nginx.conf \ && ln -sf /dev/stdout /var/log/nginx/passbolt-access.log \ && ln -sf /dev/stderr /var/log/nginx/passbolt-error.log \ && ln -sf /dev/stderr /var/log/passbolt/error.log \ diff --git a/spec/docker_image/image_spec.rb b/spec/docker_image/image_spec.rb index 92fa81c..8bb736b 100644 --- a/spec/docker_image/image_spec.rb +++ b/spec/docker_image/image_spec.rb @@ -8,30 +8,29 @@ describe 'Dockerfile' do 'DATASOURCES_DEFAULT_PASSWORD' => 'P4ssb0lt', 'DATASOURCES_DEFAULT_USERNAME' => 'passbolt', 'DATASOURCES_DEFAULT_DATABASE' => 'passbolt', - 'PASSBOLT_GPG_KEYRING' => '/var/lib/nginx/.gnupg' + 'PASSBOLT_GPG_KEYRING' => '/var/lib/passbolt/.gnupg' } - @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES, { 'dockerfile' => 'debian/Dockerfile' }) set :docker_image, @image.id set :docker_container_create_options, { 'Cmd' => '/bin/sh' } end let(:nginx_conf) { '/etc/nginx/nginx.conf' } - let(:php_conf) { '/usr/local/etc/php-fpm.d/expose.conf' } - let(:site_conf) { '/etc/nginx/conf.d/default.conf' } + let(:php_conf) { '/etc/php/7.3/fpm/php.ini' } + let(:site_conf) { '/etc/nginx/sites-enabled/nginx-passbolt.conf' } let(:supervisor_conf) do [ '/etc/supervisor/conf.d/nginx.conf', '/etc/supervisor/conf.d/php.conf', '/etc/supervisor/conf.d/cron.conf' ] end - let(:passbolt_home) { '/var/www/passbolt' } - let(:passbolt_tmp) { '/var/www/passbolt/tmp' } - let(:passbolt_image) { '/var/www/passbolt/webroot/img/public' } + let(:passbolt_home) { '/usr/share/php/passbolt' } + let(:passbolt_tmp) { '/var/lib/passbolt/tmp' } + let(:passbolt_image) { "#{passbolt_home}/webroot/img/public" } let(:passbolt_owner) { 'www-data' } let(:exposed_ports) { [ '80', '443' ] } - let(:composer) { '/usr/local/bin/composer'} let(:php_extensions) { [ - 'curl', 'gd', 'intl', 'json', 'mcrypt', 'mysqlnd', 'xsl', 'phar', + 'gd', 'intl', 'json', 'mysqlnd', 'xsl', 'phar', 'posix', 'xml', 'zlib', 'ctype', 'pdo', 'gnupg', 'pdo_mysql' ] } let(:wait_for) { '/usr/bin/wait-for.sh' } @@ -44,12 +43,6 @@ describe 'Dockerfile' do end end - describe 'php composer' do - it 'is not installed' do - expect(file(composer)).to_not exist - end - end - describe 'supervisor' do it 'is installed' do expect(package('supervisor')).to be_installed @@ -62,12 +55,6 @@ describe 'Dockerfile' do end end - describe 'mariadb-client' do - it 'is installed' do - expect(package('mariadb-client')).to be_installed - end - end - describe 'wait-for' do it 'is installed' do expect(file(wait_for)).to exist and be_executable @@ -82,17 +69,17 @@ describe 'Dockerfile' do end it 'must be owned by correct user' do - expect(file(passbolt_home)).to be_owned_by(passbolt_owner) + expect(file(passbolt_home)).to be_owned_by('root') expect(file(passbolt_tmp)).to be_owned_by(passbolt_owner) expect(file(passbolt_image)).to be_owned_by(passbolt_owner) end it 'must have the correct permissions on tmp' do - expect(file(passbolt_tmp)).to be_mode('775') + expect(file(passbolt_tmp)).to be_mode('755') end it 'must have the correct permissions on img' do - expect(file(passbolt_image)).to be_mode('775') + expect(file(passbolt_image)).to be_mode('755') end end @@ -102,7 +89,7 @@ describe 'Dockerfile' do end it 'does not expose php version' do - expect(file(php_conf).content).to match(/^php_flag\[expose_php\]\s+=\s+off$/) + expect(file(php_conf).content).to match(/^expose_php\s+=\s+Off$/) end end @@ -126,7 +113,7 @@ describe 'Dockerfile' do end it 'points to the correct root folder' do - expect(file(site_conf).content).to match 'root /var/www/passbolt/webroot' + expect(file(site_conf).content).to match "root #{passbolt_home}/webroot" end it 'has server tokens off' do diff --git a/spec/docker_runtime/runtime_spec.rb b/spec/docker_runtime/runtime_spec.rb index 6578e38..972fadb 100644 --- a/spec/docker_runtime/runtime_spec.rb +++ b/spec/docker_runtime/runtime_spec.rb @@ -24,7 +24,7 @@ describe 'passbolt_api service' do sleep 1 end - @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES, { 'dockerfile' => 'debian/Dockerfile' }) @container = Docker::Container.create( 'Env' => [ "DATASOURCES_DEFAULT_HOST=#{@mysql.json['NetworkSettings']['IPAddress']}", @@ -54,10 +54,6 @@ describe 'passbolt_api service' do it 'is running supervised' do expect(service('php-fpm')).to be_running.under('supervisor') end - - it 'has its port open' do - expect(@container.json['Config']['ExposedPorts']).to have_key('9000/tcp') - end end describe 'email cron' do @@ -86,28 +82,8 @@ describe 'passbolt_api service' do end end - describe 'passbolt serverkey unaccessible' do - let(:uri) { '/config/gpg/serverkey.asc' } - it "returns 404" do - expect(command(curl).stdout).to eq '404' - end - end - - describe 'passbolt serverkey private unaccessible' do - let(:uri) { '/config/gpg/serverkey_private.asc' } - it 'returns 404' do - expect(command(curl).stdout).to eq '404' - end - end - - describe 'passbolt conf unaccessible' do - let(:uri) { '/config/app.php' } - it 'returns 404' do - expect(command(curl).stdout).to eq '404' - end - end - describe 'passbolt tmp folder is unaccessible' do - let(:uri) { '/tmp/cache/database/empty' } + describe 'can not access outside webroot' do + let(:uri) { '/vendor/autoload.php' } it 'returns 404' do expect(command(curl).stdout).to eq '404' end @@ -120,7 +96,7 @@ describe 'passbolt_api service' do end it 'hides nginx version' do - expect(command("#{curl} | grep 'Server:'").stdout.strip).to match(/^Server:\s+nginx$/) + expect(command("#{curl} | grep 'server:'").stdout.strip).to match(/^server:\s+nginx$/) end end diff --git a/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb b/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb index 3672732..1709459 100644 --- a/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb +++ b/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb @@ -24,13 +24,13 @@ describe 'passbolt_api service' do sleep 1 end - @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES) + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES, { 'dockerfile' => 'debian/Dockerfile' }) @container = Docker::Container.create( 'Env' => [ "DATASOURCES_DEFAULT_HOST=#{@mysql.json['NetworkSettings']['IPAddress']}", ], - 'Binds' => [ "#{FIXTURES_PATH + '/passbolt.php'}:/var/www/passbolt/config/passbolt.php" ], + 'Binds' => [ "#{FIXTURES_PATH + '/passbolt.php'}:/etc/passbolt/passbolt.php" ], 'Image' => @image.id) @container.start @@ -53,10 +53,6 @@ describe 'passbolt_api service' do it 'is running supervised' do expect(service('php-fpm')).to be_running.under('supervisor') end - - it 'has its port open' do - expect(@container.json['Config']['ExposedPorts']).to have_key('9000/tcp') - end end describe 'email cron' do @@ -85,28 +81,8 @@ describe 'passbolt_api service' do end end - describe 'passbolt serverkey unaccessible' do - let(:uri) { '/config/gpg/serverkey.asc' } - it "returns 404" do - expect(command(curl).stdout).to eq '404' - end - end - - describe 'passbolt serverkey private unaccessible' do - let(:uri) { '/config/gpg/serverkey_private.asc' } - it 'returns 404' do - expect(command(curl).stdout).to eq '404' - end - end - - describe 'passbolt conf unaccessible' do - let(:uri) { '/config/app.php' } - it 'returns 404' do - expect(command(curl).stdout).to eq '404' - end - end - describe 'passbolt tmp folder is unaccessible' do - let(:uri) { '/tmp/cache/database/empty' } + describe 'can not access outside webroot' do + let(:uri) { '/vendor/autoload.php' } it 'returns 404' do expect(command(curl).stdout).to eq '404' end @@ -119,7 +95,7 @@ describe 'passbolt_api service' do end it 'hides nginx version' do - expect(command("#{curl} | grep 'Server:'").stdout.strip).to match(/^Server:\s+nginx$/) + expect(command("#{curl} | grep 'server:'").stdout.strip).to match(/^server:\s+nginx$/) end end From 66fa785f2717689f60fe7294594625c997db0911 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Date: Tue, 23 Feb 2021 11:57:52 +0000 Subject: [PATCH 24/24] Fix cron --- conf/supervisor/cron.conf | 2 +- debian/Dockerfile.rootless | 26 +++-- debian/bin/docker-entrypoint.sh | 2 - debian/bin/docker-entrypoint.sh.rootless | 141 +++++++++++++++++++++++ 4 files changed, 160 insertions(+), 11 deletions(-) create mode 100755 debian/bin/docker-entrypoint.sh.rootless diff --git a/conf/supervisor/cron.conf b/conf/supervisor/cron.conf index 07bce67..d2b105d 100644 --- a/conf/supervisor/cron.conf +++ b/conf/supervisor/cron.conf @@ -1,5 +1,5 @@ [program:cron] -command=/bin/bash -c "declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /etc/environment; cron -f -l" +command=/usr/local/bin/supercronic /etc/cron.d/passbolt-ce-server autostart=true priority=20 stdout_logfile=/dev/stdout diff --git a/debian/Dockerfile.rootless b/debian/Dockerfile.rootless index 9a1fd7a..254337d 100644 --- a/debian/Dockerfile.rootless +++ b/debian/Dockerfile.rootless @@ -2,15 +2,20 @@ FROM debian:buster-slim LABEL maintainer="Passbolt SA " -ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D -ENV PHP_VERSION=7.3 -ENV GNUPGHOME=/var/lib/passbolt/.gnupg - +ARG SUPERCRONIC_ARCH=amd64 ARG PASSBOLT_REPO_URL="https://download.passbolt.com/ce/debian" ARG PASSBOLT_DISTRO="buster" ARG PASSBOLT_COMPONENT="stable" ARG PASSBOLT_PKG=passbolt-ce-server +ENV PASSBOLT_PKG_KEY=0xDE8B853FC155581D +ENV PHP_VERSION=7.3 +ENV GNUPGHOME=/var/lib/passbolt/.gnupg +ENV SUPERCRONIC_VERSION=0.1.12 +ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v${SUPERCRONIC_VERSION}/supercronic-linux-${SUPERCRONIC_ARCH} \ + SUPERCRONIC=supercronic-linux-${SUPERCRONIC_ARCH} \ + SUPERCRONIC_SHA1SUM=048b95b48b708983effb2e5c935a1ef8483d9e3e + RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ ca-certificates \ @@ -21,7 +26,13 @@ RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install --no-install-recommends \ nginx \ $PASSBOLT_PKG \ - supervisor + supervisor \ + curl \ + && curl -fsSLO "$SUPERCRONIC_URL" \ + && echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC}" | sha1sum -c - \ + && chmod +x "$SUPERCRONIC" \ + && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \ + && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic RUN sed -i 's,listen 80;,listen 8080;,' /etc/nginx/sites-enabled/nginx-passbolt.conf \ && rm /etc/nginx/sites-enabled/default \ @@ -55,11 +66,10 @@ RUN sed -i 's,listen 80;,listen 8080;,' /etc/nginx/sites-enabled/nginx-passbolt. && chown -R www-data:0 /var/log/supervisor \ && touch /var/www/.profile \ && chown www-data:www-data /var/www/.profile \ - && sed -i 's,www-data.*$,www-data exec /bin/bash -c ". /etc/environment \&\& $PASSBOLT_BASE_DIR/bin/cron",' /etc/cron.d/$PASSBOLT_PKG \ - && crontab /etc/cron.d/$PASSBOLT_PKG + && sed -i 's,www-data\s,,' /etc/cron.d/$PASSBOLT_PKG COPY conf/supervisor/*.conf /etc/supervisor/conf.d/ -COPY debian/bin/docker-entrypoint.sh /docker-entrypoint.sh +COPY debian/bin/docker-entrypoint.sh.rootless /docker-entrypoint.sh COPY scripts/wait-for.sh /usr/bin/wait-for.sh EXPOSE 8080 4443 diff --git a/debian/bin/docker-entrypoint.sh b/debian/bin/docker-entrypoint.sh index 0eddac9..5c1f803 100755 --- a/debian/bin/docker-entrypoint.sh +++ b/debian/bin/docker-entrypoint.sh @@ -138,6 +138,4 @@ install echo -e "$deprecation_message" -echo -e "$deprecation_message" - exec /usr/bin/supervisord -n diff --git a/debian/bin/docker-entrypoint.sh.rootless b/debian/bin/docker-entrypoint.sh.rootless new file mode 100755 index 0000000..7a6ced1 --- /dev/null +++ b/debian/bin/docker-entrypoint.sh.rootless @@ -0,0 +1,141 @@ +#!/usr/bin/env bash + +set -exo pipefail + +passbolt_config="/etc/passbolt" +gpg_private_key="${PASSBOLT_GPG_SERVER_KEY_PRIVATE:-$passbolt_config/gpg/serverkey_private.asc}" +gpg_public_key="${PASSBOLT_GPG_SERVER_KEY_PUBLIC:-$passbolt_config/gpg/serverkey.asc}" + +ssl_key='/etc/passbolt/certs/certificate.key' +ssl_cert='/etc/passbolt/certs/certificate.crt' + +deprecation_message="" + +entropy_check() { + local entropy_avail + + entropy_avail=$(cat /proc/sys/kernel/random/entropy_avail) + + if [ "$entropy_avail" -lt 2000 ]; then + + cat < $gpg_private_key + gpg --homedir $GNUPGHOME --armor --export $key_email > $gpg_public_key +} + +gpg_import_key() { + gpg --homedir $GNUPGHOME --batch --import $gpg_public_key + gpg --homedir $GNUPGHOME --batch --import $gpg_private_key +} + +gen_ssl_cert() { + openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ + -subj '/C=FR/ST=Denial/L=Springfield/O=Dis/CN=www.passbolt.local' \ + -keyout $ssl_key -out $ssl_cert +} + +install() { + if [ ! -f "$passbolt_config/app.php" ]; then + cp $passbolt_config/app.default.php $passbolt_config/app.php + fi + + if [ -z "${PASSBOLT_GPG_SERVER_KEY_FINGERPRINT+xxx}" ] && [ ! -f "$passbolt_config/passbolt.php" ]; then + gpg_auto_fingerprint="$(gpg --homedir $GNUPGHOME --list-keys --with-colons ${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com} |grep fpr |head -1| cut -f10 -d:)" + export PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=$gpg_auto_fingerprint + fi + + /usr/share/php/passbolt/bin/cake passbolt install --no-admin || /usr/share/php/passbolt/bin/cake passbolt migrate && echo "Enjoy! ☮" +} + +create_deprecation_message() { + deprecation_message+="\033[33;5;7mWARNING: $1 is deprecated, point your docker volume to $2\033[0m\n" +} + +check_deprecated_paths() { + declare -A deprecated_paths + local deprecated_avatar_path="/var/www/passbolt/webroot/img/public/Avatar" + local avatar_path="/usr/share/php/passbolt/webroot/img/public/Avatar" + local deprecated_subscription_path="/var/www/passbolt/webroot/img/public/Avatar" + local subscription_path="/etc/passbolt/license" + deprecated_paths=( + ['/var/www/passbolt/config/gpg/serverkey.asc']='/etc/passbolt/gpg/serverkey.asc' + ['/var/www/passbolt/config/gpg/serverkey_private.asc']='/etc/passbolt/gpg/serverkey_private.asc' + ) + + if [ -z "$PASSBOLT_GPG_SERVER_KEY_PUBLIC" ] || [ -z "$PASSBOLT_GPG_SERVER_KEY_PRIVATE" ]; then + for path in "${!deprecated_paths[@]}" + do + if [ -f "$path" ] && [ ! -f "${deprecated_paths[$path]}" ]; then + ln -s "$path" "${deprecated_paths[$path]}" + create_deprecation_message "$path" "${deprecated_paths[$path]}" + fi + done + fi + + if [ -d "$deprecated_avatar_path" ] && [ ! -d "$avatar_path" ]; then + ln -s "$deprecated_avatar_path" "$avatar_path" + create_deprecation_message "$deprecated_avatar_path" "$avatar_path" + fi + + if [ -f "$deprecated_subscription_path" ] && [ ! -f "$subscription_path" ]; then + ln -s "$deprecated_subscription_path" "$subscription_path" + create_deprecation_message "$deprecated_subscription_path" "$subscription_path" + fi +} + +check_deprecated_paths + +if [ ! -f "$gpg_private_key" ] || \ + [ ! -f "$gpg_public_key" ]; then + gpg_gen_key + gpg_import_key +else + gpg_import_key +fi + +if [ ! -f "$ssl_key" ] && [ ! -L "$ssl_key" ] && \ + [ ! -f "$ssl_cert" ] && [ ! -L "$ssl_cert" ]; then + gen_ssl_cert +fi + +install + +echo -e "$deprecation_message" + +exec /usr/bin/supervisord -n