Skip to content

Commit

Permalink
Support force encryption for the MSSQL server
Browse files Browse the repository at this point in the history
  • Loading branch information
andyundso committed Jul 27, 2024
1 parent 1149cc8 commit 804915f
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 6 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ jobs:
name: Tests
strategy:
matrix:
force-encryption:
- "true"
- "false"
os:
# ignore ARM64 flavours
- ubuntu-20.04
Expand All @@ -22,7 +25,12 @@ jobs:
version:
- 2017
exclude:
- os: ubuntu-24.04
- force-encryption: "true"
os: ubuntu-24.04
version: 2017

- force-encryption: "false"
os: ubuntu-24.04
version: 2017

runs-on: ${{ matrix.os }}
Expand All @@ -39,6 +47,7 @@ jobs:
uses: ./action
with:
components: sqlcmd,sqlengine
force-encryption: ${{ matrix.force-encryption }}
sa-password: "bHuZH81%cGC6"
version: ${{ matrix.version }}

Expand All @@ -47,4 +56,5 @@ jobs:
action/test.ps1
shell: pwsh
env:
FORCE_ENCRYPTION: ${{ matrix.force-encryption }}
SA_PASSWORD: "bHuZH81%cGC6"
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ inputs:
components:
description: "The components to install"
required: true
force-encryption:
description: "Should the server force encryption?"
required: false
default: "false"
sa-password:
description: "The SA password for the SQL instance"
required: true
Expand All @@ -20,6 +24,7 @@ runs:
run: |
$params = @{
Components = ("${{ inputs.components }}" -split ",").Trim()
ForceEncryption = "${{ inputs.force-encryption }}" -eq "true"
SaPassword = "${{ inputs.sa-password }}"
Version = "${{ inputs.version }}"
}
Expand Down
51 changes: 46 additions & 5 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
param (
[ValidateSet("sqlcmd", "sqlengine")]
[string[]]$Components,
[bool]$ForceEncryption,
[string]$SaPassword,
[ValidateSet("2017")]
[string]$Version
Expand All @@ -9,7 +10,7 @@ param (
function Wait-ForContainer {
$checkInterval = 5
$containerName = "sql"
$timeout = 120
$timeout = 60

$startTime = Get-Date
Write-Host "Waiting for the container '$containerName' to be healthy..."
Expand Down Expand Up @@ -73,8 +74,31 @@ if ("sqlengine" -in $Components) {
exit 1
}

if ($ForceEncryption) {
Write-Output "Force encryption is set, generating self-signed certificate ..."

# SOURCE: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-security?view=sql-server-ver16#encrypt-connections-to-sql-server-linux-containers
& mkdir -p /opt/mssql
& openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sql1.contoso.com' -keyout /opt/mssql/mssql.key -out /opt/mssql/mssql.pem -days 365
$MssqlConf = @'
[network]
tlscert = /etc/ssl/certs/mssql.pem
tlskey = /etc/ssl/private/mssql.key
tlsprotocols = 1.2
forceencryption = 1
'@

Set-Content -Path /opt/mssql/mssql.conf -Value $MssqlConf
& sudo chmod -R 775 /opt/mssql

Copy-Item -Path /opt/mssql/mssql.pem -Destination /usr/share/ca-certificates/mssql.crt
& sudo dpkg-reconfigure ca-certificates

$AdditionalContainerConfiguration = "-v /opt/mssql/mssql.conf:/var/opt/mssql/mssql.conf -v /opt/mssql/mssql.pem:/etc/ssl/certs/mssql.pem -v /opt/mssql/mssql.key:/etc/ssl/private/mssql.key"
}

Write-Output "Starting a Docker Container"
Invoke-Expression "docker run --name=`"sql`" -e `"ACCEPT_EULA=Y`"-e `"SA_PASSWORD=$SaPassword`" -e `"MSSQL_PID=Express`" --health-cmd=`"/opt/mssql-tools/bin/sqlcmd -C -S localhost -U sa -P '$SaPassword' -Q 'SELECT 1' -b -o /dev/null`" --health-start-period=`"10s`" --health-retries=3 --health-interval=`"10s`" -p 1433:1433 -d `"mcr.microsoft.com/mssql/server:$Version-latest`""
Invoke-Expression "docker run --name=`"sql`" -e `"ACCEPT_EULA=Y`"-e `"SA_PASSWORD=$SaPassword`" -e `"MSSQL_PID=Express`" --health-cmd=`"/opt/mssql-tools/bin/sqlcmd -C -S localhost -U sa -P '$SaPassword' -Q 'SELECT 1' -b -o /dev/null`" --health-start-period=`"10s`" --health-retries=3 --health-interval=`"10s`" -p 1433:1433 $AdditionalContainerConfiguration -d `"mcr.microsoft.com/mssql/server:$Version-latest`""
Wait-ForContainer
}

Expand All @@ -88,9 +112,26 @@ if ("sqlengine" -in $Components) {

Write-Host "Configuring SQL Express ..."
stop-service MSSQL`$SQLEXPRESS
set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql14.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpdynamicports -value ''
set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql14.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpport -value 1433
set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql14.SQLEXPRESS\mssqlserver\' -name LoginMode -value 2

$InstancePath = "HKLM:\software\microsoft\microsoft sql server\mssql14.SQLEXPRESS\mssqlserver"
$SuperSocketNetLibPath = "$InstancePath\supersocketnetlib"
set-itemproperty -path "$SuperSocketNetLibPath\tcp\ipall" -name tcpdynamicports -value ''
set-itemproperty -path "$SuperSocketNetLibPath\tcp\ipall" -name tcpport -value 1433
set-itemproperty -path $InstancePath -name LoginMode -value 2

# SOURCE: https://blogs.infosupport.com/configuring-sql-server-encrypted-connections-using-powershell/
if ($ForceEncryption) {
Write-Output "Force encryption is set, configuring SQL server to do so ..."

$params = @{
DnsName = 'sql1.contoso.com'
CertStoreLocation = 'Cert:\LocalMachine\My'
}
$Certificate = New-SelfSignedCertificate @params

Set-ItemProperty $SuperSocketNetLibPath -Name "Certificate" -Value $Certificate.Thumbprint.ToLowerInvariant()
Set-ItemProperty $SuperSocketNetLibPath -Name "ForceEncryption" -Value 1
}

Write-Host "Starting SQL Express ..."
start-service MSSQL`$SQLEXPRESS
Expand Down
21 changes: 21 additions & 0 deletions test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,24 @@ else {

Write-Output "Checking if SQL Server is available ..."
& sqlcmd -S 127.0.0.1 -U sa -P $env:SA_PASSWORD -Q "SELECT 1"

Write-Output "Check status of connection encryption ..."

$sqlQuery = @"
SELECT
session_id,
encrypt_option
FROM sys.dm_exec_connections
WHERE session_id = @@SPID;
"@

$results = sqlcmd -S 127.0.0.1 -U sa -P $env:SA_PASSWORD -Q $sqlQuery -h -1 -W

if ($env:FORCE_ENCRYPTION -eq "false" -And $results -match "TRUE") {
Write-Error "Somehow the connection to the SQL server is encrypted, misconfiguration?"
exit 1
}
elseif ($env:FORCE_ENCRYPTION -eq "true" -And -not ($results -match "TRUE")) {
Write-Error "Connection to SQL server is not encrypted!"
exit 1
}

0 comments on commit 804915f

Please sign in to comment.