Skip to content

Commit b12e3c9

Browse files
authored
Build shibboleth-idp for testing purposes (#91216) (#91293)
We currently use unicon/shibboleth-idp:3.4.2 to help test our SAML integration. That container is no longer actively supported and does not support ARM architectures. This commit is a partial clone from Unicon/shibboleth-idp-dockerized 3.4.3. Changes from upstream include: Use openjdk:11.0.16-jre as the base image for support for ARM architectures Handle missing keystore download from Jetty Fix URL paths for artifacts to download Changes to this repository include: Copied required Jetty configuration files from upstream project Updates to docker compose Placed the missing keystore Jetty downloads in a separate location (jetty-custom) The final result is a bit messy. Mixing cloned files with custom files and mixing Jetty and IDP concerns. However, it is not much messier than prior and now that we control building the image we can more easily upgrade shibboleth IDP The upgrade to the latest version is fairly involved and as such we will need to deviate more from the clone which should allow some additional clean up. part of: #71378 related: #91144 supersedes: #89674
1 parent 728c671 commit b12e3c9

File tree

18 files changed

+555
-15
lines changed

18 files changed

+555
-15
lines changed

x-pack/qa/saml-idp-tests/build.gradle

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import org.elasticsearch.gradle.Architecture
2-
31
Project idpFixtureProject = xpackProject("test:idp-fixture")
42

53
apply plugin: 'elasticsearch.internal-java-rest-test'
@@ -13,17 +11,17 @@ dependencies {
1311
testFixtures.useFixture ":x-pack:test:idp-fixture"
1412

1513
String outputDir = "${project.buildDir}/generated-resources/${project.name}"
16-
def copyIdpFiles = tasks.register("copyIdpFiles", Copy) {
14+
def copyIdpFiles = tasks.register("copyIdpFiles", Sync) {
1715
from idpFixtureProject.files('idp/shibboleth-idp/credentials/idp-browser.pem', 'idp/shibboleth-idp/metadata/idp-metadata.xml',
1816
'idp/shibboleth-idp/credentials/sp-signing.key', 'idp/shibboleth-idp/credentials/sp-signing.crt');
1917
into outputDir
18+
outputs.upToDateWhen { false } //ensure this copy is always done to prevent stale configuration
2019
}
2120

2221
def setupPorts = tasks.register("setupPorts") {
2322
dependsOn copyIdpFiles, idpFixtureProject.postProcessFixture
2423
// Don't attempt to get ephemeral ports when Docker is not available
25-
// Also, shibboleth fixture is not available on aarch64
26-
onlyIf { idpFixtureProject.postProcessFixture.state.skipped == false && Architecture.current() == Architecture.X64 }
24+
onlyIf { idpFixtureProject.postProcessFixture.state.skipped == false }
2725
doLast {
2826
String portString = idpFixtureProject.postProcessFixture.ext."test.fixtures.shibboleth-idp.tcp.4443"
2927
int ephemeralPort = Integer.valueOf(portString)
@@ -43,7 +41,7 @@ project.sourceSets.javaRestTest.output.dir(outputDir, builtBy: [copyIdpFiles])
4341

4442
tasks.named("javaRestTest").configure {
4543
dependsOn setupPorts
46-
onlyIf { idpFixtureProject.postProcessFixture.state.skipped == false && Architecture.current() == Architecture.X64 }
44+
onlyIf { idpFixtureProject.postProcessFixture.state.skipped == false }
4745
}
4846

4947
testClusters.matching { it.name == "javaRestTest" }.configureEach {

x-pack/test/idp-fixture/docker-compose.yml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,22 +137,20 @@ services:
137137
- ./openldap/certs:/container/service/slapd/assets/certs
138138

139139
shibboleth-idp:
140-
image: "unicon/shibboleth-idp:3.4.2"
140+
build:
141+
context: .
142+
dockerfile: ./idp/Dockerfile
141143
depends_on:
142144
- openldap
143145
environment:
144146
- JETTY_MAX_HEAP=64m
145-
- JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=secret
146-
- JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=secret
147147
ports:
148-
- "4443"
148+
- 4443
149+
expose:
150+
- 4443
149151
links:
150152
- openldap:openldap
151-
volumes:
152-
- ./idp/shibboleth-idp/conf:/opt/shibboleth-idp/conf
153-
- ./idp/shibboleth-idp/credentials:/opt/shibboleth-idp/credentials
154-
- ./idp/shibboleth-idp/metadata:/opt/shibboleth-idp/metadata
155-
- ./idp/shib-jetty-base/start.d/ssl.ini:/opt/shib-jetty-base/start.d/ssl.ini
153+
restart: always #ensure ephemeral port mappings are properly updated
156154

157155
oidc-provider:
158156
build:
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
FROM openjdk:11.0.16-jre AS javabase
2+
3+
ENV JAVA_HOME=/usr/local/openjdk-11
4+
5+
# below is mostly a fork from https://github.com/Unicon/shibboleth-idp-dockerized/blob/master/Dockerfile
6+
# building entire image to allow for easier upgrades since published image has not been updated for years
7+
ENV jetty_version=9.3.27.v20190418 \
8+
jetty_hash=7c7c80dd1c9f921771e2b1a05deeeec652d5fcaa \
9+
idp_version=3.4.3 \
10+
idp_hash=eb86bc7b6366ce2a44f97cae1b014d307b84257e3149469b22b2d091007309db \
11+
dta_hash=2f547074b06952b94c35631398f36746820a7697 \
12+
slf4j_version=1.7.25 \
13+
slf4j_hash=da76ca59f6a57ee3102f8f9bd9cee742973efa8a \
14+
logback_version=1.2.3 \
15+
logback_classic_hash=7c4f3c474fb2c041d8028740440937705ebb473a \
16+
logback_core_hash=864344400c3d4d92dfeb0a305dc87d953677c03c \
17+
logback_access_hash=e8a841cb796f6423c7afd8738df6e0e4052bf24a
18+
19+
ENV JETTY_HOME=/opt/jetty-home \
20+
JETTY_BASE=/opt/shib-jetty-base \
21+
PATH=$PATH:$JAVA_HOME/bin \
22+
JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=secret \
23+
JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=secret
24+
25+
# Manually override the jetty keystore otherwise it will attempt to download and fail
26+
RUN mkdir -p /opt/shib-jetty-base/modules
27+
COPY ./idp/jetty-custom/ssl.mod /opt/shib-jetty-base/modules/ssl.mod
28+
COPY ./idp/jetty-custom/keystore /opt/shib-jetty-base/etc/keystore
29+
30+
# Download Jetty, verify the hash, and install, initialize a new base
31+
RUN wget -q https://repo.maven.apache.org/maven2/org/eclipse/jetty/jetty-distribution/$jetty_version/jetty-distribution-$jetty_version.tar.gz \
32+
&& echo "$jetty_hash jetty-distribution-$jetty_version.tar.gz" | sha1sum -c - \
33+
&& tar -zxvf jetty-distribution-$jetty_version.tar.gz -C /opt \
34+
&& ln -s /opt/jetty-distribution-$jetty_version/ /opt/jetty-home
35+
36+
# Config Jetty
37+
RUN mkdir -p /opt/shib-jetty-base/modules /opt/shib-jetty-base/lib/ext /opt/shib-jetty-base/lib/logging /opt/shib-jetty-base/resources \
38+
&& cd /opt/shib-jetty-base \
39+
&& touch start.ini \
40+
&& java -jar ../jetty-home/start.jar --add-to-startd=http,https,deploy,ext,annotations,jstl,rewrite
41+
42+
# Download Shibboleth IdP, verify the hash, and install
43+
RUN wget -q https://shibboleth.net/downloads/identity-provider/archive/$idp_version/shibboleth-identity-provider-$idp_version.tar.gz \
44+
&& echo "$idp_hash shibboleth-identity-provider-$idp_version.tar.gz" | sha256sum -c - \
45+
&& tar -zxvf shibboleth-identity-provider-$idp_version.tar.gz -C /opt \
46+
&& ln -s /opt/shibboleth-identity-provider-$idp_version/ /opt/shibboleth-idp
47+
48+
# Download the library to allow SOAP Endpoints, verify the hash, and place
49+
RUN wget -q https://build.shibboleth.net/nexus/content/repositories/releases/net/shibboleth/utilities/jetty9/jetty9-dta-ssl/1.0.0/jetty9-dta-ssl-1.0.0.jar \
50+
&& echo "$dta_hash jetty9-dta-ssl-1.0.0.jar" | sha1sum -c - \
51+
&& mv jetty9-dta-ssl-1.0.0.jar /opt/shib-jetty-base/lib/ext/
52+
53+
# Download the slf4j library for Jetty logging, verify the hash, and place
54+
RUN wget -q https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/$slf4j_version/slf4j-api-$slf4j_version.jar \
55+
&& echo "$slf4j_hash slf4j-api-$slf4j_version.jar" | sha1sum -c - \
56+
&& mv slf4j-api-$slf4j_version.jar /opt/shib-jetty-base/lib/logging/
57+
58+
# Download the logback_classic library for Jetty logging, verify the hash, and place
59+
RUN wget -q https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/$logback_version/logback-classic-$logback_version.jar \
60+
&& echo "$logback_classic_hash logback-classic-$logback_version.jar" | sha1sum -c - \
61+
&& mv logback-classic-$logback_version.jar /opt/shib-jetty-base/lib/logging/
62+
63+
# Download the logback-core library for Jetty logging, verify the hash, and place
64+
RUN wget -q https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/$logback_version/logback-core-$logback_version.jar \
65+
&& echo "$logback_core_hash logback-core-$logback_version.jar" | sha1sum -c - \
66+
&& mv logback-core-$logback_version.jar /opt/shib-jetty-base/lib/logging/
67+
68+
# Download the logback-access library for Jetty logging, verify the hash, and place
69+
RUN wget -q https://repo.maven.apache.org/maven2/ch/qos/logback/logback-access/$logback_version/logback-access-$logback_version.jar \
70+
&& echo "$logback_access_hash logback-access-$logback_version.jar" | sha1sum -c - \
71+
&& mv logback-access-$logback_version.jar /opt/shib-jetty-base/lib/logging/
72+
73+
## Copy local files
74+
COPY idp/shib-jetty-base/ /opt/shib-jetty-base/
75+
COPY idp/shibboleth-idp/ /opt/shibboleth-idp/
76+
COPY idp/bin/ /usr/local/bin/
77+
78+
# Setting owner ownership and permissions
79+
RUN useradd jetty -U -s /bin/false \
80+
&& chown -R root:jetty /opt \
81+
&& chmod -R 640 /opt \
82+
&& chown -R root:jetty /opt/shib-jetty-base \
83+
&& chmod -R 640 /opt/shib-jetty-base \
84+
&& chmod -R 750 /opt/shibboleth-idp/bin
85+
86+
RUN chmod 750 /usr/local/bin/run-jetty.sh /usr/local/bin/init-idp.sh
87+
RUN chmod +x /opt/jetty-home/bin/jetty.sh
88+
89+
# Opening 4443 (browser TLS), 8443 (mutual auth TLS)
90+
EXPOSE 4443 8443
91+
92+
CMD ["run-jetty.sh"]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
3+
cd /opt/shibboleth-idp/bin
4+
5+
echo "Please complete the following for your IdP environment:"
6+
./ant.sh -Didp.target.dir=/opt/shibboleth-idp-tmp -Didp.src.dir=/opt/shibboleth-idp/ install
7+
8+
find /opt/shibboleth-idp-tmp/ -type d -exec chmod 750 {} \;
9+
10+
mkdir -p /ext-mount/customized-shibboleth-idp/conf/
11+
chmod -R 750 /ext-mount/customized-shibboleth-idp/
12+
13+
# Copy the essential and routinely customized config to out Docker mount.
14+
cd /opt/shibboleth-idp-tmp
15+
cp -r credentials/ /ext-mount/customized-shibboleth-idp/
16+
cp -r metadata/ /ext-mount/customized-shibboleth-idp/
17+
cp conf/{attribute-resolver*.xml,attribute-filter.xml,cas-protocol.xml,idp.properties,ldap.properties,metadata-providers.xml,relying-party.xml,saml-nameid.*} /ext-mount/customized-shibboleth-idp/conf/
18+
19+
# Copy the basic UI components, which are routinely customized
20+
cp -r views/ /ext-mount/customized-shibboleth-idp/
21+
mkdir /ext-mount/customized-shibboleth-idp/webapp/
22+
cp -r edit-webapp/css/ /ext-mount/customized-shibboleth-idp/webapp/
23+
cp -r edit-webapp/images/ /ext-mount/customized-shibboleth-idp/webapp/
24+
rm -r /ext-mount/customized-shibboleth-idp/views/user-prefs.js
25+
26+
echo "A basic Shibboleth IdP config and UI has been copied to ./customized-shibboleth-idp/ (assuming the default volume mapping was used)."
27+
echo "Most files, if not being customized can be removed from what was exported/the local Docker image and baseline files will be used."
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
3+
#set -x
4+
5+
if [ -e "/opt/shibboleth-idp/ext-conf/idp-secrets.properties" ]; then
6+
export JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=`gawk 'match($0,/^jetty.backchannel.sslContext.keyStorePassword=\s?(.*)\s?$/, a) {print a[1]}' /opt/shibboleth-idp/ext-conf/idp-secrets.properties`
7+
export JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=`gawk 'match($0,/^jetty\.sslContext\.keyStorePassword=\s?(.*)\s?$/, a) {print a[1]}' /opt/shibboleth-idp/ext-conf/idp-secrets.properties`
8+
fi
9+
10+
export JETTY_ARGS="jetty.sslContext.keyStorePassword=$JETTY_BROWSER_SSL_KEYSTORE_PASSWORD jetty.backchannel.sslContext.keyStorePassword=$JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD"
11+
sed -i "s/^-Xmx.*$/-Xmx$JETTY_MAX_HEAP/g" /opt/shib-jetty-base/start.ini
12+
13+
exec /opt/jetty-home/bin/jetty.sh run
3.61 KB
Binary file not shown.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#
2+
# SSL Keystore module
3+
#
4+
5+
[name]
6+
ssl
7+
8+
[depend]
9+
server
10+
11+
[xml]
12+
etc/jetty-ssl.xml
13+
etc/jetty-ssl-context.xml
14+
15+
[files]
16+
# keystore originally sourced from https://github.com/eclipse/jetty.project/raw/jetty-9.3.x/jetty-server/src/main/config/etc/keystore
17+
/opt/shib-jetty-base/etc/keystore
18+
19+
[ini-template]
20+
### TLS(SSL) Connector Configuration
21+
22+
## Connector host/address to bind to
23+
# jetty.ssl.host=0.0.0.0
24+
25+
## Connector port to listen on
26+
# jetty.ssl.port=8443
27+
28+
## Connector idle timeout in milliseconds
29+
# jetty.ssl.idleTimeout=30000
30+
31+
## Connector socket linger time in seconds (-1 to disable)
32+
# jetty.ssl.soLingerTime=-1
33+
34+
## Number of acceptors (-1 picks default based on number of cores)
35+
# jetty.ssl.acceptors=-1
36+
37+
## Number of selectors (-1 picks default based on number of cores)
38+
# jetty.ssl.selectors=-1
39+
40+
## ServerSocketChannel backlog (0 picks platform default)
41+
# jetty.ssl.acceptorQueueSize=0
42+
43+
## Thread priority delta to give to acceptor threads
44+
# jetty.ssl.acceptorPriorityDelta=0
45+
46+
## Whether request host names are checked to match any SNI names
47+
# jetty.ssl.sniHostCheck=true
48+
49+
## max age in seconds for a Strict-Transport-Security response header (default -1)
50+
# jetty.ssl.stsMaxAgeSeconds=31536000
51+
52+
## include subdomain property in any Strict-Transport-Security header (default false)
53+
# jetty.ssl.stsIncludeSubdomains=true
54+
55+
### SslContextFactory Configuration
56+
## Note that OBF passwords are not secure, just protected from casual observation
57+
## See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html
58+
59+
## Keystore file path (relative to $jetty.base)
60+
# jetty.sslContext.keyStorePath=etc/keystore
61+
62+
## Truststore file path (relative to $jetty.base)
63+
# jetty.sslContext.trustStorePath=etc/keystore
64+
65+
## Keystore password
66+
# jetty.sslContext.keyStorePassword=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
67+
68+
## Keystore type and provider
69+
# jetty.sslContext.keyStoreType=JKS
70+
# jetty.sslContext.keyStoreProvider=
71+
72+
## KeyManager password
73+
# jetty.sslContext.keyManagerPassword=OBF:1u2u1wml1z7s1z7a1wnl1u2g
74+
75+
## Truststore password
76+
# jetty.sslContext.trustStorePassword=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
77+
78+
## Truststore type and provider
79+
# jetty.sslContext.trustStoreType=JKS
80+
# jetty.sslContext.trustStoreProvider=
81+
82+
## whether client certificate authentication is required
83+
# jetty.sslContext.needClientAuth=false
84+
85+
## Whether client certificate authentication is desired
86+
# jetty.sslContext.wantClientAuth=false
87+
88+
## Whether cipher order is significant (since java 8 only)
89+
# jetty.sslContext.useCipherSuitesOrder=true
90+
91+
## To configure Includes / Excludes for Cipher Suites or Protocols see tweak-ssl.xml example at
92+
## https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites
93+
94+
## Set the size of the SslSession cache
95+
# jetty.sslContext.sslSessionCacheSize=-1
96+
97+
## Set the timeout (in seconds) of the SslSession cache timeout
98+
# jetty.sslContext.sslSessionTimeout=-1
99+
100+
## Allow SSL renegotiation
101+
# jetty.sslContext.renegotiationAllowed=true
102+
# jetty.sslContext.renegotiationLimit=5
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
3+
4+
<Configure id="Server" class="org.eclipse.jetty.server.Server">
5+
6+
<!-- ============================================================= -->
7+
<!-- TLS context factory with optional client auth -->
8+
<!-- and no container trust (delegate to application) -->
9+
<!-- for backchannel (SOAP) communication to IdP -->
10+
<!-- ============================================================= -->
11+
<New id="shibContextFactory" class="net.shibboleth.utilities.jetty9.DelegateToApplicationSslContextFactory">
12+
<Set name="KeyStorePath"><Property name="jetty.backchannel.sslContext.keyStorePath" /></Set>
13+
<Set name="KeyStoreType"><Property name="jetty.backchannel.sslContext.keyStoreType" /></Set>
14+
<Set name="KeyStorePassword"><Property name="jetty.backchannel.sslContext.keyStorePassword" /></Set>
15+
<!-- This is a tweak to work around a bug in Jetty when using the PKCS12 keystore type. -->
16+
<Set name="TrustStoreType"><Property name="jetty.backchannel.sslContext.keyStoreType" /></Set>
17+
<Set name="EndpointIdentificationAlgorithm"></Set>
18+
<Set name="renegotiationAllowed">false</Set>
19+
<Set name="useCipherSuitesOrder">true</Set>
20+
<Set name="excludeProtocols">
21+
<Array type="String">
22+
<Item>SSL</Item>
23+
<Item>SSLv2</Item>
24+
<Item>SSLv3</Item>
25+
</Array>
26+
</Set>
27+
<Set name="IncludeCipherSuites">
28+
<Array type="String">
29+
<Item>TLS_ECDHE.*</Item>
30+
<Item>TLS_RSA.*</Item>
31+
</Array>
32+
</Set>
33+
<Set name="ExcludeCipherSuites">
34+
<Array type="String">
35+
<Item>.*NULL.*</Item>
36+
<Item>.*RC4.*</Item>
37+
<Item>.*MD5.*</Item>
38+
<Item>.*DES.*</Item>
39+
<Item>.*DSS.*</Item>
40+
</Array>
41+
</Set>
42+
</New>
43+
44+
<New id="shibHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
45+
<Arg><Ref refid="httpConfig"/></Arg>
46+
<Call name="addCustomizer">
47+
<Arg>
48+
<New class="org.eclipse.jetty.server.SecureRequestCustomizer">
49+
<Arg type="boolean"><Property name="jetty.ssl.sniHostCheck" default="true"/></Arg>
50+
</New>
51+
</Arg>
52+
</Call>
53+
</New>
54+
55+
<!-- ============================================================= -->
56+
<!-- IdP SOAP protocol connector -->
57+
<!-- ============================================================= -->
58+
<Call id="shibConnector" name="addConnector">
59+
<Arg>
60+
<New class="org.eclipse.jetty.server.ServerConnector">
61+
<Arg name="server"><Ref refid="Server" /></Arg>
62+
<Arg name="acceptors" type="int"><Property name="jetty.ssl.acceptors" default="-1"/></Arg>
63+
<Arg name="selectors" type="int"><Property name="jetty.ssl.selectors" default="-1"/></Arg>
64+
<Arg name="factories">
65+
<Array type="org.eclipse.jetty.server.ConnectionFactory">
66+
<Item>
67+
<New class="org.eclipse.jetty.server.SslConnectionFactory">
68+
<Arg name="next">http/1.1</Arg>
69+
<Arg name="sslContextFactory"><Ref refid="shibContextFactory"/></Arg>
70+
</New>
71+
</Item>
72+
<Item>
73+
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
74+
<Arg name="config"><Ref refid="shibHttpConfig"/></Arg>
75+
</New>
76+
</Item>
77+
</Array>
78+
</Arg>
79+
<Set name="host"><Property name="jetty.backchannel.host" default="0.0.0.0" /></Set>
80+
<Set name="port"><Property name="jetty.backchannel.port" default="8443"/></Set>
81+
<Set name="idleTimeout"><Property name="jetty.ssl.timeout" default="30000"/></Set>
82+
<Set name="soLingerTime"><Property name="jetty.ssl.soLingerTime" default="-1"/></Set>
83+
<Set name="acceptorPriorityDelta"><Property name="jetty.ssl.acceptorPriorityDelta" default="0"/></Set>
84+
<Set name="selectorPriorityDelta"><Property name="jetty.ssl.selectorPriorityDelta" default="0"/></Set>
85+
<Set name="acceptQueueSize"><Property name="jetty.ssl.acceptQueueSize" default="0"/></Set>
86+
</New>
87+
</Arg>
88+
</Call>
89+
90+
</Configure>

0 commit comments

Comments
 (0)