Merge branch 'develop'

This commit is contained in:
Diego Lendoiro 2021-02-23 13:35:01 +01:00
commit 802c9f7c84
No known key found for this signature in database
GPG Key ID: 3808AD1A50FF0B59
22 changed files with 617 additions and 131 deletions

2
.gitignore vendored
View File

@ -32,3 +32,5 @@ conf/*.key
src
.ruby-version
.bundle

13
.gitlab-ci.yml Normal file
View File

@ -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'

View File

@ -0,0 +1,64 @@
.build:
stage: build
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
- |
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/$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-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-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

View File

@ -0,0 +1,61 @@
# 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/
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}-${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
- |
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

View File

@ -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

View File

@ -1,5 +1,5 @@
[program:cron]
command=cron -f -l
command=/usr/local/bin/supercronic /etc/cron.d/passbolt-ce-server
autostart=true
priority=20
stdout_logfile=/dev/stdout

View File

@ -1,5 +1,5 @@
[program:php-fpm]
command=php-fpm -F
command=php-fpm7.3 -F
autostart=true
priority=5
stdout_logfile=/dev/stdout

50
debian/Dockerfile vendored Normal file
View File

@ -0,0 +1,50 @@
FROM debian:buster-slim
LABEL maintainer="Passbolt SA <contact@passbolt.com>"
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 \
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 \
&& 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 \
&& 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 \
&& 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"]

81
debian/Dockerfile.rootless vendored Normal file
View File

@ -0,0 +1,81 @@
FROM debian:buster-slim
LABEL maintainer="Passbolt SA <contact@passbolt.com>"
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 \
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 \
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 \
&& 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,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 \
&& 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 \
&& 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.rootless /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"]

141
debian/bin/docker-entrypoint.sh vendored Executable file
View File

@ -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 <<EOF
==================================================================================
Your entropy pool is low. This situation could lead GnuPG to not
be able to create the gpg serverkey so the container start process will hang
until enough entropy is obtained.
Please consider installing rng-tools and/or virtio-rng on your host as the
preferred method to generate random numbers using a TRNG.
If rngd (rng-tools) does not provide enough or fast enough randomness you could
consider installing haveged as a helper to speed up this process.
Using haveged as a replacement for rngd is not recommended. You can read more
about this topic here: https://lwn.net/Articles/525459/
==================================================================================
EOF
fi
}
gpg_gen_key() {
key_email="${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com}"
key_name="${PASSBOLT_KEY_NAME:-Passbolt default user}"
key_length="${PASSBOLT_KEY_LENGTH:-2048}"
subkey_length="${PASSBOLT_SUBKEY_LENGTH:-2048}"
expiration="${PASSBOLT_KEY_EXPIRATION:-0}"
entropy_check
su -c "gpg --homedir $GNUPGHOME --batch --no-tty --gen-key <<EOF
Key-Type: default
Key-Length: $key_length
Subkey-Type: default
Subkey-Length: $subkey_length
Name-Real: $key_name
Name-Email: $key_email
Expire-Date: $expiration
%no-protection
%commit
EOF" -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 --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

141
debian/bin/docker-entrypoint.sh.rootless vendored Executable file
View File

@ -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 <<EOF
==================================================================================
Your entropy pool is low. This situation could lead GnuPG to not
be able to create the gpg serverkey so the container start process will hang
until enough entropy is obtained.
Please consider installing rng-tools and/or virtio-rng on your host as the
preferred method to generate random numbers using a TRNG.
If rngd (rng-tools) does not provide enough or fast enough randomness you could
consider installing haveged as a helper to speed up this process.
Using haveged as a replacement for rngd is not recommended. You can read more
about this topic here: https://lwn.net/Articles/525459/
==================================================================================
EOF
fi
}
gpg_gen_key() {
key_email="${PASSBOLT_KEY_EMAIL:-passbolt@yourdomain.com}"
key_name="${PASSBOLT_KEY_NAME:-Passbolt default user}"
key_length="${PASSBOLT_KEY_LENGTH:-2048}"
subkey_length="${PASSBOLT_SUBKEY_LENGTH:-2048}"
expiration="${PASSBOLT_KEY_EXPIRATION:-0}"
entropy_check
gpg --homedir $GNUPGHOME --batch --no-tty --gen-key <<EOF
Key-Type: default
Key-Length: $key_length
Subkey-Type: default
Subkey-Length: $subkey_length
Name-Real: $key_name
Name-Email: $key_email
Expire-Date: $expiration
%no-protection
%commit
EOF
gpg --homedir $GNUPGHOME --armor --export-secret-keys $key_email > $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

1
debian/conf vendored Symbolic link
View File

@ -0,0 +1 @@
../conf

1
debian/scripts vendored Symbolic link
View File

@ -0,0 +1 @@
../scripts

View File

@ -76,11 +76,14 @@ RUN apt-get update \
&& 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"
&& 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 bin/docker-entrypoint.sh /docker-entrypoint.sh
COPY dev/bin/docker-entrypoint.sh /docker-entrypoint.sh
COPY scripts/wait-for.sh /usr/bin/wait-for.sh
EXPOSE 80 443

View File

@ -84,15 +84,6 @@ install() {
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! ☮"
}
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
gpg_gen_key
@ -107,6 +98,5 @@ if [ ! -f "$ssl_key" ] && [ ! -L "$ssl_key" ] && \
fi
install
email_cron_job
exec /usr/bin/supervisord -n

1
dev/conf Symbolic link
View File

@ -0,0 +1 @@
../conf

1
dev/scripts Symbolic link
View File

@ -0,0 +1 @@
../scripts

View File

@ -10,18 +10,16 @@ services:
- "127.0.0.1:3306:3306"
passbolt:
image: passbolt/passbolt:2.13.5-pro-debian
image: passbolt/passbolt:3.0.0-pro
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
- ./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

View File

@ -10,17 +10,15 @@ services:
- "127.0.0.1:3306:3306"
passbolt:
image: passbolt/passbolt:2.13.5-debian
image: passbolt/passbolt:3.0.0-ce
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:/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:
- 80:80

View File

@ -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

View File

@ -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

View File

@ -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