从Spark保存到S3 / S3A的数据帧是未加密的,尽管设置了"fs.s3a.encryption.algorithm PP_5 fs.s3a.encryption.key"



描述

在PySpark中,即使DataFrame可以保存到S3/S3A(不是AWS,而是S3兼容的存储器(,但其数据仍会以未加密的方式保存,尽管使用了设置fs.s3a.encryption.algorithm(SSE-C(和fs.s3a.encryption.key

再现性

生成如下密钥:

encKey=$(openssl rand -base64 32)

启动PySpark外壳:

pyspark --master spark://[some_host]:7077 
--packages io.delta:delta-core_2.12:2.0.0,org.apache.hadoop:hadoop-aws:3.3.1,com.amazonaws:aws-java-sdk-bundle:1.11.901,org.apache.hadoop:hadoop-common:3.3.1 
--conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" 
--conf "spark.sql.catalog.spark_catalog=org.apache.spark.sql.delta.catalog.DeltaCatalog"

在PySpark中,一个玩具示例:

sc._jsc.hadoopConfiguration().set("fs.s3a.access.key", "[access.key]")
sc._jsc.hadoopConfiguration().set("fs.s3a.secret.key", "[secret.key]")
sc._jsc.hadoopConfiguration().set("fs.s3a.endpoint", "[s3.compliant.endpoint]")
sc._jsc.hadoopConfiguration().set("fs.s3a.encryption.algorithm", "SSE-C")
sc._jsc.hadoopConfiguration().set("fs.s3a.encryption.key", "[the_encKey_above]")
from pyspark.sql.types import StructType,StructField, StringType, IntegerType
data2 = [("James","","Smith","36636","M",3000),
("Michael","Rose","","40288","M",4000),
("Robert","","Williams","42114","M",4000),
("Maria","Anne","Jones","39192","F",4000),
("Jen","Mary","Brown","","F",-1)
]
schema = StructType([ 
StructField("firstname",StringType(),True), 
StructField("middlename",StringType(),True), 
StructField("lastname",StringType(),True), 
StructField("id", StringType(), True), 
StructField("gender", StringType(), True), 
StructField("salary", IntegerType(), True) 
])

df = spark.createDataFrame(data=data2,schema=schema)
#df.write.format("csv").option("header", "true").save("s3a://data/test")
df.repartition(1).write.format("csv").option("header", "true").save("s3a://data/test")

我们可以看到创建的文件夹s3a://data/test,其中有一个CSV文件。但不幸的是,该文件是未加密的。也就是说,它甚至可以通过网络浏览器手动下载,然后用记事本查看!设置fs.s3a.encryption.algorithm似乎被忽略了。

环境

  • Apache Spark v3.2.2
  • Hadoop aws v3.3.1/Hadoop common v3.3.1
  • openjdk 11.0.16.1 2022-08-12(Temurin(
  • Python 3.10.4
  • Ubuntu 22.04 LTS

调试

有趣的是,如果使用AWS CLI:,那么同一个端点对上传的文件进行加密没有问题

aws --endpoint-url https://[s3.compliant.endpoint] 
s3api put-object 
--body "/home/[a_user]/Desktop/a_file.csv" 
--bucket "data" 
--key "test/a_file.csv" 
--sse-customer-algorithm AES256 
--sse-customer-key $encKey 
--sse-customer-key-md5 $md5Key
aws -version
# aws-cli/2.7.35 Python/3.9.11 Linux/5.15.0-48-generic exe/x86_64.ubuntu.22 prompt/off

我阅读了使用加密S3数据的手册指南,但没有任何帮助。

找到了一个解决方案:

hadoop-aws v3.3.1/aws-java-sdk-bundle v1.11.901/hadoop-common v3.3.1一定有一些错误,或者只是与S3的最新协议不兼容(截至2022.10.06(。可以通过使用库的最新版本来克服上述问题,即:hadoop-aws v3.3.4(因此是aws-java-sdk-bundle v1.12.262依赖项(和hadoop-common v3.3.4(以匹配hadoop-aws(。

在3.3.2至3.3.4的发行说明中,可能有一些与AWS/S3相关的修复程序有助于解决该问题。

  • https://hadoop.apache.org/docs/r3.3.2/hadoop-project-dist/hadoop-common/release/3.3.2/CHANGELOG.3.3.2.html
  • https://hadoop.apache.org/docs/r3.3.3/hadoop-project-dist/hadoop-common/release/3.3.3/CHANGELOG.3.3.3.html
  • https://hadoop.apache.org/docs/r3.3.4/hadoop-project-dist/hadoop-common/release/3.3.4/CHANGELOG.3.3.4.html

总结一下,对于PySpark,使用:

pyspark --master spark://[some_host]:7077 
--packages io.delta:delta-core_2.12:2.0.0,org.apache.hadoop:hadoop-aws:3.3.4,com.amazonaws:aws-java-sdk-bundle:1.12.262,org.apache.hadoop:hadoop-common:3.3.4 
--conf "spark.sql.extensions=io.delta.sql.DeltaSparkSessionExtension" 
...

使用hadoop 3.3.1或更早版本时,请使用fs.s3a.server-side-encryption算法和"fs.s3a.服务器端加密密钥";;";fs.s3a.encryption。*";选项仅在hadoop3.3.2中提供,并在hadoop-13887 中支持客户端加密

相关内容

最新更新