Veritabanı Yöneticilerinin Veriye Erişimini Kısıtlamak(Control Server ve sysadmin Farkları)
Control Server Yetkisi SQL Server 2005 ile beraber hayatımıza girdi. Bu yetki sysadmin’in bir alternatifi olarak karşımıza çıktı. Sysadmin ise bildiğiniz gibi sql server’da herşeyi yapma hakkına sahip olan süper bir kullanıcı.
Control server ve sysadmin’in farklarını benim gördüğüm kadarıyla aşağıdaki tabloda bulabilirsiniz. Bunlar ilk anda gördüğüm farklar. Eminim başka farkları da vardır. Ama bu kadar fark durmam için yetti diyebilirim.
Control Server |
sysadmin |
|
Instance Seviyesinde Deny Edilebiliyor Mu? |
Evet |
Hayır |
Database Mail’i Konfigüre Edebiliyor Mu? |
Hayır |
Evet |
Job’ları Yönetebiliyor Mu? |
Hayır |
Evet |
Linked Server Oluşturabiliyor Mu? |
Hayır |
Evet |
Sysadmin Haklarına Sahip Diğer Kullancıları Taklit(Impersonate) Edebiliyor Mu? |
Evet |
Evet |
Gördüğünüz gibi Control Server yetkisinin en önemli özelliğinin sysadmin hakkına sahip olmasa bile sysadmin hakkına sahip kullanıcıları taklit(impersonate) edebiliyor.
Control Server yetkisine sahip bir kullanıcının server seviyesindeki haklarını aşağıda görebilirsiniz.
CONNECT SQL
SHUTDOWN
CREATE ENDPOINT
CREATE ANY DATABASE
CREATE AVAILABILITY GROUP
ALTER ANY LOGIN
ALTER ANY CREDENTIAL
ALTER ANY ENDPOINT
ALTER ANY LINKED SERVER
ALTER ANY EXTERNAL DATA SOURCE
ALTER ANY EXTERNAL FILE FORMAT
ALTER ANY CONNECTION
ALTER ANY DATABASE
ALTER RESOURCES
ALTER SETTINGS
ALTER TRACE
ALTER ANY AVAILABILITY GROUP
ADMINISTER BULK OPERATIONS
AUTHENTICATE SERVER
EXTERNAL ACCESS ASSEMBLY
VIEW ANY DATABASE
VIEW ANY DEFINITION
VIEW SERVER STATE
CREATE DDL EVENT NOTIFICATION
CREATE TRACE EVENT NOTIFICATION
ALTER ANY EVENT NOTIFICATION
ALTER SERVER STATE
UNSAFE ASSEMBLY
ALTER ANY SERVER AUDIT
CREATE SERVER ROLE
ALTER ANY SERVER ROLE
ALTER ANY EVENT SESSION
CONNECT ANY DATABASE
IMPERSONATE ANY LOGIN
CONTROL SERVER
Aşağıdaki sorgu ile bağlı olduğunuz kullanıcının instance üzerinde hangi yetkilerinin olduğunu görebilirsiniz.
SELECT entity_name, permission_name
FROM sys.fn_my_permissions(NULL, NULL)
Konunun daha net anlaşılması için öncelikle SQL Server 2014 ile birlikte gelen aşağıdaki yetkileri anlamanız gerekmektedir.
CONNECT ANY DATABASE: Bu yetkiyi bir login’e verirseniz Instance üzerindeki veritabanlarına bağlanabilir fakat veritabanları üzerinde hiçbir yetkisi olmaz. Yani tablolara select bile çekemez.
IMPERSONATE ANY LOGIN: Bu yetkiyi bir login’e verirseniz Instance üzerindeki bir sysadmin’i taklit edebilir. Ya da tam tersi CONTROL Server yetkisi olan birinin sysadmin’i taklit etmesini engellemek için deny edebilirsiniz. 🙂
SELECT ALL USER SECURABLES: Bu yetkiyi bir login’e verirseniz bağlanabildiği her veritabanındaki verilere erişebilir. CONNECT ANY DATABASE yetkisi ile beraber verirseniz bir anlam ifade edecektir.
Yukarda bahsi geçen tüm yetkileri içeren bir senaryo düşünelim.
Kurumumuza yeni gelmiş bir dba olsun. Ve bu DBA’in bir çok işi yapmasını ama verileri görememesini sağlamak gibi bir amacımız olsun.
Öncelikle bu login’e CONTROL Server yetkisi verelim.
Sonrasında ise verileri görememesi için SELECT ALL USER SECURABLES yetkisini DENY edelim.
Ardından Instance üzerindeki bir sysadmin’i taklit edememesi için de IMPERSONATE ANY LOGIN yetkisini DENY edelim.
Böylelikle bu login yukarda CONTROL SERVER’ın yetkileri kısmında gördüğünüz herşeyi yapabilecek, fakat verilere erişemeyecektir. CONTROL SERVER yetkisi ile yapılamayacak olan işlemlerde sysdamin haklarına sahip kullanıcı nezdinde gerçekleştirilebilir.
Yukarda anlattığım senaryoyu gerçek bir örnek yaparak uygulayalım.
Öncelikle sysadmin hakkına sahip sysadminLogin isminde bir kullanıcı oluşturuyoruz. “Login oluşturmak ve yetkilendirmek” isimli makalede bu işlemi nasıl yapacağınızı görebilirsiniz.
Daha sonra server ya da veritabanı seviyesinde hiç yetkisi olmayan controlserverLogin isminde başka bir login oluşturalım.
Daha sonra aşağıdaki gibi Instance üzerinde sağ tıklayarak properties diyoruz.
Karşımıza gelen ekranda Permission sekmesine gelerek Search diyoruz.
Karşımıza gelen ekranda Select these object roles kısmında Logins, Server Roles seçili iken Browse diyoruz.
Karşımıza gelen ekranda controlserverLogin’i bularak yanındaki kutucuğu tıklıyoruz ve ok diyoruz.
Karşımıza tekrar bir önceki ekran geliyor. Bu ekranda aşağıdaki gibi controlserverLogin’i seçiyoruz ve controlserverLogin seçili iken alt taraftaki Control server’a Grant veriyoruz.(Grant’ın altındaki kutucuğu tıklıyoruz) Ok diyerek işlemi tamamlıyoruz.
Yukardaki gibi controlserverLogin’e instance seviyesinde control server yetkisi verdikten sonra bu login ile instance’a bağlanarak yapabildiklerini test ediyoruz.
İlk olarak gördüğünüz gibi SQL Server Agent’ı göremiyoruz.
Server Object kısmından new server login dediğimizde aşağıdaki gibi bir hata alıyoruz. Fakat mevcut bir linked server’ı alter edebiliyoruz.
A required operation could not be completed. You must be a member of the sysadmin role to perform this operation.
Peki ControlServerLogin ile bir veritabanında yetkisi olan bir kullanıcı oluşturabiliyor muyuz?
Aşağıdaki script’te gördüğünüz gibi bir login oluşturup veritabanında alter yetkisi veren script’i herhangi bir engel karşılaşmadan verebiliyoruz.
USE [master] GO CREATE LOGIN [controlservertest] WITH PASSWORD=N'xx', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF GO USE [AdventureWorks2014Yeni] GO CREATE USER [controlservertest] FOR LOGIN [controlservertest] GO GRANT ALTER TO [controlservertest] GO
Eğer login’e aşağıdaki script yardımıyla db_owner hakkı vermek istersek aşağıdaki gibi hata alıyoruz.
USE [AdventureWorks2014Yeni] GO ALTER ROLE [db_owner] ADD MEMBER [controlservertest] GO
Msg 15151, Level 16, State 1, Line 4
Cannot alter the role ‘db_owner’, because it does not exist or you do not have permission.
ControlServerLogin ile aşağıdaki gibi herhangi bir veritabanına select çekebiliyor yada veritabanı oluşturup silebiliyoruz.
Kısaca birkaç özellik göstermek istedim. Makalenin başında yapabileceklerini listelemiştim. Burada hepsine tek tek değinmemiz biraz zor olacaktır. İlgisi olan arkadaşlar tek tek deneyebilirler.
Konumuza geri dönecek olursak amacımız Control Server yetkisine sahip birinin verileri görmesini engellemekti. Bu yüzden Instance seviyesinde SELECT ALL USER SECURABLES hakkını DENY etmemiz gerekiyor.
Instance üzerinde yeniden sağ tıklayarak properties diyoruz ve permission sekmesine gelerek Login and roles kısmından controlserverLogin’i seçiyoruz(Burada yoksa yukarda anlattığım şekilde search diyebilirsiniz). Ve aşağıdaki permission kısmından Select All User Securables’ı seçip DENY diyoruz.
Artık controlServerLogin’i ile tablolardan birine select çektiğinizde aşağıdaki gibi hata alırsınız.
Msg 229, Level 14, State 5, Line 2
The SELECT permission was denied on the object ‘DatabaseLog’, database ‘AdventureWorks2014Yeni’, schema ‘dbo’.
Son aşama olarak controlserverLogin’in sysadminLogin gibi nasıl davranabileceğini ve bunu nasıl engelleyeceğimizi anlatıp makaleyi noktalayacağım.
Biraz önce tabloya select çektiğimizde hata almıştık. controlserverLogin’e sysadminLogin’i taklit ettirek aynı select sorgusunu yeniden çalıştırtalım.
Aşağıdaki script ile bunu yapabilirsiniz.
EXECUTE AS LOGIN = 'sysadminLogin' GO SELECT * FROM [AdventureWorks2014Yeni].[dbo].[DatabaseLog]
Gördüğünüz gibi normalde tablolara select çekemezken sysadminLogin’i taklit ederek controlserverLogin ile bunu başarabildik.
Stored Procedure’lerde de taklit etme işlemini(impersonate) aşağıdaki şekilde yapabiliriz.
CREATE PROCEDURE [dbo].[procedureismi] WITH EXECUTE AS 'sysadminLogin' AS . .
Peki CONTROL SERVER yetkisinin taklit etme(impersonate) yeteneğini nasıl engelleriz?
Makalenin başında da bahsettiğim gibi instance seviyesinde IMPERSONATE ANY LOGIN yetkisini DENY ederek bunu başarabiliriz. Bir önceki adımda Select All User Securables yetkisini DENY ettiğimiz şekilde Impersonate Any Login’i de DENY etmelisiniz.