Skip to content

Commit cd006e6

Browse files
committed
workflows get rid of mysql_ssl_rsa_setup
Generate certificates manually using openssl as the mysql_ssl_rsa_setup is deprecated.
1 parent 32c1e93 commit cd006e6

File tree

3 files changed

+387
-25
lines changed

3 files changed

+387
-25
lines changed

.github/workflows/clang-cl-qt6.yml

Lines changed: 119 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,28 +270,137 @@ jobs:
270270
run: |
271271
mysqld.exe --initialize-insecure --console
272272
273-
- name: MySQL generate SSL certificates
273+
# We can't generate certificates first and then initialize MySQL data folder, MySQL throws
274+
# error, it also generates all keys and certificates so we have remove them to generate are own
275+
- name: MySQL SSL certificates remove
274276
working-directory: ${{ env.TinyMySQLDataPath }}
277+
run: >-
278+
Remove-Item ./ca.pem, ./ca-key.pem, ./server-cert.pem, ./server-key.pem,
279+
./client-cert.pem, ./client-key.pem
280+
281+
- name: MySQL SSL certificates initialize
282+
id: openssl-initialize-mysql-certificates
283+
run: |
284+
$folderPath = Join-Path -Path '${{ env.TinyRunnerWorkPath }}' `
285+
-ChildPath 'tiny-mysql-certificates'
286+
287+
# Create an empty folder for generating certificates
288+
New-Item -Type Directory $folderPath
289+
290+
"FolderPath=$folderPath" >> $env:GITHUB_OUTPUT
291+
292+
# This hash invalidates the MySQL certificates cache every month
293+
$hash = Get-Date -Format 'yyyyMM'
294+
"Hash=$hash" >> $env:GITHUB_OUTPUT
295+
296+
- name: MySQL SSL certificates restore cache
297+
uses: actions/cache/restore@v3
298+
id: openssl-cache-mysql-certificates
299+
with:
300+
path: |
301+
${{ env.folder_path }}/*.pem
302+
key: ${{ runner.os }}-openssl-${{ env.cache_name }}-${{ env.cache_hash }}
303+
env:
304+
# This hash invalidates this certificates cache every month
305+
cache_hash: ${{ steps.openssl-initialize-mysql-certificates.outputs.Hash }}
306+
cache_name: mysql-certificates
307+
folder_path: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
308+
309+
- name: MySQL SSL certificates generate
310+
if: steps.openssl-cache-mysql-certificates.outputs.cache-hit != 'true'
311+
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
312+
run: |
313+
Write-Output '::group::Print openssl version'
314+
openssl.exe version -a
315+
Write-Output '::endgroup::'
316+
317+
Write-Output '::group::Create .rnd file'
318+
openssl.exe rand -out ./.rnd -writerand ./.rnd
319+
Write-Output '::endgroup::'
320+
321+
Write-Output '::group::CA certificate'
322+
# -days 32 is important, -days 30 is not enough
323+
openssl.exe req -new -x509 -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_CA -days 32 `
324+
-keyout ./ca-key.pem -out ./ca.pem
325+
Write-Output '::endgroup::'
326+
327+
Write-Output '::group::Server certificate'
328+
openssl.exe req -new -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_SERVER -keyout ./server-key.pem `
329+
-out ./server-req.pem
330+
$env:OPENSSL_SAN = "DNS:${env:DB_MYSQL_HOST}"
331+
openssl.exe x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 01 `
332+
-extfile $env:extfile -in ./server-req.pem -out ./server-cert.pem
333+
Write-Output '::endgroup::'
334+
335+
Write-Output '::group::Client certificate'
336+
openssl.exe req -new -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_CLIENT `
337+
-keyout ./client-key.pem -out client-req.pem
338+
$env:OPENSSL_SAN = "DNS:${env:DB_MYSQL_HOST_CLIENT}"
339+
openssl.exe x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 02 `
340+
-extfile $env:extfile -in ./client-req.pem -out ./client-cert.pem
341+
Write-Output '::endgroup::'
342+
env:
343+
extfile: ${{ github.workspace }}/.github/resources/openssl/usr_cert.cnf
344+
DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST_SSL }}
345+
DB_MYSQL_HOST_CLIENT: ${{ secrets.DB_MYSQL_HOST_CLIENT_SSL }}
346+
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
347+
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
348+
DB_MYSQL_SSL_SUBJECT_SERVER: ${{ secrets.DB_MYSQL_SSL_SUBJECT_SERVER }}
349+
350+
# Always verify, regardless if certificates were newly generated or restored from the cache
351+
- name: MySQL SSL certificates verify
352+
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
353+
run: |
354+
openssl.exe verify -CAfile ./ca.pem ./server-cert.pem ./client-cert.pem
355+
356+
# Save the cache only if certificates were newly generated
357+
# The actions/cache/save allows to use the Move-Item during the install step
358+
- name: MySQL SSL certificates save cache
359+
if: steps.openssl-cache-mysql-certificates.outputs.cache-hit != 'true'
360+
uses: actions/cache/save@v3
361+
with:
362+
path: |
363+
${{ env.folder_path }}/*.pem
364+
key: ${{ steps.openssl-cache-mysql-certificates.outputs.cache-primary-key }}
365+
env:
366+
folder_path: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
367+
368+
- name: MySQL SSL certificates install
369+
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
275370
run: |
276-
# It's enough to remove only these three certificate-related files
277-
Remove-Item ./ca.pem, ./server-cert.pem, ./server-key.pem
278-
mysql_ssl_rsa_setup.exe --suffix=TinyORM
371+
Write-Output '::group::Install CA certificate'
372+
Move-Item -Path ./ca.pem -Destination '${{ env.TinyMySQLDataPath }}'
373+
Write-Output '::endgroup::'
374+
375+
Write-Output '::group::Install server certificates'
376+
Move-Item -Path ./server-cert.pem, ./server-key.pem `
377+
-Destination '${{ env.TinyMySQLDataPath }}'
378+
Write-Output '::endgroup::'
379+
380+
Write-Output '::group::Install client certificates'
381+
Move-Item -Path ./client-cert.pem, ./client-key.pem `
382+
-Destination '${{ env.TinyMySQLDataPath }}'
383+
Write-Output '::endgroup::'
279384
280385
- name: MySQL service install/start
281386
run: |
282387
mysqld.exe --install MySQL
283388
Start-Service MySQL
284389
390+
# Securing the root account even on localhost is for testing to make sure that everything
391+
# works as expected
285392
- name: MySQL change ${{ secrets.DB_MYSQL_ROOT_USERNAME }} password
286393
run: >-
287394
"alter user '$env:DB_MYSQL_ROOT_USERNAME'@'localhost'
288395
identified with caching_sha2_password by '$env:DB_MYSQL_ROOT_PASSWORD'
289-
require issuer '/CN=MySQL_Server_TinyORM_Auto_Generated_CA_Certificate' and
290-
subject '/CN=MySQL_Server_TinyORM_Auto_Generated_Client_Certificate';" |
396+
require issuer '${{ env.DB_MYSQL_SSL_SUBJECT_CA }}' and
397+
subject '${{ env.DB_MYSQL_SSL_SUBJECT_CLIENT }}';" |
291398
mysql.exe --user=$env:DB_MYSQL_ROOT_USERNAME --skip-password
292399
env:
293400
DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }}
294401
DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }}
402+
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
403+
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
295404

296405
- name: MySQL time zone POSIX tables initialize download
297406
id: downloads-initialize-mysql-timezone-tables
@@ -389,8 +498,8 @@ jobs:
389498
run: >-
390499
"create user '$env:DB_MYSQL_USERNAME'@'%'
391500
identified with caching_sha2_password by '$env:DB_MYSQL_PASSWORD'
392-
require issuer '/CN=MySQL_Server_TinyORM_Auto_Generated_CA_Certificate' and
393-
subject '/CN=MySQL_Server_TinyORM_Auto_Generated_Client_Certificate';
501+
require issuer '${{ env.DB_MYSQL_SSL_SUBJECT_CA }}' and
502+
subject '${{ env.DB_MYSQL_SSL_SUBJECT_CLIENT }}';
394503
grant all privileges on ``tinyorm\_%``.* to '$env:DB_MYSQL_USERNAME'@'%';
395504
grant select on ``mysql``.``time_zone_name`` to '$env:DB_MYSQL_USERNAME'@'%';
396505
flush privileges;" |
@@ -399,6 +508,8 @@ jobs:
399508
DB_MYSQL_PASSWORD: ${{ secrets.DB_MYSQL_PASSWORD }}
400509
DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }}
401510
DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }}
511+
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
512+
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
402513
DB_MYSQL_USERNAME: ${{ secrets.DB_MYSQL_USERNAME }}
403514

404515
- name: MySQL add libmysql.dll on the $env:Path, INCLUDE, and LIB

.github/workflows/linux-qt6.yml

Lines changed: 149 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,13 @@ jobs:
279279
pg_isready
280280
echo '::endgroup::'
281281
282+
# Adding the DB_MYSQL_HOST_CLIENT isn't strictly needed (works without it too)
282283
- name: Hosts add MySQL server hostname
283284
run: >-
284-
sudo -- sh -c "echo '127.0.0.1\t$DB_MYSQL_HOST' >> /etc/hosts"
285+
sudo -- sh -c "echo '127.0.0.1\t$DB_MYSQL_HOST $DB_MYSQL_HOST_CLIENT' >> /etc/hosts"
285286
env:
286287
DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST_SSL }}
288+
DB_MYSQL_HOST_CLIENT: ${{ secrets.DB_MYSQL_HOST_CLIENT_SSL }}
287289

288290
- name: MySQL initialize crystal_mysqld.cnf configuration
289291
working-directory: .github/resources/linux
@@ -300,11 +302,136 @@ jobs:
300302
env:
301303
DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST_SSL }}
302304

303-
- name: MySQL generate SSL certificates
305+
# Remove certificates to generate are own
306+
- name: MySQL SSL certificates remove
307+
run: >-
308+
sudo --user=mysql --
309+
rm /var/lib/mysql/{ca,ca-key,server-cert,server-key,client-cert,client-key}.pem
310+
311+
- name: MySQL SSL certificates initialize
312+
id: openssl-initialize-mysql-certificates
313+
run: |
314+
folderPath='${{ env.TinyRunnerWorkPath }}/tiny-mysql-certificates'
315+
316+
# Create an empty folder for generating certificates
317+
sudo mkdir "$folderPath"
318+
sudo chown runner:docker "$folderPath"
319+
320+
echo "FolderPath=$folderPath" >> $GITHUB_OUTPUT
321+
322+
# This hash invalidates the MySQL certificates cache every month
323+
hash=$(date +%4Y%2m)
324+
echo "Hash=$hash" >> $GITHUB_OUTPUT
325+
326+
- name: MySQL SSL certificates restore cache
327+
uses: actions/cache/restore@v3
328+
id: openssl-cache-mysql-certificates
329+
with:
330+
path: |
331+
${{ env.folder_path }}/*.pem
332+
key: ${{ runner.os }}-openssl-${{ env.cache_name }}-${{ env.cache_hash }}
333+
env:
334+
# This hash invalidates this certificates cache every month
335+
cache_hash: ${{ steps.openssl-initialize-mysql-certificates.outputs.Hash }}
336+
cache_name: mysql-certificates
337+
folder_path: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
338+
339+
- name: MySQL SSL certificates generate
340+
if: steps.openssl-cache-mysql-certificates.outputs.cache-hit != 'true'
341+
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
342+
run: |
343+
echo '::group::Print openssl version'
344+
openssl version -a
345+
echo '::endgroup::'
346+
347+
echo '::group::CA certificate'
348+
# -days 32 is important, -days 30 is not enough
349+
openssl req -new -x509 -nodes -subj "$DB_MYSQL_SSL_SUBJECT_CA" -days 32 \
350+
-keyout ./ca-key.pem -out ./ca.pem
351+
echo '::endgroup::'
352+
353+
echo '::group::Server certificate'
354+
openssl req -new -nodes -subj "$DB_MYSQL_SSL_SUBJECT_SERVER" -keyout ./server-key.pem -out \
355+
./server-req.pem
356+
OPENSSL_SAN="DNS:${DB_MYSQL_HOST}" \
357+
openssl x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 01 \
358+
-extfile "$extfile" -in ./server-req.pem -out ./server-cert.pem
359+
echo '::endgroup::'
360+
361+
echo '::group::Client certificate'
362+
openssl req -new -nodes -subj "$DB_MYSQL_SSL_SUBJECT_CLIENT" -keyout ./client-key.pem \
363+
-out ./client-req.pem
364+
OPENSSL_SAN="DNS:${DB_MYSQL_HOST_CLIENT}" \
365+
openssl x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 02 \
366+
-extfile "$extfile" -in ./client-req.pem -out ./client-cert.pem
367+
echo '::endgroup::'
368+
env:
369+
extfile: ${{ github.workspace }}/.github/resources/openssl/usr_cert.cnf
370+
DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST_SSL }}
371+
DB_MYSQL_HOST_CLIENT: ${{ secrets.DB_MYSQL_HOST_CLIENT_SSL }}
372+
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
373+
DB_MYSQL_SSL_SUBJECT_SERVER: ${{ secrets.DB_MYSQL_SSL_SUBJECT_SERVER }}
374+
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
375+
376+
- name: MySQL SSL certificates print
377+
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
378+
run: |
379+
echo '::group::CA certificate'
380+
openssl x509 -noout -text -in ./ca.pem
381+
echo '::endgroup::'
382+
383+
echo '::group::Server certificate'
384+
openssl x509 -noout -text -in ./server-cert.pem
385+
echo '::endgroup::'
386+
387+
echo '::group::Client certificate'
388+
openssl x509 -noout -text -in ./client-cert.pem
389+
echo '::endgroup::'
390+
391+
# Always verify, regardless if certificates were newly generated or restored from the cache
392+
- name: MySQL SSL certificates verify
393+
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
394+
run: |
395+
openssl verify -CAfile ./ca.pem ./server-cert.pem ./client-cert.pem
396+
397+
# Save the cache only if certificates were newly generated
398+
# The actions/cache/save allows to use the Move-Item during the install step
399+
- name: MySQL SSL certificates save cache
400+
if: steps.openssl-cache-mysql-certificates.outputs.cache-hit != 'true'
401+
uses: actions/cache/save@v3
402+
with:
403+
path: |
404+
${{ env.folder_path }}/*.pem
405+
key: ${{ steps.openssl-cache-mysql-certificates.outputs.cache-primary-key }}
406+
env:
407+
folder_path: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
408+
409+
- name: MySQL SSL certificates install
410+
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
304411
run: |
305-
# It's enough to remove only these three certificate-related files
306-
sudo --user=mysql -- rm /var/lib/mysql/{ca,server-cert,server-key}.pem
307-
sudo mysql_ssl_rsa_setup --suffix=TinyORM --uid=mysql
412+
mysqlDataPath=/var/lib/mysql
413+
414+
echo '::group::Install CA certificate'
415+
sudo mv --target-directory="$mysqlDataPath" ./ca.pem
416+
sudo chmod 644 "$mysqlDataPath/ca.pem"
417+
sudo chown mysql:mysql "$mysqlDataPath/ca.pem"
418+
echo '::endgroup::'
419+
420+
echo '::group::Install server certificates'
421+
sudo mv --target-directory="$mysqlDataPath" ./server-{cert,key}.pem
422+
sudo chmod 640 "$mysqlDataPath/server-cert.pem"
423+
sudo chmod 600 "$mysqlDataPath/server-key.pem"
424+
sudo chown mysql:mysql "$mysqlDataPath"/server-{cert,key}.pem
425+
echo '::endgroup::'
426+
427+
echo '::group::Install client certificates'
428+
sudo mv --target-directory="$mysqlDataPath" ./client-{cert,key}.pem
429+
sudo chmod 640 "$mysqlDataPath/client-cert.pem"
430+
sudo chmod 600 "$mysqlDataPath/client-key.pem"
431+
sudo chown mysql:mysql "$mysqlDataPath"/client-{cert,key}.pem
432+
echo '::endgroup::'
433+
env:
434+
pg_data_path: ${{ steps.databases-initialize-mysql.outputs.PgDataPath }}
308435

309436
- name: MySQL copy SSL certificates for runner user
310437
run: |
@@ -323,18 +450,22 @@ jobs:
323450
run: |
324451
sudo systemctl start mysql.service
325452
453+
# Securing the root account even on localhost is for testing to make sure that everything
454+
# works as expected
326455
- name: MySQL change ${{ secrets.DB_MYSQL_ROOT_USERNAME }} password
327456
run: >-
328457
echo "
329458
alter user '$DB_MYSQL_ROOT_USERNAME'@'localhost'
330459
identified with caching_sha2_password by '$DB_MYSQL_ROOT_PASSWORD'
331-
require issuer '/CN=MySQL_Server_TinyORM_Auto_Generated_CA_Certificate' and
332-
subject '/CN=MySQL_Server_TinyORM_Auto_Generated_Client_Certificate';" |
460+
require issuer '$DB_MYSQL_SSL_SUBJECT_CA' and
461+
subject '$DB_MYSQL_SSL_SUBJECT_CLIENT';" |
333462
mysql --user="$DB_MYSQL_ROOT_USERNAME" --password="$DB_MYSQL_ROOT_PASSWORD_DEFAULT"
334463
env:
335464
DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }}
336465
DB_MYSQL_ROOT_PASSWORD_DEFAULT: ${{ secrets.DB_MYSQL_ROOT_PASSWORD_DEFAULT }}
337466
DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }}
467+
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
468+
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
338469

339470
- name: MySQL populate time zone tables 👌
340471
run: >-
@@ -382,8 +513,8 @@ jobs:
382513
echo "
383514
create user '$DB_MYSQL_USERNAME'@'%'
384515
identified with caching_sha2_password by '$DB_MYSQL_PASSWORD'
385-
require issuer '/CN=MySQL_Server_TinyORM_Auto_Generated_CA_Certificate' and
386-
subject '/CN=MySQL_Server_TinyORM_Auto_Generated_Client_Certificate';
516+
require issuer '$DB_MYSQL_SSL_SUBJECT_CA' and
517+
subject '$DB_MYSQL_SSL_SUBJECT_CLIENT';
387518
grant all privileges on \`tinyorm\\_%\`.* to '$DB_MYSQL_USERNAME'@'%';
388519
grant select on \`mysql\`.\`time_zone_name\` to '$DB_MYSQL_USERNAME'@'%';
389520
flush privileges;" |
@@ -393,6 +524,15 @@ jobs:
393524
DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }}
394525
DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }}
395526
DB_MYSQL_USERNAME: ${{ secrets.DB_MYSQL_USERNAME }}
527+
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
528+
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
529+
530+
- name: MySQL test TinyORM user
531+
run: |
532+
mysql --user="$DB_MYSQL_USERNAME" --password="$DB_MYSQL_PASSWORD"
533+
env:
534+
DB_MYSQL_PASSWORD: ${{ secrets.DB_MYSQL_PASSWORD }}
535+
DB_MYSQL_USERNAME: ${{ secrets.DB_MYSQL_USERNAME }}
396536

397537
- name: SQLite create TinyORM database
398538
run: |

0 commit comments

Comments
 (0)