Skip to content

Commit

Permalink
Fix Dockerfile to have the proper permissions in directories (#4967)
Browse files Browse the repository at this point in the history
Signed-off-by: Agustín Martínez Fayó <amartinezfayo@gmail.com>
  • Loading branch information
amartinezfayo committed Jun 7, 2024
1 parent 7e9964e commit ecabb6c
Show file tree
Hide file tree
Showing 17 changed files with 81 additions and 94 deletions.
73 changes: 34 additions & 39 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,38 +23,6 @@ ARG TARGETPLATFORM
ARG TARGETARCH
COPY --link --from=xx / /

# For users that wish to run SPIRE containers as a non-root user,
# provide a default unprivileged user such that the default paths
# that SPIRE will try to read from, write to, and create at runtime
# can be given the correct file ownership/permissions at build time.
ARG spireuid=1000
ARG spiregid=1000

# Set up directories that SPIRE expects by default
# Set up base directories
RUN install -d -o root -g root -m 777 /spireroot
RUN install -d -o root -g root -m 755 /spireroot/etc/ssl/certs
RUN install -d -o root -g root -m 755 /spireroot/run
RUN install -d -o root -g root -m 755 /spireroot/var/lib
RUN install -d -o root -g root -m 1777 /spireroot/tmp

# Set up directories used by SPIRE
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireroot/etc/spire
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireroot/run/spire
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireroot/var/lib/spire

# Set up spire-server directories
RUN cp -r /spireroot /spireserverroot
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireserverroot/etc/spire/server
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireserverroot/run/spire/server/private
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireserverroot/var/lib/spire/server

# Set up spire-agent directories
RUN cp -r /spireroot /spireagentroot
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireagentroot/etc/spire/agent
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireagentroot/run/spire/agent/public
RUN install -d -o ${spireuid} -g ${spiregid} -m 755 /spireagentroot/var/lib/spire/agent

RUN xx-go --wrap
RUN set -e ; xx-apk --no-cache --update add build-base musl-dev libseccomp-dev
ENV CGO_ENABLED=1
Expand All @@ -65,26 +33,53 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
for f in $(find bin -executable -type f); do xx-verify --static $f; done

FROM --platform=${BUILDPLATFORM} scratch AS spire-base
COPY --link --from=builder --chown=root:root --chmod=755 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
WORKDIR /opt/spire
CMD []
COPY --link --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# Preparation environment for setting up directories
FROM alpine as prep-spire-server
RUN mkdir -p /spireroot/opt/spire/bin \
/spireroot/etc/spire/server \
/spireroot/run/spire/server/private \
/spireroot/tmp/spire-server/private \
/spireroot/var/lib/spire/server

FROM alpine as prep-spire-agent
RUN mkdir -p /spireroot/opt/spire/bin \
/spireroot/etc/spire/agent \
/spireroot/run/spire/agent/public \
/spireroot/tmp/spire-agent/public \
/spireroot/var/lib/spire/agent

# For users that wish to run SPIRE containers as a non-root user,
# a default unprivileged user is provided such that the default paths
# that SPIRE will try to read from, write to, and create at runtime
# can be given the correct file ownership/permissions at build time.
# This is done through the spireuid and spiregid arguments that the
# spire-server, spire-agent, and oidc-discovery-provider build stages use.

# SPIRE Server
FROM spire-base AS spire-server
ARG spireuid=1000
ARG spiregid=1000
USER ${spireuid}:${spiregid}
ENTRYPOINT ["/opt/spire/bin/spire-server", "run"]
COPY --link --from=builder /spireserverroot /
COPY --link --from=builder /spire/bin/static/spire-server bin/
COPY --link --from=prep-spire-server --chown=${spireuid}:${spiregid} --chmod=755 /spireroot /
COPY --link --from=builder --chown=${spireuid}:${spiregid} --chmod=755 /spire/bin/static/spire-server /opt/spire/bin/

# SPIRE Agent
FROM spire-base AS spire-agent
ARG spireuid=1000
ARG spiregid=1000
USER ${spireuid}:${spiregid}
ENTRYPOINT ["/opt/spire/bin/spire-agent", "run"]
COPY --link --from=builder /spireagentroot /
COPY --link --from=builder /spire/bin/static/spire-agent bin/
COPY --link --from=prep-spire-agent --chown=${spireuid}:${spiregid} --chmod=755 /spireroot /
COPY --link --from=builder --chown=${spireuid}:${spiregid} --chmod=755 /spire/bin/static/spire-agent /opt/spire/bin/

# OIDC Discovery Provider
FROM spire-base AS oidc-discovery-provider
ARG spireuid=1000
ARG spiregid=1000
USER ${spireuid}:${spiregid}
ENTRYPOINT ["/opt/spire/bin/oidc-discovery-provider"]
COPY --link --from=builder /spire/bin/static/oidc-discovery-provider bin/
COPY --link --from=builder --chown=${spireuid}:${spiregid} --chmod=755 /spire/bin/static/oidc-discovery-provider /opt/spire/bin/
2 changes: 1 addition & 1 deletion test/integration/setup/x509pop/gencerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func writeKey(path string, key crypto.Signer) {
Type: "PRIVATE KEY",
Bytes: keyBytes,
})
writeFile(path, pemBytes, 0o600)
writeFile(path, pemBytes, 0o644) // This key is used only for testing purposes.
}

func writeCerts(path string, certs ...*x509.Certificate) {
Expand Down
4 changes: 2 additions & 2 deletions test/integration/suites/delegatedidentity/05-test-endpoints
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/bin/bash

log-info "Test Delegated Identity API (for success)"
docker-compose exec -u 1001 -T spire-agent \
docker-compose exec -u 1001:1000 -T spire-agent \
/opt/spire/conf/agent/delegatedidentityclient -expectedID spiffe://domain.test/workload || fail-now "Failed to check Delegated Identity API"

log-info "Test Delegated Identity API (expecting permission denied)"
docker-compose exec -u 1002 -T spire-agent \
docker-compose exec -u 1002:1000 -T spire-agent \
/opt/spire/conf/agent/delegatedidentityclient || fail-now "Failed to check Delegated Identity API"
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ docker-compose exec -T spire-server \
/opt/spire/bin/spire-server entry create \
-parentID "spiffe://domain.test/node" \
-spiffeID "spiffe://domain.test/workload" \
-selector "unix:uid:0" \
-selector "unix:uid:1000" \
-ttl 0

# Check at most 30 times (with one second in between) that the agent has
Expand Down
33 changes: 18 additions & 15 deletions test/integration/suites/k8s/conf/agent/spire-agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,32 @@ metadata:
namespace: spire

---

# Required cluster role to allow spire-agent to query k8s API server
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spire-agent-cluster-role
rules:
- apiGroups: [""]
resources: ["pods","nodes","nodes/proxy"]
verbs: ["get"]
- apiGroups: [""]
resources: ["pods", "nodes", "nodes/proxy"]
verbs: ["get"]

---

# Binds above cluster role to spire-agent service account
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: spire-agent-cluster-role-binding
subjects:
- kind: ServiceAccount
name: spire-agent
namespace: spire
- kind: ServiceAccount
name: spire-agent
namespace: spire
roleRef:
kind: ClusterRole
name: spire-agent-cluster-role
apiGroup: rbac.authorization.k8s.io


---

# ConfigMap for the SPIRE agent featuring:
# 1) PSAT node attestation
# 2) K8S Workload Attestation over the secure kubelet port
Expand Down Expand Up @@ -90,7 +86,6 @@ data:
}
---

apiVersion: apps/v1
kind: DaemonSet
metadata:
Expand All @@ -117,6 +112,12 @@ spec:
serviceAccountName: spire-agent
containers:
- name: spire-agent
# Make sure that we can create the directory for the socket in the host,
# this is needed because we use a hostPath volume to share the socket
# for the Workload API.
securityContext:
runAsUser: 0
runAsGroup: 0
image: spire-agent:latest-local
imagePullPolicy: Never
args: ["-config", "/run/spire/config/agent.conf"]
Expand Down Expand Up @@ -151,14 +152,16 @@ spec:
- name: spire-bundle
configMap:
name: spire-bundle
# The volume containing the SPIRE Agent socket that will be used by
# the workload container.
- name: spire-agent-socket
hostPath:
path: /run/spire/agent-sockets
type: DirectoryOrCreate
- name: spire-token
projected:
sources:
- serviceAccountToken:
path: spire-agent
expirationSeconds: 7200
audience: spire-server
- serviceAccountToken:
path: spire-agent
expirationSeconds: 7200
audience: spire-server
7 changes: 0 additions & 7 deletions test/integration/suites/k8s/conf/server/spire-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,6 @@ spec:
- name: spire-config
mountPath: /run/spire/config
readOnly: true
- name: spire-server-socket
mountPath: /tmp/spire-server/private
readOnly: false
livenessProbe:
httpGet:
path: /live
Expand All @@ -218,10 +215,6 @@ spec:
- name: spire-config
configMap:
name: spire-server
- name: spire-server-socket
hostPath:
path: /run/spire/server-sockets
type: DirectoryOrCreate

---

Expand Down
6 changes: 3 additions & 3 deletions test/integration/suites/nested-rotation/00-setup
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#!/bin/bash

# create shared folder for root agent socket
mkdir -p shared/rootSocket
mkdir -p -m 777 shared/rootSocket

# create shared folder for intermediateA agent socket
mkdir -p shared/intermediateASocket
mkdir -p -m 777 shared/intermediateASocket

# create shared folder for intermediateB agent socket
mkdir -p shared/intermediateBSocket
mkdir -p -m 777 shared/intermediateBSocket

# root certificates
"${ROOTDIR}/setup/x509pop/setup.sh" root/server root/agent
Expand Down
2 changes: 2 additions & 0 deletions test/integration/suites/nested-rotation/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ services:
- ./root/agent:/opt/spire/conf/agent
- /var/run/docker.sock:/var/run/docker.sock
command: ["-config", "/opt/spire/conf/agent/agent.conf"]
# Make sure that we can access the Docker daemon socket
user: 0:0
# IntermediateA
intermediateA-server:
# Share the host pid namespace so this server can be attested by the root agent
Expand Down
2 changes: 0 additions & 2 deletions test/integration/suites/node-attestation/00-setup
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ echo ${ROOTDIR}
# Move test x509pop certificate and key
mv conf/agent.key.pem conf/agent/test.key.pem
mv conf/agent.crt.pem conf/agent/test.crt.pem
# add read access to prevent error when reading with user 1001
chmod +r conf/agent/test.key.pem

"${ROOTDIR}/setup/node-attestation/build.sh" "${RUNDIR}/conf/server/node-attestation"
"${ROOTDIR}/setup/node-attestation/build.sh" "${RUNDIR}/conf/agent/node-attestation"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
#!/bin/bash

# Test node attestation api
jointoken=`docker-compose exec -u 1001 -T spire-server /opt/spire/conf/server/node-attestation -testStep jointoken`
jointoken=`docker-compose exec -u 1000 -T spire-server /opt/spire/conf/server/node-attestation -testStep jointoken`
echo "Created Join Token" $jointoken

svid1=`docker-compose exec -u 1001 -T spire-agent /opt/spire/conf/agent/node-attestation -testStep jointokenattest -tokenName $jointoken`
svid1=`docker-compose exec -u 1000 -T spire-agent /opt/spire/conf/agent/node-attestation -testStep jointokenattest -tokenName $jointoken`
if [[ $? -ne 0 ]];
then
fail-now "Failed to do initial join token attestation"
fi
echo "Received initial SVID:" $svid1

svid2=`docker-compose exec -u 1001 -T spire-agent /opt/spire/conf/agent/node-attestation -testStep renew -certificate "${svid1}"`
svid2=`docker-compose exec -u 1000 -T spire-agent /opt/spire/conf/agent/node-attestation -testStep renew -certificate "${svid1}"`
if [[ $? -ne 0 ]];
then
fail-now "Failed to do SVID renewal"
fi
echo "Received renewed SVID:" $svid2

docker-compose exec -u 1001 -T spire-server /opt/spire/conf/server/node-attestation -testStep ban -tokenName ${jointoken}
docker-compose exec -u 1000 -T spire-server /opt/spire/conf/server/node-attestation -testStep ban -tokenName ${jointoken}
if [[ $? -ne 0 ]];
then
fail-now "Failed to do initial join token attestation"
fi
echo "Agent banned"

if docker-compose exec -u 1001 -T spire-server /opt/spire/conf/server/node-attestation -testStep renew -certificate "${svid2}"
if docker-compose exec -u 1000 -T spire-server /opt/spire/conf/server/node-attestation -testStep renew -certificate "${svid2}"
then
fail-now "Expected agent to be banned"
fi
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ docker-compose exec -T spire-server \
/opt/spire/bin/spire-server entry create \
-parentID "spiffe://domain.test/spire/agent/x509pop/$(fingerprint conf/agent/agent.crt.pem)" \
-spiffeID "spiffe://domain.test/admin" \
-selector "unix:uid:1001" \
-selector "unix:uid:1000" \
-admin \
-ttl 0
check-synced-entry "spire-agent" "spiffe://domain.test/admin"

log-debug "running x509pop test..."
docker-compose exec -u 1001 -T spire-agent /opt/spire/conf/agent/node-attestation -testStep x509pop || fail-now "failed to check x509pop attestion"
docker-compose exec -u 1000 -T spire-agent /opt/spire/conf/agent/node-attestation -testStep x509pop || fail-now "failed to check x509pop attestion"
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ services:
- ./conf/agent:/opt/spire/conf/agent
- /var/run/docker.sock:/var/run/docker.sock
command: [ "-config", "/opt/spire/conf/agent/agent.conf" ]
user: 0:0 # Required to access the Docker daemon socket
oidc-discovery-provider-server:
image: oidc-discovery-provider:latest-local
hostname: oidc-discovery-provider-server
Expand All @@ -24,6 +25,7 @@ services:
- ./conf/agent:/opt/spire/conf/agent
- ./conf/server:/opt/spire/conf/server
command: [ "-config", "/opt/spire/conf/oidc-discovery-provider/provider-server-api.conf" ]
user: 0:0 # Required to access the Docker daemon socket
oidc-discovery-provider-workload:
pid: "host"
image: oidc-discovery-provider:latest-local
Expand All @@ -37,3 +39,4 @@ services:
- ./conf/agent:/opt/spire/conf/agent
- ./conf/server:/opt/spire/conf/server
command: [ "-config", "/opt/spire/conf/oidc-discovery-provider/provider-workload-api.conf" ]
user: 0:0 # Required to access the Docker daemon socket
2 changes: 1 addition & 1 deletion test/integration/suites/rotation/04-create-workload-entry
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ docker-compose exec -T spire-server \
/opt/spire/bin/spire-server entry create \
-parentID "spiffe://domain.test/spire/agent/x509pop/$(fingerprint conf/agent/agent.crt.pem)" \
-spiffeID "spiffe://domain.test/workload" \
-selector "unix:uid:0" \
-selector "unix:uid:1000" \
-ttl 0

# Check at most 30 times (with one second in between) that the agent has
Expand Down
4 changes: 2 additions & 2 deletions test/integration/suites/svidstore/common
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ check-stored-svids() {
fi
done

docker-compose exec -u 1001 -T spire-server \
docker-compose exec -u 1000 -T spire-server \
/opt/spire/conf/server/checkstoredsvids /opt/spire/conf/agent/svids.json || fail-now "failed to check stored svids"
}

Expand All @@ -48,6 +48,6 @@ check-deleted-svids() {
fail-now "timed out waiting for agent to delete all svids"
fi

docker-compose exec -u 1001 -T spire-server \
docker-compose exec -u 1000 -T spire-server \
/opt/spire/conf/server/checkstoredsvids /opt/spire/conf/agent/svids.json || fail-now "failed to check stored svids"
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ spec:
- name: spire-config
mountPath: /run/spire/config
readOnly: true
- name: spire-server-socket
mountPath: /tmp/spire-server/private
readOnly: false
livenessProbe:
httpGet:
path: /live
Expand All @@ -147,7 +144,3 @@ spec:
- name: spire-config
configMap:
name: spire-server
- name: spire-server-socket
hostPath:
path: /run/spire/server-sockets
type: DirectoryOrCreate
Loading

0 comments on commit ecabb6c

Please sign in to comment.