diff --git a/.github/workflows/acme-container-test.yml b/.github/workflows/acme-container-test.yml index 6eb9e7cd889..3fcf6cb3491 100644 --- a/.github/workflows/acme-container-test.yml +++ b/.github/workflows/acme-container-test.yml @@ -156,11 +156,12 @@ jobs: # TODO: review owners/permissions cat > expected << EOF drwxrwx--- 17 root backup - -rw-rw-rw- root root catalina.$DATE.log - -rw-rw-rw- root root host-manager.$DATE.log - -rw-rw-rw- root root localhost.$DATE.log - -rw-rw-rw- root root localhost_access_log.$DATE.txt - -rw-rw-rw- root root manager.$DATE.log + -rw-rw-rw- 17 root catalina.$DATE.log + -rw-rw-rw- 17 root host-manager.$DATE.log + -rw-rw-rw- 17 root localhost.$DATE.log + -rw-rw-rw- 17 root localhost_access_log.$DATE.txt + -rw-rw-rw- 17 root manager.$DATE.log + drwxrwxrwx 17 root pki EOF diff expected output diff --git a/.github/workflows/server-container-test.yml b/.github/workflows/server-container-test.yml index 20b1dfd2aa3..c8ebf7f5a15 100644 --- a/.github/workflows/server-container-test.yml +++ b/.github/workflows/server-container-test.yml @@ -6,6 +6,7 @@ env: DB_IMAGE: ${{ vars.DB_IMAGE || 'quay.io/389ds/dirsrv' }} jobs: + # https://github.com/dogtagpki/pki/wiki/Deploying-PKI-Server-Container test: name: Test runs-on: ubuntu-latest @@ -27,12 +28,10 @@ jobs: - name: Create network run: docker network create example - - name: Set up server container + - name: Create shared folders run: | - docker run --name pki --detach pki-server - - - name: Connect server container to network - run: docker network connect example pki --alias pki.example.com + mkdir certs + mkdir data - name: Set up client container run: | @@ -43,8 +42,19 @@ jobs: - name: Connect client container to network run: docker network connect example client --alias client.example.com - - name: Wait for server container to start + - name: Set up server container run: | + docker run \ + --name server \ + --hostname pki.example.com \ + --network example \ + --network-alias pki.example.com \ + -v $PWD/certs:/certs \ + -v $PWD/data:/data \ + --detach \ + pki-server + + # wait for server to start docker exec client curl \ --retry 60 \ --retry-delay 0 \ @@ -54,18 +64,140 @@ jobs: -o /dev/null \ https://pki.example.com:8443 - - name: Gather artifacts from server container + - name: Check data dir + if: always() + run: | + ls -l data \ + | sed \ + -e '/^total/d' \ + -e 's/^\(\S*\) *\S* *\(\S*\) *\(\S*\) *\S* *\S* *\S* *\S* *\(.*\)$/\1 \2 \3 \4/' \ + | tee output + + # everything should be owned by pkiuser:root (UID=17, GID=0) + # TODO: review owners/permissions + cat > expected << EOF + drwxrwxrwx 17 root conf + drwxrwxrwx 17 root logs + EOF + + diff expected output + + - name: Check data/conf dir if: always() run: | - mkdir -p /tmp/artifacts/server - docker logs pki > /tmp/artifacts/server/container.out 2> /tmp/artifacts/server/container.err - mkdir -p /tmp/artifacts/server/var/lib - docker cp pki:/var/lib/tomcats /tmp/artifacts/server/var/lib + ls -l data/conf \ + | sed \ + -e '/^total/d' \ + -e 's/^\(\S*\) *\S* *\(\S*\) *\(\S*\) *\S* *\S* *\S* *\S* *\(.*\)$/\1 \2 \3 \4/' \ + | tee output + + # everything should be owned by pkiuser:root (UID=17, GID=0) + # TODO: review owners/permissions + cat > expected << EOF + drwxrwxrwx 17 root Catalina + drwxrwxrwx 17 root alias + -rw-rw-rw- 17 root catalina.policy + lrwxrwxrwx 17 root catalina.properties -> /usr/share/pki/server/conf/catalina.properties + drwxrwxrwx 17 root certs + lrwxrwxrwx 17 root context.xml -> /etc/tomcat/context.xml + -rw-rw-rw- 17 root jss.conf + lrwxrwxrwx 17 root logging.properties -> /usr/share/pki/server/conf/logging.properties + -rw-rw-rw- 17 root password.conf + -rw-rw-rw- 17 root server.xml + -rw-rw-rw- 17 root tomcat.conf + lrwxrwxrwx 17 root web.xml -> /etc/tomcat/web.xml + EOF + + diff expected output + + - name: Check data/logs dir + if: always() + run: | + ls -l data/logs \ + | sed \ + -e '/^total/d' \ + -e 's/^\(\S*\) *\S* *\(\S*\) *\(\S*\) *\S* *\S* *\S* *\S* *\(.*\)$/\1 \2 \3 \4/' \ + | tee output + + DATE=$(date +'%Y-%m-%d') + + # everything should be owned by pkiuser:root (UID=17, GID=0) + # TODO: review owners/permissions + cat > expected << EOF + drwxrwx--- 17 root backup + -rw-rw-rw- 17 root catalina.$DATE.log + -rw-rw-rw- 17 root host-manager.$DATE.log + -rw-rw-rw- 17 root localhost.$DATE.log + -rw-rw-rw- 17 root localhost_access_log.$DATE.txt + -rw-rw-rw- 17 root manager.$DATE.log + drwxrwxrwx 17 root pki + EOF + + diff expected output + + - name: Check server info locally + run: | + docker exec server pki info + + - name: Install CA signing cert + run: | + docker exec client pki nss-cert-import \ + --cert $SHARED/certs/ca_signing.crt \ + --trust CT,C,C \ + ca_signing + + - name: Check server info remotely + run: | + docker exec client pki \ + -U https://pki.example.com:8443 \ + info + + - name: Restart server + run: | + docker restart server + sleep 5 + + # wait for server to restart + docker exec client curl \ + --retry 60 \ + --retry-delay 0 \ + --retry-connrefused \ + -s \ + -k \ + -o /dev/null \ + https://pki.example.com:8443 + + - name: Check server info remotely again + run: | + docker exec client pki \ + -U https://pki.example.com:8443 \ + info + + - name: Check server container logs + if: always() + run: | + docker logs server 2>&1 + + - name: Gather artifacts + if: always() + run: | + docker exec server ls -la /etc/pki + mkdir -p /tmp/artifacts/server/etc + docker cp server:/etc/pki /tmp/artifacts/server/etc + + docker exec server ls -la /var/log/pki + mkdir -p /tmp/artifacts/server/var/log + docker cp server:/var/log/pki /tmp/artifacts/server/var/log + + docker logs server > /tmp/artifacts/server/container.out 2> /tmp/artifacts/server/container.err + + mkdir -p /tmp/artifacts/client + docker logs client > /tmp/artifacts/client/container.out 2> /tmp/artifacts/client/container.err continue-on-error: true - - name: Upload artifacts from server container + - name: Upload artifacts if: always() uses: actions/upload-artifact@v4 with: - name: server-container-test - path: /tmp/artifacts/server + name: server-container + path: /tmp/artifacts diff --git a/Dockerfile b/Dockerfile index f13ab881a10..a433c6c8ef2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -158,6 +158,19 @@ RUN pki-server http-connector-cert-add \ --keystoreType pkcs11 \ --keystoreProvider Mozilla-JSS +# Deploy ROOT webapp +RUN pki-server webapp-deploy \ + --descriptor /usr/share/pki/server/conf/Catalina/localhost/ROOT.xml \ + ROOT + +# Deploy PKI webapp +RUN pki-server webapp-deploy \ + --descriptor /usr/share/pki/server/conf/Catalina/localhost/pki.xml \ + pki + +# Store default config files +RUN cp -r /data/conf /var/lib/pki/pki-tomcat/conf.default + # Grant the root group the full access to PKI server files # https://www.openshift.com/blog/jupyter-on-openshift-part-6-running-as-an-assigned-user-id RUN chgrp -Rf root /var/lib/pki/pki-tomcat @@ -188,8 +201,8 @@ RUN pki-server ca-create # Deploy CA subsystem RUN pki-server ca-deploy -# Store default config files -RUN mv /data/conf /var/lib/pki/pki-tomcat/conf.default +# Store additional default config files +RUN cp -r /data/conf/* /var/lib/pki/pki-tomcat/conf.default # Grant the root group the full access to PKI server files # https://www.openshift.com/blog/jupyter-on-openshift-part-6-running-as-an-assigned-user-id @@ -219,8 +232,8 @@ RUN pki-server kra-create # Deploy KRA subsystem RUN pki-server kra-deploy -# Store default config files -RUN mv /data/conf /var/lib/pki/pki-tomcat/conf.default +# Store additional default config files +RUN cp -r /data/conf/* /var/lib/pki/pki-tomcat/conf.default # Grant the root group the full access to PKI server files # https://www.openshift.com/blog/jupyter-on-openshift-part-6-running-as-an-assigned-user-id @@ -250,8 +263,8 @@ RUN pki-server ocsp-create # Deploy OCSP subsystem RUN pki-server ocsp-deploy -# Store default config files -RUN mv /data/conf /var/lib/pki/pki-tomcat/conf.default +# Store additional default config files +RUN cp -r /data/conf/* /var/lib/pki/pki-tomcat/conf.default # Grant the root group the full access to PKI server files # https://www.openshift.com/blog/jupyter-on-openshift-part-6-running-as-an-assigned-user-id @@ -299,8 +312,8 @@ RUN rm -f /usr/share/pki/acme/webapps/acme/WEB-INF/classes/logging.properties # Deploy PKI ACME application RUN pki-server acme-deploy -# Store default config files -RUN mv /data/conf /var/lib/pki/pki-tomcat/conf.default +# Store additional default config files +RUN cp -r /data/conf/* /var/lib/pki/pki-tomcat/conf.default # Grant the root group the full access to PKI ACME files # https://www.openshift.com/blog/jupyter-on-openshift-part-6-running-as-an-assigned-user-id diff --git a/base/server/bin/pki-server-run b/base/server/bin/pki-server-run index 5fc518694aa..fde969b8b76 100755 --- a/base/server/bin/pki-server-run +++ b/base/server/bin/pki-server-run @@ -7,6 +7,34 @@ . /usr/share/pki/scripts/config +# Allow the owner of the container (who might not be in the root group) +# to manage the config and log files. +umask 000 + +echo "################################################################################" + +if [ -d /data/conf ] +then + echo "info: Reusing /data/conf" +else + echo "INFO: Creating /data/conf" + cp -r /var/lib/pki/pki-tomcat/conf.default /data/conf + chown -Rf pkiuser:root /data/conf + find /data/conf -type f -exec chmod +rw -- {} + + find /data/conf -type d -exec chmod +rwx -- {} + +fi + +echo "################################################################################" + +if [ -d /data/logs ] +then + echo "INFO: Reusing /data/logs" +else + echo "INFO: Creating /data/logs" + mkdir /data/logs + chown -Rf pkiuser:root /data/logs +fi + echo "################################################################################" # import ca_signing.cert and ca_signing.key if available @@ -25,14 +53,22 @@ then -name ca_signing \ -passout file:/tmp/password + # trust CA signing cert in PKCS #12 file + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + pkcs12-cert-mod \ + --pkcs12 /tmp/certs.p12 \ + --password-file /tmp/password \ + --trust-flags CT,C,C \ + ca_signing + # import PKCS #12 file into NSS database - pki -d /var/lib/pki/pki-tomcat/conf/alias pkcs12-import \ + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + pkcs12-import \ --pkcs12 /tmp/certs.p12 \ --password-file /tmp/password - # trust imported CA signing cert - certutil -M -d /var/lib/pki/pki-tomcat/conf/alias -n ca_signing -t CT,C,C - rm /tmp/certs.p12 rm /tmp/password fi @@ -43,28 +79,38 @@ then echo "INFO: Importing Certificates and Keys from PKCS #12 File" # import PKCS #12 file into NSS database - pki -d /var/lib/pki/pki-tomcat/conf/alias pkcs12-import \ + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + pkcs12-import \ --pkcs12 /certs/certs.p12 \ --password-file /certs/password fi # check whether CA signing certificate is available rc=0 -certutil -L -d /var/lib/pki/pki-tomcat/conf/alias -n ca_signing -a > /dev/null 2>&1 || rc=$? +pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-export \ + --output-file /certs/ca_signing.crt \ + ca_signing || rc=$? # generate a CA signing certificate if not available if [ $rc -ne 0 ] then - echo "INFO: Issuing Self-signed CA Signing Certificate" + echo "INFO: Creating CA signing cert" # generate CA signing CSR - pki -d /var/lib/pki/pki-tomcat/conf/alias nss-cert-request \ + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-request \ --subject "CN=CA Signing Certificate" \ --ext /usr/share/pki/server/certs/ca_signing.conf \ --csr /certs/ca_signing.csr # issue self-signed CA signing cert - pki -d /var/lib/pki/pki-tomcat/conf/alias nss-cert-issue \ + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-issue \ --csr /certs/ca_signing.csr \ --ext /usr/share/pki/server/certs/ca_signing.conf \ --validity-length 1 \ @@ -72,49 +118,93 @@ then --cert /certs/ca_signing.crt # import and trust CA signing cert into NSS database - pki -d /var/lib/pki/pki-tomcat/conf/alias nss-cert-import \ + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-import \ --cert /certs/ca_signing.crt \ --trust CT,C,C \ ca_signing fi -echo "INFO: CA Signing Certificate:" -certutil -L -d /var/lib/pki/pki-tomcat/conf/alias -n ca_signing +echo "INFO: CA signing cert:" +pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-show \ + ca_signing echo "################################################################################" # check whether SSL server certificate is available rc=0 -certutil -L -d /var/lib/pki/pki-tomcat/conf/alias -n sslserver -a > /dev/null 2>&1 || rc=$? +pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-export \ + --output-file /certs/sslserver.crt \ + sslserver || rc=$? # generate a SSL server certificate if not available if [ $rc -ne 0 ] then - echo "INFO: Issuing SSL Server Certificate" + echo "INFO: Creating SSL server cert" # generate SSL server CSR - pki -d /var/lib/pki/pki-tomcat/conf/alias nss-cert-request \ + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-request \ --subject "CN=$HOSTNAME" \ --ext /usr/share/pki/server/certs/sslserver.conf \ --csr /certs/sslserver.csr # issue SSL server cert - pki -d /var/lib/pki/pki-tomcat/conf/alias nss-cert-issue \ + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-issue \ --issuer ca_signing \ --csr /certs/sslserver.csr \ --ext /usr/share/pki/server/certs/sslserver.conf \ --cert /certs/sslserver.crt # import SSL server cert into NSS database - pki -d /var/lib/pki/pki-tomcat/conf/alias nss-cert-import \ + pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-import \ --cert /certs/sslserver.crt \ sslserver fi -echo "INFO: SSL Server Certificate:" -certutil -L -d /var/lib/pki/pki-tomcat/conf/alias -n sslserver +echo "INFO: SSL server cert:" +pki \ + -d /var/lib/pki/pki-tomcat/conf/alias \ + nss-cert-show \ + sslserver + +echo "################################################################################" + +# check whether CA signing cert exists in default NSS database +rc=0 +pki nss-cert-export ca_signing > /dev/null || rc=$? + +if [ $rc -ne 0 ] +then + echo "INFO: Importing CA signing cert" + pki nss-cert-import \ + --cert /certs/ca_signing.crt \ + --trust CT,C,C \ + ca_signing +fi echo "################################################################################" echo "INFO: Starting PKI server" -pki-server run --as-current-user +if [ "$UID" = "0" ]; then + # In Docker/Podman the server runs as pkiuser (UID=17) that + # belongs to the root group (GID=0). + pki-server run + +else + # In OpenShift the server runs as an OpenShift-assigned user + # (with a random UID) that belongs to the root group (GID=0). + # + # https://www.redhat.com/en/blog/jupyter-on-openshift-part-6-running-as-an-assigned-user-id + pki-server run --as-current-user +fi