Skip to content

Commit

Permalink
workflows get rid of mysql_ssl_rsa_setup
Browse files Browse the repository at this point in the history
Generate certificates manually using openssl as the mysql_ssl_rsa_setup
is deprecated.
  • Loading branch information
silverqx committed Jun 8, 2024
1 parent d842b27 commit 15d70d9
Show file tree
Hide file tree
Showing 2 changed files with 238 additions and 16 deletions.
127 changes: 119 additions & 8 deletions .github/workflows/clang-cl-qt6.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,28 +271,137 @@ jobs:
run: |
mysqld.exe --initialize-insecure --console
- name: MySQL generate SSL certificates
# We can't generate certificates first and then initialize MySQL data folder, MySQL throws
# error, it also generates all keys and certificates so we have remove them to generate are own
- name: MySQL SSL certificates remove
working-directory: ${{ env.TinyMySQLDataPath }}
run: >-
Remove-Item ./ca.pem, ./ca-key.pem, ./server-cert.pem, ./server-key.pem,
./client-cert.pem, ./client-key.pem
- name: MySQL SSL certificates initialize
id: openssl-initialize-mysql-certificates
run: |
$folderPath = Join-Path -Path '${{ env.TinyRunnerWorkPath }}' `
-ChildPath 'tiny-mysql-certificates'
# Create an empty folder for generating certificates
New-Item -Type Directory $folderPath
"FolderPath=$folderPath" >> $env:GITHUB_OUTPUT
# This hash invalidates the MySQL certificates cache every month
$hash = Get-Date -Format 'yyyyMM'
"Hash=$hash" >> $env:GITHUB_OUTPUT
- name: MySQL SSL certificates restore cache
uses: actions/cache/restore@v3
id: openssl-cache-mysql-certificates
with:
path: |
${{ env.folder_path }}/*.pem
key: ${{ runner.os }}-openssl-${{ env.cache_name }}-${{ env.cache_hash }}
env:
# This hash invalidates this certificates cache every month
cache_hash: ${{ steps.openssl-initialize-mysql-certificates.outputs.Hash }}
cache_name: mysql-certificates
folder_path: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}

- name: MySQL SSL certificates generate
if: steps.openssl-cache-mysql-certificates.outputs.cache-hit != 'true'
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
run: |
Write-Output '::group::Print openssl version'
openssl.exe version -a
Write-Output '::endgroup::'
Write-Output '::group::Create .rnd file'
openssl.exe rand -out ./.rnd -writerand ./.rnd
Write-Output '::endgroup::'
Write-Output '::group::CA certificate'
# -days 32 is important, -days 30 is not enough
openssl.exe req -new -x509 -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_CA -days 32 `
-keyout ./ca-key.pem -out ./ca.pem
Write-Output '::endgroup::'
Write-Output '::group::Server certificate'
openssl.exe req -new -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_SERVER -keyout ./server-key.pem `
-out ./server-req.pem
$env:OPENSSL_SAN = "DNS:${env:DB_MYSQL_HOST}"
openssl.exe x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 01 `
-extfile $env:extfile -in ./server-req.pem -out ./server-cert.pem
Write-Output '::endgroup::'
Write-Output '::group::Client certificate'
openssl.exe req -new -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_CLIENT `
-keyout ./client-key.pem -out client-req.pem
$env:OPENSSL_SAN = "DNS:${env:DB_MYSQL_HOST_CLIENT}"
openssl.exe x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 02 `
-extfile $env:extfile -in ./client-req.pem -out ./client-cert.pem
Write-Output '::endgroup::'
env:
extfile: ${{ github.workspace }}/.github/resources/openssl/usr_cert.cnf
DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST_SSL }}
DB_MYSQL_HOST_CLIENT: ${{ secrets.DB_MYSQL_HOST_CLIENT_SSL }}
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
DB_MYSQL_SSL_SUBJECT_SERVER: ${{ secrets.DB_MYSQL_SSL_SUBJECT_SERVER }}

# Always verify, regardless if certificates were newly generated or restored from the cache
- name: MySQL SSL certificates verify
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
run: |
openssl.exe verify -CAfile ./ca.pem ./server-cert.pem ./client-cert.pem
# Save the cache only if certificates were newly generated
# The actions/cache/save allows to use the Move-Item during the install step
- name: MySQL SSL certificates save cache
if: steps.openssl-cache-mysql-certificates.outputs.cache-hit != 'true'
uses: actions/cache/save@v3
with:
path: |
${{ env.folder_path }}/*.pem
key: ${{ steps.openssl-cache-mysql-certificates.outputs.cache-primary-key }}
env:
folder_path: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}

- name: MySQL SSL certificates install
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
run: |
# It's enough to remove only these three certificate-related files
Remove-Item ./ca.pem, ./server-cert.pem, ./server-key.pem
mysql_ssl_rsa_setup.exe --suffix=TinyORM
Write-Output '::group::Install CA certificate'
Move-Item -Path ./ca.pem -Destination '${{ env.TinyMySQLDataPath }}'
Write-Output '::endgroup::'
Write-Output '::group::Install server certificates'
Move-Item -Path ./server-cert.pem, ./server-key.pem `
-Destination '${{ env.TinyMySQLDataPath }}'
Write-Output '::endgroup::'
Write-Output '::group::Install client certificates'
Move-Item -Path ./client-cert.pem, ./client-key.pem `
-Destination '${{ env.TinyMySQLDataPath }}'
Write-Output '::endgroup::'
- name: MySQL service install/start
run: |
mysqld.exe --install MySQL
Start-Service MySQL
# Securing the root account even on localhost is for testing to make sure that everything
# works as expected
- name: MySQL change ${{ secrets.DB_MYSQL_ROOT_USERNAME }} password
run: >-
"alter user '$env:DB_MYSQL_ROOT_USERNAME'@'localhost'
identified with caching_sha2_password by '$env:DB_MYSQL_ROOT_PASSWORD'
require issuer '/CN=MySQL_Server_TinyORM_Auto_Generated_CA_Certificate' and
subject '/CN=MySQL_Server_TinyORM_Auto_Generated_Client_Certificate';" |
require issuer '${{ env.DB_MYSQL_SSL_SUBJECT_CA }}' and
subject '${{ env.DB_MYSQL_SSL_SUBJECT_CLIENT }}';" |
mysql.exe --user=$env:DB_MYSQL_ROOT_USERNAME --skip-password
env:
DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }}
DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }}
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}

- name: MySQL time zone POSIX tables initialize download
id: downloads-initialize-mysql-timezone-tables
Expand Down Expand Up @@ -390,8 +499,8 @@ jobs:
run: >-
"create user '$env:DB_MYSQL_USERNAME'@'%'
identified with caching_sha2_password by '$env:DB_MYSQL_PASSWORD'
require issuer '/CN=MySQL_Server_TinyORM_Auto_Generated_CA_Certificate' and
subject '/CN=MySQL_Server_TinyORM_Auto_Generated_Client_Certificate';
require issuer '${{ env.DB_MYSQL_SSL_SUBJECT_CA }}' and
subject '${{ env.DB_MYSQL_SSL_SUBJECT_CLIENT }}';
grant all privileges on ``tinyorm\_%``.* to '$env:DB_MYSQL_USERNAME'@'%';
grant select on ``mysql``.``time_zone_name`` to '$env:DB_MYSQL_USERNAME'@'%';
flush privileges;" |
Expand All @@ -400,6 +509,8 @@ jobs:
DB_MYSQL_PASSWORD: ${{ secrets.DB_MYSQL_PASSWORD }}
DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }}
DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }}
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
DB_MYSQL_USERNAME: ${{ secrets.DB_MYSQL_USERNAME }}

- name: MySQL add libmysql.dll on the $env:Path, INCLUDE, and LIB
Expand Down
127 changes: 119 additions & 8 deletions .github/workflows/msvc2022-qt6.yml
Original file line number Diff line number Diff line change
Expand Up @@ -284,28 +284,137 @@ jobs:
run: |
mysqld.exe --initialize-insecure --console
- name: MySQL generate SSL certificates
# We can't generate certificates first and then initialize MySQL data folder, MySQL throws
# error, it also generates all keys and certificates so we have remove them to generate are own
- name: MySQL SSL certificates remove
working-directory: ${{ env.TinyMySQLDataPath }}
run: >-
Remove-Item ./ca.pem, ./ca-key.pem, ./server-cert.pem, ./server-key.pem,
./client-cert.pem, ./client-key.pem
- name: MySQL SSL certificates initialize
id: openssl-initialize-mysql-certificates
run: |
$folderPath = Join-Path -Path '${{ env.TinyRunnerWorkPath }}' `
-ChildPath 'tiny-mysql-certificates'
# Create an empty folder for generating certificates
New-Item -Type Directory $folderPath
"FolderPath=$folderPath" >> $env:GITHUB_OUTPUT
# This hash invalidates the MySQL certificates cache every month
$hash = Get-Date -Format 'yyyyMM'
"Hash=$hash" >> $env:GITHUB_OUTPUT
- name: MySQL SSL certificates restore cache
uses: actions/cache/restore@v3
id: openssl-cache-mysql-certificates
with:
path: |
${{ env.folder_path }}/*.pem
key: ${{ runner.os }}-openssl-${{ env.cache_name }}-${{ env.cache_hash }}
env:
# This hash invalidates this certificates cache every month
cache_hash: ${{ steps.openssl-initialize-mysql-certificates.outputs.Hash }}
cache_name: mysql-certificates
folder_path: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}

- name: MySQL SSL certificates generate
if: steps.openssl-cache-mysql-certificates.outputs.cache-hit != 'true'
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
run: |
Write-Output '::group::Print openssl version'
openssl.exe version -a
Write-Output '::endgroup::'
Write-Output '::group::Create .rnd file'
openssl.exe rand -out ./.rnd -writerand ./.rnd
Write-Output '::endgroup::'
Write-Output '::group::CA certificate'
# -days 32 is important, -days 30 is not enough
openssl.exe req -new -x509 -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_CA -days 32 `
-keyout ./ca-key.pem -out ./ca.pem
Write-Output '::endgroup::'
Write-Output '::group::Server certificate'
openssl.exe req -new -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_SERVER -keyout ./server-key.pem `
-out ./server-req.pem
$env:OPENSSL_SAN = "DNS:${env:DB_MYSQL_HOST}"
openssl.exe x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 01 `
-extfile $env:extfile -in ./server-req.pem -out ./server-cert.pem
Write-Output '::endgroup::'
Write-Output '::group::Client certificate'
openssl.exe req -new -nodes -subj $env:DB_MYSQL_SSL_SUBJECT_CLIENT `
-keyout ./client-key.pem -out client-req.pem
$env:OPENSSL_SAN = "DNS:${env:DB_MYSQL_HOST_CLIENT}"
openssl.exe x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 02 `
-extfile $env:extfile -in ./client-req.pem -out ./client-cert.pem
Write-Output '::endgroup::'
env:
extfile: ${{ github.workspace }}/.github/resources/openssl/usr_cert.cnf
DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST_SSL }}
DB_MYSQL_HOST_CLIENT: ${{ secrets.DB_MYSQL_HOST_CLIENT_SSL }}
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
DB_MYSQL_SSL_SUBJECT_SERVER: ${{ secrets.DB_MYSQL_SSL_SUBJECT_SERVER }}

# Always verify, regardless if certificates were newly generated or restored from the cache
- name: MySQL SSL certificates verify
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
run: |
openssl.exe verify -CAfile ./ca.pem ./server-cert.pem ./client-cert.pem
# Save the cache only if certificates were newly generated
# The actions/cache/save allows to use the Move-Item during the install step
- name: MySQL SSL certificates save cache
if: steps.openssl-cache-mysql-certificates.outputs.cache-hit != 'true'
uses: actions/cache/save@v3
with:
path: |
${{ env.folder_path }}/*.pem
key: ${{ steps.openssl-cache-mysql-certificates.outputs.cache-primary-key }}
env:
folder_path: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}

- name: MySQL SSL certificates install
working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }}
run: |
# It's enough to remove only these three certificate-related files
Remove-Item ./ca.pem, ./server-cert.pem, ./server-key.pem
mysql_ssl_rsa_setup.exe --suffix=TinyORM
Write-Output '::group::Install CA certificate'
Move-Item -Path ./ca.pem -Destination '${{ env.TinyMySQLDataPath }}'
Write-Output '::endgroup::'
Write-Output '::group::Install server certificates'
Move-Item -Path ./server-cert.pem, ./server-key.pem `
-Destination '${{ env.TinyMySQLDataPath }}'
Write-Output '::endgroup::'
Write-Output '::group::Install client certificates'
Move-Item -Path ./client-cert.pem, ./client-key.pem `
-Destination '${{ env.TinyMySQLDataPath }}'
Write-Output '::endgroup::'
- name: MySQL service install/start
run: |
mysqld.exe --install MySQL
Start-Service MySQL
# Securing the root account even on localhost is for testing to make sure that everything
# works as expected
- name: MySQL change ${{ secrets.DB_MYSQL_ROOT_USERNAME }} password
run: >-
"alter user '$env:DB_MYSQL_ROOT_USERNAME'@'localhost'
identified with caching_sha2_password by '$env:DB_MYSQL_ROOT_PASSWORD'
require issuer '/CN=MySQL_Server_TinyORM_Auto_Generated_CA_Certificate' and
subject '/CN=MySQL_Server_TinyORM_Auto_Generated_Client_Certificate';" |
require issuer '${{ env.DB_MYSQL_SSL_SUBJECT_CA }}' and
subject '${{ env.DB_MYSQL_SSL_SUBJECT_CLIENT }}';" |
mysql.exe --user=$env:DB_MYSQL_ROOT_USERNAME --skip-password
env:
DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }}
DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }}
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}

- name: MySQL time zone POSIX tables initialize download
id: downloads-initialize-mysql-timezone-tables
Expand Down Expand Up @@ -403,8 +512,8 @@ jobs:
run: >-
"create user '$env:DB_MYSQL_USERNAME'@'%'
identified with caching_sha2_password by '$env:DB_MYSQL_PASSWORD'
require issuer '/CN=MySQL_Server_TinyORM_Auto_Generated_CA_Certificate' and
subject '/CN=MySQL_Server_TinyORM_Auto_Generated_Client_Certificate';
require issuer '${{ env.DB_MYSQL_SSL_SUBJECT_CA }}' and
subject '${{ env.DB_MYSQL_SSL_SUBJECT_CLIENT }}';
grant all privileges on ``tinyorm\_%``.* to '$env:DB_MYSQL_USERNAME'@'%';
grant select on ``mysql``.``time_zone_name`` to '$env:DB_MYSQL_USERNAME'@'%';
flush privileges;" |
Expand All @@ -413,6 +522,8 @@ jobs:
DB_MYSQL_PASSWORD: ${{ secrets.DB_MYSQL_PASSWORD }}
DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }}
DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }}
DB_MYSQL_SSL_SUBJECT_CA: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CA }}
DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }}
DB_MYSQL_USERNAME: ${{ secrets.DB_MYSQL_USERNAME }}

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

0 comments on commit 15d70d9

Please sign in to comment.