更新时间:2025-12-16 GMT+08:00
分享

配置Spark动态脱敏

操作场景

动态脱敏是一种安全特性,允许你根据用户的权限或角色对数据进行部分或全部屏蔽,从而保护敏感数据不被未经授权的用户访问。

Spark动态脱敏开启后,配置脱敏列的数据可以参与计算,计算结果输出时不可见,在集群内脱敏策略会根据血缘关系自动传递,更大地发挥数据的价值同时,保障数据的隐私性。

约束与限制

  • 本章节仅适用于MRS 3.3.1-LTS及之后版本。
  • 管理面提交作业方式不支持开启动态脱敏特性。
  • 不支持Hudi表的脱敏。
  • 不支持非SQL使用方法的脱敏。
  • 不支持涉及直接读写HDFS的操作的脱敏。
  • 不支持复杂类型array、map、struct的脱敏。
  • 只支持spark-beeline(JDBC 连接)方式提交Spark作业。
  • 脱敏策略传递时,若目标表已有脱敏策略且与源表有冲突,则目标表脱敏策略强制重置为Custom:“***”。
  • MRS 3..6.0之前版本:当前仅支持int、char、varchar、date、decimal、float、bigint、timestamp 、tinyint、smallint、double、string、binary数据类型的脱敏,其中int、date、decimal、float、bigint、timestamp 、tinyint、smallint、double类型配置脱敏策略后,spark-beeline查询结果存在与策略预期不一致的现象,但查询结果非原始值,如需要与策略结果保持一致,则推荐使用“Nullify”脱敏策略。
  • MRS 3.6.0-LTS及之后版本:当前仅支持int、char、varchar、date、decimal、float、bigint、timestamp 、tinyint、smallint、double、string、binary数据类型的脱敏,其中int、date、decimal、float、bigint、timestamp 、tinyint、smallint、double、binary类型配置脱敏策略后,spark-beeline查询结果为null,如需要与策略结果保持一致,则推荐使用“Nullify”脱敏策略。
  • 对于不支持的数据类型,如果配置了脱敏策略或输出列涉及脱敏传递,最终都按“Nullify”脱敏策略处理。
  • MRS 3.6.0-LTS及之后版本:对于操作符、UDF返回的类型为不支持的类型时,如果在动态脱敏处理范围,统一按“Nullify”脱敏策略处理。对于不支持的类型,可能出现空指针问题,如:使用distinct操作符,入参大于2时,返回结果为struct类型,如果入参中包含脱敏涉及字段,在spark-beeline场景下,会出现空指针问题。
  • 管理面提交作业方式不支持开启动态脱敏特性。

配置Spark动态脱敏

  1. 修改JDBCServer实例配置。登录FusionInsight Manager页面,选择“集群 > 服务 > Spark > 配置 > 全部配置 > JDBCServer(角色)”,修改如下参数,保存配置,并重启Spark服务。

    • 使用Ranger鉴权场景,在参数“custom”中添加如下自定义参数:

      参数

      参数说明

      spark.dynamic.masked.enabled

      true

      是否启用动态脱敏,启用该功能可以增强数据安全性。

      • true:启用动态数据屏蔽功能。
      • false:禁用动态数据屏蔽功能。

      spark.ranger.plugin.authorization.enable

      true

      是否开启Ranger鉴权功能。启用该功能可以增强数据访问的安全性,如果需要细粒度的访问控制,建议启用此功能并进行相应的配置。

      • true:启用Ranger鉴权功能。
      • false:禁用Ranger鉴权功能。

      修改如下参数值:

      参数名称

      参数说明

      spark.ranger.plugin.masking.enable

      true

      配置是否启用Ranger插件的列脱敏功能。启用该功能可以增强数据的安全性,但需要确保 Ranger服务已经正确配置,并且定义了合适的屏蔽策略。

      • true:启用Ranger插件的列脱敏功能。
      • false:禁用Ranger插件的列脱敏功能。

      spark.sql.authorization.enabled

      true

      安全模式下开启SQL鉴权,启用此功能后,Spark会根据用户的角色和权限来执行SQL查询,从而提供细粒度的访问控制。

      • true:启用SQL鉴权功能。
      • false:禁用SQL鉴权功能。
    • 对于不使用Ranger鉴权,依然使用Hive元数据鉴权场景,在参数“custom”中添加如下自定义参数:

      参数名称

      参数说明

      spark.ranger.plugin.use.hive.acl.enable

      true

      是否启用Spark使用Hive的ACL进行授权检查。

      • true:启用Spark使用Hive的ACL进行授权检查。
      • false:禁用Spark使用Hive的ACL进行授权检查。

      spark.dynamic.masked.enabled

      true

      是否启用动态脱敏,启用该功能可以增强数据安全性。

      • true:启用动态数据屏蔽功能。
      • false:禁用动态数据屏蔽功能。

      spark.ranger.plugin.authorization.enable

      true

      是否开启Ranger鉴权功能。启用该功能可以增强数据访问的安全性,如果需要细粒度的访问控制,建议启用此功能并进行相应的配置。

      • true:启用Ranger鉴权功能。
      • false:禁用Ranger鉴权功能。

      修改如下参数值:

      参数名称

      参数说明

      spark.ranger.plugin.masking.enable

      true

      配置是否启用Ranger插件的列脱敏功能。

      • true:启用Ranger插件的列脱敏功能。
      • false:禁用Ranger插件的列脱敏功能。
    不使用Ranger鉴权,使用Hive元数据鉴权场景,如果Ranger中未完成Hive策略初始化,需要做以下操作:
    1. 开启组件Hive的“Ranger鉴权”的功能,重启Hive组件+Spark组件。
    2. 开启组件Spark的“Ranger鉴权”的功能,重启Spark组件。
    3. 关闭组件Hive的“Ranger鉴权”的功能,重启Hive组件。
    4. 关闭组件Spark的“Ranger鉴权”的功能,重启Spark组件。
    1. 登录Ranger WebUI界面,如果“HADOOP SQL”下存在Hive组件表示已经完成Hive策略初始化,不存在则未初始化。
    2. 如果集群同时安装了HetuEngine组件,且需要Spark动态脱敏触发策略传递时自动同步更新Ranger、HetuEngine空间的脱敏策略,需要将参数“spark.dynamic.masked.hetu.policy.sync.update.enable”设置为“true”,且需将内置用户Spark的Ranger用户类型调整为Admin用户类型。

  2. 登录Spark客户端节点,执行如下命令:

    进入客户端目录:
    cd 客户端安装目录

    加载环境变量:

    source bigdata_env

    加载组件环境变量:

    source Spark/component_env

    安全模式执行安全认证,普通模式无需执行:

    kinit test

    输入密码完成认证(首次登录需要修改密码)

  3. 使用Spark的beeline命令提交任务,创建Spark表:

    spark-beeline
    create table sparktest(a int, b string);
    insert into sparktest values (1,"test01"), (2,"test02");

  4. 参考添加Spark的Ranger访问权限策略,给sparktest表配置脱敏策略,验证脱敏是否生效:

    select  * from sparktest;

  5. 验证脱敏策略传递:

    create table sparktest02 as select * from sparktest;
    select * from sparktest02;

    出现以上结果表示,动态脱敏配置已生效,登录ranger脱敏策略管理界面可以看到有自动生成的表sparktest02的脱敏策略。

特性说明

  • Spark动态脱敏后返回字段类型与输出列的schema类型一致,无法保持一致的使用null表示脱敏后的结果。
  • 支持不脱敏UDF名单和强制hash脱敏UDF名单配置。

    参数名称

    说明

    取值示例

    spark.sql.udf.hash.dynamic.mask

    开启动态脱敏后,使用Partial mask: show last 4、Partial mask: show first 4、Custom脱敏策略脱敏时,需要强制使用hash脱敏处理的函数名单。如果有多个函数需要强制使用hash脱敏处理,则以英文逗号隔开。

    substr,substring,left,right,concat,concat_ws,lpad,repeat,rpad,reverse

    spark.sql.udf.skip.dynamic.mask

    开启动态脱敏后,不需要脱敏处理的函数名单。如果有多个函数不需要脱敏处理,则以英文逗号隔开。

    count

    配置的UDF函数名需要为执行计划真实使用的函数名。如left函数,执行时使用的是substring函数,所以配置spark.sql.udf.hash.dynamic.mask或spark.sql.udf.skip.dynamic.mask时需要配置substring,配置left不生效。

    可以使用explain语句获取执行时对应的函数名,如:

    spark.sql.udf.skip.dynamic.mask的优先级大于spark.sql.udf.hash.dynamic.mask。如果一个函数名同时配置在spark.sql.udf.skip.dynamic.mask和spark.sql.udf.hash.dynamic.mask中时,会按照spark.sql.udf.skip.dynamic.mask逻辑处理,不进行脱敏处理。

  • Custom脱敏策略支持配置mask_partial函数:
    mask_partial函数介绍
    1. 处理数值类型的mask_partial说明。
      mask_partial(column_name, mask_digital, mask_from[, mask_to])

      描述:针对数值类型数据(int、decimal、float、bigint、tinyint、smallint、double),将第mask_from到mask_to位的数字部分脱敏成mask_digital对应的数字。

      表1 参数说明1

      参数

      说明

      mask_to

      允许缺省,缺省时即脱敏到数据结束位置。

      mask_digital

      只能取[1,9]区间内的数字。

      返回值类型:与入参column_name数据类型相同。

      对于decimal、float、double类型,小数点参与计数,但不参与脱敏。如:列内容为:3.1415926,mask_partial('2',1,3),返回值:2.2415926。

      Spark-beeline场景下,使用mask_partial对decimal脱敏后,结果会不符合预期,但结果是脱敏的,非原始值。

    2. 处理字符类型的mask_partial说明。
      mask_partial(column_name , mask_char, mask_from[, mask_to])

      描述:针对字符类型数据(char, varchar,string),对照指定的输入输出格式,将第mask_from到mask_to位的数字部分脱敏成mask_char指定的字符。

      表2 参数说明2

      参数

      说明

      mask_char

      脱敏字符,仅允许长度为1的任意字符。支持字符范围:

      • 大写字母:A, B, C, D, E, ..., Z
      • 小写字母:a, b, c, d, e, ..., z
      • 阿拉伯数字:0, 1, 2, 3, 4, 5, 6, 7, 8, 9
      • 标点符号:句号(.)、逗号(,)、问号(?)、感叹号(!)、冒号(:)、分号(;)、引号(")、括号(( 或 ),[ 或 ],{ 或 })、连字符(-)
      • 特殊符号:@ 符号 (@)、井号 (#)、美元符号 ($)、百分号 (%)、和号 (&)、星号 (*)、加号 (+)、等号 (=)、波浪号 (~)、下划线 (_)、竖线 (|)

      mask_from

      脱敏范围的起始位置,要求大于0。

      mask_to

      脱敏范围的结束位置,允许缺省。缺省时,即脱敏到原始数据结束位置。

      返回值类型:与入参column_name数据类型相同。

    1. 处理时间类型的mask_partial说明。

      mask_partial(column_name, mask_digital, mask_from[, mask_to])

      描述:针对时间类型数据(Date、TimeStamp),将第mask_from到mask_to位的数字部分脱敏成mask_digital对应的数字。

      表3 参数说明3

      参数

      说明

      mask_to

      允许缺省,缺省时即脱敏到数据结束位置。

      mask_digital

      只能取[1,9]区间内的数字。

      返回值类型:与入参column_name数据类型相同。
      1. Date只支持年、月、日的脱敏。
      2. TimeStamp支持年、月、日、时、分、秒、毫秒/微秒/纳秒的脱敏。
        • Date、TimeStamp中的“-”、“/”、空格、“:”参与计数,不脱敏。
        • Date、TimeStamp中,月、日的值脱敏后超过正常范围后将进行反转处理,例如:

          月的值为02,脱敏后为33,最终值为33%12=9。

          日的值为10,脱敏后为44,最终值为44 % (脱敏后的年对应的脱敏后的月的天数) , 假设脱敏后的年为2024,脱敏后的月为9(2024年9月有30天), 最终值为14。

      3. TimeStamp中的时、分、秒、毫秒/微秒/纳秒脱敏后,超过正常范围后,也进行反转处理。
        • 时的值为20,脱敏后为66,最终值为66%24=18。
        • 分的值为30,脱敏后为66,最终值为66%60=6。
        • 秒的值为50,脱敏后为66,最终值为66%60=6。
        • 毫秒/微秒/纳秒不涉及超出正常值范围场景。

          例如:

          date类型脱敏:值为1920-01-03,使用mask_partial('2',5,8)脱敏后,结果为1920-10-03。

          TimeStamp类型脱敏:值为'2023-12-05 12:34:56.789' ,使用mask_partial('2',5,8)脱敏后,结果为'2023-10-05 12:34:56.789'。

    mask_partial使用约束与限制说明
    • MRS mask_partial的入参中不支持嵌套UDF。
    • mask_partial遇到数值、字符、时间之外的不支持的类型时,统一返回null。
    • mask_from从1开始计数,即mask_from要求是大于0的整数,小于1时,默认按照1处理。
    • mask_to可以不填,不填时,默认为对应字符的结束位置,mask_to可以为负数,-1表示字符的结束位置。
    • mask_to对应字符串的位置不能在mask_from之前,遇到该情况时,统一返回null。
    • mask_partial处理类型为数值类型时, mask_digital不属于[1,9]区间内的数字时,UDF函数返回null。
    • mask_partial处理类型为字符类型时, mask_char不支持该字符类型时,UDF函数返回null。
    • 遇到mask_partial编写错误、入参不支持、入参有误场景, 引擎直接发生异常。
    • 支持中文字符的脱敏

    mask_partial使用介绍

    在ranger上配置脱敏策略,Mask Conditions选择Custom,在自定义输入框中填写mask_partial(mask_digital, mask_from[, mask_to]),其中mask_digital需要使用单引号括起来,如'9'、'*'。

    例如:mask_partial('*',1,5)

    Mask Conditions选择Custom,配置mask_partial脱敏函数时,第一个入参不需要指定列名,直接从mask_partial函数介绍中的第二个入参开始填写。

相关文档