تقویت امنیت SQL Server: راهنمای جامع شناسایی و حذف کاربران و لاگینهای راکد(Drop Logins)
واقعیت این است که افراد سازمانها را ترک میکنند و اغلب، آثاری از آنها در محیط SQL Server شما باقی میماند. لاگینهای SQL Server، کاربران پایگاه داده و نقشهای احتمالی پایگاه داده نمونههای خوبی از این “عناصر بلااستفاده” هستند. این موارد اغلب به عنوان یک ریسک امنیتی بالقوه یا صرفاً شلوغی، نادیده گرفته میشوند. واقعیت ساده این است که باید به طور منظم حذف شوند(Drop Logins). این مقاله بر شناسایی این موارد بلااستفاده تمرکز دارد تا بتوانید اقدام به پاکسازی آنها کنید و امنیت SQL Server خود را افزایش دهید.
ابتدا، هر لاگینی را که نقش سرور (server role) ندارد، شناسایی میکنیم. اینها معمولاً لاگینهای “کاربری” هستند و گزینههای خوبی برای بررسی بیشتر محسوب میشوند. دو نوع اصلی از لاگینها که به دنبال آنها خواهیم بود عبارتند از:
- لاگینهای SQL (SQL logins)
- لاگینهای ویندوز (Windows logins)
برای این کوئری اولیه، ما به سادگی به دنبال لاگینهایی هستیم که هیچ نقش سروری به آنها اختصاص داده نشده است. شناسایی این لاگینها اولین گام مهم در مدیریت امنیت SQL Server و کاهش ریسکهای احتمالی است.
کوئری زیر به شما کمک میکند تا لاگینهای بدون نقش سرور را در SQL Server خود بیابید:
SELECT name AS LoginName ,
type_desc AS LoginType
FROM sys.server_principals
WHERE is_disabled = 0
AND type IN ( 'S', 'U', 'G' ) -- S = SQL Login, U = Windows User, G = Windows Group
EXCEPT
SELECT l.name AS LoginName ,
l.type_desc AS LoginType
FROM sys.server_principals AS l
JOIN sys.server_role_members AS rm ON rm.member_principal_id = l.principal_id
WHERE l.type IN ( 'S', 'U', 'G' )
AND l.is_disabled = 0;
این کوئری لیستی از لاگینهای فعال (غیرفعال نشده) SQL Server، کاربران ویندوز و گروههای ویندوز را که عضو هیچ یک از نقشهای سرور نیستند، برمیگرداند. بررسی این لاگینها برای امنیت و بهینهسازی SQL Server ضروری است.
در گام بعدی، لاگینهایی را شناسایی میکنیم که به هیچ پایگاه دادهای نگاشت کاربری (user mapping) ندارند. اگر یک لاگین هیچ نگاشت کاربری به هیچ پایگاه دادهای نداشته باشد، عملاً نمیتواند در هیچ یک از پایگاههای داده کاری انجام دهد. ممکن است آنها دارای نقشهای سرور باشند، اما مگر اینکه sysadmin باشند یا مجوزهای خاصی داشته باشند، در غیر این صورت صرفاً باعث شلوغی و اضافه بار در سیستم مدیریت SQL Server شما خواهند بود. این لاگینها نیز کاندیدای خوبی برای بررسی و پاکسازی بیشتر هستند و به بهبود امنیت و عملکرد SQL Server کمک میکنند.
برای یافتن لاگینهایی که به هیچ پایگاه دادهای دسترسی ندارند، از کوئری زیر استفاده کنید:
SELECT l.name AS LoginName ,
l.type_desc AS LoginType
FROM sys.server_principals AS l
WHERE l.type IN ( 'S', 'U', 'G' )
AND l.is_disabled = 0
EXCEPT
SELECT l.name AS LoginName ,
l.type_desc AS LoginType
FROM sys.server_principals AS l
JOIN sys.database_principals AS dp ON dp.sid = l.sid
WHERE l.type IN ( 'S', 'U', 'G' )
AND l.is_disabled = 0
AND dp.is_ms_shipped = 0;
این کوئری لیستی از لاگینهای SQL Server را برمیگرداند که فعال هستند اما به هیچ کاربری در هیچ پایگاه دادهای نگاشت نشدهاند. شناسایی و بررسی دقیق این لاگینها میتواند به شناسایی کاربران غیرفعال SQL Server و افزایش امنیت محیط شما کمک شایانی کند.
اکنون، لاگینهای SQL Server را شناسایی میکنیم که تاریخ “آخرین فعالیت” (last activity) ندارند. این یکی از کاربردیترین کوئریهاست، زیرا به شما نشان میدهد که آخرین بار چه زمانی از این لاگین استفاده شده است. این قابلیت فقط برای لاگینهای SQL Server کار میکند و برای لاگینهای ویندوز قابل استفاده نیست. شناسایی لاگینهای بلااستفاده بر اساس آخرین فعالیت، گام مهمی در مدیریت کاربران SQL Server و حذف لاگینهای اضافی است.
کوئری زیر به شما کمک میکند تا این لاگینها را پیدا کنید:
SELECT name AS LoginName ,
create_date AS CreationDate ,
modify_date AS LastModifiedDate ,
( SELECT MAX(last_user_update)
FROM sys.dm_db_index_usage_stats
WHERE database_id > 4
) AS LastUserActivity -- This is not directly tied to login activity, but general db activity
FROM sys.server_principals
WHERE type = 'S' -- SQL Logins only
AND is_disabled = 0
AND name NOT IN ( 'sa' ); -- Exclude 'sa'
نکته مهم: این کوئری بخش `LastUserActivity` در کد اصلی مقاله، به جای تاریخ آخرین فعالیت لاگین، حداکثر تاریخ آخرین بهروزرسانی کاربر از طریق ایندکسها را در پایگاههای داده کاربر (با `database_id > 4`) نشان میدهد. این ممکن است مستقیماً با لاگین خاصی مرتبط نباشد اما یک نشانگر کلی از فعالیت پایگاه داده فراهم میکند. برای ردیابی دقیقتر فعالیت لاگین، نیاز به رویکردهای دیگری مانند Audit یا Login Triggers دارید. هدف از این بخش، شناسایی لاگینهای SQL فعال (غیر از sa) است که ممکن است مدتهاست استفاده نشده باشند و برای پاکسازی SQL Server مورد بررسی قرار گیرند.
با تمرکز بر کاربران پایگاه داده، اکنون کاربرانی را شناسایی میکنیم که لاگین مرتبطی ندارند. این کاربران اغلب به عنوان “کاربران یتیم” (`orphaned users`) ایجاد میشوند، به خصوص زمانی که یک پایگاه داده از یک نمونه SQL Server دیگر بازیابی (`restore`) میشود. اگر این کاربران لاگینی نداشته باشند، نمیتوانند وارد سیستم شوند و کاری انجام دهند. شناسایی این کاربران بسیار مهم است، زیرا حتی اگر یتیم باشند، ممکن است همچنان صاحب آبجکتها یا دارای مجوزهایی باشند. این کاربران کاندیداهای خوبی برای حذف هستند، چرا که به افزایش امنیت و پاکسازی SQL Server کمک میکنند.
کوئری زیر به شما کمک میکند تا کاربران پایگاه داده بدون لاگین را پیدا کنید:
SELECT dp.name AS UserName ,
dp.type_desc AS UserType
FROM sys.database_principals AS dp
WHERE dp.type IN ( 'S', 'U', 'G' )
AND dp.sid IS NOT NULL
AND dp.sid NOT IN (
SELECT sp.sid
FROM sys.server_principals AS sp
WHERE sp.type IN ( 'S', 'U', 'G' )
)
AND dp.is_ms_shipped = 0;
این کوئری لیستی از کاربران پایگاه داده را بازمیگرداند که دارای SID هستند اما SID آنها در لیست لاگینهای سرور یافت نمیشود، به این معنی که آنها “یتیم” هستند. مدیریت کاربران یتیم بخش مهمی از نگهداری و امنیت SQL Server است.
در نهایت، کاربرانی را در پایگاه داده شناسایی میکنیم که هیچ آبجکتی را مالک نیستند و هیچ مجوزی (permission) ندارند. این کاربران صرفاً باعث شلوغی و اضافه بار هستند و کاندیداهای بسیار خوبی برای حذف محسوب میشوند. حذف این کاربران به بهینهسازی SQL Server و حفظ یک محیط کاری تمیز و امن کمک میکند.
کوئری زیر به شما امکان میدهد این کاربران را در هر پایگاه داده پیدا کنید:
EXEC sp_MSForEachDB '
USE [?]
SELECT dp.name AS UserName ,
dp.type_desc AS UserType
FROM sys.database_principals AS dp
WHERE dp.type IN ( ''S'', ''U'', ''G'' )
AND dp.is_ms_shipped = 0
AND dp.principal_id NOT IN (
SELECT major_id
FROM sys.objects
WHERE schema_id = dp.principal_id
)
AND dp.principal_id NOT IN (
SELECT grantee_principal_id
FROM sys.database_permissions
WHERE grantee_principal_id = dp.principal_id
)
AND dp.principal_id NOT IN (
-- Exclude database roles
SELECT principal_id FROM sys.database_principals WHERE type = ''R''
)
AND dp.name NOT IN (''guest'', ''dbo'', ''INFORMATION_SCHEMA'', ''sys'', ''public'');
';
این کوئری تمام پایگاههای داده را بررسی میکند و کاربرانی را که نه صاحب آبجکتها هستند و نه دارای مجوز هستند، لیست میکند. حذف این کاربران به طور چشمگیری به بهبود امنیت و کارایی در محیط SQL Server شما کمک میکند، زیرا از انباشت کاربران بلااستفاده جلوگیری میکند.
به این ترتیب، یک راه ساده برای شناسایی عناصر بلااستفاده در SQL Server را در اختیار دارید. با استفاده از این کوئریها، میتوانید برخی از مقصرهای رایجی که اغلب نادیده گرفته میشوند را شناسایی کنید. بررسی منظم این موارد، محیط SQL Server شما را امنتر و کمتر شلوغ خواهد کرد. اگرچه تصمیم نهایی برای حذف یک لاگین یا کاربر پایگاه داده همیشه به عهده شماست، اما این روش حداقل نقطه شروع خوبی برای بررسیهای دقیقتر فراهم میکند. این رویکرد به شما کمک میکند تا مدیریت SQL Server خود را بهبود بخشیده و از امنیت پایداری برخوردار شوید.