序章

Consulは、インフラストラクチャ全体のさまざまなサービスの状態を簡単に検出して追跡するために使用できるサービス検出ツールです。 consulを使用してサービスを管理し、分散チェックシステムを維持して、アプリケーションまたはサーバーがダウンしたときに応答できることを確認できます。

最後のガイドでは、本番環境に対応した環境を準備することに焦点を当てました。 これには、実際にサービスを開始するために起動および起動スクリプトで読み取られる構成ファイルの作成が含まれていました。

これにより、最終的な基本構成にほとんど到達しましたが、構成を完全に保護することはできませんでした。 ゴシッププロトコルを非常に簡単に暗号化する単純な共有秘密ソリューションを実装しました。

ただし、RPC通信はこの時点ではまだ完全に暗号化されていません。 この問題を解決するために、領事館はTLS暗号化をネイティブにサポートしています。これについては、このガイドで取り上げます。 これを実装するには、認証局を作成し、署名してノードにキーを配布する必要があります。

前提条件と目標

このガイドを完了する前に、本番環境に対応した領事インフラストラクチャのセットアップに関する前回のガイドで残したように、領事サーバーのシステムをセットアップしておく必要があります。

そのガイド用に用意したサーバーには、次のプロパティがありました。

ホスト名 IPアドレス 役割
server1.example.com 192.0.2.1 ブートストラップ領事サーバー
server2.example.com 192.0.2.2 領事サーバー
server3.example.com 192.0.2.3 領事サーバー
agent1.example.com 192.0.2.50 領事クライアント

これらは64ビットのUbuntu14.04サーバーです。 これらの各サーバーは同じドメイン内にあることに注意してください。 これは、このガイドで実装する構成にとって重要です。これは、ドメイン内の任意のホストに一致するワイルドカード証明書を利用するためです。

このガイドでは、各サーバーの証明書に署名するためのTLS認証局の作成に焦点を当てます。 これにより、領事館のコンポーネントがIDを確認し、トラフィックを暗号化できるようになります。 次に、構成ファイルを少し変更して、ノードにトラフィックの暗号化を強制します。

SSL構造を作成する

まず、キーの管理に使用するいくつかの基本的なファイルとディレクトリを設定します。

繰り返しになりますが、このガイドのすべての手順をルートシェル内から実行します。 rootとしてログインするか、sudo権限を持つユーザーとしてsudo -iを使用してください。

各領事館のメンバーで、/etc/consul.dディレクトリ内にsslディレクトリを作成します。 これは、RPCトラフィックを暗号化するために必要なファイルを保持する場所です。

mkdir /etc/consul.d/ssl

認証局として使用する予定のサーバーでは、このディレクトリ内にサブディレクトリを作成して、証明書の作成と署名に必要なすべてのファイルを格納します。 認証局を収容するサーバーを選択できますが、ここでは、ブートストラップ構成も収容するserver1を使用します。

このサーバーで、作成したディレクトリの下にCAというサブディレクトリを作成します。

mkdir /etc/consul.d/ssl/CA

これには、他の人にアクセスさせたくない機密データが含まれている可能性があるため、アクセス許可をロックダウンしましょう。

chmod 0700 /etc/consul.d/ssl/CA

CAサーバのこのディレクトリに移動します。

cd /etc/consul.d/ssl/CA

ここでは、証明書署名のために存在する必要があるいくつかの基本的なファイルを作成します。 まず、証明書に次に使用可能なシリアル番号でインクリメントされるファイルを作成する必要があります。 これに値を事前にシードする必要があります。

これを行うには、000aの値をシリアルファイルにエコーします。

echo "000a" > serial

また、認証局が署名した証明書を記録できるファイルを提供する必要があります。 このファイルをcertindexと呼びます。

touch certindex

自己署名ルート証明書を作成する

認証局を使い始めるために必要な最初のステップは、自己署名ルート証明書を作成することです。 これは、Ubuntuマシンにデフォルトでインストールされているopensslコマンドを使用して実行できます。

証明書の作成に使用するコマンドは次のとおりです。

openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -out ca.cert

これが何を意味するのかを見てみましょう。

  • req :この引数は、リクエストを作成または処理することにより、 PKCS#10証明書を操作することに関心があることをopensslに通知します。
  • -x509 :この引数は、証明書要求の代わりに自己署名証明書が必要であることを指定します。 これは通常、ルートCA証明書に対して行われます。
  • -newkey rsa:2048 :これはopensslに新しい証明書要求と秘密鍵を生成するように指示します。 2048ビットのRSAキーが必要であることを指定する引数を渡します。
  • -日数3650:ここでは、証明書が有効であると見なされる日数を指定します。 3650の値を使用しています。これは10年です。
  • -nodes :これは、生成された秘密鍵がDESで暗号化されないことを指定します。これには、パスワードが必要です。 これにより、その要件が回避されます。
  • -out ca.cert :生成された証明書ファイルに使用されるファイル名を設定します。

証明書の作成プロセス中に、認証するホストに関する情報を入力するように求められます。 サーバーについて必要な関連情報をこれに入力できます。

. . .
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:ConsulCA
Email Address []:[email protected]

他の証明書で重要となるCommon Nameについては、お好きなものをお付けいただけます。

終了すると、ca.cert証明書ファイルと、privkey.pemという関連キーが作成されます。

ワイルドカード証明書署名要求を作成する

ルートCA証明書を取得したので、クライアントマシンの証明書署名要求を生成できます。

この場合、現在運用しているサーバーを含め、すべての領事メンバーがクライアントです。 サーバーごとに一意の証明書を生成してCAで署名する代わりに、ドメイン内のすべてのホストで有効なワイルドカード証明書を作成します。

コマンドの一般的な形式は同じですが、いくつかの小さな違いがあります。

openssl req -newkey rsa:1024 -nodes -out consul.csr -keyout consul.key

作成した自己署名ルートCA証明書要求と、現在生成している新しい証明書署名要求の違いは次のとおりです。

  • no -x509フラグ:自己署名証明書の代わりに証明書署名要求を生成するために、-x509フラグを削除しました。
  • -out consul.csr :出力されたファイルは証明書自体ではなく、証明書署名要求です。
  • -keyout consul.key :証明書署名要求に関連付けられているキーの名前を指定しました。

繰り返しになりますが、証明書署名要求(CSR)に対する応答を求められます。 これは、自己署名ルートCA証明書に対して提供した回答よりも重要です。 ここでは、証明書が各ホストに対して有効であるとチェックアウトするために、ワイルドカードCommon Nameを使用する必要があります。

. . .
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:*.example.com
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

ここに表示されているように、ドメイン内のすべてのホストに対して証明書が有効であると見なされる必要があることを示すために、ホストとしてアスタリスクを付けてドメインを使用しました。 最後に追加されるチャレンジパスワードとオプションの会社名プロンプトを安全にスキップできます。

認証局構成ファイルを作成する

これで、自己署名ルートCA証明書ファイルと、ドメイン内のすべてのホストに一致するワイルドカード証明書署名要求ができました。 CA証明書を使用して署名要求に署名する前に、これがどのように行われるかを制御する構成ファイルを作成する必要があります。

作成しているファイルをmyca.confと呼び、CA情報を保持します。 このファイルを今すぐ開きます。

nano /etc/consul.d/ssl/CA/myca.conf

このファイルは、セクションに分割されたINI形式を使用しています。 最初に定義するセクションは、caセクションです。 ここで行う唯一のことは、実際のCA情報を含むユーザー定義セクションを指すことです。

[ ca ]
default_ca = myca

次に、参照したセクションを作成します。 これには、CA構成の詳細の大部分が含まれます。

証明書プロンプトに入力される情報が一意である必要はないことを指定します。 次に、署名プロセスに必要な、作成したすべてのファイルの場所を指定します。 opensslに、現在のディレクトリに新しい証明書を配置するように指示します。

また、コマンドラインで代替が指定されていない場合に使用するデフォルトをいくつか選択します。 署名された証明書を10年間有効であると選択し、sha1アルゴリズムを使用します。 最後に、追加情報を定義するために作成するいくつかの追加セクションを示します。

[ myca ]
unique_subject = no
new_certs_dir = .
certificate = ca.cert
database = certindex
private_key = privkey.pem
serial = serial
default_days = 3650
default_md = sha1
policy = myca_policy
x509_extensions = myca_extensions

ここで、先ほど参照した最初のユーザー定義セクションに焦点を当てましょう。このセクションは、CSRを受け入れるために提供する必要のある情報を決定するために使用されます。 一部のフィールドを必須としてマークし、他のフィールドをオプションとしてマークします。 通常のプロンプトに対して、かなり標準的な選択を行います。

[ myca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional

最後のセクションでは、証明書に署名するときに使用するx509拡張機能を定義します。

まず、署名する証明書がCA証明書ではないことを伝える必要があります。 16進文字列(代替)は強く推奨されないため、サブジェクトキー識別子には「ハッシュ」の標準値を使用します。

権限キー識別子を「keyid」に設定して、親証明書からサブジェクトキー識別子をコピーします。 また、キーを署名として、またはキーを暗号化するプロトコルで使用できることも指定します。 キーの拡張使用がサーバーおよびクライアント認証に使用できることを指定します。

[ myca_extensions ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth,clientAuth

全体として、ファイルは次のようになります。

[ ca ]
default_ca = myca

[ myca ]
unique_subject = no
new_certs_dir = .
certificate = ca.cert
database = certindex
private_key = privkey.pem
serial = serial
default_days = 3650
default_md = sha1
policy = myca_policy
x509_extensions = myca_extensions

[ myca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional

[ myca_extensions ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth,clientAuth

終了したら、ファイルを保存して閉じます。 これで、以前に生成した証明書署名要求に署名するために使用できる実質的な構成ファイルができました。

証明書署名要求に署名して、証明書を生成します

これで、CSRに署名して証明書を生成するために必要なすべてのコンポーネントが揃いました。 作成した構成ファイルを参照し、生成したCSRを渡すだけです。

使用するコマンドは次のとおりです。

openssl ca -batch -config myca.conf -notext -in consul.csr -out consul.cert

使用するオプションは次のとおりです。

  • ca :opensslの認証局管理機能を使用します。
  • -batch :バッチモードに入る必要があることを指定します。 バッチモードでは、プロンプトを表示せずに、渡されたCSRが自動的に認証されます。
  • -config myca.conf :作成した構成ファイルを渡します。
  • -notext :証明書のテキスト形式を出力しません。

残りのオプションは、入力ファイルと出力ファイルを指定します。

これにより、現在のディレクトリにconsul.certというファイルが作成されます。 また、serialおよびcertindexファイルの新しいバージョンを作成し、古いバージョンをバックアップファイルに移動します。 .pemファイルも、serialファイルのシリアル番号に基づいて作成されます。

ファイルを正しい場所に移動します

これで、/etc/consul.d/ssl/CAディレクトリ内に必要なすべてのコンポーネントができました。 必要な3つのファイルを/etc/consul.d/sslディレクトリにコピーします。ここでそれらを参照します。

cp ca.cert consul.key consul.cert ..

CAを保持するserver1マシンには、必要な証明書とキーファイルが正しい場所にあります。

それらをインフラストラクチャ内の他のマシンに取り込むには、scpが適切な選択です。 server1/etc/consul.d/sslディレクトリから、次のように入力して、必要なファイルを他のサーバーにプッシュできます。

cd /etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@192.0.2.2:/etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@192.0.2.3:/etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@192.0.2.50:/etc/consul.d/ssl

インフラストラクチャ内の各マシンを参照するようにIPアドレスを変更します。

領事構成ファイルを変更する

ルート証明書ファイルと領事メンバーの証明書/キーのペアができたので、領事構成ファイルを変更してこれらのファイルを参照できます。

サーバー上の各領事館の構成ファイルを開きます。 server1マシンの場合、ブートストラップ構成ファイルから始めます。

nano /etc/consul.d/bootstrap/config.json

現在、ファイルは次のようになっているはずです。

{
    "bootstrap": true,
    "server": true,
    "datacenter": "nyc2",
    "data_dir": "/var/consul",
    "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
    "log_level": "INFO",
    "enable_syslog": true
}

最初に行うべきことは、consulパラメーターを使用して新しいファイルをそれぞれ識別することです。 ca_fileパラメーターは、CA証明書ファイルの場所を参照します。 cert_fileおよびkey_fileパラメーターは、それぞれクライアントの証明書ファイルとキーファイルを参照します。

これらは暗号化にも関係しているため、わかりやすくするためにencryptパラメーターの下に追加します。

{
    "bootstrap": true,
    "server": true,
    "datacenter": "nyc2",
    "data_dir": "/var/consul",
    "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
    "ca_file": "/etc/consul.d/ssl/ca.cert",
    "cert_file": "/etc/consul.d/ssl/consul.cert",
    "key_file": "/etc/consul.d/ssl/consul.key",
    "log_level": "INFO",
    "enable_syslog": true
}

これで、これらのファイルの場所を定義しましたが、これらのファイルを使用して各ホストの信頼性を検証することを領事に伝えていません。 これを行うには、領事に着信接続と発信接続の両方を確認するように指示します。

{
    "bootstrap": true,
    "server": true,
    "datacenter": "nyc2",
    "data_dir": "/var/consul",
    "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
    "ca_file": "/etc/consul.d/ssl/ca.cert",
    "cert_file": "/etc/consul.d/ssl/consul.cert",
    "key_file": "/etc/consul.d/ssl/consul.key",
    "verify_incoming": true,
    "verify_outgoing": true,
    "log_level": "INFO",
    "enable_syslog": true
}

終了したら、ファイルを保存して閉じます。

領事館のメンバーが使用する各構成ファイルに、これらと同じ変更を加えます。

server1では、/etc/consul.d/bootstrap/config.jsonおよび/etc/consul.d/server/config.jsonにこれらの変更を加える必要があります。

他のサーバーでは、/etc/consul.d/server/config.jsonを変更するだけです。 クライアントマシンでは、/etc/consul.d/client/config.jsonを変更する必要があります。

サーバーの再起動

暗号化されたトラフィックを実装するには、各領事メンバーで順番に領事セッションを再開する必要があります。

インフラストラクチャ内の各マシンで、一時的に停止してから、領事館を再開します。

stop consul && sleep 5 && start consul

これにより、プロセスが停止し、一時的に再開されます。

各領事メンバーでこれを順番に行うと、領事メンバーはSSLを使用してメンバー間のRPCトラフィックを暗号化するように切り替わります。 一部のトラフィックのみが切り替えられると、一部のトラフィックが暗号化されていないために拒否されるため、通信の問題が一時的に発生する可能性があります。

すべてのメンバーを再起動するときは、RPCトラフィックを完全に暗号化する必要があります。

結論

この時点で、インフラストラクチャ用にかなり安全なサービス検出システムを導入する必要があります。 領事館で利用可能なすべてのネイティブセキュリティシステムを活用して、アクセスをロックダウンし、さまざまなマシンのなりすましを防止しました。