Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

第35章 IPsec を使用したノード間のトラフィックの暗号化

35.1. 概要

IPsec は、インターネットプロトコル (IP) を使用して通信するすべてのマスターとノードホスト間の通信を暗号化することによって OpenShift Container Platform クラスターのトラフィックを保護します。

このトピックでは、すべてのクラスター管理および Pod データトラフィックを含め、OpenShift Container Platform ホストが IP アドレスを受信する IP サブセット全体の通信のセキュリティーを保護する方法について説明します。

注記

OpenShift Container Platform 管理トラフィックは HTTPS を使用するため、IPsec の有効化により 2 度目の管理トラフィックの暗号化が実行されることになります。

重要

この手順はクラスターの各マスターホストで繰り返し、その後にノードホストで実行される必要があります。IPsec が有効にされていないホストは、これが有効にされているホストと通信することができません。

35.2. ホストの暗号化

前提条件

  • libreswan 3.15 以降がクラスターホストにインストールされていることを確認します。便宜的なグループ (opportunistic group) 機能が必要な場合は、libreswan バージョン 3.19 以降が必要になります。
  • 本トピックでは、62 バイトを必要とする IPsec 設定について説明します。クラスターが MTU (最大伝送単位) の値が 1500 バイトであるイーサネットネットワークで動作する場合、IPsec および SDN のカプセル化のオーバーヘッドに対応するために SDN MTU の値を 1388 バイトに変更する必要があります。クラスター内のノードの MTU を変更するには、以下の手順を実行します。

    1. node-config-masternode-config-infranode-config-compute の ConfigMap のそれぞれを編集します。

      1. 以下のコマンドを実行して ConfigMap を編集します.<config_map> を編集する ConfigMap の名前に置き換えます。

        # oc edit cm <config_map> -n openshift-node
      2. mtu パラメーターを、1388 バイトなどの IPsec オーバーヘッドに十分な MTU サイズに更新します。

        networkConfig:
          mtu: 1388
    2. 以下のコマンドを実行して SDN インターフェースを削除します。<ovs_pod_name> を OVS Pod の名前に置き換えます。

      # oc exec <ovs_pod_name> -- ovs-vsctl del-br br0
    3. クラスターの各ノードについて、以下のアクションを実行します。

      1. 更新した MTU 値が /etc/origin/node/node-config.yaml ファイルに保存されていることを確認します。
      2. 以下のコマンドを実行して SDN および OVS Pod を再起動します。

        # oc delete pod -n openshift-sdn -l=app=ovs
        # oc delete pod -n openshift-sdn -l=app=sdn

35.2.1. 証明書での IPsec の設定

OpenShift Container Platform の内部認証局 (CA) を使用して、IPsec に適した RSA キーを生成できます。内部 CA の共通名 (CN) の値は openshift-signer に設定されます。

  1. 以下のコマンドを実行して、マスターノードで RSA 証明書を生成します。

    # export CA=/etc/origin/master
    
    # oc adm ca create-server-cert \
      --signer-cert=$CA/ca.crt --signer-key=$CA/ca.key \
      --signer-serial=$CA/ca.serial.txt \
      --hostnames='<hostname>' \ 1
      --cert=<hostname>.crt \ 2
      --key=<hostname>.key 3
    1 2 3
    <hostname> をノードの完全修飾ドメイン名 (FQDN) に置き換えます。
  2. openssl を使用してクライアント証明書、CA 証明書、およびプライベートキーファイルを PKCS#12 ファイルに追加します。これは、複数の証明書およびキーの共通ファイル形式です。

    # openssl pkcs12 -export \
      -in <hostname>.crt \ 1
      -inkey <hostname>.key \ 2
      -certfile  /etc/origin/master/ca.crt \
      -passout pass: \
      -out <hostname>.p12 3
    1 2 3
    ノードの完全修飾ドメイン名 (FQDN) で置き換えます。
  3. クラスター内の各ノードについて、直前の手順でホストに作成したファイルを安全に転送し、PKCS#12 ファイルを libreswan 証明書データベースにインポートします。

    -W オプションは、パスワードが一時的で PKCS#12 ファイルに割り当てられないため、空のままになります。

    # ipsec initnss
    # pk12util -i <hostname>.p12 -d sql:/etc/ipsec.d -W ""
    # rm <hostname>.p12

35.2.2. libreswan IPsec ポリシーの作成

必要な証明書が libreswan 証明書データベースにインポートされた後に、それらを使用してクラスター内のホスト間の通信をセキュリティー保護するポリシーを作成します。

libreswan 3.19 以降を使用している場合、便宜的なグループ (opportunistic group) 設定が推奨されます。これ以外の場合は、明示的な接続が必要になります。

35.2.2.1. 便宜的なグループ (opportunistic group) の設定

以下の設定は 2 つの libreswan 接続を作成します。最初の設定は OpenShift Container Platform 証明書を使用してトラフィックを暗号化し、2 つ目の設定はクラスターの外部トラフィック用に暗号化に対する例外を作成します。

  1. 以下を /etc/ipsec.d/openshift-cluster.conf ファイルに配置します。

    conn private
    	left=%defaultroute
    	leftid=%fromcert
    	# our certificate
    	leftcert="NSS Certificate DB:<cert_nickname>" 1
    	right=%opportunisticgroup
    	rightid=%fromcert
    	# their certificate transmitted via IKE
    	rightca=%same
    	ikev2=insist
    	authby=rsasig
    	failureshunt=drop
    	negotiationshunt=hold
    	auto=ondemand
    	encapsulation=yes 2
    
    conn clear
    	left=%defaultroute
    	right=%group
    	authby=never
    	type=passthrough
    	auto=route
    	priority=100
    1
    <cert_nickname> を、手順 1 の証明書ニックネームに置き換えます。
    2
    NAT を使用しない場合、カプセル化を強制的に実行するには、設定に encapsulation=yes を含める必要があります。 Amazon および Azure 内部クラウドネットワークは IPsec ESP または AH パケットをルーティングしません。 これらのパケットは UDP でカプセル化される必要があり、設定されている場合、NAT 検出は ESPUDP のカプセル化に設定します。 NAT を使用する場合や、前述の Network/Cloud-Provider の制限下にない場合には、このパラメーターおよび値を省略します。
  2. libreswan に対して、/etc/ipsec.d/policies/ のポリシーファイルを使用して各ポリシーを適用する IP サブネットおよびホストを示します。このファイルでは、それぞれの設定された接続に対応するポリシーファイルが設定されます。そのため、上記の例では、private および clear の 2 つの接続のそれぞれに /etc/ipsec.d/policies/ のファイルが設定されます。

    /etc/ipsec.d/policies/private には、ホストの IP アドレスの受信元であるクラスターの IP サブネットが含まれる必要があります。これにより、デフォルトでは、リモートホストのクライアント証明書がローカルホストの認証局の証明書に対して認証される場合、クラスターサブネットのホスト間のすべての通信が暗号化されることになります。リモートホストの証明書が認証されない場合、2 つのホスト間のすべてのトラフィックがブロックされます。

    たとえば、すべてのホストが 172.16.0.0/16 アドレス空間のアドレスを使用するように設定される場合、private ポリシーファイルには 172.16.0.0/16 が含まれることになります。暗号化する追加サブセットの任意の数がこのファイルに追加され、それらのサブネットへのすべてのトラフィックでも IPsec が使用されることになります。

  3. トラフィックがクラスターに出入りすることを確認するためにすべてのホストとサブネットゲートウェイ間の通信の暗号化を解除します。ゲートウェイを /etc/ipsec.d/policies/clear ファイルに追加します。

    172.16.0.1/32

    追加のホストおよびサブネットをこのファイルに追加できます。これにより、これらのホストおよびサブネットへのすべてのトラフィックの暗号が解除されます。

35.2.2.2. 明示的な接続の設定

この設定では、各 IPSec ノード設定がクラスター内の他のすべてのノードの設定を明示的に一覧表示する必要があります。各ノードで Ansible などの設定管理ツールを使用してこのファイルを生成することが推奨されます。

注記

node-config.yaml ファイルを手動で編集できません。クラスターのノードを変更するには、ノード設定マップを必要に応じて更新します。

また、この設定では各ノードの完全な証明書サブジェクトをその他のノードの設定に配置する必要があります。

  1. openssl を使用して、このサブジェクトをノードの証明書から読み取ります。

    # openssl x509 \
      -in /path/to/client-certificate -text | \
      grep "Subject:" | \
      sed 's/[[:blank:]]*Subject: //'
  2. 以下の行を、クラスター内のその他のノード用に各ノードの /etc/ipsec.d/openshift-cluster.conf ファイルに配置します。

    conn <other_node_hostname>
            left=<this_node_ip> 1
            leftid="CN=<this_node_cert_nickname>" 2
            leftrsasigkey=%cert
            leftcert=<this_node_cert_nickname> 3
            right=<other_node_ip> 4
            rightid="<other_node_cert_full_subject>" 5
            rightrsasigkey=%cert
            auto=start
            keyingtries=%forever
    	encapsulation=yes 6
    1
    <this_node_ip> をこのノードのクラスター IP アドレスに置き換えます。
    2 3
    <this_node_cert_nickname> を手順 1 のノードの証明書ニックネームに置き換えます。
    4
    <other_node_ip> を他のノードのクラスター IP アドレスに置き換えます。
    5
    <other_node_cert_full_subject> を上記の他のノードの証明書に置き換えます。たとえば、"O=system:nodes,CN=openshift-node-45.example.com" のようになります。
    6
    NAT を使用しない場合、カプセル化を強制的に実行するには、設定に encapsulation=yes を含める必要があります。 Amazon および Azure 内部クラウドネットワークは IPsec ESP または AH パケットをルーティングしません。 これらのパケットは UDP でカプセル化される必要があり、設定されている場合、NAT 検出は ESPUDP のカプセル化に設定します。 NAT を使用する場合や、前述の Network/Cloud-Provider の制限下にない場合には、このパラメーターおよび値を省略します。
  3. 以下を各ノードの /etc/ipsec.d/openshift-cluster.secrets ファイルに配置します。

    : RSA "<this_node_cert_nickname>" 1
    1
    <this_node_cert_nickname> を手順 1 のノードの証明書ニックネームに置き換えます。

35.3. IPsec ファイアウォールの設定

クラスター内のすべてのノードは、IPSec 関連のネットワークトラフィックを許可する必要があります。これには、UDP ポート 500 だけでなく IP プロトコル番号の 50 と 51 が含まれます。

たとえば、クラスターノードがインターフェース eth0 で通信する場合、以下のようになります。

-A OS_FIREWALL_ALLOW -i eth0 -p 50 -j ACCEPT
-A OS_FIREWALL_ALLOW -i eth0 -p 51 -j ACCEPT
-A OS_FIREWALL_ALLOW -i eth0 -p udp --dport 500 -j ACCEPT
注記

また IPSec は、NAT traversal に UDP ポート 4500 を使用します。ただし、これは通常のクラスターデプロイメントに適用することはできません。

35.4. IPSec の開始および終了

  1. ipsec サービスを開始し、新規の設定およびポリシーを読み込み、暗号化を開始します。

    # systemctl start ipsec
  2. ipsec サービスを有効にして起動時に開始します。

    # systemctl enable ipsec

35.5. IPSec の最適化

IPSec を使用した暗号化の場合のパフォーマンス関連の提案についての詳細は、『Scaling and Performance Guide』を参照してください。

35.6. トラブルシューティング

2 つのノード間で認証を完了できない場合、すべてのトラフィックが拒否されるため、それらの間で ping を行うことはできません。clear ポリシーが適切に設定されていない場合も、クラスター内の別のホストから SSH をホストに対して実行することはできません。

ipsec status コマンドを使用して clear および private ポリシーが読み込まれていることを確認できます。