Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(inputs.sqlserver): Check SQL Server "encryptionEnforce" with xp_instance_regread #13284

Merged
merged 3 commits into from
Jun 1, 2023

Conversation

MartinHBA
Copy link
Contributor

@MartinHBA MartinHBA commented May 18, 2023

resolves #12933

Added new query that collects required info from SQL Server registry

@telegraf-tiger telegraf-tiger bot added the feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin label May 18, 2023
@powersj
Copy link
Contributor

powersj commented May 18, 2023

@Trovalo could I request your sql server knowledge once again :) and take a quick look at this one? Thanks!

@powersj powersj self-assigned this May 18, 2023
@Trovalo
Copy link
Collaborator

Trovalo commented May 18, 2023

I'm not that knowledgeable in this particular area of SQL Server but I'll have a look at it.

@srebhan srebhan changed the title feat(sql-server): checking SQL Server encryptionEnforce with xp_insta… feat(inputs.sqlserver): Check SQL Server "encryptionEnforce" with xp_instance_regread May 22, 2023
@srebhan srebhan added area/sqlserver ready for final review This pull request has been reviewed and/or tested by multiple users and is ready for a final review. labels May 22, 2023
Copy link
Member

@srebhan srebhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Thanks for your contribution @MartinHBA! Tagging in @Trovalo to comment on the SQL statement. ;-)

@srebhan srebhan requested a review from Trovalo May 22, 2023 07:48
Copy link
Collaborator

@Trovalo Trovalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the SQL statement it's fixed the whole thing should work (also permission-wise), BUT

I'm not sure about having a whole query about it, it's just too specific, therefore I see mainly two options:

  • having a more generic "Registry" query to fetch registry values (I'm not sure how many useful registry values there are tho)
  • add this new field in an existing query, like the ServerProperties one

I'll think about it some more...

@@ -247,6 +247,24 @@ SELECT
EXEC sp_executesql @SqlStatement
`

const SQLServerForceEncryption = `
SET DEADLOCK_PRIORITY -10;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This query won't run, single quotes have to be escaped inside the string itself (''' ), and the output variable has to be declared inside the statement itself in order to have the proper scope.
also it's missing the instance name, and you won't be able to distinguish between multiple servers without it

SET DEADLOCK_PRIORITY -10;
DECLARE @SqlStatement nvarchar(max)

SET @SqlStatement = N'
DECLARE @ForceEncryption INT

EXEC [master].[dbo].[xp_instance_regread]
       @rootkey = ''HKEY_LOCAL_MACHINE'',
       @key = ''SOFTWARE\Microsoft\Microsoft SQL Server\MSSQLServer\SuperSocketNetLib'',
       @value_name = ''ForceEncryption'',
       @value = @ForceEncryption OUTPUT;

SELECT @@SERVERNAME AS sql_instance, @ForceEncryption AS ForceEncryption'

EXEC sp_executesql @SqlStatement

@MartinHBA
Copy link
Contributor Author

  • having a more generic "Registry" query to fetch registry values (I'm not sure how many useful registry values there are tho)

exactly my thought when I was creating it, it could be more generic registry reader function and for example it can also read SQL port numbers from registry in future and much more, let me know your decision and what naming / changes you want to do, we can close this PR and I will create new incorporating your suggestions

@powersj powersj removed the ready for final review This pull request has been reviewed and/or tested by multiple users and is ready for a final review. label May 24, 2023
@Trovalo
Copy link
Collaborator

Trovalo commented May 29, 2023

@MartinHBA I've thought about having a new query about "Registry" values vs adding stuff to the existing one (ServerProperties).

As long as need few values I think it makes more sense to add new columns to the "ServerProperties" one, I've tested it and it doesn't look ugly.
Also I don't think there are many values worth taking from the registry... is there something worth taking other than

  • ForceEncryption
  • Port
  • PortType (Static/Dynamic)

Let me know if you think there are more things to fetch from the registry (SQL Server related ofc) as I've kind of ended my useful list with just 3 attributes...
Let me know what you think

Here is the whole query, just to give you an idea/sample

SET DEADLOCK_PRIORITY -10;
IF SERVERPROPERTY('EngineEdition') NOT IN (2,3,4) BEGIN /*NOT IN Standard,Enterpris,Express*/
	DECLARE @ErrorMessage AS nvarchar(500) = 'Telegraf - Connection string Server:'+ @@ServerName + ',Database:' + DB_NAME() +' is not a SQL Server Standard,Enterprise or Express. Check the database_type parameter in the telegraf configuration.';
	RAISERROR (@ErrorMessage,11,1)
	RETURN
END

DECLARE
	 @SqlStatement AS nvarchar(max) = ''
	,@MajorMinorVersion AS int = CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS nvarchar),4) AS int)*100 + CAST(PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS nvarchar),3) AS int)
	,@Columns AS nvarchar(MAX) = ''

IF CAST(SERVERPROPERTY('ProductVersion') AS varchar(50)) >= '10.50.2500.0'
	SET @Columns = N'
	,CASE [virtual_machine_type_desc]
		WHEN ''NONE'' THEN ''PHYSICAL Machine''
		ELSE [virtual_machine_type_desc]
	END AS [hardware_type]'

SET @SqlStatement = '

DECLARE @ForceEncryption INT
DECLARE @DynamicportNo NVARCHAR(50);
DECLARE @StaticportNo NVARCHAR(50);

EXEC [master].[dbo].[xp_instance_regread]
       @rootkey = ''HKEY_LOCAL_MACHINE'',
       @key = ''SOFTWARE\Microsoft\Microsoft SQL Server\MSSQLServer\SuperSocketNetLib'',
       @value_name = ''ForceEncryption'',
       @value = @ForceEncryption OUTPUT;

EXEC xp_instance_regread @rootkey = ''HKEY_LOCAL_MACHINE''
                        ,@key =
                         ''Software\Microsoft\Microsoft SQL Server\MSSQLServer\SuperSocketNetLib\Tcp\IpAll''
                        ,@value_name = ''TcpDynamicPorts''
                        ,@value = @DynamicportNo OUTPUT

EXEC xp_instance_regread @rootkey = ''HKEY_LOCAL_MACHINE''
                        ,@key =
                         ''Software\Microsoft\Microsoft SQL Server\MSSQLServer\SuperSocketNetLib\Tcp\IpAll''
                        ,@value_name = ''TcpPort''
                        ,@value = @StaticportNo OUTPUT

SELECT
	 ''sqlserver_server_properties'' AS [measurement]
	,REPLACE(@@SERVERNAME,''\'','':'') AS [sql_instance]
	,@@SERVICENAME AS [service_name]
	,si.[cpu_count]
	,(SELECT [total_physical_memory_kb] FROM sys.[dm_os_sys_memory]) AS [server_memory]
	,(SELECT [available_physical_memory_kb] FROM sys.[dm_os_sys_memory]) AS [available_server_memory]
	,SERVERPROPERTY(''Edition'') AS [sku]
	,CAST(SERVERPROPERTY(''EngineEdition'') AS int) AS [engine_edition]
	,DATEDIFF(MINUTE,si.[sqlserver_start_time],GETDATE()) AS [uptime]
	,SERVERPROPERTY(''ProductVersion'') AS [sql_version]
	,SERVERPROPERTY(''IsClustered'') AS [instance_type]
	,LEFT(@@VERSION,CHARINDEX('' - '',@@VERSION)) AS [sql_version_desc]
	,@ForceEncryption AS ForceEncryption
	,COALESCE(@DynamicportNo,@StaticportNo) AS Port
	,IIF(@DynamicportNo IS NULL, ''Static'', ''Dynamic'') AS PortType
	,dbs.[db_online]
	,dbs.[db_restoring]
	,dbs.[db_recovering]
	,dbs.[db_recoveryPending]
	,dbs.[db_suspect]
	,dbs.[db_offline]'
	+ @Columns + N'
	FROM sys.[dm_os_sys_info] AS si
	CROSS APPLY (
		SELECT
			 SUM(CASE WHEN state = 0 THEN 1 ELSE 0 END) AS [db_online]
			,SUM(CASE WHEN state = 1 THEN 1 ELSE 0 END) AS [db_restoring]
			,SUM(CASE WHEN state = 2 THEN 1 ELSE 0 END) AS [db_recovering]
			,SUM(CASE WHEN state = 3 THEN 1 ELSE 0 END) AS [db_recoveryPending]
			,SUM(CASE WHEN state = 4 THEN 1 ELSE 0 END) AS [db_suspect]
			,SUM(CASE WHEN state IN(6, 10) THEN 1 ELSE 0 END) AS [db_offline]
		FROM sys.databases
	) AS dbs
'

EXEC sp_executesql @SqlStatement

@powersj powersj added the waiting for response waiting for response from contributor label May 30, 2023
@MartinHBA
Copy link
Contributor Author

hi @Trovalo , updated now, please check and let me know, also let me thank you for your valuable inputs and your time!

@telegraf-tiger telegraf-tiger bot removed the waiting for response waiting for response from contributor label May 30, 2023
Copy link
Collaborator

@Trovalo Trovalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only formatted the SQL code coherently (commas, brackets, etc) as my sample had been put together quickly (and it was used as-is)

After that we are good to go, thanks @MartinHBA

@telegraf-tiger
Copy link
Contributor

@powersj powersj requested a review from Trovalo May 31, 2023 17:56
@powersj
Copy link
Contributor

powersj commented Jun 1, 2023

Thank you both!

@powersj powersj merged commit 1c60c05 into influxdata:master Jun 1, 2023
@srebhan srebhan added this to the v1.27.0 milestone Jun 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/sqlserver feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"Enforced encryption by server" property collected in SQLServerProperties
4 participants