メッセージングのセキュリティ¶
このセクションでは、OpenStack で使用される最も一般的なメッセージキュー製品である、Rabbit MQ、Qpid、ZeroMQ の堅牢化アプローチについて説明します。
メッセージ通信路のセキュリティ¶
AMQP ベースの製品 (Qpid, RabbitMQ) は TLSを用いた通信路レベルのセキュリティに対応しています。ZeroMQ はTLSをネイティブでサポートしていませんが、ラベル付き IPsec や CIPSO ネットワークラベルを用いた通信路レベルのセキュア化に対応しています。
メッセージキューには、通信路レベルでの暗号化を強く推奨します。メッセージクライアントとの接続に TLS を用いることで、メッセージサーバとの通信路における通信の改ざんや傍受を防ぐことが可能です。以下、よく使われる 2 種類のメッセージサーバ Qpid、および、RabbitMQ における一般的な TLS の設定について説明します。クライアント接続の正当性を保証する目的でメッセージサーバに証明機関 (CA) バンドルを設定する場合、該当ノードに限定した CA の使用を、またなるべくなら組織内部で管理している CA の使用を推奨します。信頼された CA バンドルは許可を与えるクライアント接続証明書を決定し、TLS 接続を張るためのクライアントサーバ検証のステップを通過させます。証明書とキーのファイルをインストールする際は、chmod 0600
などでファイルのパーミッションを限定させ、所有者をメッセージサーバのデーモンユーザに限定させるようにしてください。こうすることで、メッセージサーバ上の許可を与えていない他プロセスやユーザによるアクセスを防ぐことできます。
RabbitMQ サーバにおける SSL 設定¶
下記の設定を RabbitMQ のシステム設定ファイルに追加します。通常、/etc/rabbitmq/rabbitmq.config
に保存されています。
[
{rabbit, [
{tcp_listeners, [] },
{ssl_listeners, [{"<IP address or hostname of management network interface>", 5671}] },
{ssl_options, [{cacertfile,"/etc/ssl/cacert.pem"},
{certfile,"/etc/ssl/rabbit-server-cert.pem"},
{keyfile,"/etc/ssl/rabbit-server-key.pem"},
{verify,verify_peer},
{fail_if_no_peer_cert,true}]}
]}
].
Note, the tcp_listeners
option is set to []
to prevent it from
listening on a non-SSL port. The ssl_listeners
option should be
restricted to only listen on the management network for the services.
RabbitMQ の SSL 設定に関する詳細は、以下を参照してください。
Qpid サーバ SSL 設定¶
Apache Foundation が Qpid のメッセージングセキュリティガイドを発行しています。
キューの認証およびアクセス制御¶
RabbitMQ と Qpid はキューへのアクセス制御を目的とした、認証およびアクセス制御の仕組みを持っています。ZeroMQ にはこのような仕組みは備わっていません。
Simple Authentication and Security Layer (SASL) はインターネットプロトコルにおける認証とデータセキュリティのフレームワークです。RabbitMQ と Qpid は SASL の他、プラグイン形式の認証メカニズムを提供しており、単純なユーザ名とパスワードよりもセキュアな認証が可能になっています。RabbitMQ は SASL をサポートしているものの、現在の OpenStack は特定の SASL 認証メカニズムの使用を許可していません。RabbitMQ では、非暗号化接続でのユーザ名とパスワード認証か、X.509 クライアント証明書を用いたセキュアな TLS 接続でのユーザ名とパスワード認証がサポートされています。
全ての OpenStack サービスノードにおいて、メッセージキューへのクライアント接続に X.509 クライアント証明書を設定することを推奨します。また可能なら、X.509 クライアント証明書での認証も推奨します (現時点では対応しているのは Qpid のみ)。ユーザ名とパスワードを用いる場合、キューに対するアクセスの監査の粒度を細かくするため、アカウントはサービス毎、ノード毎に作成するべきです。
導入前に、キューサーバが使用する TLS ライブラリについて考慮します。Qpid はMozilla の NSS ライブラリを、RabbitMQ は OpenSSL を使う Erlang の TLS モジュールを用いています。
認証設定例: RabbitMQ¶
RabbitMQ サーバーにおいて、デフォルトの guest
ユーザーを削除します。
# rabbitmqctl delete_user guest
RabbitMQ サーバにて、メッセージキューを使用する各 OpenStack サービス、または、ノード毎にユーザアカウントと権限を設定します。
# rabbitmqctl add_user compute01 RABBIT_PASS
# rabbitmqctl set_permissions compute01 ".*" ".*" ".*"
RABBIT_PASS を適切なパスワードに置き換えます。
追加の設定情報は以下を参照してください。
OpenStack サービス設定: RabbitMQ¶
[DEFAULT]
rpc_backend = nova.openstack.common.rpc.impl_kombu
rabbit_use_ssl = True
rabbit_host = RABBIT_HOST
rabbit_port = 5671
rabbit_user = compute01
rabbit_password = RABBIT_PASS
kombu_ssl_keyfile = /etc/ssl/node-key.pem
kombu_ssl_certfile = /etc/ssl/node-cert.pem
kombu_ssl_ca_certs = /etc/ssl/cacert.pem
認証設定例: Qpid¶
設定情報は以下を参照してください。
OpenStack サービス設定: Qpid¶
[DEFAULT]
rpc_backend = nova.openstack.common.rpc.impl_qpid
qpid_protocol = ssl
qpid_hostname = <IP or hostname of management network interface of messaging server>
qpid_port = 5671
qpid_username = compute01
qpid_password = QPID_PASS
オプションとして Qpid で SASL を使用する場合は、下記のように SASL メカニズムを指定します。
qpid_sasl_mechanisms = <space separated list of SASL mechanisms to use for auth>
メッセージキュープロセスのアイソレーションとポリシー¶
各プロジェクトは多数のサービスを提供し、それぞれがメッセージを送信、消費します。メッセージを送信した各バイナリは、リプライのみの場合、該当キューからメッセージを消費するはずです。
メッセージキューサービスのプロセスは、他のキューサービスのプロセスや、同一マシン上の他プロセスと分離すべきです。
名前空間¶
ネットワーク名前空間の設定は、OpenStack コンピュートハイパーバイザを動作させる全てのサービスで強く推奨します。ネットワーク名前空間を用いることで、VM ゲストと管理ネットワークのトラフィックがブリッジングされることを防ぎます。
ZeroMQ メッセージングを使用する場合、ネットワーク経由のメッセージ受信と、IPC経由によるローカルプロセスへのメッセージ送信のために、各ホストに最低 1 つの ZeroMQ メッセージレシーバーを走らせる必要があります。IPC 名前空間内にプロジェクト毎で独立したメッセージレシーバーを構築することが可能であり望ましいです。また同様に、同一プロジェクト内でも異なるサービスごとに独立したメッセージレシーバーを構築することが望ましいです。
ネットワークポリシー¶
キューサーバーは管理ネットワークからの接続のみを受け付けるべきであり、この方針はあらゆる実装に適用されます。サービスの設定を通して実装し、任意でグローバルネットワークポリシーを追加で実装します。
ZeroMQ を使用するのであれば、各プロジェクトで独立した専用のポート上で動作する ZeroMQ レシーバープロセスを用意すべきです。これは、AMQP のコントロール exchange の概念に相当します。
強制アクセス制御¶
強制アクセス制御と任意アクセス制御を併用して、プロセスの設定をそれらのプロセスのみに制限します。この制限により、これらのプロセスが、同じマシンで動作している他のプロセスから分離されることを防ぎます。