Skip to content

Commit

Permalink
feat(security): Add new implementation for security bootstrapping/ins…
Browse files Browse the repository at this point in the history
…tallation

Closes: #2884

The scurity container bootstrapping initiates with security-bootstrapper service, in which it bootstraps
the pre-seeded secrets and credentials.

The security-bootstrapper starts with seeding the vault_wait_install.sh script (contains the dockerize utility)
to be available for other containers that needs to wait for the intended done-listener is issued and connected.

The other containers in the security bootstrapping process currently are:
 - Redis bootstrapping
 - Consul bootstrapping
 - Kong bootstrapping
 - Postgres bootstrapping

The dockerize utility is used on those above containers to wait for that security-bootstrapper
tcp listener done signal and then those container can proceed to start up.

Security-bootstrapper's entrypoint script is also for other edgex-core-services to wait for the intended port to be ready.

The majority of edgex-core-services are converted to alpine-based image to facilitate the ability to use entrypoint scripts.

Also remove unused environment flag: SECRETSTORE_SETUP_DONE_FLAG from secretstore_setup's entrypoint script
That env flag will also needed to be cleaned up on the docker-compose file

All timeout for dockerize wait-timeout in one central place.
Also add the consul local config for disabling the auto check upate as currently consul is not running in SSL mode.

Add lib/pq into Attribution.txt

Run security-bootstrapper executeable as non-root user, $$EDGEX_USER

All env. variables of entrypoint scripts are populated from the env files of compose builder in developer-scripts

Signed-off-by: Jim Wang <[email protected]>
  • Loading branch information
jim-wang-intel committed Jan 21, 2021
1 parent 4ca1de5 commit 401c9bf
Show file tree
Hide file tree
Showing 50 changed files with 2,960 additions and 127 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ cmd/sys-mgmt-agent/sys-mgmt-agent
cmd/sys-mgmt-executor/sys-mgmt-executor
cmd/security-bootstrap-redis/security-bootstrap-redis
cmd/secrets-config/secrets-config
cmd/security-bootstrapper/security-bootstrapper

docs/_build/

Expand Down
3 changes: 3 additions & 0 deletions Attribution.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,6 @@ https://github.com/go-playground/validator/blob/master/LICENSE

leodido/go-urn (MIT) https://github.com/leodido/go-urn
https://github.com/leodido/go-urn

github.com/lib/pq (MIT) https://github.com/lib/pq
https://github.com/lib/pq/blob/master/LICENSE.md
20 changes: 13 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ DOCKERS= \
docker_support_scheduler \
docker_security_proxy_setup \
docker_security_secretstore_setup \
docker_security_bootstrap_redis
docker_security_bootstrapper

.PHONY: $(DOCKERS)

Expand All @@ -35,7 +35,8 @@ MICROSERVICES= \
cmd/security-secretstore-setup/security-secretstore-setup \
cmd/security-file-token-provider/security-file-token-provider \
cmd/security-bootstrap-redis/security-bootstrap-redis \
cmd/secrets-config/secrets-config
cmd/secrets-config/secrets-config \
cmd/security-bootstrapper/security-bootstrapper

.PHONY: $(MICROSERVICES)

Expand Down Expand Up @@ -87,6 +88,9 @@ cmd/security-bootstrap-redis/security-bootstrap-redis:
cmd/secrets-config/secrets-config:
$(GO) build $(GOFLAGS) -o ./cmd/secrets-config ./cmd/secrets-config

cmd/security-bootstrapper/security-bootstrapper:
$(GO) build $(GOFLAGS) -o ./cmd/security-bootstrapper/security-bootstrapper ./cmd/security-bootstrapper

clean:
rm -f $(MICROSERVICES)

Expand Down Expand Up @@ -186,10 +190,12 @@ docker_security_secretstore_setup:
-t edgexfoundry/docker-security-secretstore-setup-go:$(DOCKER_TAG) \
.

docker_security_bootstrap_redis:
docker build \
-f cmd/security-bootstrap-redis/Dockerfile \
docker_security_bootstrapper:
docker build \
--build-arg http_proxy \
--build-arg https_proxy \
-f cmd/security-bootstrapper/Dockerfile \
--label "git_sha=$(GIT_SHA)" \
-t edgexfoundry/docker-security-bootstrap-redis-go:$(GIT_SHA) \
-t edgexfoundry/docker-security-bootstrap-redis-go:$(DOCKER_TAG) \
-t edgexfoundry/docker-security-bootstrapper-go:$(GIT_SHA) \
-t edgexfoundry/docker-security-bootstrapper-go:$(DOCKER_TAG) \
.
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ There are 2 major components that are responsible for security features:
When starting a secure EdgeX deployment, the sequence is [see docker-compose-nexus-redis.yml for reference](https://github.com/edgexfoundry/developer-scripts/blob/master/releases/nightly-build/compose-files/docker-compose-nexus-redis.yml))

1. Start [Vault by HashiCorp](https://www.vaultproject.io/)
1. Start the `edgex-vault-worker` container from the `docker-edgex-security-secretstore-setup-go` image to create the shared secrets needed by the microservices.
1. Finally, the start the `edgex-proxy` container from the `docker-edgex-security-proxy-setup-go` image once [Kong](https://konghq.com/) is up.
1. Start the `edgex-secretstore-setup` container from the `docker-edgex-security-secretstore-setup-go` image to create the shared secrets needed by the microservices.
1. Finally, the start the `edgex-proxy-setup` container from the `docker-edgex-security-proxy-setup-go` image once [Kong](https://konghq.com/) is up.

## Get Started

Expand Down
6 changes: 4 additions & 2 deletions cmd/core-command/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ COPY . .

RUN make cmd/core-command/core-command

FROM scratch
FROM alpine:3.12

RUN apk add --update --no-cache dumb-init

LABEL license='SPDX-License-Identifier: Apache-2.0' \
copyright='Copyright (c) 2018: Dell, Cavium'
copyright='Copyright (c) 2018: Dell, Cavium, Copyright (c) 2021: Intel Corporation'

ENV APP_PORT=48082
#expose command data port
Expand Down
2 changes: 1 addition & 1 deletion cmd/core-data/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ EXPOSE $APP_PORT
# So we can try these.
RUN sed -e 's/dl-cdn[.]alpinelinux.org/nl.alpinelinux.org/g' -i~ /etc/apk/repositories

RUN apk add --update --no-cache zeromq
RUN apk add --update --no-cache zeromq dumb-init
COPY --from=builder /edgex-go/Attribution.txt /
COPY --from=builder /edgex-go/cmd/core-data/core-data /
COPY --from=builder /edgex-go/cmd/core-data/res/configuration.toml /res/configuration.toml
Expand Down
6 changes: 4 additions & 2 deletions cmd/core-metadata/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ COPY . .
RUN make cmd/core-metadata/core-metadata

#Next image - Copy built Go binary into new workspace
FROM scratch
FROM alpine:3.12

RUN apk add --update --no-cache dumb-init

LABEL license='SPDX-License-Identifier: Apache-2.0' \
copyright='Copyright (c) 2018: Dell, Cavium'
copyright='Copyright (c) 2018: Dell, Cavium, Copyright (c) 2021: Intel Corporation'

ENV APP_PORT=48081
#expose meta data port
Expand Down
53 changes: 0 additions & 53 deletions cmd/security-bootstrap-redis/Dockerfile

This file was deleted.

27 changes: 0 additions & 27 deletions cmd/security-bootstrap-redis/entrypoint.sh

This file was deleted.

83 changes: 83 additions & 0 deletions cmd/security-bootstrapper/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# ----------------------------------------------------------------------------------
# Copyright 2021 Intel Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# SPDX-License-Identifier: Apache-2.0
# ----------------------------------------------------------------------------------

ARG BUILDER_BASE=golang:1.15-alpine3.12
FROM ${BUILDER_BASE} AS builder

WORKDIR /edgex-go

RUN sed -e 's/dl-cdn[.]alpinelinux.org/nl.alpinelinux.org/g' -i~ /etc/apk/repositories

RUN apk add --update --no-cache make git

COPY go.mod .

RUN go mod download

COPY . .

RUN make cmd/security-bootstrapper/security-bootstrapper \
&& make cmd/security-bootstrap-redis/security-bootstrap-redis

FROM alpine:3.12

RUN apk add --update --no-cache dumb-init openssl su-exec

LABEL license='SPDX-License-Identifier: Apache-2.0' \
copyright='Copyright (c) 2021 Intel Corporation'

# Use dockerize utility for services to wait for certain ports to be available
ENV DOCKERIZE_VERSION v0.6.1
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz

ENV SECURITY_INIT_DIR /edgex-init
ARG BOOTSTRAP_REDIS_DIR=${SECURITY_INIT_DIR}/bootstrap-redis

RUN mkdir -p ${SECURITY_INIT_DIR} \
&& mkdir -p ${BOOTSTRAP_REDIS_DIR} \
&& echo "Move dockerize executable" \
&& mv /usr/local/bin/dockerize ${SECURITY_INIT_DIR}

WORKDIR ${SECURITY_INIT_DIR}

# copy all entrypoint scripts into shared folder
COPY --from=builder /edgex-go/cmd/security-bootstrapper/entrypoint-scripts/ ${SECURITY_INIT_DIR}/
RUN chmod +x ${SECURITY_INIT_DIR}/*.sh

COPY --from=builder /edgex-go/Attribution.txt /
COPY --from=builder /edgex-go/cmd/security-bootstrapper/security-bootstrapper .
COPY --from=builder /edgex-go/cmd/security-bootstrapper/res/configuration.toml ./res/

# needed for bootstrapping Redis db
COPY --from=builder /edgex-go/cmd/security-bootstrap-redis/security-bootstrap-redis ${BOOTSTRAP_REDIS_DIR}/
COPY --from=builder /edgex-go/cmd/security-bootstrap-redis/res/configuration.toml ${BOOTSTRAP_REDIS_DIR}/res/

# Expose the file directory as a volume since there's long-running state
VOLUME ${SECURITY_INIT_DIR}

# setup entry point script
COPY --from=builder /edgex-go/cmd/security-bootstrapper/entrypoint.sh /
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

# gate is one subcommand for security-bootstrapper to do security bootstrapping
CMD ["gate"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/dumb-init /bin/sh
# ----------------------------------------------------------------------------------
# Copyright (c) 2021 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
# ----------------------------------------------------------------------------------

# This is customized entrypoint script for Consul and run on the consul's container
# In particular, it waits for Vault to be ready to roll

set -e

# function to check on Vault for readiness
vault_ready()
{
vault_host=$1
vault_port=$2
resp_code=$(curl --write-out '%{http_code}' --silent --output /dev/null "${vault_host}":"${vault_port}"/v1/sys/health)
if [ "$resp_code" -eq 200 ] ; then
echo 1
else
echo 0
fi
}

# env settings are populated from env files of docker-compose

echo "Script for waiting security bootstrapping on Consul"

echo "$(date) Consul waits on Vault to be initialized"
# check the http status code from Vault using SECRETSTORE_HOST and SECRETSTORE_PORT as input to the function call
vault_inited=$(vault_ready "${SECRETSTORE_HOST}" "${SECRETSTORE_PORT}")
until [ "$vault_inited" -eq 1 ]; do
echo "$(date) waiting for Vault ${SECRETSTORE_HOST}:${SECRETSTORE_PORT} to be initialized";
sleep 1;
vault_inited=$(vault_ready "${SECRETSTORE_HOST}" "${SECRETSTORE_PORT}")
done

# only in json format according to Consul's documentation
DEFAULT_CONSUL_LOCAL_CONFIG='
{
"enable_local_script_checks": true,
"disable_update_check": true
}
'

# set the default value to environment var if not present
CONSUL_LOCAL_CONFIG=${CONSUL_LOCAL_CONFIG:-$DEFAULT_CONSUL_LOCAL_CONFIG}

export CONSUL_LOCAL_CONFIG

echo "$(date) CONSUL_LOCAL_CONFIG: ${CONSUL_LOCAL_CONFIG}"

echo "$(date) Starting edgex-consul..."
exec docker-entrypoint.sh agent -ui -bootstrap -server -client 0.0.0.0 &

# wait for the consul port
echo "$(date) Executing dockerize on Consul with waiting on its own port \
tcp://${STAGEGATE_REGISTRY_HOST}:${STAGEGATE_REGISTRY_PORT}"
/edgex-init/dockerize -wait tcp://"${STAGEGATE_REGISTRY_HOST}":"${STAGEGATE_REGISTRY_PORT}" \
-timeout "${SECTY_BOOTSTRAP_GATING_TIMEOUT_DURATION}"

# Signal that Consul is ready for services blocked waiting on Consul
/edgex-init/security-bootstrapper --confdir=/edgex-init/res listenTcp \
--port="${STAGEGATE_REGISTRY_READYPORT}" --host="${STAGEGATE_REGISTRY_HOST}"
if [ $? -ne 0 ]; then
echo "$(date) failed to gating the consul ready port, exits"
fi
Loading

0 comments on commit 401c9bf

Please sign in to comment.