-
Notifications
You must be signed in to change notification settings - Fork 39
299 lines (245 loc) · 11 KB
/
sslTesting.yml
File metadata and controls
299 lines (245 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# ===================================================================
# GitHub Action: SSL Certificate Validation Test with Squid Proxy
#
# Purpose:
# This workflow simulates real-world SSL trust chain configurations
# to validate JDBC driver support for:
# - Custom trust stores
# - System trust stores
# - Self-signed certificate handling
# - Revocation and fallback behavior
#
# How:
# - Generates a Root CA, Intermediate CA, and signs a server cert (mirroring real world use-cases)
# - Starts a Squid HTTPS proxy using the signed cert
# - Creates a Java truststore with the correct anchors
# - Optionally installs the Root CA into system trust store
# - Runs targeted JDBC integration tests using SSLTest.java
# ===================================================================1
name: SSL Certificate Validation Test with Squid Proxy
on:
push:
branches: [ main ]
workflow_dispatch:
inputs:
branch:
description: 'Branch to checkout'
required: false
default: 'main'
repository:
description: 'Repository to checkout (e.g., user/repo)'
required: false
default: 'databricks/databricks-jdbc'
permissions:
id-token: write
contents: read
jobs:
ssl-test:
runs-on:
group: databricks-protected-runner-group
labels: linux-ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.head.ref || inputs.branch }}
repository: ${{ github.event.pull_request.head.repo.full_name || inputs.repository }}
- name: Set Up Java
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4
with:
java-version: "21"
distribution: "adopt"
- name: Get JFrog OIDC token
run: |
set -euo pipefail
# Get GitHub OIDC ID token
ID_TOKEN=$(curl -sLS \
-H "User-Agent: actions/oidc-client" \
-H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=jfrog-github" | jq .value | tr -d '"')
echo "::add-mask::${ID_TOKEN}"
# Exchange for JFrog access token
ACCESS_TOKEN=$(curl -sLS -XPOST -H "Content-Type: application/json" \
"https://databricks.jfrog.io/access/api/v1/oidc/token" \
-d "{\"grant_type\": \"urn:ietf:params:oauth:grant-type:token-exchange\", \"subject_token_type\":\"urn:ietf:params:oauth:token-type:id_token\", \"subject_token\": \"${ID_TOKEN}\", \"provider_name\": \"github-actions\"}" | jq .access_token | tr -d '"')
echo "::add-mask::${ACCESS_TOKEN}"
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
echo "FAIL: Could not extract JFrog access token"
exit 1
fi
echo "JFROG_ACCESS_TOKEN=${ACCESS_TOKEN}" >> "$GITHUB_ENV"
echo "JFrog OIDC token obtained successfully"
- name: Configure maven
run: |
set -euo pipefail
mkdir -p ~/.m2
cat > ~/.m2/settings.xml << EOF
<settings>
<mirrors>
<mirror>
<id>jfrog-central</id>
<mirrorOf>*</mirrorOf>
<url>https://databricks.jfrog.io/artifactory/db-maven/</url>
</mirror>
</mirrors>
<servers>
<server>
<id>jfrog-central</id>
<username>gha-service-account</username>
<password>${JFROG_ACCESS_TOKEN}</password>
</server>
</servers>
</settings>
EOF
echo "Maven configured to use JFrog registry"
- name: Set Environment Variables
env:
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
DATABRICKS_HTTP_PATH: ${{ secrets.DATABRICKS_HTTP_PATH }}
HTTP_PROXY_URL: "http://localhost:3128"
HTTPS_PROXY_URL: "https://localhost:3129"
TRUSTSTORE_PATH: "/tmp/ssl-certs/test-truststore.jks"
TRUSTSTORE_PASSWORD: "changeit"
run: |
echo "DATABRICKS_TOKEN=${DATABRICKS_TOKEN}" >> $GITHUB_ENV
echo "DATABRICKS_HOST=${DATABRICKS_HOST}" >> $GITHUB_ENV
echo "DATABRICKS_HTTP_PATH=${DATABRICKS_HTTP_PATH}" >> $GITHUB_ENV
echo "HTTP_PROXY_URL=${HTTP_PROXY_URL}" >> $GITHUB_ENV
echo "HTTPS_PROXY_URL=${HTTPS_PROXY_URL}" >> $GITHUB_ENV
echo "TRUSTSTORE_PATH=${TRUSTSTORE_PATH}" >> $GITHUB_ENV
echo "TRUSTSTORE_PASSWORD=${TRUSTSTORE_PASSWORD}" >> $GITHUB_ENV
- name: Install Squid and SSL Tools
run: |
sudo apt-get update
sudo apt-get install -y squid openssl libnss3-tools ca-certificates
- name: Create Root CA and Certificates
run: |
mkdir -p /tmp/ssl-certs
cd /tmp/ssl-certs
# Generate Root CA
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 365 -out rootCA.crt \
-subj "/C=US/ST=California/L=San Francisco/O=Databricks Test/OU=Testing/CN=Databricks Test Root CA"
# Generate Intermediate CA
openssl genrsa -out intermediateCA.key 4096
openssl req -new -key intermediateCA.key -out intermediateCA.csr \
-subj "/C=US/ST=California/L=San Francisco/O=Databricks Test/OU=Testing/CN=Databricks Test Intermediate CA"
# Create extension file for intermediate CA
cat > intermediate_ext.cnf << EOF
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
EOF
# Sign Intermediate CA with Root CA
openssl x509 -req -in intermediateCA.csr -CA rootCA.crt -CAkey rootCA.key \
-CAcreateserial -out intermediateCA.crt -days 365 -sha256 \
-extfile intermediate_ext.cnf -extensions v3_ca
# Generate Squid Proxy Certificate
openssl genrsa -out squid.key 2048
openssl req -new -key squid.key -out squid.csr \
-subj "/C=US/ST=California/L=San Francisco/O=Databricks Test/OU=Testing/CN=localhost"
# Create extension file for Squid certificate
cat > squid_ext.cnf << EOF
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.1 = 127.0.0.1
EOF
# Sign Squid certificate with Intermediate CA
openssl x509 -req -in squid.csr -CA intermediateCA.crt -CAkey intermediateCA.key \
-CAcreateserial -out squid.crt -days 365 -sha256 \
-extfile squid_ext.cnf -extensions v3_req
# Create PEM file for Squid
cat squid.crt squid.key > squid.pem
chmod 400 squid.pem
# Copy to appropriate locations
sudo cp squid.pem /etc/squid/
sudo chown proxy:proxy /etc/squid/squid.pem
# Extract the Databricks workspace certificate
echo -n | openssl s_client -connect ${DATABRICKS_HOST}:443 -showcerts 2>/dev/null | \
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > databricks_workspace.crt
# Create Java Keystore from Root CA - with proper trust anchors
rm -f test-truststore.jks
# Create a truststore with the root CA as a trusted certificate entry
keytool -importcert -noprompt -trustcacerts -alias rootca -file rootCA.crt \
-keystore test-truststore.jks -storepass changeit
# Also add the intermediate CA to the trust store
keytool -importcert -noprompt -trustcacerts -alias intermediateca -file intermediateCA.crt \
-keystore test-truststore.jks -storepass changeit
# Add the Databricks workspace certificate to the trust store
keytool -importcert -noprompt -trustcacerts -alias databricksworkspace -file databricks_workspace.crt \
-keystore test-truststore.jks -storepass changeit
chmod 644 test-truststore.jks
- name: Configure Squid with Standard SSL
run: |
sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.orig
echo "
# Basic Configuration
http_port 3128
# Plain HTTPS port with certificate
https_port 3129 tls-cert=/etc/squid/squid.pem
# Access Control - very permissive for testing
http_access allow all
always_direct allow all
# Avoid DNS issues in test environment
dns_v4_first on
# Disable caching for testing
cache deny all
# Logging
debug_options ALL,1
logfile_rotate 0
cache_log /var/log/squid/cache.log
access_log /var/log/squid/access.log squid
" | sudo tee /etc/squid/squid.conf
sudo mkdir -p /var/log/squid
sudo chown -R proxy:proxy /var/log/squid
sudo chmod 755 /var/log/squid
sudo squid -k parse || echo "Configuration has issues but we'll try to run it anyway"
- name: Start Squid Proxy
run: |
sudo systemctl stop squid || true
sudo pkill squid || true
sudo squid -N -d 3 -f /etc/squid/squid.conf &
sleep 5
ps aux | grep squid
- name: Wait for Squid to be Ready
run: |
for i in {1..5}; do
if curl -v -x http://localhost:3128 http://databricks.com -m 10 -o /dev/null; then
echo "HTTP proxy on 3128 is working!"
break
fi
sleep 3
done
if ps aux | grep -v grep | grep squid > /dev/null; then
echo "Squid is running"
else
echo "Squid is not running! Attempting restart..."
sudo squid -N -d 3 -f /etc/squid/squid.conf &
sleep 5
fi
- name: Install Root CA in System Trust Store
run: |
sudo cp /tmp/ssl-certs/rootCA.crt /usr/local/share/ca-certificates/databricks-test-rootca.crt
sudo update-ca-certificates
- name: Maven Build
run: |
mvn -pl jdbc-core clean package -DskipTests
- name: Run SSL Tests
run: |
mvn -pl jdbc-core test -Dtest=**/SSLTest.java
- name: Cleanup
if: always()
run: |
sudo systemctl stop squid
sudo systemctl disable squid
sudo pkill squid
sudo rm -f /usr/local/share/ca-certificates/databricks-test-rootca.crt
sudo update-ca-certificates --fresh