We had a requirement for PCI compliance that all admin connections to SQL Server must be encrypted. I took this a little bit further to ensure that this requirement was easily enforced using Login triggers.
In our environment, we have a certificate server as part of SCOM so I use this to generate the certificates. The Trusted Root certificate should already exist on the server as part of the SCOM component install which would have been done before the server was handed over to the DBA’s.
Generating the Certificate:
RDP onto the certificate server
Open IE and browse to http://
Click on “Request a certificate”
Click on “Advanced Certificate Request”
Click on “Create and submit a request to this CA”
Fill in or select the following details;
Name: FQDN of server
Email: Blank
Company: Your Company Name
Department: IT
City: Your City
State: Your State
Country: Your Country
Type of Certificate: Server Auth Certificate
Create New Key Set (unless renewing expired certificate)
CSP: Microsoft Enhanced Cryptographic Provider 1.0 (is default)
Key Usage: Both (is default)
Key Size: 1024 (is default)
Automatic key container name (is default)
TICK mark keys as exportable (NOT default)
Un-tick Export keys to a file (is default) – this exports the private key to a separate file, we will use pfx format which includes key with cert
Un-tick Enable strong private key protection (is default) – this requires password to be entered each time key is used(which would be each time SQL is started)
Un-tick Store certificate in local computer certificate store (is default) – certificate will go into store of SQL Server service account
Request Format: CMC (is default)
Hash Algorithm: SHA1 (is default)
Un-tick Save request to a file (is default)
Attributes: Blank
Friendly name: NETBIOS name of server (server name)
Click SUBMIT
Click “Yes” to generate the certificate.
Now the Certificate Pending page should be displayed. The certificate now needs to be issued. You may require someone else do this part for you unless you are a local administrator on the server. Note the request ID just in case there are many certificates waiting to be issued.
To Issue the Certificate:
Run up a MMC
Add Certificate Authority snap-in
In the left pane, open the Certificate Authority all the way to Pending Requests. In the right pane, right click on your requestID and select All Tasks > Issue
Go back to the browser window and select Home in the top right hand corner.
Click on the “View the Status of a Pending Certificate Request”. You should see your Server Authentication Certificate. Click on this. Then Click on “Install this certificate”. The certificate was installed onto the server you are logged onto in your terminal session.
Now back to the MMC and add the Certificates snap-in to “My user account”
In the left pane, open Certificates – Current User > Personal > Certificates and you should see your certificate in the right pane. You need to export this certificate so it can be moved to your server and installed to SQL Server. Right click > All Tasks > Export
Run through the wizard selecting the following…
Yes, export the private key (not default)
Personal Information Exchange should be the only option. Select the following options…
Tick Include all certificates in the certificate path if possible (not default)
Un-Tick Enable strong protection (not default)
Tick Delete the private key if export is successful (not default)
Enter a password of your choice
Select a path to export the certificate to, including a name for the certificate. Next. Finish. You should get a response back “The export was successful”
Now, copy that certificate over to the server that you want this to be installed to.
Before closing the MMC,delete the certificate from your personal store that you just created.
Adding the Certificate to SQL Server
RDP onto the SQL Server.
Run the MMC as the SQL Server service account.
1. runas /user:
If your accounts don’t allow interactive login then this will not work and generate an error saying “the user has not been granted the requested logon type at this computer”. Making a local admin will still not work for this.
2. Temporarily make your SQL Server service account a local administrator. Using Windows Explorer, browse to C:\Windows\System32 and shift-right click on mmc.exe to “run as a different user”. Enter the details of the account used to run the SQL Server database engine.
Once open, add the Certificates MMC snap-in as “My user account” which is the correct option as you are currently running as your SQL service account
Open the Certificates folder and right click on the Personal folder and select All Tasks > Import to start the import certificate wizard.When you get to the password option, enter the same password that you put when exporting the certificate. Un-tick the box “Enable strong private key protection”.
Now the certificate is installed for the SQL Server service account and will be used next time SQL is stopped and then re-started. This is instead of using the Self Generated Certificate.
You should also see that by this method the root certificate will aalso be added into the personal store. This can be safely deleted.
Open the SQL Server log and you should see … The certificate [Cert Hash(sha1) “D86CD68AB1D37403E145673586EFD9999B444694″] was successfully loaded for encryption.
instead of… A self-generated certificate was successfully loaded for encryption.
Encrypting connections to SQL Server
You can selectively encrypt connections now or you can encrypt all connections. We only want to encrypt admin connections only.
Open SSMS and register the server. As part of the registration process, click on the Connection Properties tab and check the box to Encrypt Connection.You can verify this is working so far by running the following query…
SELECT * FROM sys.dm_exec_connections WHERE session_id = @@SPID
The encrypt_option column should read “TRUE”.
Now, this needs to be enforced as still anyone can connect unencrypted. This is achieved using a logon trigger.
USE master ;
GO
IF EXISTS ( SELECT *
FROM sys.server_triggers
WHERE name = 'deny_nonencrypted_ssms_sessions' )
BEGIN
DROP TRIGGER deny_nonencrypted_ssms_sessions ON ALL SERVER ;
-- DISABLE TRIGGER deny_nonencrypted_ssms_sessions ON ALL SERVER
END
GO
CREATE TRIGGER deny_nonencrypted_ssms_sessions ON ALL SERVER
FOR LOGON
AS
IF IS_SRVROLEMEMBER('sysadmin') = 1
BEGIN
IF EXISTS ( SELECT *
FROM sys.dm_exec_sessions AS s
INNER JOIN sys.dm_exec_connections AS c ON s.session_id = c.session_id
WHERE s.session_id = @@SPID
AND ( s.program_name LIKE 'Microsoft SQL Server Management Studio%'
OR s.program_name = 'SQL Query Analyzer'
)
AND c.encrypt_option = 'FALSE' )
ROLLBACK
END
ELSE
RETURN
If you want to capture all connections that are not encrypted, take out the IF IS_SRVROLEMEMBER clause. One caveat here is that to be able to trip the trigger, the login must have VIEW SERVER STATE permission.
To over-ride the trigger, connect using the DAC (Dedicated Admin Connection).
Optional extra:
While you have the MMC open as the SQL Service account, you can add the SQL Configuration Manager snap-in. Open SQL Server Netwrok Configuration and right click on “Protocols for MSSQLSERVER” and select properties. The second tab is Certificate and here you can also add the certificate, so that it is visible. Adding the certificate in here writes the thumbprint of the certificate to a registry key…
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQLServer\SuperSocketNetLib and the key is called Certificate.
You can actually enter this value in manually… open the certificate and on the details tab of the certificate copy the hash value for the thumbprint. Paste this into notepad and then remove all the spaces from between the characters. Please also note that there is a leading space at the beginning that needs to be removed which you cannot see.
Now, you can query for the certificate rather than looking the entry in the SQL Error Log.
EXEC sys.xp_regread N’HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQLServer\SuperSocketNetLib’, N’Certificate’
No certificate returns NULL, an installed certificate returns the thumbprint.
Remember, it is not necessary to do this but I find it makes the certificate more visible.
