From 20d592684b230bc9411d0cb21f9a74440c70d8d1 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 8 Mar 2021 11:51:29 +0100 Subject: [PATCH 1/7] Changed: fix non root supervisord cron configuration file --- conf/supervisor/cron.conf.rootless | 2 +- debian/Dockerfile.rootless | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/conf/supervisor/cron.conf.rootless b/conf/supervisor/cron.conf.rootless index d2b105d..b11f152 100644 --- a/conf/supervisor/cron.conf.rootless +++ b/conf/supervisor/cron.conf.rootless @@ -1,5 +1,5 @@ [program:cron] -command=/usr/local/bin/supercronic /etc/cron.d/passbolt-ce-server +command=/usr/local/bin/supercronic /etc/cron.d/__PASSBOLT_PACKAGE__ autostart=true priority=20 stdout_logfile=/dev/stdout diff --git a/debian/Dockerfile.rootless b/debian/Dockerfile.rootless index bd80beb..0ca7e99 100644 --- a/debian/Dockerfile.rootless +++ b/debian/Dockerfile.rootless @@ -16,6 +16,7 @@ ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v${ SUPERCRONIC=supercronic-linux-${SUPERCRONIC_ARCH} \ SUPERCRONIC_SHA1SUM=048b95b48b708983effb2e5c935a1ef8483d9e3e + RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ ca-certificates \ @@ -34,6 +35,8 @@ RUN apt-get update \ && mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \ && ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic +COPY conf/supervisor/cron.conf.rootless /etc/supervisor/conf.d/cron.conf + 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 \ @@ -66,9 +69,9 @@ 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\s,,' /etc/cron.d/$PASSBOLT_PKG + && sed -i 's,www-data\s,,' /etc/cron.d/$PASSBOLT_PKG \ + && sed -i "s,__PASSBOLT_PACKAGE__,$PASSBOLT_PKG," /etc/supervisor/conf.d/cron.conf -COPY conf/supervisor/cron.conf.rootless /etc/supervisor/conf.d/cron.conf COPY conf/supervisor/nginx.conf /etc/supervisor/conf.d/nginx.conf COPY conf/supervisor/php.conf /etc/supervisor/conf.d/php.conf COPY debian/bin/docker-entrypoint.sh.rootless /docker-entrypoint.sh From 2d2f4095ee5a9d53f7f7248e531db372b5176306 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 8 Mar 2021 11:53:24 +0100 Subject: [PATCH 2/7] Changed: remove empty line --- debian/Dockerfile.rootless | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/Dockerfile.rootless b/debian/Dockerfile.rootless index 0ca7e99..d09ea07 100644 --- a/debian/Dockerfile.rootless +++ b/debian/Dockerfile.rootless @@ -16,7 +16,6 @@ ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v${ SUPERCRONIC=supercronic-linux-${SUPERCRONIC_ARCH} \ SUPERCRONIC_SHA1SUM=048b95b48b708983effb2e5c935a1ef8483d9e3e - RUN apt-get update \ && DEBIAN_FRONTEND=non-interactive apt-get -y install \ ca-certificates \ From 07e08d0b6fec65b21fefec20c394f94faf69f30c Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Mon, 8 Mar 2021 12:29:38 +0100 Subject: [PATCH 3/7] Changed: use latest tag on composer file --- docker-compose-pro.yml | 4 ++-- docker-compose.yml | 4 ++-- env/passbolt.env | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docker-compose-pro.yml b/docker-compose-pro.yml index c8b31e1..8d4bcfd 100644 --- a/docker-compose-pro.yml +++ b/docker-compose-pro.yml @@ -10,9 +10,9 @@ services: - "127.0.0.1:3306:3306" passbolt: - image: passbolt/passbolt:3.0.1-pro + image: passbolt/passbolt:latest-pro #Alternatively you can use rootless: - #image: passbolt/passbolt:3.0.0-pro-non-root + #image: passbolt/passbolt:latest-pro-non-root tty: true depends_on: - db diff --git a/docker-compose.yml b/docker-compose.yml index 76f826f..661189c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,9 +10,9 @@ services: - "127.0.0.1:3306:3306" passbolt: - image: passbolt/passbolt:3.0.1-ce + image: passbolt/passbolt:latest-ce #Alternatively you can use rootless: - #image: passbolt/passbolt:3.0.0-ce-non-root + #image: passbolt/passbolt:latest-ce-non-root tty: true depends_on: - db diff --git a/env/passbolt.env b/env/passbolt.env index cb83100..21be0fc 100644 --- a/env/passbolt.env +++ b/env/passbolt.env @@ -1,7 +1,5 @@ # URL APP_FULL_BASE_URL=https://passbolt.local -# For rootless images -#APP_FULL_BASE_URL=https://passbolt.local:4433 # Database settings DATASOURCES_DEFAULT_HOST=db From 77cbc65941b0877ce5f118367e5c308db5bbee69 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Thu, 11 Mar 2021 18:48:43 +0100 Subject: [PATCH 4/7] Changed: parametrize tests to add rootless supports --- spec/spec_helper.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 39299aa..0f08e78 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,7 +4,23 @@ require 'docker' ROOT_DOCKERFILES = File.expand_path('../../', __FILE__) FIXTURES_PATH = File::expand_path("fixtures", File::dirname(__FILE__)) +$cron_binary = '/usr/sbin/cron' +$dockerfile = 'debian/Dockerfile' +$http_port = '80' +$https_port = '443' +$root_user = 'root' + set :backend, :docker Docker.options[:read_timeout] = 3600 Docker.options[:write_timeout] = 3600 +if ENV['ROOTLESS'] == "true" + $cron_binary = '/usr/local/bin/supercronic' + $dockerfile = 'debian/Dockerfile.rootless' + $http_port = '8080' + $https_port = '4433' + # Where www-data has to be the owner instead of root + $root_user = 'www-data' +end + +puts($root_user) From adee1543b3b9fce0b19215207f8037f1607779ad Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Thu, 11 Mar 2021 18:49:36 +0100 Subject: [PATCH 5/7] Changed: adapt runtime tests to rootltess support --- spec/docker_runtime/runtime_spec.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/docker_runtime/runtime_spec.rb b/spec/docker_runtime/runtime_spec.rb index 972fadb..a5aca6d 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, { 'dockerfile' => 'debian/Dockerfile' }) + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES, { 'dockerfile' => $dockerfile }) @container = Docker::Container.create( 'Env' => [ "DATASOURCES_DEFAULT_HOST=#{@mysql.json['NetworkSettings']['IPAddress']}", @@ -48,7 +48,7 @@ describe 'passbolt_api service' do let(:passbolt_host) { @container.json['NetworkSettings']['IPAddress'] } let(:uri) { "/healthcheck/status.json" } - let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}/#{uri}" } + let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/#{uri}" } describe 'php service' do it 'is running supervised' do @@ -67,12 +67,12 @@ describe 'passbolt_api service' do expect(service('nginx')).to be_running.under('supervisor') end - it 'is listening on port 80' do - expect(@container.json['Config']['ExposedPorts']).to have_key('80/tcp') + it "is listening on port #{$http_port}" do + expect(@container.json['Config']['ExposedPorts']).to have_key("#{$http_port}/tcp") end - it 'is listening on port 443' do - expect(@container.json['Config']['ExposedPorts']).to have_key('443/tcp') + it "is listening on port #{$https_port}" do + expect(@container.json['Config']['ExposedPorts']).to have_key("#{$https_port}/tcp") end end @@ -90,13 +90,13 @@ describe 'passbolt_api service' do end describe 'hide information' do - let(:curl) { "curl -Isk -H 'Host: passbolt.local' https://#{passbolt_host}/" } + let(:curl) { "curl -Isk -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/" } it 'hides php version' do expect(command("#{curl} | grep 'X-Powered-By: PHP'").stdout).to be_empty 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 91f6d744107e59adac612fe0b75c5d43a5b71c59 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Thu, 11 Mar 2021 18:49:59 +0100 Subject: [PATCH 6/7] Changed: adapt image test to add rootless support --- spec/docker_image/image_spec.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/docker_image/image_spec.rb b/spec/docker_image/image_spec.rb index 8bb736b..a48a70d 100644 --- a/spec/docker_image/image_spec.rb +++ b/spec/docker_image/image_spec.rb @@ -11,7 +11,7 @@ describe 'Dockerfile' do 'PASSBOLT_GPG_KEYRING' => '/var/lib/passbolt/.gnupg' } - @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES, { 'dockerfile' => 'debian/Dockerfile' }) + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES, { 'dockerfile' => $dockerfile }) set :docker_image, @image.id set :docker_container_create_options, { 'Cmd' => '/bin/sh' } end @@ -28,7 +28,7 @@ describe 'Dockerfile' do 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(:exposed_ports) { [ $http_port, $https_port ] } let(:php_extensions) { [ 'gd', 'intl', 'json', 'mysqlnd', 'xsl', 'phar', 'posix', 'xml', 'zlib', 'ctype', 'pdo', 'gnupg', 'pdo_mysql' @@ -55,6 +55,10 @@ describe 'Dockerfile' do end end + describe file($cron_service) do + it { should exist and be_executable } + end + describe 'wait-for' do it 'is installed' do expect(file(wait_for)).to exist and be_executable @@ -99,7 +103,7 @@ describe 'Dockerfile' do end it 'has the correct permissions' do - expect(file(nginx_conf)).to be_owned_by 'root' + expect(file(nginx_conf)).to be_owned_by $root_user end end @@ -109,16 +113,12 @@ describe 'Dockerfile' do end it 'has the correct permissions' do - expect(file(site_conf)).to be_owned_by 'root' + expect(file(site_conf)).to be_owned_by $root_user end it 'points to the correct root folder' do expect(file(site_conf).content).to match "root #{passbolt_home}/webroot" end - - it 'has server tokens off' do - expect(file(nginx_conf).content).to match(/^\s+server_tokens off;/) - end end describe 'ports exposed' do From d3fd5b2d376ec27efda6e5500f045ea171aa31d5 Mon Sep 17 00:00:00 2001 From: Daniel Del Rio Figueira Date: Fri, 12 Mar 2021 09:25:37 +0100 Subject: [PATCH 7/7] Changed: adapt runtime_no_envs tests to rootless image --- spec/docker_runtime_no_envs/runtime_no_envs_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 1709459..5515320 100644 --- a/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb +++ b/spec/docker_runtime_no_envs/runtime_no_envs_spec.rb @@ -24,7 +24,7 @@ describe 'passbolt_api service' do sleep 1 end - @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES, { 'dockerfile' => 'debian/Dockerfile' }) + @image = Docker::Image.build_from_dir(ROOT_DOCKERFILES, { 'dockerfile' => $dockerfile }) @container = Docker::Container.create( 'Env' => [ @@ -47,7 +47,7 @@ describe 'passbolt_api service' do let(:passbolt_host) { @container.json['NetworkSettings']['IPAddress'] } let(:uri) { "/healthcheck/status.json" } - let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}/#{uri}" } + let(:curl) { "curl -sk -o /dev/null -w '%{http_code}' -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/#{uri}" } describe 'php service' do it 'is running supervised' do @@ -67,11 +67,11 @@ describe 'passbolt_api service' do end it 'is listening on port 80' do - expect(@container.json['Config']['ExposedPorts']).to have_key('80/tcp') + expect(@container.json['Config']['ExposedPorts']).to have_key("#{$http_port}/tcp") end it 'is listening on port 443' do - expect(@container.json['Config']['ExposedPorts']).to have_key('443/tcp') + expect(@container.json['Config']['ExposedPorts']).to have_key("#{$https_port}/tcp") end end @@ -89,13 +89,13 @@ describe 'passbolt_api service' do end describe 'hide information' do - let(:curl) { "curl -Isk -H 'Host: passbolt.local' https://#{passbolt_host}/" } + let(:curl) { "curl -Isk -H 'Host: passbolt.local' https://#{passbolt_host}:#{$https_port}/" } it 'hides php version' do expect(command("#{curl} | grep 'X-Powered-By: PHP'").stdout).to be_empty 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