Spark セキュリティ

Sparkセキュリティ: 知らなければならない事

SparkでのセキュリティはデフォルトではOFFです。これはデフォルトでは攻撃に脆弱性があることを意味します。Sparkは複数の配備の種類をサポートし、それぞれは異なるレベルのセキュリティをサポートします。全ての環境で全ての配備が安全なわけではありません。デフォルトでは安全ではありません。環境、Sparkが何をサポートするのかを確認し、Sparkの配備を安全にするために適切な方法を取ってください。

セキュリティの問題には様々な種類があります。Sparkは必ずしも全てを保護するわけではありません。以下でリスト化されたものはSparkがサポートするものの一部です。また、配備固有の設定に使用している配備の種類について、配備ドキュメントを調べてください。ドキュメント化されていないものは全てSparkはサポートしません。

Spark RPC (Sparkプロセス間の通信プロトコル)

認証

現在のところSparkは共有秘密鍵を使ってRPCチャネルのための認証をサポートします。認証はspark.authenticate設定パラメータを設定することで有効にすることができます。

共有鍵を生成および分配するために使われる正確な仕組みは配備に固有です。

YARN上あるいはローカ配備のSparkのために、Sparkは共有秘密鍵の生成と配布を自動的に処理します。各アプリケーションはユニークな共有鍵を使うでしょう。YARNの場合、この機能は秘密鍵を安全に配布するために有効にされるYARN RJPC暗号化に依存します。

他のリソースマネージャーの場合、spark.authenticate.secretが各ノード上で設定される必要があります。この秘密鍵は全てのデーモンとアプリケーションで共有されるため、この配備設定は特にマルチテナントクラスタを考慮した場合、上記ほど安全ではありません。この設定では、秘密鍵を持つユーザは他のユーザに事実上成り済ますことができます。

Rest Submission サーバと MesosClusterDispatcher は認証をサポートしません。REST API & MesosClusterDispatcher (デフォルトではそれぞれポート 6066 および 7077) への全てのネットワークアクセスが、ジョブの送信が信頼されているホストに制限されていることを確認する必要があります。

プロパティ名デフォルト意味
spark.authenticate false Sparkが内部接続を認証するかどうか。
spark.authenticate.secret None 認証に使われる秘密鍵。この設定が設定される時については、上記を見てください。

暗号化

Spark は RPC接続のために AESベースの暗号化をサポートします。暗号化を有効にするためには、RPC認証も有効にして適切に設定する必要があります。AES 暗号化は Apache Commons Crypto ライブラリを使用し、Sparkの設定システムによって上級ユーザ向けにそのライブラリの設定にアクセスすることができます。

SASLベースの暗号化もサポートされますが、非推奨と見なされるべきです。2.2.0より古いSparkバージョンからシャッフルサービスに通信する時にまだ必要とされます。

以下の表はこの機能を設定するために利用可能な様々なオプションを示します。

プロパティ名デフォルト意味
spark.network.crypto.enabled false 2.2.0で追加された新しい認証プロトコルを含む、AESベースのRPC暗号化を有効にします。
spark.network.crypto.keyLength 128 生成する暗号化キーのビット単位の長さ。有効な値は 128, 192 および 256 です。
spark.network.crypto.keyFactoryAlgorithm PBKDF2WithHmacSHA1 暗号化キーを生成する時に使用する キー ファクトリー アルゴリズム。使用されるJREでの javax.crypto.SecretKeyFactory クラスでサポートされるアルゴリズムのうちの一つでなければなりません。
spark.network.crypto.config.* None どのcipher実装を使うかなどの共通暗号化ライブラリのための設定値。設定名はcommons.crypto プリフィックス無しのcommons-crypto設定の名前にする必要があります。
spark.network.crypto.saslFallback true Sparkの内部機構を使った認証が失敗した時にSASL認証にフォールバックするかどうか。内部的なSpark認証プロトコルをサポートしない古いシャッフルサービスにアプリケーションが接続している時に便利です。シャッフルサービス側では、この機能を無効にすると古いクライアントの認証がブロックされます。
spark.authenticate.enableSaslEncryption false SASLベースの暗号化通信。
spark.network.sasl.serverAlwaysEncrypt false SASL認証を使っているポートについて非暗号化通信を無効にします。これにより、認証が有効になっているがSASLベースの暗号化を要求しないクライアントからの接続が拒否されます。

ローカルストレージの暗号化

Spark はローカルディスクに書きこまれた一時データの暗号化をサポートします。これはシャッフルファイル、シャッフルスピル、およびディスクに格納されたデータブロックが含まれます (キャッシュ変数とブロードキャスト変数の両方) 。saveAsHadoopFile あるいは saveAsTable のようなAPIを使ってアプリケーションによって生成された暗号化出力データは含まれません。ユーザによって明示的に作成された一時ファイルを含まないかもしれません。

以下の設定はディスクに書き込まれたデータの暗号化を有効にします:

プロパティ名デフォルト意味
spark.io.encryption.enabled false ローカルディスク I/Oの暗号化を有効にします。現在のところ、Mesosを除いて全てのモードでサポートされます。この機能を使う場合は、RPC暗号化を有効にすることを強くお勧めします。
spark.io.encryption.keySizeBits 128 IO 暗号化キーサイズのビット数。サポートされる値は 128, 192 と 256 です。
spark.io.encryption.keygen.algorithm HmacSHA1 IO暗号化キーを生成する場合に使うアルゴリズム。サポートされるアルゴリズムは Java Cryptography Architecture Standard Algorithm Name ドキュメントのKeyGeneratorの章で説明されます。
spark.io.encryption.commons.config.* None どのcipher実装を使うかなどの共通暗号化ライブラリのための設定値。設定名はcommons.crypto プリフィックス無しのcommons-crypto設定の名前にする必要があります。

Web UI

認証と権限

Web UIのための認証を有効にするには、javax servlet filtersを使用します。配備したい認証方法を実装するフィルタが必要です。Spark jは組み込みの認証フィルタを提供しません。

Spark は認証フィルタが存在する場合のUIへのアクセス制御もサポートします。各アプリケーションは独自の個別のアクセス制限リスト (ACL)を使って設定することができます。 Sparkは “view” 権限 (誰がアプリケーションのUIを見ることができるか) と “modify” 権限 (誰が実行中のアプリケーションでジョブを強制終了できるか) を区別します。

ACL はユーザあるいはグループのいずれかに設定できます。設定エントリは入力としてカンマ区切りのリストを受け付けます。つまり複数のユーザあるいはグループに必要な権限を付与できます。 これは、共有クラスタ上で実行し、自分で起動していないアプリケーションを監視する必要がある管理者あるいは開発者のセットがある場合に使うことができます。特定のACLに追加されたワイルドカード (*) は、全てのユーザがそれぞれの権限を持つことを意味します。デフォルトでは、アプリケーションを送信するユーザだけがACLに追加されます。

グループメンバーシップは設定可能なグループマッピング プロバイダを使って確立されます。マッパーは以下の表で説明されるspark.user.groups.mapping 設定オプションを使って設定されます。

以下のオプションはWeb UIの認証を制御します:

プロパティ名デフォルト意味
spark.ui.filters None フィルターをどのように設定するかについては、Spark UI 設定を見てください。
spark.acls.enable false UIのACLを有効にするかどうか。有効な場合、これはユーザがアプリケーションを表示あるいは変更するためのアクセス権限を持っているかどうかを確認します。これにはユーザが認証される必要があるため、もし認証フィルターがインストールされていない場合、このオプションは何もしません。
spark.admin.acls None Sparkアプリケーションへの表示と変更のアクセスを持つユーザのカンマ区切りのリスト。
spark.admin.acls.groups None Sparkアプリケーションへの表示と変更のアクセスを持つグループのカンマ区切りのリスト。
spark.modify.acls None Sparkアプリケーションへの変更のアクセスを持つユーザのカンマ区切りのリスト。
spark.modify.acls.groups None Sparkアプリケーションへの変更のアクセスを持つグループのカンマ区切りのリスト。
spark.ui.view.acls None Sparkアプリケーションへの表示のアクセスを持つユーザのカンマ区切りのリスト。
spark.ui.view.acls.groups None Sparkアプリケーションへの表示のアクセスを持つグループのカンマ区切りのリスト。
spark.user.groups.mapping org.apache.spark.security.ShellBasedGroupsMappingProvider ユーザのためのグループのリストは、プロパティによって設定することができる org.apache.spark.security.GroupMappingServiceProviderによって定義されるグループマッピングサービスによって決定されます。
デフォルトで、ホストOSからこの情報を集めるUnixシェルベースの実装が使われます。
注意: この実装は Unix/Linuxベースの環境のみサポートします。Windows環境は現在のところサポートされません。ただし、上記の特性を実装することにより、新しいプラットフォームをサポートできます。

YARN上では、表示と変更ACLはアプリケーションを送信した時にYARNサービスに提供され、YARNインタフェースを介してそれぞれの権限を持つユーザを制御します。

Spark履歴サーバのACLs

SHS Web UIのための認証は、servletフィルタを使って通常のアプリケーションと同じ方法で有効にされます。

SHSで認証を有効にするために、幾つかの追加オプションが使われます:

プロパティ名デフォルト意味
spark.history.ui.acls.enable false 履歴サーバ内でアプリケーションを表示するユーザを認証するために、ACLをチェックするかどうかを指定します。有効な場合、個々のアプリケーションがspark.ui.acls.enableに設定した内容に関係なく、アクセス制限のチェックが行われます。アプリケーションの所有者は自身のアプリケーションを見るために常に認証されることになり、アプリエケ-ションが実行された場合にspark.ui.view.aclsを使って指定された全てのユーザとspark.ui.view.acls.groups を使って指定されたグループもアプリケーションを見るために認証されるでしょう。無効な場合、履歴サーバを介して利用可能なアプリケーションのUIについてアクセス制限チェックは行われません。
spark.history.ui.admin.acls None 履歴サーバ内で全てのSparkアプリケーションへのviewアクセスを持つユーザのカンマ区切りのリスト。
spark.history.ui.admin.acls.groups None 履歴サーバ内で全てのSparkアプリケーションへのviewアクセスを持つグループのカンマ区切りのリスト。

SHSは同じ設定を使用してグループマッピング プロバイダを通常のアプリケーションとして設定します。この場合、グループマッピング プロバイダはSHSによって全てのUIサーバに適用され、個々のアプリケーションの設定は無視されます。

SSL 設定

SSLのための設定は階層構造によって整理されます。プロトコル固有の設定で上書きされていない限り、ユーザは全てのサポートされる通信プロトコルのために使われるデフォルトのSSL設定を設定することができます。このようにユーザは全てのプロトコルのための共通の設定を、それぞれ個々に設定する機能を無効にすること無しに、簡単に提供することができます。以下の表はSSL設定名前空間を示します。

設定の名前空間 コンポーネント
spark.ssl デフォルトのSSL設定。これらの値は、名前空間レベルで明示的に上書きされない限り、以下の全ての名前空間に適用されます。
spark.ssl.ui Spark アプリケーション Web UI
spark.ssl.standalone スタンドアローン マスター / ワーカー Web UI
spark.ssl.historyServer 履歴サーバ Web UI

利用可能なSSLオプションの完全なブレークダウンは以下で見つけることができます。${ns}のプレースホルダーは上記の名前空間のうちの1つで置き換えられなければなりません。

プロパティ名デフォルト意味
${ns}.enabled false SSLを有効にします。有効にする場合、${ns}.ssl.protocol が必要です。
${ns}.port None SSLサービスがlistenするポート。
ポートは特定の名前空間設定内で定義されなければなりません。デフォルトの名前空間はこの設定を読む時に無視されます。
設定しない場合は、SSLポートは同じサービスの非SSLポートから取得されるでしょう。"0" の値はサービスを短命ポートに結びつけるでしょう。
${ns}.enabledAlgorithms None cipherのカンマ区切りのリスト。指定されたcipherはJVMによってサポートされなければなりません。
プロトコルのリファレンスのリストはJavaセキュリティガイドの "JSSE Cipher Suite Names" の章で見つけることができます。Java 8 のリストはこのページで見つけることができます。
注意: 設定しない場合、JREのためのデフォルトのcipherスイートが使われます。
${ns}.keyPassword None キーストア内の秘密鍵へのパスワード。
${ns}.keyStore None キーストア ファイルへのパス。パスはプロセスが開始されたディレクトリへの絶対あるいは相対パスです。
${ns}.keyStorePassword None Password to the key store.
${ns}.keyStoreType JKS キーストアの種類。
${ns}.protocol None 使用するプロトコル。プロトコルはJVMによってサポートされなければなりません。
プロトコルのリファレンスのリストはJavaセキュリティガイドの "Additional JSSE Standard Names" の章で見つけることができます。Java 8 については、リストをこのページで見つけることができます。
${ns}.needClientAuth false クライアント認証を必要とするかどうか。
${ns}.trustStore None 信頼ストア ファイルへのパス。パスはプロセスが開始されたディレクトリへの絶対あるいは相対パスです。
${ns}.trustStorePassword None 信頼ストアのためのパスワード。
${ns}.trustStoreType JKS 信頼ストアの種類。

Spark はHadoop 資格プロバイダから${ns}.keyPassword, ${ns}.keyStorePassword および ${ns}.trustStorePasswordの取得もサポートします。 ユーザはパスワードを資格情報ファイルに保存し、以下のように異なるコンポーネントからアクセスできるようにすることができます:

hadoop credential create spark.ssl.keyPassword -value password \
    -provider jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks

資格プロバイダの場所を設定するには、以下のようにSparkが使用するHadoop設定の中のhadoop.security.credential.provider.path設定オプションを見てください:

  <property>
    <name>hadoop.security.credential.provider.path</name>
    <value>jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks</value>
  </property>

または、SparkConf の “spark.hadoop.hadoop.security.credential.provider.path=jceks://hdfs@nn1.example.com:9001/user/backup/ssl.jceks” を介して。

キーストアの準備

キーストアはkeytool プログラムで生成することができます。Java 8 のためのこのツールのリファレンス文章は ここにあります。Spark スタンドアローン配備モードのためのキーストアとtrustストアを設定する最も基本的なステップは以下の通りです:

YARN モード

クラスタモードで実行中のドライバにローカルクラスタストアあるいはキーストアを提供するために、--files コマンドライン引数 (あるいは 同等のspark.files 設定)を使ってアプリケーションと共に配布できます。ファイルはドライバの作業ディレクトリに配置されるため、TLS設定は絶対パスではなくファイル名のみを参照する必要があります。

この方法でローカルキーストアを配布するには、ファイルをHDFS (あるいはクラスタで使用される他の似た分散ファイルシステム)に置く必要があるかもしれません。そのため基礎となるファイルシステムはセキュリティを考慮して設定することをお勧めします (例えば、認証とwire暗号化を有効にする)。

スタンドアローンモード

ユーザがマスターとワーカーのためにキーストアと設定オプションを提供する必要があります。それらはSPARK_MASTER_OPTSSPARK_WORKER_OPTS 環境変数内、あるいは単にSPARK_DAEMON_JAVA_OPTSの中で、適切なJavaシステムプロパティを加えることで設定されなければなりません。

ユーザはexecutorにワーカープロセスから継承したSSL設定を使えるようにするかも知れません。これはspark.ssl.useNodeLocalConftrue に設定することで実現できます。この場合、クライアント側でユーザによって提供された設定は使われません。

Mesos モード

Mesos 1.3.0 以上はファイルベースおよび環境ベースの両方の秘密鍵としてSecrets プリミティブをサポートします。Sparkはそれぞれspark.mesos.driver.secret.filenamesspark.mesos.driver.secret.envkeys を使ってファイルベースと環境変数ベースの秘密鍵の使用を許可します。

秘密ストアに応じて、バックエンドの秘密鍵はそれぞれspark.mesos.driver.secret.namesspark.mesos.driver.secret.values構成プロパティを持つリファレンスあるいは値で渡すことができます。

参照型の秘密鍵は秘密鍵ストアとして提供され、名前で参照されます。例えば /mysecret。値型の秘密鍵はコマンドラインで渡され、適切なファイルあるいは環境変数に解釈されます。

HTTP セキュリティ ヘッダ

Apache Sparkは Cross Site Scripting (XSS), Cross-Frame Scripting (XFS), MIME-Sniffing を避けるのに役立ち、HTTP Strict Transport Securityも強制する HTTPヘッダを含むように設定することができます。

プロパティ名デフォルト意味
spark.ui.xXssProtection 1; mode=block HTTP X-XSS-Protection 応答ヘッダのための値。以下から適切な値を選択することができます:
  • 0 (XSSフィルタリングを無効にします)
  • 1 (XSS フィルタリングを有効にします。もし cross-site scripting アタックが検知されると、ブラウザはページをサニタイズするでしょう。)
  • 1; mode=block (XSS フィルタリングを有効にします。もし攻撃が検知されるとブラウザはページのレンダリングを避けるでしょう。)
spark.ui.xContentTypeOptions.enabled true 有効にされると、X-Content-Type-Options HTTP 応答ヘッダは "nosniff" に設定されるでしょう。
spark.ui.strictTransportSecurity None HTTP Strict Transport Security (HSTS) 応答ヘッダのための値。以下から適切な値を選択し、それに応じてexpire-timeを設定することができます。このオプションは SSL/TLS が有効な場合のみ使用されます。
  • max-age=<expire-time>
  • max-age=<expire-time>; includeSubDomains
  • max-age=<expire-time>; preload

ネットワークセキュリティのためのポートの設定

一般的に言って、Spark クラスタとそのサービスは公的なインターネットに配備されません。それらは一般的にプライベートなサービスで、Sparkを配備する組織のネットワーク内でのみアクセス可能な筈です。Sparkサービスによって使われるホストとポートへのアクセスはサービスへアクセスする必要があるオリジンのホストに制限されるべきです。

以下はSparkが通信のために使用する主なポートと、それらのポートの設定方法です。

スタンドアローンモードのみ

FromToデフォルトのポート目的設定備考
ブラウザ スタンドアローンマスター 8080 Web UI spark.master.ui.port /
SPARK_MASTER_WEBUI_PORT
Jetty-based. スタンドアローンモードのみ。
ブラウザ スタンドアローン ワーカー 8081 Web UI spark.worker.ui.port /
SPARK_WORKER_WEBUI_PORT
Jetty-based. スタンドアローンモードのみ。
Driver /
スタンドアローン ワーカー
スタンドアローンマスター 7077 クラスタへのジョブのサブミット /
Join cluster
SPARK_MASTER_PORT ポートをランダムに選択するには"0"を設定します。スタンドアローンモードのみ。
External Service スタンドアローンマスター 6066 REST APIを使ってジョブをクラスタに提出します spark.master.rest.port このサービスを有効/無効にするには、spark.master.rest.enabledを使います。スタンドアローンモードのみ。
スタンドアローンマスター スタンドアローン ワーカー (random) スケジュール executor SPARK_WORKER_PORT ポートをランダムに選択するには"0"を設定します。スタンドアローンモードのみ。

全てのクラスタマネージャー

FromToデフォルトのポート目的設定備考
ブラウザ アプリケーション 4040 Web UI spark.ui.port Jetty-based
ブラウザ ヒストリーサーバ 18080 Web UI spark.history.ui.port Jetty-based
Executor /
スタンドアローンマスター
Driver (random) アプリケーションへの接続 /
executor の状態の変更を通知
spark.driver.port ポートをランダムに選択するには"0"を設定します。
Executor / Driver Executor / Driver (random) ブロックマネージャー ポート spark.blockManager.port ServerSocketChannelを使ったrawソケット

Kerberos

Sparkは認証のためにKerberosを使う環境でのアプリケーションの提出をサポートします。ほとんどの場合、Sparkは、Kerberos対応サービスの認証時に現在ログインしているユーザの資格情報に依存します。そのような資格情報は設定されたKDCにkinitのようなツールを使ってログインすることで取得できます。

Hadoopベースのサービスと通信する場合、Sparkは非ローカルプロセスが認証できるように移譲トークンを取得する必要があります。SparkにはHDFSと他のHadoopシステム、HiveとHBaseのためのサポートが付属しています。

(DFS あるいは WebHDFSのような)Hadoopファイルシステムを使う場合、Sparkはユーザのホームディレクトリをホストするサービスのための関連トークンを取得します。

HBaseがアプリケーションのクラスパスにあり、HBase構成でKerberos認証が有効になっている場合 (hbase.security.authentication=kerberos)、HBaseトークンが取得されます。

同様に、Hive がクラスタパスにあり、構成にリモートのメタストア サービスのURIが含まれる場合 (hive.metastore.uris が空では無い)、Hiveトークンが取得されます。

移譲トークンのサポートは現在のところYARNとMesosモードでのみサポートされます。詳細は配備固有のページを参照してください。

以下のオプションはこの機能のきめ細やかな制御を提供します:

プロパティ名デフォルト意味
spark.security.credentials.${service}.enabled true セキュリティが有効な場合に、サービスのための証明書を取得するかどうかを制御します。デフォルトではサービスが設定されている場合に全てのサポートされるサービスのための証明書が取り出されるようにしますが、アプリケーションが実行されるのに何かしらの衝突がある場合はその挙動を無効にすることができます。

長時間実行中のアプリケーション

長時間実行中のアプリケーションは、実行時間がアクセスする必要のあるサービスで設定された移譲トークンの最大生存時間を超えた場合、問題が発生するかもしれません。

Spark はYARNモードで実行する場合にそれらのアプリケーションのための新しいトークンの自動作成をサポートします。Kerberos認証情報は spark-submit コマンドを介して--principal--keytab パラメータを使ってSparkアプリケーションに提供される必要があります。

提供されたキータブはHadoop分散キャッシュを使ってアプリケーションマスタを実行しているマシーンにコピーされるでしょう。このため、少なくともYARNとHDFSの両方を暗号化で保護することを強くお勧めします。

Kerberosログインは提供された資格情報を使って定期的に更新され、新しいサポートされる移譲トークンが作成されます。

イベントのログ

アプリケーションがイベントログを使っている場合は、イベントログが入るディレクトリ(spark.eventLog.dir) は手動で作成され、適切なパーミッションが設定されていなければなりません。ログファイルを保護するために、ディレクトリのパーミッションは drwxrwxrwxt に設定されなければなりません。ディレクトリの所有者とグループはSpark履歴サーバを実行するスーパーユーザに対応する必要があります。

これにより、全てのユーザはディレクトリに書き込むことができますが、権限のないユーザはファイルを所有していない限り、ファイルの読み込み、削除あるいは名前の変更をできません。イベントログファイルはSparkによってユーザおよびグループのみが読み書きアクセスを持つパーミッションで生成されるでしょう。

TOP
inserted by FC2 system