Skip to content

Commit fb9751c

Browse files
breskebyjfreden
authored andcommitted
Adjust docker fips entrypoint and cmd (elastic#127630)
Also extract docker fips configuration in explicit docker file
1 parent c023468 commit fb9751c

File tree

3 files changed

+214
-60
lines changed

3 files changed

+214
-60
lines changed

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ public enum DockerBase {
3131
// spotless:on
3232
// Based on WOLFI above, with more extras. We don't set a base image because
3333
// we programmatically extend from the wolfi image.
34-
CLOUD_ESS(null, "-cloud-ess", "apk", "Dockerfile.cloud-ess"),
34+
CLOUD_ESS(null, "-cloud-ess", "apk", "Dockerfile.ess"),
3535

3636
CLOUD_ESS_FIPS(
3737
"docker.elastic.co/wolfi/chainguard-base-fips:sha256-ebfc3f1d7dba992231747a2e05ad1b859843e81b5e676ad342859d7cf9e425a7@sha256:ebfc3f1d7dba992231747a2e05ad1b859843e81b5e676ad342859d7cf9e425a7",
3838
"-cloud-ess-fips",
3939
"apk",
40-
"Dockerfile"
40+
"Dockerfile.ess-fips"
4141
);
4242

4343
private final String image;

distribution/docker/src/docker/Dockerfile

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ RUN chmod 0555 /bin/tini
4141
<% } else { %>
4242
4343
# Install required packages to extract the Elasticsearch distribution
44-
<% if (docker_base == "wolfi" || docker_base == "cloud_ess_fips") { %>
44+
<% if (docker_base == "wolfi") { %>
4545
RUN <%= retry.loop(package_manager, "export DEBIAN_FRONTEND=noninteractive && ${package_manager} update && ${package_manager} update && ${package_manager} add --no-cache curl") %>
4646
<% } else { %>
4747
RUN <%= retry.loop(package_manager, "${package_manager} install -y findutils tar gzip") %>
@@ -115,51 +115,6 @@ RUN sed -i -e 's/ES_DISTRIBUTION_TYPE=tar/ES_DISTRIBUTION_TYPE=docker/' bin/elas
115115
chmod 0775 bin config config/jvm.options.d data logs plugins && \\
116116
find config -type f -exec chmod 0664 {} +
117117

118-
<% if (docker_base == "cloud_ess_fips") { %>
119-
120-
# Add plugins infrastructure
121-
RUN mkdir -p /opt/plugins/archive
122-
RUN chmod -R 0555 /opt/plugins
123-
124-
RUN mkdir -p /fips/libs
125-
COPY fips/libs/*.jar /fips/libs/
126-
127-
COPY filebeat-${version}.tar.gz metricbeat-${version}.tar.gz /tmp/
128-
RUN set -eux ; \\
129-
for beat in filebeat metricbeat ; do \\
130-
if [ ! -s /tmp/\$beat-${version}.tar.gz ]; then \\
131-
echo "/tmp/\$beat-${version}.tar.gz is empty - cannot uncompress" 2>&1 ; \\
132-
exit 1 ; \\
133-
fi ; \\
134-
if ! tar tf /tmp/\$beat-${version}.tar.gz >/dev/null; then \\
135-
echo "/tmp/\$beat-${version}.tar.gz is corrupt - cannot uncompress" 2>&1 ; \\
136-
exit 1 ; \\
137-
fi ; \\
138-
mkdir -p /opt/\$beat ; \\
139-
tar xf /tmp/\$beat-${version}.tar.gz -C /opt/\$beat --strip-components=1 ; \\
140-
done
141-
142-
COPY plugins/*.zip /opt/plugins/archive/
143-
144-
RUN chown 1000:1000 /opt/plugins/archive/*
145-
RUN chmod 0444 /opt/plugins/archive/*
146-
147-
COPY fips/resources/fips_java.security /usr/share/elasticsearch/config/fips_java.security
148-
COPY fips/resources/fips_java.policy /usr/share/elasticsearch/config/fips_java.policy
149-
150-
WORKDIR /usr/share/elasticsearch/config
151-
152-
## Add fips specific JVM options
153-
RUN cat <<EOF > /usr/share/elasticsearch/config/jvm.options.d/fips.options
154-
-Djavax.net.ssl.keyStoreType=BCFKS
155-
-Dorg.bouncycastle.fips.approved_only=true
156-
-Djava.security.properties=config/fips_java.security
157-
-Djava.security.policy=config/fips_java.policy
158-
EOF
159-
160-
<% } %>
161-
162-
163118
################################################################################
164119
# Build stage 2 (the actual Elasticsearch image):
165120
#
@@ -179,7 +134,7 @@ RUN ${package_manager} update --setopt=tsflags=nodocs -y && \\
179134
nc shadow-utils zip findutils unzip procps-ng && \\
180135
${package_manager} clean all
181136
182-
<% } else if (docker_base == "wolfi" || docker_base == "cloud_ess_fips") { %>
137+
<% } else if (docker_base == "wolfi") { %>
183138
RUN <%= retry.loop(package_manager,
184139
"export DEBIAN_FRONTEND=noninteractive && \n" +
185140
" ${package_manager} update && \n" +
@@ -208,7 +163,7 @@ RUN <%= retry.loop(
208163
<% } %>
209164
210165
211-
<% if (docker_base == "wolfi" || docker_base == "cloud_ess_fips") { %>
166+
<% if (docker_base == "wolfi") { %>
212167
RUN groupadd -g 1000 elasticsearch && \
213168
adduser -G elasticsearch -u 1000 elasticsearch -D --home /usr/share/elasticsearch elasticsearch && \
214169
adduser elasticsearch root && \
@@ -224,7 +179,7 @@ ENV ELASTIC_CONTAINER=true
224179
WORKDIR /usr/share/elasticsearch
225180
226181
COPY --from=builder --chown=0:0 /usr/share/elasticsearch /usr/share/elasticsearch
227-
<% if (docker_base != "wolfi" && docker_base != "cloud_ess_fips") { %>
182+
<% if (docker_base != "wolfi") { %>
228183
COPY --from=builder --chown=0:0 /bin/tini /bin/tini
229184
<% } %>
230185
@@ -249,7 +204,7 @@ RUN chmod g=u /etc/passwd && \\
249204
chmod 0775 /usr/share/elasticsearch && \\
250205
chown elasticsearch bin config config/jvm.options.d data logs plugins
251206

252-
<% if (docker_base == 'wolfi' || docker_base == "cloud_ess_fips") { %>
207+
<% if (docker_base == 'wolfi') { %>
253208
RUN ln -sf /etc/ssl/certs/java/cacerts /usr/share/elasticsearch/jdk/lib/security/cacerts
254209
<% } else { %>
255210
RUN ln -sf /etc/pki/ca-trust/extracted/java/cacerts /usr/share/elasticsearch/jdk/lib/security/cacerts
@@ -292,7 +247,7 @@ RUN mkdir /licenses && ln LICENSE.txt /licenses/LICENSE
292247
COPY LICENSE /licenses/LICENSE.addendum
293248
<% } %>
294249

295-
<% if (docker_base == "wolfi" || docker_base == "cloud_ess_fips") { %>
250+
<% if (docker_base == "wolfi") { %>
296251
# Our actual entrypoint is `tini`, a minimal but functional init program. It
297252
# calls the entrypoint we provide, while correctly forwarding signals.
298253
ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/docker-entrypoint.sh"]
@@ -311,13 +266,6 @@ USER 1000:0
311266
<% if (docker_base == 'iron_bank') { %>
312267
HEALTHCHECK --interval=10s --timeout=5s --start-period=1m --retries=5 CMD curl -I -f --max-time 5 http://localhost:9200 || exit 1
313268
<% } %>
314-
315-
<% if (docker_base == 'cloud_ess_fips') { %>
316-
COPY --from=builder --chown=0:0 /opt /opt
317-
ENV ES_PLUGIN_ARCHIVE_DIR=/opt/plugins/archive
318-
WORKDIR /usr/share/elasticsearch
319-
COPY --from=builder --chown=0:0 /fips/libs/*.jar /usr/share/elasticsearch/lib/
320-
<% } %>
321269
################################################################################
322270
# End of multi-stage Dockerfile
323271
################################################################################
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
################################################################################
2+
# This Dockerfile was generated from the template at distribution/src/docker/Dockerfile
3+
#
4+
# Beginning of multi stage Dockerfile
5+
################################################################################
6+
7+
<% /*
8+
This file is passed through Groovy's SimpleTemplateEngine, so dollars and backslashes
9+
have to be escaped in order for them to appear in the final Dockerfile. You
10+
can also comment out blocks, like this one. See:
11+
12+
https://docs.groovy-lang.org/latest/html/api/groovy/text/SimpleTemplateEngine.html
13+
14+
We use control-flow tags in this file to conditionally render the content. The
15+
layout/presentation here has been adjusted so that it looks reasonable when rendered,
16+
at the slight expense of how it looks here.
17+
18+
Note that this file is also filtered to squash together newlines, so we can
19+
add as many newlines here as necessary to improve legibility.
20+
*/ %>
21+
22+
################################################################################
23+
# Build stage 1 `builder`:
24+
# Extract Elasticsearch artifact
25+
################################################################################
26+
27+
FROM ${base_image} AS builder
28+
29+
# Install required packages to extract the Elasticsearch distribution
30+
RUN <%= retry.loop(package_manager, "export DEBIAN_FRONTEND=noninteractive && ${package_manager} update && ${package_manager} update && ${package_manager} add --no-cache curl") %>
31+
32+
RUN mkdir /usr/share/elasticsearch
33+
WORKDIR /usr/share/elasticsearch
34+
35+
# Fetch the appropriate Elasticsearch distribution for this architecture.
36+
# Keep this command on one line - it is replaced with a `COPY` during local builds.
37+
# It uses the `arch` shell command to fetch the correct distro for the build machine,
38+
# which is needed for Docker Hub builds.
39+
RUN curl --retry 10 -S -L --output /tmp/elasticsearch.tar.gz https://artifacts-no-kpi.elastic.co/downloads/elasticsearch/elasticsearch-${version}-linux-\$(arch).tar.gz
40+
41+
RUN tar -zxf /tmp/elasticsearch.tar.gz --strip-components=1
42+
43+
# The distribution includes a `config` directory, no need to create it
44+
COPY ${config_dir}/elasticsearch.yml config/
45+
COPY ${config_dir}/log4j2.properties config/log4j2.docker.properties
46+
47+
# 1. Configure the distribution for Docker
48+
# 2. Create required directory
49+
# 3. Move the distribution's default logging config aside
50+
# 4. Move the generated docker logging config so that it is the default
51+
# 5. Reset permissions on all directories
52+
# 6. Reset permissions on all files
53+
# 7. Make CLI tools executable
54+
# 8. Make some directories writable. `bin` must be writable because
55+
# plugins can install their own CLI utilities.
56+
# 9. Make some files writable
57+
RUN sed -i -e 's/ES_DISTRIBUTION_TYPE=tar/ES_DISTRIBUTION_TYPE=docker/' bin/elasticsearch-env && \\
58+
mkdir data && \\
59+
mv config/log4j2.properties config/log4j2.file.properties && \\
60+
mv config/log4j2.docker.properties config/log4j2.properties && \\
61+
find . -type d -exec chmod 0555 {} + && \\
62+
find . -type f -exec chmod 0444 {} + && \\
63+
chmod 0555 bin/* jdk/bin/* jdk/lib/jspawnhelper modules/x-pack-ml/platform/linux-*/bin/* && \\
64+
chmod 0775 bin config config/jvm.options.d data logs plugins && \\
65+
find config -type f -exec chmod 0664 {} +
66+
67+
# Add plugins infrastructure
68+
RUN mkdir -p /opt/plugins/archive
69+
RUN chmod -R 0555 /opt/plugins
70+
71+
RUN mkdir -p /fips/libs
72+
COPY fips/libs/*.jar /fips/libs/
73+
74+
COPY filebeat-${version}.tar.gz metricbeat-${version}.tar.gz /tmp/
75+
RUN set -eux ; \\
76+
for beat in filebeat metricbeat ; do \\
77+
if [ ! -s /tmp/\$beat-${version}.tar.gz ]; then \\
78+
echo "/tmp/\$beat-${version}.tar.gz is empty - cannot uncompress" 2>&1 ; \\
79+
exit 1 ; \\
80+
fi ; \\
81+
if ! tar tf /tmp/\$beat-${version}.tar.gz >/dev/null; then \\
82+
echo "/tmp/\$beat-${version}.tar.gz is corrupt - cannot uncompress" 2>&1 ; \\
83+
exit 1 ; \\
84+
fi ; \\
85+
mkdir -p /opt/\$beat ; \\
86+
tar xf /tmp/\$beat-${version}.tar.gz -C /opt/\$beat --strip-components=1 ; \\
87+
done
88+
89+
COPY plugins/*.zip /opt/plugins/archive/
90+
91+
RUN chown 1000:1000 /opt/plugins/archive/*
92+
RUN chmod 0444 /opt/plugins/archive/*
93+
94+
COPY fips/resources/fips_java.security /usr/share/elasticsearch/config/fips_java.security
95+
COPY fips/resources/fips_java.policy /usr/share/elasticsearch/config/fips_java.policy
96+
97+
WORKDIR /usr/share/elasticsearch/config
98+
99+
## Add fips specific JVM options
100+
RUN cat <<EOF > /usr/share/elasticsearch/config/jvm.options.d/fips.options
101+
-Djavax.net.ssl.keyStoreType=BCFKS
102+
-Dorg.bouncycastle.fips.approved_only=true
103+
-Djava.security.properties=config/fips_java.security
104+
-Djava.security.policy=config/fips_java.policy
105+
EOF
106+
107+
108+
################################################################################
109+
# Build stage 2 (the actual Elasticsearch image):
110+
#
111+
# Copy elasticsearch from stage 1
112+
# Add entrypoint
113+
################################################################################
114+
115+
FROM ${base_image}
116+
117+
RUN <%= retry.loop(package_manager,
118+
"export DEBIAN_FRONTEND=noninteractive && \n" +
119+
" ${package_manager} update && \n" +
120+
" ${package_manager} upgrade && \n" +
121+
" ${package_manager} add --no-cache \n" +
122+
" bash java-cacerts curl libstdc++ libsystemd netcat-openbsd p11-kit p11-kit-trust posix-libc-utils shadow tini unzip zip zstd && \n" +
123+
" rm -rf /var/cache/apk/* "
124+
) %>
125+
126+
# Set Bash as the default shell for future commands
127+
SHELL ["/bin/bash", "-c"]
128+
129+
RUN groupadd -g 1000 elasticsearch && \
130+
adduser -G elasticsearch -u 1000 elasticsearch -D --home /usr/share/elasticsearch elasticsearch && \
131+
adduser elasticsearch root && \
132+
chown -R 0:0 /usr/share/elasticsearch
133+
134+
ENV ELASTIC_CONTAINER=true
135+
136+
WORKDIR /usr/share/elasticsearch
137+
138+
COPY --from=builder --chown=0:0 /usr/share/elasticsearch /usr/share/elasticsearch
139+
ENV PATH=/usr/share/elasticsearch/bin:\$PATH
140+
ENV SHELL=/bin/bash
141+
COPY ${bin_dir}/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
142+
143+
# 1. Sync the user and group permissions of /etc/passwd
144+
# 2. Set correct permissions of the entrypoint
145+
# 3. Ensure that there are no files with setuid or setgid, in order to mitigate "stackclash" attacks.
146+
# We've already run this in previous layers so it ought to be a no-op.
147+
# 4. Replace OpenJDK's built-in CA certificate keystore with the one from the OS
148+
# vendor. The latter is superior in several ways.
149+
# REF: https://github.com/elastic/elasticsearch-docker/issues/171
150+
# 5. Tighten up permissions on the ES home dir (the permissions of the contents are handled earlier)
151+
# 6. You can't install plugins that include configuration when running as `elasticsearch` and the `config`
152+
# dir is owned by `root`, because the installed tries to manipulate the permissions on the plugin's
153+
# config directory.
154+
RUN chmod g=u /etc/passwd && \\
155+
chmod 0555 /usr/local/bin/docker-entrypoint.sh && \\
156+
find / -xdev -perm -4000 -exec chmod ug-s {} + && \\
157+
chmod 0775 /usr/share/elasticsearch && \\
158+
chown elasticsearch bin config config/jvm.options.d data logs plugins
159+
160+
RUN ln -sf /etc/ssl/certs/java/cacerts /usr/share/elasticsearch/jdk/lib/security/cacerts
161+
162+
EXPOSE 9200 9300
163+
164+
LABEL org.label-schema.build-date="${build_date}" \\
165+
org.label-schema.license="${license}" \\
166+
org.label-schema.name="Elasticsearch" \\
167+
org.label-schema.schema-version="1.0" \\
168+
org.label-schema.url="https://www.elastic.co/products/elasticsearch" \\
169+
org.label-schema.usage="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" \\
170+
org.label-schema.vcs-ref="${git_revision}" \\
171+
org.label-schema.vcs-url="https://github.com/elastic/elasticsearch" \\
172+
org.label-schema.vendor="Elastic" \\
173+
org.label-schema.version="${version}" \\
174+
org.opencontainers.image.created="${build_date}" \\
175+
org.opencontainers.image.documentation="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" \\
176+
org.opencontainers.image.licenses="${license}" \\
177+
org.opencontainers.image.revision="${git_revision}" \\
178+
org.opencontainers.image.source="https://github.com/elastic/elasticsearch" \\
179+
org.opencontainers.image.title="Elasticsearch" \\
180+
org.opencontainers.image.url="https://www.elastic.co/products/elasticsearch" \\
181+
org.opencontainers.image.vendor="Elastic" \\
182+
org.opencontainers.image.version="${version}"
183+
184+
LABEL name="Elasticsearch" \\
185+
maintainer="[email protected]" \\
186+
vendor="Elastic" \\
187+
version="${version}" \\
188+
release="1" \\
189+
summary="Elasticsearch" \\
190+
description="You know, for search."
191+
192+
RUN mkdir /licenses && ln LICENSE.txt /licenses/LICENSE
193+
194+
ENTRYPOINT ["/sbin/tini", "--"]
195+
CMD ["/app/elasticsearch.sh"]
196+
197+
USER 1000:0
198+
199+
COPY --from=builder --chown=0:0 /opt /opt
200+
ENV ES_PLUGIN_ARCHIVE_DIR=/opt/plugins/archive
201+
WORKDIR /usr/share/elasticsearch
202+
COPY --from=builder --chown=0:0 /fips/libs/*.jar /usr/share/elasticsearch/lib/
203+
204+
################################################################################
205+
# End of multi-stage Dockerfile
206+
################################################################################

0 commit comments

Comments
 (0)