Skip to content

Commit

Permalink
update: set custom CA Certificate installation docs (#2136)
Browse files Browse the repository at this point in the history
  • Loading branch information
VietND96 authored Feb 15, 2024
1 parent 3ac9eff commit 9fe331c
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 37 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/helm-chart-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ jobs:
command: NAME=${IMAGE_REGISTRY} VERSION=${BRANCH} BUILD_DATE=${BUILD_DATE} make chart_cluster_setup
- name: Build Docker images
run: NAME=${IMAGE_REGISTRY} VERSION=${BRANCH} BUILD_DATE=${BUILD_DATE} make build
- name: Test set custom CA certificate
run: NAME=${IMAGE_REGISTRY} VERSION=${BRANCH} BUILD_DATE=${BUILD_DATE} make test_custom_ca_cert
- name: Set test parameters
if: (matrix.test-strategy == 'job' || matrix.test-strategy == 'deployment') && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
run: |
Expand Down
8 changes: 7 additions & 1 deletion Base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ COPY supervisord.conf /etc
#==========
# Selenium & relaxing permissions for OpenShift and other non-sudo environments
#==========
RUN mkdir -p /opt/selenium /opt/selenium/assets /var/run/supervisor /var/log/supervisor ${SEL_DOWNLOAD_DIR} ${HOME}/.mozilla ${HOME}/.vnc \
RUN mkdir -p /opt/selenium /opt/selenium/assets /var/run/supervisor /var/log/supervisor ${SEL_DOWNLOAD_DIR} \
${HOME}/.mozilla ${HOME}/.vnc $HOME/.pki/nssdb \
&& touch /opt/selenium/config.toml \
&& chown -R ${SEL_USER}:${SEL_GROUP} /opt/selenium /var/run/supervisor /var/log/supervisor /etc/passwd ${HOME} \
&& chmod -R 775 /opt/selenium /var/run/supervisor /var/log/supervisor /etc/passwd ${HOME} \
Expand Down Expand Up @@ -129,6 +130,11 @@ RUN rm -fr /root/.cache/*
#===================================================
USER ${SEL_UID}:${SEL_GID}

#==========
# NSSDB initialization with an empty password
#==========
RUN certutil -d sql:$HOME/.pki/nssdb -N --empty-password

# Boolean value, maps "--bind-host"
ENV SE_BIND_HOST false
# Boolean value, maps "--reject-unsupported-caps"
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ test_video: video hub chrome firefox edge
docker run -u $$(id -u) -v $$(pwd):$$(pwd) -w $$(pwd) $(FFMPEG_BASED_NAME)/ffmpeg:$(FFMPEG_BASED_TAG) -v error -i ./tests/videos/firefox_video.mp4 -f null - 2>error.log
docker run -u $$(id -u) -v $$(pwd):$$(pwd) -w $$(pwd) $(FFMPEG_BASED_NAME)/ffmpeg:$(FFMPEG_BASED_TAG) -v error -i ./tests/videos/edge_video.mp4 -f null - 2>error.log

test_custom_ca_cert:
VERSION=$(TAG_VERSION) NAMESPACE=$(NAMESPACE) ./tests/customCACert/bootstrap.sh

chart_setup_env:
./tests/charts/make/chart_setup_env.sh

Expand Down
56 changes: 20 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1122,45 +1122,29 @@ ___

## Install certificates for Chromium-based browsers

If you need to install custom certificates, CA, intermediate CA, or client certificates (for example enterprise internal CA)
you can use the different utils that come from libnss3-tools.
The chromium-based browser uses nssdb as a certificate store.
Create a new nssdb:
```bash
certutil -d sql:$HOME/.pki/nssdb -N
```
For example, to trust a root CA certificate for issuing SSL server certificates, use
```bash
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n <certificate nickname> -i <certificate filename>
```
To import an intermediate CA certificate, use
```bash
certutil -d sql:$HOME/.pki/nssdb -A -t ",," -n <certificate nickname> -i <certificate filename>
```
You can find more information [here](https://chromium.googlesource.com/chromium/src/+/master/docs/linux/cert_management.md)
Usage example:
If your company has an internal CA you can create your own dockerimage from selenium node image.
By default, the based image is installed `libnss3-tools` and initializes `/home/seluser/.pki/nssdb`,
so you are able to add your certs with rootless.
If you need to install custom certificates, CA, intermediate CA,
or client certificates (for example, enterprise internal CA)
you can create your own docker image from selenium node image.
The Chromium-based browser uses `nssdb` as a certificate store.
You can then install all required internal certificates in your Dockerfile like this:

- Create a script for installing the certificates. For example, [cert-script.sh](tests/customCACert/cert-script.sh)
- Create a Dockerfile that uses the selenium node image as a base and copies the script to the container, and executes it.
For example, [Dockerfile](tests/customCACert/Dockerfile)
- If you have to create a set of different certificates and node images. You can create a bootstrap script to do that in one-shot.
For example, [bootstrap.sh](tests/customCACert/bootstrap.sh)

The above example can be tested with the following command:

```bash
FROM selenium/node-edge:latest
USER root
COPY certs/ /etc/certs # copy over the certificate file

#=========
# libnss3-tools
# Network Security Service tools
# Manage certificates in nssdb (certutil, pk12util, modutil, shlibsign, signtool, ssltap)
#=========
RUN apt-get update -qqy \
&& apt-get -qqy install \
libnss3-tools \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*

RUN mkdir -p -m755 /home/seluser/.pki/nssdb \ #create nssdb folder
&& certutil -d sql:/home/seluser/.pki/nssdb -N --empty-password \ # create new db without password
&& certutil -d sql:/home/seluser/.pki/nssdb -A -t "C,," -n companyca -i /etc/certs/companeca.pem \ #trust company CA
&& pk12util -d sql:/home/seluser/.pki/nssdb -i client_cert.p12 -W password_of_clent_cert # client certificate install
make test_custom_ca_cert
# ./tests/customCACert/bootstrap.sh
```

You can find more information [here](https://chromium.googlesource.com/chromium/src/+/master/docs/linux/cert_management.md)

This way the certificates will be installed and the node will start automatically as before.
___

Expand Down
21 changes: 21 additions & 0 deletions tests/customCACert/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
ARG NAMESPACE=selenium
ARG BASE=node-chrome
ARG VERSION=latest
FROM ${NAMESPACE}/${BASE}:${VERSION}

USER root

ARG CERT_FILE
ARG PERM=577
RUN mkdir -p /usr/share/ca-certificates/extra/
COPY ${CERT_FILE} /usr/share/ca-certificates/extra/
RUN chmod -R ${PERM} /usr/share/ca-certificates/extra/
RUN update-ca-certificates

ARG CERT_SCRIPT
COPY --chown="${SEL_UID}:${SEL_GID}" ${CERT_SCRIPT} /usr/share/ca-certificates/cert-script.sh
RUN chmod +x /usr/share/ca-certificates/cert-script.sh

USER ${SEL_UID}
ARG TRUST_ATTR=TCu,Cu,Tu
RUN bash /usr/share/ca-certificates/cert-script.sh /usr/share/ca-certificates/extra/ ${TRUST_ATTR}
32 changes: 32 additions & 0 deletions tests/customCACert/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash
set -x

# Function to be executed on command failure
on_failure() {
local exit_status=$?
echo "There is step failed with exit status $exit_status"
exit $exit_status
}

# Trap ERR signal and call on_failure function
trap 'on_failure' ERR

NAMESPACE=${NAME:-"selenium"}
VERSION=${VERSION:-$TAG_VERSION}
CERT_FILE=${CERT_FILE:-"./charts/selenium-grid/certs/*.pem"}
CERT_SCRIPT=${CERT_SCRIPT:-"./tests/customCACert/cert-script.sh"}

COMMON_BUILD_ARGS="--build-arg NAMESPACE=${NAMESPACE} --build-arg VERSION=${VERSION} --build-arg CERT_FILE=${CERT_FILE} --build-arg CERT_SCRIPT=${CERT_SCRIPT}"

docker build ${COMMON_BUILD_ARGS} --build-arg BASE=node-chrome -t ${NAMESPACE}/node-chrome:${VERSION} -f ./tests/customCACert/Dockerfile .
docker build ${COMMON_BUILD_ARGS} --build-arg BASE=node-firefox -t ${NAMESPACE}/node-firefox:${VERSION} -f ./tests/customCACert/Dockerfile .
docker build ${COMMON_BUILD_ARGS} --build-arg BASE=node-edge -t ${NAMESPACE}/node-edge:${VERSION} -f ./tests/customCACert/Dockerfile .

list_cert_files=($(find ./charts/selenium-grid/certs/ -name "*.pem"))
for cert_file_path in "${list_cert_files[@]}"; do
cert_file_name="$(basename ${cert_file_path})"
cert_name="${cert_file_name%.*}"
docker run --entrypoint="" --rm ${NAMESPACE}/node-chrome:${VERSION} bash -c "certutil -L -d sql:/home/seluser/.pki/nssdb -n ${cert_name}" | grep -q "SeleniumHQ"
docker run --entrypoint="" --rm ${NAMESPACE}/node-firefox:${VERSION} bash -c "certutil -L -d sql:/home/seluser/.pki/nssdb -n ${cert_name}" | grep -q "SeleniumHQ"
docker run --entrypoint="" --rm ${NAMESPACE}/node-edge:${VERSION} bash -c "certutil -L -d sql:/home/seluser/.pki/nssdb -n ${cert_name}" | grep -q "SeleniumHQ"
done
24 changes: 24 additions & 0 deletions tests/customCACert/cert-script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
set -x

echo "$(whoami) is running cert script!"

CERT_DIR=${1:-"/usr/share/ca-certificates/extra/"}
TRUST_ATTR=${2:-"TCu,Cu,Tu"}

# Get the list of certs copied
cert_files=($(ls $CERT_DIR))

# Find all "cert9.db" files
cert_db_files=($(find ${HOME}/ -name "cert9.db"))

for cert_file in "${cert_files[@]}"; do
cert_file="${CERT_DIR}/${cert_file}"
file_name=$(basename $cert_file)
cert_name="${file_name%.*}"
for cert_db_file in "${cert_db_files[@]}"; do
cert_db_path=$(dirname $cert_db_file)
certutil -d "sql:${cert_db_path}" -A -t "${TRUST_ATTR}" -n "${cert_name}" -i "${cert_file}"
certutil -L -d "sql:${cert_db_path}" -n "${cert_name}"
done
done

0 comments on commit 9fe331c

Please sign in to comment.