Linux 上的 SQL Server 的安全功能演练

适用于:Linux 上的 SQL Server

如果你是刚接触 SQL Server 的 Linux 用户,以下任务会引导你完成某些安全任务。 这些任务并非Linux独有或特有,但它们能让你了解需要进一步调查的领域。 每个示例都链接到该领域的详细文档。

本文中的代码示例使用 AdventureWorks2025AdventureWorksDW2025 示例数据库,可以从 Microsoft SQL Server 示例和社区项目 主页下载该数据库。

创建登录名和数据库用户

通过在数据库中创建带有CREATE LOGIN该语句的登录,master授权他人访问 SQL Server。 例如:

CREATE LOGIN Larry
    WITH PASSWORD = '<password>';

注意

密码应遵循 SQL Server 默认密码策略。 默认情况下,密码必须为至少八个字符且包含以下四种字符中的三种:大写字母、小写字母、十进制数字、符号。 密码可最长为 128 个字符。 使用的密码应尽可能长,尽可能复杂。

登录名可连接到 SQL Server,且能(通过有限权限)访问 master 数据库。 若要连接到用户数据库,登录名需要数据库级别的相应标识,称为数据库用户。 用户是针对每个数据库的,因此您必须在每个数据库中单独创建用户才能获得访问权限。

以下示例切换到数据库, AdventureWorks2025 然后使用该 CREATE USER 语句创建一个名为 Larry 的用户,该用户映射为 Larry的登录名。 虽然登录和用户是相关(映射到彼此的),但它们是不同的对象。 登录名是服务器级主体。 用户是数据库级主体。

USE AdventureWorks2025;
GO

CREATE USER Larry;
GO
  • SQL Server 管理员帐户可连接到任何数据库,并可在任何数据库中创建更多登录名和用户。
  • 当你创建数据库时,你会成为数据库所有者,可以连接到该数据库。 数据库所有者可以创建更多用户。

之后,可向其他登录名授予 ALTER ANY LOGIN 权限,使其可以创建更多登录名。 在数据库中,可向其他用户授予 ALTER ANY USER 权限,使其可以创建更多用户。 例如:

GRANT ALTER ANY LOGIN TO Larry;
GO

USE AdventureWorks2025;
GO

GRANT ALTER ANY USER TO Jerry;
GO

现在,登录 Larry 可以创建更多登录,用户 Jerry 也可以创建更多用户。

按最小权限原则授予访问权限

管理员和数据库所有者通常是最先连接到用户数据库的用户。 这些账户拥有数据库的所有权限。 不要用这些账户做需要更少权限的任务。

刚开始时,你可以用内置 的固定数据库角色分配一些通用权限类别。 例如, db_datareader 固定数据库角色可以读取数据库中的所有表,但不能进行更改。 通过声明 ALTER ROLE 授予固定数据库角色的成员资格。 以下示例将用户 Jerry 添加到 db_datareader 固定数据库角色中。

USE AdventureWorks2025;
GO

ALTER ROLE db_datareader ADD MEMBER Jerry;

有关固定数据库角色的列表,请参阅数据库级角色

之后,当你准备好配置更精确的数据访问时(强烈推荐),用语 CREATE ROLE 句创建你自己的用户定义数据库角色。 然后将特定精细级别的权限分配给自定义角色。

例如,以下语句创建了一个名为 Sales的数据库角色,赋予 Sales 该组读取、更新和删除 Orders 表行的能力,然后将用户 Jerry 添加到该 Sales 角色中。

CREATE ROLE Sales;

GRANT SELECT ON OBJECT::Orders TO Sales;
GRANT UPDATE ON OBJECT::Orders TO Sales;
GRANT DELETE ON OBJECT::Orders TO Sales;

ALTER ROLE Sales ADD MEMBER Jerry;

有关权限系统的详细信息,请参阅数据库引擎权限入门

配置行级别安全性

行级安全 允许您根据运行查询的用户限制数据库中对行的访问。 此功能适用于确保客户只能访问自己数据,或员工只能访问其部门数据等场景。

以下步骤将逐步介绍如何设置两个不同行级访问 Sales.SalesOrderHeader 表的用户。

创建两个用户账户以测试行级安全:

USE AdventureWorks2025;
GO

CREATE USER Manager WITHOUT LOGIN;
CREATE USER SalesPerson280 WITHOUT LOGIN;

向两个用户授予对 Sales.SalesOrderHeader 表的读取访问权限:

GRANT SELECT ON Sales.SalesOrderHeader TO Manager;
GRANT SELECT ON Sales.SalesOrderHeader TO SalesPerson280;

创建一个新架构和一个内联表值函数。 当列中的SalesPersonID行与登录IDSalesPerson匹配,或者运行查询的用户就是用户时Manager,该函数才会返回1

CREATE SCHEMA Security;
GO

CREATE FUNCTION Security.fn_securitypredicate
(@SalesPersonID INT)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
    SELECT 1 AS fn_securitypredicate_result
    WHERE ('SalesPerson' + CAST (@SalesPersonId AS VARCHAR (16)) = USER_NAME())
          OR (USER_NAME() = 'Manager')

创建一个安全策略,将此函数同时作为筛选器谓词和阻止谓词添加到表上:

CREATE SECURITY POLICY SalesFilter
    ADD FILTER PREDICATE Security.fn_securitypredicate(SalesPersonID) ON Sales.SalesOrderHeader,
    ADD BLOCK PREDICATE Security.fn_securitypredicate(SalesPersonID) ON Sales.SalesOrderHeader
    WITH (STATE = ON);

运行以下语句以每个用户身份查询 SalesOrderHeader 表。 验证是否 SalesPerson280 只看到他们自己销售额的 95 行,而 Manager 可以看到表中的所有行。

EXECUTE AS USER = 'SalesPerson280';

SELECT *
FROM Sales.SalesOrderHeader;

REVERT;

EXECUTE AS USER = 'Manager';

SELECT *
FROM Sales.SalesOrderHeader;

REVERT;

修改安全策略以禁用它。 现在两个用户都可以访问所有行。

ALTER SECURITY POLICY SalesFilter
    WITH (STATE = OFF);

启用动态数据掩码

利用动态数据掩码,你可以通过完全或部分掩蔽特定列来限制对应用程序用户公开敏感数据。

使用 ALTER TABLE 语句将掩码函数添加到 EmailAddress 表中的 Person.EmailAddress 列:

USE AdventureWorks2025;
GO

ALTER TABLE Person.EmailAddress
    ALTER COLUMN EmailAddress
        ADD MASKED WITH (FUNCTION = 'email()');

创建一个带有SELECT权限的新用户TestUser,然后执行查询以TestUser查看被掩蔽的数据:

CREATE USER TestUser WITHOUT LOGIN;

GRANT SELECT
    ON Person.EmailAddress TO TestUser;

EXECUTE AS USER = 'TestUser';

SELECT EmailAddressID,
       EmailAddress
FROM Person.EmailAddress;

REVERT;

验证掩蔽函数是否将第一条记录中的电子邮件地址更改为:

EmailAddressID 电子邮件地址
1 ken0@adventure-works.com

EmailAddressID 电子邮件地址
1 kXXX@XXXX.com

启用透明数据加密

攻击者可以从你的硬盘中窃取数据库文件。 这种情况可能发生在攻击者获得系统升级访问权限、员工窃取文件,或有人窃取存储文件的计算机时。

透明数据加密 (TDE) 对存储在硬盘上的数据文件进行加密。 master SQL Server 数据库引擎 的数据库包含加密密钥,因此 数据库引擎 可以操作数据。 如果没有密钥的访问权限,则无法读取数据库文件。 高级管理员可以管理、备份和重建密钥,因此只有特定人员可以移动数据库。 启用TDE时,SQL Server也会自动加密数据库tempdb

由于 数据库引擎 可以读取数据,TDE 无法防止计算机管理员未经授权访问,这些管理员可以通过管理员账户直接读取内存或访问 SQL Server。

配置 TDE

  • 创建主密钥
  • 创建或获取由主密钥保护的证书
  • 创建一个数据库加密密钥,并用证书保护它
  • 将数据库设置为使用加密

配置 TDE 需要对 CONTROL 数据库具有 master 权限和对用户数据库具有 CONTROL 权限。 通常由管理员配置 TDE。

以下示例展示了使用服务器上安装的证书MyServerCert对数据库进行加密和解密AdventureWorks2025

USE master;
GO

CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<master-key-password>';
GO

CREATE CERTIFICATE MyServerCert
    WITH SUBJECT = 'My Database Encryption Key Certificate';
GO

USE AdventureWorks2025;
GO

CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_256
    ENCRYPTION BY SERVER CERTIFICATE MyServerCert;
GO

ALTER DATABASE AdventureWorks2025
    SET ENCRYPTION ON;

若要移除 TDE,请运行以下命令:

ALTER DATABASE AdventureWorks2025
    SET ENCRYPTION OFF;

SQL Server 在后台线程上安排加密和解密操作。 您可以通过本文后面列表中的目录视图和动态管理视图查看这些操作的状态。

Warning

数据库加密密钥还会加密启用TDE的数据库的备份文件。 因此,当您还原这些备份时,用于保护数据库加密密钥的证书必须可用。 除了备份数据库,你还必须备份服务器证书以防止数据丢失。 如果证书不再可用,就会导致数据丢失。 有关详细信息,请参阅 SQL Server Certificates and Asymmetric Keys

有关 TDE 的详细信息,请参阅透明数据加密 (TDE)

配置备份加密

SQL Server 可以在创建备份时加密数据。 通过在创建备份时指定加密算法和加密程序(证书或非对称密钥),可创建加密的备份文件。

Warning

一定要备份证书或非对称密钥,最好备份到与备份文件不同的位置。 没有证书或非对称密钥,你将无法还原备份,从而使备份文件无法使用。

以下示例创建证书,然后创建受该证书保护的备份。

USE master;
GO

CREATE CERTIFICATE BackupEncryptCert
    WITH SUBJECT = 'Database backups';
GO

BACKUP DATABASE [AdventureWorks2025]
TO DISK = N'/var/opt/mssql/backups/AdventureWorks2025.bak'
WITH COMPRESSION,
    ENCRYPTION (ALGORITHM = AES_256, SERVER CERTIFICATE = BackupEncryptCert),
    STATS = 10;
GO

有关详细信息,请参阅备份加密