Merhaba,
SQL Server 2016 ile gelecek harika özelliklerden biri olan Dynamic Data Masking sayesinde operasyonel hiçbir iş yapmadan verilerimizi kolaylıkla maskeleyebileceğiz.
Öncelikle maskeleme nedir ona bakalım;
Veri maskeleme, veritabanları içindeki hassas veya gizli verilere erişimi engelleyen bir güvenlik yöntemidir. Bu yöntem, gerçek verilerin yerine gerçek olmayan ancak uygun verilerin yerleştirilmesiyle gerçekleştirilir. (alıntı)
Şimdiye kadar bu işlemler için her DBA kendine özgü yöntemler geliştiriyordu. Veriyi alıp, klasik update sorgusuyla kirletmek, ETL paketleri yazmak gibi.
Dynamic Data Masking ile hiçbir operasyonel işlem yapmadan admin kullanıcılar harici tüm kullanıcılara ya da istenilen bazı kullanıcılara tablodaki istenilen alanları maskelenmiş bir şekilde gösterebiliriz.
Örneğin, bir banka çağrı merkezi çalışanı müşterinin her verisini direkt görememeli. Yazılım seviyesinde yapılan bu maskeleme artık veritabanı katmanında da anlık olarak yapılabilecek.
Bir demo ile detaylandırmaya çalışayım;
Öncelikte, AdventureWorks veritabanından SELECT INTO ile DataMaskDemo isminde bir tablo oluşturuyorum.
SELECT TOP 500 ROW_NUMBER() OVER (ORDER BY p.BusinessEntityID) AS Id, p.FirstName, p.LastName, ea.EmailAddress, pp.PhoneNumber, c.CustomerID, a.AddressLine1, a.City INTO DataMaskDemo FROM Person.Person p WITH (NOLOCK) JOIN Person.EmailAddress ea ON p.BusinessEntityID = ea.BusinessEntityID JOIN Person.PersonPhone pp ON p.BusinessEntityID = pp.BusinessEntityID JOIN Sales.Customer c ON p.BusinessEntityID = c.PersonID JOIN Person.BusinessEntityAddress bea ON p.BusinessEntityID = bea.BusinessEntityID JOIN Person.Address a ON bea.AddressID = a.AddressID
Şimdi de bu tabloda bazı alanları maskeleyelim.
Maskeleme işlemi T-SQL ile yapılıyor. Alter Table komutu ile istediğimiz alanların nasıl maskelenmesi gerektiğini belirtiyoruz. Şu anda maskeleme için 3 adet hazır, 1 adet de custom function bulunuyor.
default(): Tüm veriyi xxx olarak maskeler.
email(): Email formatına uygun veriyi ilk karekteri yok sayarak maskeler. Tüm domain suffixlerini .com olarak gösterir. aXXX@XXXX.com
random([start range], [end range])): Sadece numeric alanlar için kullanabileceğimiz random fonksiyonu belirlediğimiz aralıkta rastgele sayı üretir.
Custom- partial(prefix,[padding],suffix): String alanlar için custom fonksiyon da yazabiliriz.
Örneğin; partial(2,”xxxx”,1) şeklinde tanımlama yaptığımızda ilk 2 ve son 1 karakter dışında kalan tüm karakterleri xxxx olarak maskeleyecektir. Eğer alan 2 veya daha az karakter içeriyorsa sadece xxxx olarak görünecektir.
LastName, EmailAddress, PhoneNumber, CustomerID ve AddressLine1 alanlarını maskeleyelim.
ALTER TABLE DataMaskDemo ALTER COLUMN LastName ADD MASKED WITH (FUNCTION = 'partial(3,"XXXX",0)'); GO ALTER TABLE DataMaskDemo ALTER COLUMN EmailAddress ADD MASKED WITH (FUNCTION = 'email()'); GO ALTER TABLE DataMaskDemo ALTER COLUMN PhoneNumber ADD MASKED WITH (FUNCTION = 'partial(0,"XXX-XXX XX XX",0)'); GO ALTER TABLE DataMaskDemo ALTER COLUMN CustomerID ADD MASKED WITH (FUNCTION = 'random(10, 99)'); GO ALTER TABLE DataMaskDemo ALTER COLUMN AddressLine1 ADD MASKED WITH (FUNCTION = 'default()'); GO
Maskelenmiş veriyi görmek için test kullanıcısı oluşturup sadece select yetkisi verelim.
CREATE USER TestUser WITHOUT LOGIN; GRANT SELECT ON DataMaskDemo TO TestUser;
Şimdi de sanki TestUser ile login olmuş gibi tabloya select yapalım. İşaretlediğim alanların maskelendiğini görebiliriz.
EXECUTE AS USER = 'TestUser'; SELECT * FROM DataMaskDemo; REVERT;
Eğer istersek TestUser kullanıcısına gerçek veriyi Grant Unmask komutuyla gösterebiliriz.
GRANT UNMASK TO TestUser;
Tekrardan maskeli veriyi görmesi için de Revoke Unmask yapabiliriz.
REVOKE UNMASK TO TestUser;
Notlar:
- Maskeli veriyi gören kullanıcıların veriyi update etme yetkisi varsa bu işlem engellenmez. Bu yüzden best practise olarak bu tip kullanıcıların veriyi değiştirme yetkilerini kısıtlamakta fayda var.
- Kullanıcılar, Select Into veya Insert Into ile veriyi aldıklarında gerçek veriyi değil maskeli veriyi insert yapmış olurlar.
- Import / Export tool’u ile alınan veri de yine maskelenmiş olarak çekilecektir.
Veritabanında hangi tablolarda ve alanlarda maskeleme olduğunu şu sorgu ile görebiliriz.
SELECT c.name, tbl.name as table_name, c.is_masked, c.masking_function FROM sys.masked_columns AS c JOIN sys.tables AS tbl ON c.[object_id] = tbl.[object_id] WHERE is_masked = 1;
Maskelemeyi kaldırmak için yine Alter Table komutunu kullanacağız.
ALTER TABLE DataMaskDemo ALTER COLUMN LastName DROP MASKED;
Umarım faydalı bir makale olmuştur.
Anlaşılmayan bir yer veya sorunuz olursa lütfen yorum olarak yazın.