Hadoop-安全实践指南-三-

66 阅读11分钟

Hadoop 安全实践指南(三)

原文:Practical Hadoop security

协议:CC BY-NC-SA 4.0

十一、附录 C:为 HTTP 加密设置密钥库和信任库

一个密钥库是一个数据库或密钥和证书库,用于各种目的,包括认证、加密或数据完整性。一般来说,密钥库包含两种类型的信息:密钥条目和可信证书。

我已经在第四章的“加密 HTTP 通信”一节中讨论了如何用网络加密配置您的 Hadoop 集群。作为设置的一部分,您需要创建 HTTPS 证书和密钥库。

创建 HTTPS 证书和密钥库/信任库文件

要创建 HTTPS 证书和密钥库,您需要执行以下步骤:

  1. 对于每个主机,在SKEYLOC创建一个目录来存储密钥库和信任库(您可以根据自己的喜好替换目录名)。

  2. For each host, create a key pair and a separate KeyStore. If your operating system command prompt is $, you have set the SKEYLOC directory parameter, and assuming an example of a two-node cluster with hosts pract_hdp_sec and pract_hdp_sec2, the necessary code would look like the following:

    $ cd $SKEYLOC
    
    $ keytool -genkey -alias pract_hdp_sec -keyalg RSA -keysize 1024 –dname "CN=pract_hdp_sec,OU=IT,O=Ipsos,L=Chicago,ST=IL,C=us" -keypass 12345678 -keystore phsKeyStore1 -storepass 87654321
    
    $ keytool -genkey -alias pract_hdp_sec2 -keyalg RSA -keysize 1024 -dname "CN=pract_hdp_sec2,OU=IT,O=Ipsos,L=Chicago,ST=IL,C=us" -keypass 56781234 -keystore phsKeyStore2 –storepass 43218765
    
    

    这段代码生成两个密钥对(一个公钥和相关的私钥)和单元素证书链,分别存储为密钥库phsKeyStore1中的条目pract_hdp_sec和密钥库phsKeyStore2中的条目pract_hdp_sec2。请注意,RSA 算法用于公钥加密,密钥长度为 1024。

  3. 对于每台主机,将证书的公钥导出到单独的证书文件:

    $cd $SKEYLOC;
    $keytool -export -alias pract_hdp_sec -keystore phsKeyStore1 -rfc -file pract_hdp_sec_cert -storepass 87654321
    $keytool -export -alias pract_hdp_sec2 -keystore phsKeyStore2 -rfc -file pract_hdp_sec2_cert -storepass 43218765
    
    
  4. For all the hosts, import the certificates into TrustStore file:

    $cd $SKEYLOC;
    $keytool -import -noprompt -alias pract_hdp_sec -file pract_hdp_sec_cert -keystore phsTrustStore1 -storepass 4324324
    $keytool -import -noprompt -alias pract_hdp_sec2 -file pract_hdp_sec2_cert -keystore phsTrustStore1 -storepass 4324324
    
    

    注意,信任库文件是新创建的,以防它不存在。

  5. 将密钥库和信任库文件复制到相应的节点:

    $scp phsKeyStore1 phsTrustStore1 root@pract_hdp_sec:/etc/hadoop/conf/
    $scp phsKeyStore2 phsTrustStore2 root@pract_hdp_sec2:/etc/hadoop/conf/
    
    
  6. 验证通用信任库文件:

    $keytool -list -v -keystore phsTrustStore1 -storepass 4324324
    
    

调整密钥库/信任库文件的权限

Keystore 文件只需要拥有所有者和组的读取权限,组应该设置为hadoop。信任库文件应该对每个人(所有者、组和其他人)都有读取权限。以下命令对此进行了设置:

$ssh root@pract_hdp_sec "cd /etc/hadoop/conf;chgrp hadoop phsKeyStore1;
chmod 0440 phsKeyStore1;chmod 0444 phsTrustStore1

$ssh root@pract_hdp_sec2 "cd /etc/hadoop/conf;chgrp hadoop phsKeyStore2;
chmod 0440 phsKeyStore2;chmod 0444 phsTrustStore2

如果需要,您可以生成公钥证书安装在您的浏览器中。这就完成了 HTTP 加密的密钥库和信任库的设置。

十二、附录 D:Hadoop 指标及其与安全性的相关性

在第七章的“Hadoop 指标”部分,您回顾了什么是 Hadoop 指标,如何对指标应用过滤器,以及如何将它们定向到文件或监控软件,如 Ganglia。您将很快了解到,您也可以将这些指标用于安全性。

您应该记得,您可以使用 Hadoop 指标来设置警报,以捕捉系统资源中的突然变化。此外,您可以设置 Hadoop 集群来监控 NameNode 资源,并在任何指定的资源偏离所需参数时生成警报。例如,我将向您展示当以下资源的偏差超过月平均值 50%或更多时,如何生成警报:

FilesCreated
FilesDeleted
Transactions_avg_time
GcCount
GcTimeMillis
LogFatal
MemHeapUsedM
ThreadsWaiting

首先,我将 NameNode 指标输出到一个文件中。为此,我将下面几行添加到目录$HADOOP_INSTALL/hadoop/conf中的文件hadoop-metrics2.properties中:

*.sink.tfile.class=org.apache.hadoop.metrics2.sink.FileSink
namenode.sink.tfile.filename = namenode-metrics.log

接下来,我设置过滤器只包含必要的指标:

*.source.filter.class=org.apache.hadoop.metrics2.filter.GlobFilter
*.record.filter.class=${*.source.filter.class}
*.metric.filter.class=${*.source.filter.class}
namenode.sink.file.metric.filter.include=FilesCreated
namenode.sink.file.metric.filter.include=FilesDeleted
namenode.sink.file.metric.filter.include=Transactions_avg_time
namenode.sink.file.metric.filter.include=GcCount
namenode.sink.file.metric.filter.include=GcTimeMillis
namenode.sink.file.metric.filter.include=LogFatal
namenode.sink.file.metric.filter.include=MemHeapUsedM
namenode.sink.file.metric.filter.include=ThreadsWaiting

我过滤后的指标列表现在正被写入输出文件namenode-metrics.log

接下来,我开发了一个脚本,每天将这个文件加载到 HDFS,并将其作为一个新分区添加到一个 Hive 表中。然后,我重新计算 30 天的平均值,同时考虑新的值,并将平均值与新加载的每日值进行比较。

如果这些值的偏差超过 50%,我可以向我的 Hadoop 系统管理员发送一条消息,告知该节点的名称和偏离的指标。然后,系统管理员可以检查适当的日志,以确定是否存在任何安全漏洞。例如,如果ThreadsWaiting指标偏离超过 50%,那么系统管理员将需要检查审计日志,以查看当时谁在访问集群以及谁在执行作业,然后检查审计日志指示的相关作业。例如,一个可疑的作业可能需要检查 JobTracker 和适当的 TaskTracker 日志。

或者,您可以将这些作业的输出定向到 Ganglia,然后使用 Nagios 在任何指标值出现偏差时生成警报。

表 D-1 到 D-4 列出了一些常用的 Hadoop 指标。首先列出 JVM 和 RPC 上下文指标,因为它们是由所有 Hadoop 守护进程生成的。

表 D-1 。JVM 和 RPC 上下文度量

|

度量组

|

度量名称

|

描述

| | --- | --- | --- | | 虚拟机(Java Virtual Machine 的缩写) | GcCount | 企业控制台 JVM 的垃圾收集数量 | |   | GcTimeMillis | 计算所有垃圾收集花费的总时间(以毫秒为单位) | |   | LogError | 出现 Log4j 级别错误的日志行数 | |   | LogFatal | Log4j 级别致命的日志行数 | |   | LogWarn | Log4j 级别警告的日志行数 | |   | LogInfo | 包含 Log4j 级别信息的日志行数 | |   | MemHeapCommittedM | 计算企业控制台 JVM 提交的堆内存 | |   | MemHeapUsedM | 计算企业控制台 JVM 提交的堆内存 | |   | ThreadsBlocked | 处于阻塞状态的线程数,这意味着它们正在等待锁 | |   | ThreadsWaiting | 处于等待状态的线程数,这意味着它们正在等待另一个线程执行某个操作 | |   | ThreadsRunnable | 在 JVM 中执行但可能正在等待系统资源(如 CPU)的处于可运行状态的线程数 | |   | ThreadsTerminated | 处于终止状态的线程数,这意味着它们已完成执行。该值应该大约为零,因为该指标仅收集活动线程的信息。 | |   | ThreadsNew | 处于新状态的线程数,这意味着它们尚未启动 | | 位置遥控(remote position control) | ReceivedBytes | RPC 接收的字节数 | |   | SentBytes | RPC 发送的字节数 | |   | RpcProcessingTimeAvgTime | 处理 RPC 请求的平均时间 | |   | RpcProcessingTimeNumOps | 已处理的 RPC 请求数 | |   | RpcQueueTimeAvgTime | RPC 请求在队列中花费的平均时间 | |   | RpcQueueTimeNumOps | 排队的 RPC 请求数 | |   | RpcAuthorizationSuccesses | 成功的 RPC 授权调用数 | |   | RpcAuthorizationFailures | 失败的 RPC 授权调用数 | |   | RpcAuthenticationSuccesses | 成功的 RPC 认证调用的次数 | |   | RpcAuthenticationFailures | 失败的 RPC 认证调用数 |

表 D-2。NameNode 和 DataNode 指标

|

度量组

|

度量名称

|

描述

| | --- | --- | --- | | Hadoop.HDFS.NameNode | AddBlockOps | 群集的添加块操作数 | |   | CapacityRemaining | HDFS 剩余的总产能 | |   | CapacityTotal | HDFS 和其他分布式文件系统中剩余的总容量 | |   | CapacityUsed | HDFS 使用的总容量 | |   | CreateFileOps | 群集的创建文件操作次数 | |   | DeadNodes | 群集中存在的死节点数 | |   | DecomNodes | 群集中存在的退役节点的数量 | |   | DeleteFileOps | 在 HDFS 发生的“删除”文件操作的数量 | |   | FSState | NameNode 的状态,可以是安全模式或操作模式 | |   | FileInfoOps | 群集中发生的文件访问操作的数量 | |   | FilesAppended | 集群中附加的文件数量 | |   | FilesCreated | 群集中创建的文件数量 | |   | FilesDeleted | 群集中删除的文件数 | |   | FilesInGetListingOps | 群集中发生的获取列表操作的数量 | |   | FilesRenamed | 群集中重命名的文件数 | |   | LiveNodes | 群集中活动节点的数量 | |   | NonDfsUsedSpace | 计算群集中使用的非 HDFS 空间 | |   | PercentRemaining | 剩余 HDFS 容量的百分比 | |   | PercentUsed | 已用 HDFS 容量的百分比 | |   | Safemode | 计算安全模式状态:1 表示安全模式开启;0 表示安全模式关闭 | |   | SafemodeTime | 显示 NameNode 在安全模式下花费的时间 | |   | Syncs_avg_time | 同步操作的平均时间 | |   | Syncs_num_ops | 同步操作的次数 | |   | TotalBlocks | 簇中的总块数 | |   | TotalFiles | 群集中的文件总数 | |   | Transactions_avg_time | 交易的平均时间 | |   | Transactions_num_ops | 交易操作的数量 | |   | UpgradeFinalized | 指示升级最终确定为真还是假 | |   | addBlock_avg_time | 在集群中创建新块的平均时间 | |   | addBlock_num_ops | 在集群中添加数据块的操作次数 | |   | blockReceived_avg_time | 接收块操作的平均时间 | |   | blockReceived_num_ops | 块接收操作的数量 | |   | blockReport_num_ops | 块报告操作的数量 | |   | blockReport_avg_time | 块报告操作的平均时间 | |   | TimeSinceLastCheckpoint | 计算自上次检查点以来的时间 | | Hadoop.HDFS.DataNode | BlocksRead | 从硬盘读取块的次数,包括复制块 | |   | BlocksRemoved | DataNode 上已删除或失效的块数 | |   | BlocksReplicated | 从一个 DataNode 传输或复制到另一个 DataNode 的块数 | |   | BlocksVerified | 块验证的次数,包括成功或失败的尝试 | |   | BlocksWritten | 写入磁盘的块数 | |   | BytesRead | 读取和复制块时读取的字节数 | |   | BytesWritten | 为响应接收到的块而写入磁盘的字节数 | |   | HeartbeatsAvgTime | 从 DataNode 向 NameNode 发送心跳的平均时间 | |   | BlocksRemoved | DataNode 上已删除或失效的块数 | |   | BlocksReplicated | 从一个 DataNode 传输或复制到另一个 DataNode 的块数 | |   | HeartbeatsNumOps | 群集中发生的心跳操作的数量 |

表 D-3。JobTracker 生成的 MapReduce 度量

|

度量组

|

度量名称

|

描述

| | --- | --- | --- | | Hadoop.Mapreduce.Jobtracker | blacklisted_maps | 每个任务跟踪者中列入黑名单的地图槽的数量 | |   | Heartbeats | JobTracker 检测信号的总数 | |   | blacklisted_reduces | 每个 TaskTracker 中列入黑名单的 reduce 槽的数量 | |   | callQueueLen | 计算 RPC 调用队列长度 | |   | HeartbeatAvgTime | 心跳的平均时间 | |   | jobs_completed | 已完成作业的数量 | |   | jobs_failed | 失败的作业数 | |   | jobs_killed | 被终止的作业数量 | |   | jobs_running | 正在运行的作业数量 | |   | jobs_submitted | 提交的作业数量 | |   | maps_completed | 已完成地图的数量 | |   | maps_failed | 失败地图的数量 | |   | maps_killed | 被杀死的地图数量 | |   | maps_launched | 已启动地图的数量 | |   | memNonHeapCommittedM | 非堆提交的内存(MB) | |   | memNonHeapUsedM | 非堆使用的内存(MB) | |   | occupied_map_slots | 已占用地图位置的数量 | |   | map_slots | 地图位置的数量 | |   | occupied_reduce_slots | 已占用的缩减插槽数量 | |   | reduce_slots | 缩减插槽的数量 | |   | reduces_completed | 完成的减速器数量 | |   | reduces_failed | 失败的减速器数量 | |   | reduces_killed | 死亡人数减少 | |   | reduces_launched | 投放的减速器数量 | |   | reserved_map_slots | 保留的映射槽数量 | |   | reserved_reduce_slots | 保留的缩减插槽数量 | |   | running_0 | 正在运行的作业数量 | |   | running_1440 | 运行时间超过 24 小时的作业数 | |   | running_300 | 运行时间超过五小时的作业数 | |   | running_60 | 运行超过一小时的作业数 | |   | running_maps | 运行地图的数量 | |   | running_reduces | 跑步次数减少 | |   | Trackers | TaskTrackers 数量 | |   | trackers_blacklisted | 列入黑名单的 TaskTrackers 数量 | |   | trackers_decommissioned | 退役的 TaskTrackers 数量 | |   | trackers_graylisted | 灰色列表任务跟踪器的数量 | |   | waiting_reduces | 等待次数减少 | |   | waiting_maps | 等待地图的数量 |

表 D-4 。h 基本指标

|

度量组

|

度量名称

|

描述

| | --- | --- | --- | | hbase.master | MemHeapUsedM | 使用的堆内存(MB) | |   | MemHeapCommittedM | 提交的堆内存(MB) | |   | averageLoad | 每个区域服务器服务的平均区域数 | |   | numDeadRegionServers | 死区服务器的数量 | |   | numRegionServers | 在线区域服务器的数量 | |   | ritCount | 转型区域的数量 | |   | ritCountOverThreshold | 超过由属性rit.metrics.threshold.time定义的阈值的过渡区域的数量 | |   | clusterRequests | 从所有区域服务器到群集的请求总数 | |   | HlogSplitTime_mean | 分割预写日志文件总大小的平均时间 | |   | HlogSplitTime_min | 分割预写日志文件总大小的最短时间 | |   | HlogSplitTime_max | 重新启动后分割预写日志文件的最长时间 | |   | HlogSplitTime_num_ops | 分割预写日志文件的时间 | |   | HlogSplitSize_mean | 分割 Hlog 文件总大小的平均时间 | |   | HlogSplitSize_min | 分割 Hlog 文件总大小的最短时间 | |   | HlogSplitSize_max | 分割 Hlog 文件总大小的最长时间 | |   | HlogSplitSize_num_ops | 被拆分的预写日志文件的大小 | | hbase.regionserver | appendCount | WAL 附加的数量 | |   | blockCacheCount | 块缓存中缓存的存储文件数 | |   | blockCacheEvictionCount | 已从块缓存中收回的块的总数 | |   | blockCacheFreeSize | 块缓存中空闲的字节数 | |   | blockCacheExpressHitPercent | 计算打开缓存的请求的块缓存命中率 | |   | blockCacheHitCount | 请求的块缓存命中总数,不考虑缓存设置 | |   | blockCountHitPercent | 不管缓存设置如何,所有请求的块缓存命中率 | |   | blockCacheMissCount | 请求的块缓存未命中总数,不考虑缓存设置 | |   | blockCacheSize | 缓存块使用的字节数 | |   | compactionQueueLength | CompactionQueue 上的 HRegions 数。这些区域对所有存储调用 compact,然后确定是否需要压缩以及压缩的类型。 | |   | MemMaxM | 计算使用的总堆内存(MB) | |   | MemHeapUsedM | 计算使用的堆内存(MB) | |   | MemHeapCommittedM | 计算提交的堆内存(MB) | |   | GcCount | 垃圾收集总数 | |   | updatesBlockedTime | 为了刷新内存存储而被阻止的内存存储更新的数量 | |   | memstoreSize | 以 MB 为单位计算所有区域中所有内存的大小 | |   | readRequestCount | 区域服务器读取请求的数量 | |   | regionCount | 区域服务器服务的在线区域数量 | |   | slowAppendCount | 花费 1000 毫秒以上完成的追加数 | |   | slowGetCount | 完成时间超过 1000 毫秒的获取数 | |   | slowPutCount | 花费超过 1000 毫秒完成的 put 数 | |   | slowIncrementCount | 完成时间超过 1000 毫秒的增量数 | |   | slowDeleteCount | 完成时间超过 1000 毫秒的删除数 | |   | storeFileIndexSize | 以 MB 为单位计算所有存储文件索引的大小。这些不一定在内存中,因为它们也存储在块缓存中,可能已经被收回。 | |   | storeFileCount | 所有商店和地区的商店文件数量 | |   | storeCount | 所有地区的商店数量 | |   | staticBloomSize | 计算所有布隆过滤器的总大小,这些过滤器不一定加载到内存中 | |   | writeRequestCount | 对区域服务器的写入请求数 | |   | staticIndexSize | 计算所有区域服务器实体的总静态索引大小 |

第一部分:Hadoop 及其安全性简介

第二部分:在您的 Hadoop 集群中进行认证和授权

第三部分:审核日志记录和安全监控

第四部分:Hadoop 加密

第五部分:附录