diff --git a/.github/workflows/clang-cl-qt6.yml b/.github/workflows/clang-cl-qt6.yml index 8d117585f..1d0c7b3c6 100644 --- a/.github/workflows/clang-cl-qt6.yml +++ b/.github/workflows/clang-cl-qt6.yml @@ -270,28 +270,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 @@ -389,8 +498,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;" | @@ -399,6 +508,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 diff --git a/.github/workflows/linux-qt6.yml b/.github/workflows/linux-qt6.yml index 124e22e84..cb6b175bc 100644 --- a/.github/workflows/linux-qt6.yml +++ b/.github/workflows/linux-qt6.yml @@ -279,11 +279,13 @@ jobs: pg_isready echo '::endgroup::' + # Adding the DB_MYSQL_HOST_CLIENT isn't strictly needed (works without it too) - name: Hosts add MySQL server hostname run: >- - sudo -- sh -c "echo '127.0.0.1\t$DB_MYSQL_HOST' >> /etc/hosts" + sudo -- sh -c "echo '127.0.0.1\t$DB_MYSQL_HOST $DB_MYSQL_HOST_CLIENT' >> /etc/hosts" env: DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST_SSL }} + DB_MYSQL_HOST_CLIENT: ${{ secrets.DB_MYSQL_HOST_CLIENT_SSL }} - name: MySQL initialize crystal_mysqld.cnf configuration working-directory: .github/resources/linux @@ -300,11 +302,136 @@ jobs: env: DB_MYSQL_HOST: ${{ secrets.DB_MYSQL_HOST_SSL }} - - name: MySQL generate SSL certificates + # Remove certificates to generate are own + - name: MySQL SSL certificates remove + run: >- + sudo --user=mysql -- + rm /var/lib/mysql/{ca,ca-key,server-cert,server-key,client-cert,client-key}.pem + + - name: MySQL SSL certificates initialize + id: openssl-initialize-mysql-certificates + run: | + folderPath='${{ env.TinyRunnerWorkPath }}/tiny-mysql-certificates' + + # Create an empty folder for generating certificates + sudo mkdir "$folderPath" + sudo chown runner:docker "$folderPath" + + echo "FolderPath=$folderPath" >> $GITHUB_OUTPUT + + # This hash invalidates the MySQL certificates cache every month + hash=$(date +%4Y%2m) + echo "Hash=$hash" >> $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: | + echo '::group::Print openssl version' + openssl version -a + echo '::endgroup::' + + echo '::group::CA certificate' + # -days 32 is important, -days 30 is not enough + openssl req -new -x509 -nodes -subj "$DB_MYSQL_SSL_SUBJECT_CA" -days 32 \ + -keyout ./ca-key.pem -out ./ca.pem + echo '::endgroup::' + + echo '::group::Server certificate' + openssl req -new -nodes -subj "$DB_MYSQL_SSL_SUBJECT_SERVER" -keyout ./server-key.pem -out \ + ./server-req.pem + OPENSSL_SAN="DNS:${DB_MYSQL_HOST}" \ + openssl x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 01 \ + -extfile "$extfile" -in ./server-req.pem -out ./server-cert.pem + echo '::endgroup::' + + echo '::group::Client certificate' + openssl req -new -nodes -subj "$DB_MYSQL_SSL_SUBJECT_CLIENT" -keyout ./client-key.pem \ + -out ./client-req.pem + OPENSSL_SAN="DNS:${DB_MYSQL_HOST_CLIENT}" \ + openssl x509 -req -CA ./ca.pem -CAkey ./ca-key.pem -days 32 -set_serial 02 \ + -extfile "$extfile" -in ./client-req.pem -out ./client-cert.pem + echo '::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_SERVER: ${{ secrets.DB_MYSQL_SSL_SUBJECT_SERVER }} + DB_MYSQL_SSL_SUBJECT_CLIENT: ${{ secrets.DB_MYSQL_SSL_SUBJECT_CLIENT }} + + - name: MySQL SSL certificates print + working-directory: ${{ steps.openssl-initialize-mysql-certificates.outputs.FolderPath }} + run: | + echo '::group::CA certificate' + openssl x509 -noout -text -in ./ca.pem + echo '::endgroup::' + + echo '::group::Server certificate' + openssl x509 -noout -text -in ./server-cert.pem + echo '::endgroup::' + + echo '::group::Client certificate' + openssl x509 -noout -text -in ./client-cert.pem + echo '::endgroup::' + + # 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 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 - sudo --user=mysql -- rm /var/lib/mysql/{ca,server-cert,server-key}.pem - sudo mysql_ssl_rsa_setup --suffix=TinyORM --uid=mysql + mysqlDataPath=/var/lib/mysql + + echo '::group::Install CA certificate' + sudo mv --target-directory="$mysqlDataPath" ./ca.pem + sudo chmod 644 "$mysqlDataPath/ca.pem" + sudo chown mysql:mysql "$mysqlDataPath/ca.pem" + echo '::endgroup::' + + echo '::group::Install server certificates' + sudo mv --target-directory="$mysqlDataPath" ./server-{cert,key}.pem + sudo chmod 640 "$mysqlDataPath/server-cert.pem" + sudo chmod 600 "$mysqlDataPath/server-key.pem" + sudo chown mysql:mysql "$mysqlDataPath"/server-{cert,key}.pem + echo '::endgroup::' + + echo '::group::Install client certificates' + sudo mv --target-directory="$mysqlDataPath" ./client-{cert,key}.pem + sudo chmod 640 "$mysqlDataPath/client-cert.pem" + sudo chmod 600 "$mysqlDataPath/client-key.pem" + sudo chown mysql:mysql "$mysqlDataPath"/client-{cert,key}.pem + echo '::endgroup::' + env: + pg_data_path: ${{ steps.databases-initialize-mysql.outputs.PgDataPath }} - name: MySQL copy SSL certificates for runner user run: | @@ -323,18 +450,22 @@ jobs: run: | sudo systemctl start mysql.service + # 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: >- echo " alter user '$DB_MYSQL_ROOT_USERNAME'@'localhost' identified with caching_sha2_password by '$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 '$DB_MYSQL_SSL_SUBJECT_CA' and + subject '$DB_MYSQL_SSL_SUBJECT_CLIENT';" | mysql --user="$DB_MYSQL_ROOT_USERNAME" --password="$DB_MYSQL_ROOT_PASSWORD_DEFAULT" env: DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }} DB_MYSQL_ROOT_PASSWORD_DEFAULT: ${{ secrets.DB_MYSQL_ROOT_PASSWORD_DEFAULT }} 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 populate time zone tables 👌 run: >- @@ -382,8 +513,8 @@ jobs: echo " create user '$DB_MYSQL_USERNAME'@'%' identified with caching_sha2_password by '$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 '$DB_MYSQL_SSL_SUBJECT_CA' and + subject '$DB_MYSQL_SSL_SUBJECT_CLIENT'; grant all privileges on \`tinyorm\\_%\`.* to '$DB_MYSQL_USERNAME'@'%'; grant select on \`mysql\`.\`time_zone_name\` to '$DB_MYSQL_USERNAME'@'%'; flush privileges;" | @@ -393,6 +524,15 @@ jobs: DB_MYSQL_ROOT_PASSWORD: ${{ secrets.DB_MYSQL_ROOT_PASSWORD }} DB_MYSQL_ROOT_USERNAME: ${{ secrets.DB_MYSQL_ROOT_USERNAME }} DB_MYSQL_USERNAME: ${{ secrets.DB_MYSQL_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 test TinyORM user + run: | + mysql --user="$DB_MYSQL_USERNAME" --password="$DB_MYSQL_PASSWORD" + env: + DB_MYSQL_PASSWORD: ${{ secrets.DB_MYSQL_PASSWORD }} + DB_MYSQL_USERNAME: ${{ secrets.DB_MYSQL_USERNAME }} - name: SQLite create TinyORM database run: | diff --git a/.github/workflows/msvc2022-qt6.yml b/.github/workflows/msvc2022-qt6.yml index ec6c06a9c..a2a9f18cf 100644 --- a/.github/workflows/msvc2022-qt6.yml +++ b/.github/workflows/msvc2022-qt6.yml @@ -283,28 +283,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 @@ -402,8 +511,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;" | @@ -412,6 +521,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