ネットワークエンジニアのITブログ

長らくネットワークで生活してきましたが、ここ数年クラウドとサーバー系に触れる機会が増えて、日々成長しています。最近のお気に入りはNSXALBとGoogle Cloud。

NSXALBでサーバー証明書を発行しSSL通信を行う

NSXALBでは、通信の暗号化をサポートしており、SSL/TLSのパターンとしては、以下の4パターンがあります。
今回は、一般的なパススルーとクライアント側暗号化を実施してみます。

  • パススルー

 クライアントからのSSLトラフィックをNSXALBで終端せずに、暗号化したまま負荷分散先のサーバーへパススルーする。

  • クライアント側の暗号化

 クライアントからNSXALBへの通信はHTTPSでNSXALBで復号化、負荷分散先のサーバーへはHTTPで転送する。

  • サーバー側の暗号化

 クライアントからNSXALBへの通信はHTTPでNSXALBで暗号化、負荷分散先のサーバーへはHTTPSで転送する。

 クライアントからNSXALBへの通信はHTTPSでNSXALBで復号化再暗号化、負荷分散先のサーバーへはHTTPSで転送する。

サーバー証明書の発行にあたっては、NSXALBで自己証明書を簡単に発行できますが、CSRの作成及び、CentOS7で構築したプライベート認証局での発行手順を紹介します。

ネットワーク構成


プライベート認証局の構築

まずは、サーバー証明書を発行するためのプライベート認証局を構築します。
CentOS7には、最小パッケージのインストールでもopensslがインストールされているので、設定変更を行っていきます。

openssl.confの修正

証明書の有効期限、デフォルトの国と都市を修正し、CAの機能を有効にします。
ファイルは、/etc/pki/tls/openssl.cnfをviで編集します。
各設定変更箇所の行番号を参考に記載しています。

[root@cent36 CA]# vi /etc/pki/tls/openssl.cnf

68  # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
69  # so this is commented out by default to leave a V1 CRL.
70  # crlnumber must also be commented out to leave a V1 CRL.
71  # crl_extensions        = crl_ext
72
73  default_days    = 3650    ★365から3650に修正
74  default_crl_days= 30                    
75  default_md      = sha256                
76  preserve        = no                    

128 [ req_distinguished_name ]
129 countryName                     = Country Name (2 letter code)
130 countryName_default             = JP    ★JPを入力
131 countryName_min                 = 2
132 countryName_max                 = 2
133
134 stateOrProvinceName             = State or Province Name (full name)
135 stateOrProvinceName_default     = Tokyo    ★Tokyoを入力

169 # This goes against PKIX guidelines but some CAs do it and some software
170 # requires this to avoid interpreting an end user certificate as a CA.
171
172 basicConstraints=CA:TRUE    ★コメントを削除
CAスクリプトの修正

CAの有効期限と、SAN (Subject Alternative Name) の設定を読み込むための修正を行います。
ファイルは、/etc/pki/tls/misc/CAをviで編集します。

64  CADAYS="-days 3650"    ★1095から3650へ修正

修正前:156 $CA -policy policy_anything -out newcert.pem -infiles newreq.pem
修正後:156 $CA -policy policy_anything -extfile san.txt -out newcert.pem -infiles newreq.pem
                                       ★-extfile san.txt を追加
認証局の構築

事前の準備ができたので、./CA -newca で秘密鍵と公開鍵を作成します。

[root@cent36 misc]# ./CA -newca
CA certificate filename (or enter to create)

Making CA certificate ...
Generating a 2048 bit RSA private key
.......+++
....................................................................................................+++
writing new private key to '/etc/pki/CA/private/./cakey.pem'
Enter PEM pass phrase:    ★パスワードを入力
Verifying - Enter PEM pass phrase:    ★再度パスワードを入力
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]:    ★Enterを入力
State or Province Name (full name) [Tokyo]:    ★Enterを入力
Locality Name (eg, city) [Default City]:    ★Enterを入力
Organization Name (eg, company) [Default Company Ltd]:    ★Enterを入力
Organizational Unit Name (eg, section) []:    ★Enterを入力
Common Name (eg, your name or your server's hostname) []:My Private CA   ★認証局の名前を入力
Email Address []:    ★Enterを入力

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:    ★Enterを入力
An optional company name []:    ★Enterを入力
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/./cakey.pem:    ★最初に設定したパスワードを入力
Check that the request matches the signature
Signature ok

~(中略)~

Write out database with 1 new entries
Data Base Updated
[root@cent36 misc]# 

作成した鍵の情報は以下のパスに格納されます。
秘密鍵 /etc/pki/CA/private/cakey.pem
公開鍵 /etc/pki/CA/cacert.pem

CSRの作成

NSXALBにSSLサーバ証明書を導入するには、サーバー証明書を導入するサーバで、ウェブサイトの情報(ディスティングイッシュネーム)などを入力して、証明書の署名リクエスト(Certificate Signing Request)を作成します。
Template > Security > SSL/TLS Certificates > CREATE > Application Certificateをクリックします。

以下の情報を入力し、SAVEします。
Name:wwwlab01.home.local
Type:CSR
Common Name:wwwlab01.home.local
State Name of Province:Tokyo
Country:JP


作成が完了すると証明書のステータスがオレンジとなっているので、右端の鉛筆マークをクリックします。

COPY TO CLIPBORADをクリックし、CSRの情報をテキストファイルに「newreq.pem」として保存します。

サーバー証明書の発行

SANファイルの編集

以前は、Common Nameのチェックのみとなっていましたが、最近のブラウザは、Common Nameのチェックを廃止、SAN (Subject Alternative Name)による確認を行うようになっています。今回作成したプライベート認証局は、デフォルトで、SANの情報を付与しないため、あらかじめSAN.txtを作成し、サーバー証明書を作成する際に読み込むように設定変更を行いました。
SAN.txtでは、ドメイン名やIPアドレスをカンマ区切りで複数記載することができ、ドメインの場合はサブドメインワイルドカード (*) も使用可能です。
ドメインの場合は頭にDNS:を付与し、IPアドレスの場合はIP:を付与します。
今回作成するFQDNは、「wwwlab01.home.local」であるため、SAN.txtには、以下のように記載します。

subjectAltName = DNS:wwwlab01.home.local

参考までに、IPアドレスも紐づける場合は、以下のように記載します
subjectAltName = DNS:wwwlab01.home.local, IP:192.168.7.77

サーバー証明書の発行

「newreq.pem」と「SAN.txt」の情報を、/etc/pki/tls/misc 配下に格納し、./CA -sign を実行して、サーバー証明書を発行します。

[root@cent36 misc]# pwd
/etc/pki/tls/misc
[root@cent36 misc]#
[root@cent36 misc]# ll
合計 40
-rwxr-xr-x 1 root root 5196  6月 24 14:48 CA
-rwxr-xr-x 1 root root 5178  3月 21 01:13 CA.bak
-rwxr-xr-x 1 root root  119  3月 21 01:13 c_hash
-rwxr-xr-x 1 root root  152  3月 21 01:13 c_info
-rwxr-xr-x 1 root root  112  3月 21 01:13 c_issuer
-rwxr-xr-x 1 root root  110  3月 21 01:13 c_name
-rw-r--r-- 1 root root 1009  6月 24 19:11 newreq.pem    ★CSRを格納する
-rw-r--r-- 1 root root   41  6月 24 19:03 san.txt    ★SAN情報を格納する
[root@cent36 misc]#
[root@cent36 misc]#
[root@cent36 misc]# ./CA -sign
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:    ★CAを作成した際のパスワードを入力する
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            b6:5c:08:e8:f3:b8:d4:f0
        Validity
            Not Before: Jun 24 10:12:16 2023 GMT
            Not After : Jun 21 10:12:16 2033 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            commonName                = wwwlab01.home.local
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:wwwlab01.home.local
Certificate is to be certified until Jun 21 10:12:16 2033 GMT (3650 days)
Sign the certificate? [y/n]:y    ★yを入力する


1 out of 1 certificate requests certified, commit? [y/n]y    ★yを入力する
Write out database with 1 new entries
Data Base Updated
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            b6:5c:08:e8:f3:b8:d4:f0
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, O=Default Company Ltd, CN=My Private CA
        Validity
            Not Before: Jun 24 10:12:16 2023 GMT
            Not After : Jun 21 10:12:16 2033 GMT
        Subject: C=JP, ST=Tokyo, CN=wwwlab01.home.local
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b2:bb:4e:92:0e:a1:80:2d:9d:32:36:5c:9f:41:
                    46:3f:57:89:30:63:1d:21:04:db:5d:4f:6f:c9:fe:
                    c1:a4:4a:f1:e6:ad:7d:64:65:7e:01:28:c6:4b:52:
                    7b:42:cb:0c:01:66:01:af:32:fe:cc:3d:92:e7:16:
                    c7:3d:6f:be:2d:02:96:31:fa:f7:2d:7f:36:d7:70:
                    3e:fe:5c:9f:5b:c6:71:cc:cb:a0:26:2d:34:9c:09:
                    ca:2f:6c:d4:36:5b:b0:61:b5:59:4e:a8:58:cb:95:
                    7a:44:85:a8:6b:fa:ad:03:06:5c:f2:44:38:4d:3e:
                    28:b6:0b:e5:10:dc:0a:df:b5:aa:d9:a6:f5:a0:38:
                    f8:68:cc:cd:19:a6:85:b1:dc:b2:9e:d0:36:29:9d:
                    9d:80:4f:f2:af:07:05:38:68:80:47:e8:d4:55:38:
                    e1:d0:4c:64:cb:7c:98:68:aa:15:64:b1:99:c2:35:
                    b3:a8:08:c2:8b:72:64:64:1d:fe:1e:51:98:34:40:
                    20:67:b8:6e:6c:b1:48:73:bb:3d:a1:95:c6:b6:44:
                    88:c0:11:58:ee:97:9b:09:52:60:b7:02:a9:7b:f1:
                    b1:69:d5:68:a0:1b:1e:cf:dd:ca:2d:8a:94:5e:6f:
                    17:54:b0:17:40:23:86:72:d6:a2:c1:80:c9:ef:13:
                    8d:6d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:wwwlab01.home.local
    Signature Algorithm: sha256WithRSAEncryption
         8d:ff:be:55:d0:b8:cd:08:92:e2:25:ed:e3:df:70:cb:c8:54:
         05:25:a9:93:f8:1b:87:59:11:9c:f2:de:2e:cd:a6:4a:41:3f:
         54:6f:ae:98:6d:56:00:de:c4:d0:b5:1c:78:22:28:f7:6b:7d:
         e2:de:da:69:15:f2:28:98:1c:0a:27:8c:0b:f5:c6:70:12:b5:
         df:6a:81:3e:76:c1:d1:b0:09:06:f7:26:97:b3:3d:f4:27:60:
         0d:36:0f:60:c8:04:f2:6f:16:45:e9:b5:09:4d:2a:70:6f:08:
         0a:2c:49:6c:8c:12:aa:dd:14:dc:e1:e3:6b:96:35:c9:49:9e:
         af:a4:88:fd:41:5b:cf:54:21:8e:88:a4:8a:2d:41:8f:d3:03:
         5e:f2:a8:75:28:21:49:b2:0d:89:28:c5:12:1d:73:81:63:b8:
         a1:8c:96:6f:01:fb:66:fb:80:cc:43:9b:f4:e8:f6:90:d7:0c:
         80:b7:68:9d:93:9b:2f:ad:4d:85:41:91:74:05:b1:77:9e:8d:
         2b:e2:a9:47:43:62:4c:95:7c:67:12:6c:2b:a3:b7:93:e1:da:
         4a:80:c7:97:5a:35:32:6b:23:6e:e0:97:d5:70:b4:22:c9:0b:
         7c:08:63:a7:9b:1b:12:79:03:cc:58:20:77:3d:f7:1f:85:2b:
         70:0c:78:11
-----BEGIN CERTIFICATE-----
MIIDMzCCAhugAwIBAgIJALZcCOjzuNTwMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
BAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55
IEx0ZDEWMBQGA1UEAwwNTXkgUHJpdmF0ZSBDQTAeFw0yMzA2MjQxMDEyMTZaFw0z
MzA2MjExMDEyMTZaMDsxCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEcMBoG
A1UEAwwTd3d3bGFiMDEuaG9tZS5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALK7TpIOoYAtnTI2XJ9BRj9XiTBjHSEE211Pb8n+waRK8eatfWRl
fgEoxktSe0LLDAFmAa8y/sw9kucWxz1vvi0CljH69y1/NtdwPv5cn1vGcczLoCYt
NJwJyi9s1DZbsGG1WU6oWMuVekSFqGv6rQMGXPJEOE0+KLYL5RDcCt+1qtmm9aA4
+GjMzRmmhbHcsp7QNimdnYBP8q8HBThogEfo1FU44dBMZMt8mGiqFWSxmcI1s6gI
wotyZGQd/h5RmDRAIGe4bmyxSHO7PaGVxrZEiMARWO6XmwlSYLcCqXvxsWnVaKAb
Hs/dyi2KlF5vF1SwF0AjhnLWosGAye8TjW0CAwEAAaMiMCAwHgYDVR0RBBcwFYIT
d3d3bGFiMDEuaG9tZS5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEAjf++VdC4zQiS
4iXt499wy8hUBSWpk/gbh1kRnPLeLs2mSkE/VG+umG1WAN7E0LUceCIo92t94t7a
aRXyKJgcCieMC/XGcBK132qBPnbB0bAJBvcml7M99CdgDTYPYMgE8m8WRem1CU0q
cG8ICixJbIwSqt0U3OHja5Y1yUmer6SI/UFbz1Qhjoikii1Bj9MDXvKodSghSbIN
iSjFEh1zgWO4oYyWbwH7ZvuAzEOb9Oj2kNcMgLdonZObL61NhUGRdAWxd56NK+Kp
R0NiTJV8ZxJsK6O3k+HaSoDHl1o1MmsjbuCX1XC0IskLfAhjp5sbEnkDzFggdz33
H4UrcAx4EQ==
-----END CERTIFICATE-----
Signed certificate is in newcert.pem
[root@cent36 misc]#
[root@cent36 misc]#
[root@cent36 misc]#
[root@cent36 misc]# ll
合計 44
-rwxr-xr-x 1 root root 5196  6月 24 14:48 CA
-rwxr-xr-x 1 root root 5178  3月 21 01:13 CA.bak
-rwxr-xr-x 1 root root  119  3月 21 01:13 c_hash
-rwxr-xr-x 1 root root  152  3月 21 01:13 c_info
-rwxr-xr-x 1 root root  112  3月 21 01:13 c_issuer
-rwxr-xr-x 1 root root  110  3月 21 01:13 c_name
-rw-r--r-- 1 root root 3985  6月 24 19:12 newcert.pem    ★サーバー証明書が発行されました
-rw-r--r-- 1 root root 1009  6月 24 19:11 newreq.pem
-rw-r--r-- 1 root root   41  6月 24 19:03 san.txt
[root@cent36 misc]#

サーバー証明書のインポート

認証局で発行したサーバー証明書をNSXALBにインポートしていきます。
CSRの情報をコピーした画面の下に、インポートのボタンがあるので、そこで発行した「newcert.pem」をインポートして、SAVEします。

サーバー証明書のステータスがオレンジからグリーンに変わりサーバー証明書のインポートが完了しました。
ただ、よく見ると、Nameの部分に「Issuer Certificate Missing」と表示されています。
これは、認証局のルートCA証明書(プライベート認証局の公開鍵)がインポートされていないので、追加でインポートします。
認証局のルートCA証明書は、/etc/pki/CA/cacert.pem にあるので取り出しておきます。

ルートCA証明書のインポート

ルート証明書は、以下からインポートします。
Template > Security > SSL/TLS Certificates > CREATE > Application Certificateをクリックします。

IMPORT FILEから、「cacert.pem」をインポートし、「VALIDATE」をクリックします。

VALIDATEが問題ないと、Common Nameに「My Private CA」が反映されるので、SAVEします。

再度、作成したサーバー証明書のステータスを確認し、先ほどの「Issuer Certificate Missing」が消えていれば完了です。

クライアント側の暗号化設定

サーバー証明書の準備ができたので、クライアントとALB間の暗号化を行うVSを作成します。

Poolの作成

以下の内容でPoolを作成します。

Name Pool-lab01
Default Server Port 80
Load Balance Algorithm Round Robin
Servers 192.168.8.122
Servers 192.168.8.123



VIPの作成

VIPを192.168.8.170で作成します。

VSの作成

Pool、VIP、サーバー証明書をもとにVSを作成します。


パススルーの設定

ALBでパススルーしてサーバーでSSL通信の復号化をする構成がわかりやすいところですが、別途サーバーを用意するのが面倒なので、クライアント暗号化で用意したVSをサーバーと見立てて、さらに前段にVSを用意することで、フロントのVSがパススルーして、バックエンドのVSに転送するような構成をとりたいと思います。

Poolの作成

以下の内容でPoolを作成します。

Name Pool-front01
Default Server Port 443
Load Balance Algorithm Round Robin
Servers 192.168.8.170



VIPの作成

VIPを192.168.7.170で作成します。

VSの作成

Pool、VIP、サーバー証明書をもとにVSを作成します。

認証局のルートCA証明書(プライベート認証局の公開鍵)のインポート

VSの作成が完了しましたが、この段階で接続しても、SSL接続になっているものの、「保護されていない通信」がURLバーのところに表示されています。
これは、接続元のクライアントに、このサーバー証明書を発行した認証局のルートCA証明書(プライベート認証局の公開鍵)がインストールされていないためです。
一般的に、主要な認証局のルートCA証明書は、WindowsUpdateなどで自動的にインストールされますが、今回のようなプライベート認証局の場合は、手動でインストールする必要があります。
ChromeFirefoxでインストール方法が異なるので、分けて紹介します。

Chromeの場合

Chromeは、Windows OSの「信頼されたルート証明機関」として認証局のルートCA証明書をインポートします。
作成した「newcert.pem」を接続元のPCへダウンロードします。
WindowsOSは、拡張子がpemの場合、証明書ファイルとして認識しないので、拡張子を.pemから.cerに変更します。

タスクバーの検索から「証明書」と入力し、「ユーザー証明書の管理」から「信頼されたルート証明機関」の「証明書」を選択します。

右クリックから、すべてのタスク > インポート を選択します。

次へをクリックします。

「newcert.cer」を選択し、次へをクリックします。

「証明書をすべて次のストアに配置する」となっていることを確認し、次へをクリックします。

完了をクリックします。

セキュリティ警告が表示されますが、この証明書をインストールするので、はいをクリックし、正しくインポートされましたと表示されれば完了です。

Firefoxの場合

Firefoxは、Windows OSの「信頼されたルート証明機関」は参照しないため、個別に証明書のインポートを実施する必要があります。
FirefoxのURLバーに「about:preferences#privacy」と入力し、証明書から「証明書を表示」をクリックします。

証明書マネージャーのタブから「認証局証明書」を選択し、インポートをクリックします。

ダウロードした「newcert.pem」を読み込むと、証明書のインポート画面が表示されるので、「この認証局によるウェブサイトの識別を信頼する」にチェックを入れ、OKをクリックする。

動作確認

クライアント暗号化

DNSサーバーで「wwwlab01.home.local」のAレコードを「192.168.8.170」として登録しておきます。

C:\>nslookup wwwlab01.home.local
サーバー:  cent32.home.local
Address:  192.168.1.32

名前:    wwwlab01.home.local
Address:  192.168.8.170

C:\>

ChromeおよびFirefoxから「https://wwwlab01.home.local」に接続し、ブラウザーの警告エラーもなく、正常にページが表示されることが確認できました。

また、VSのログからも、HTTPS通信をALBで復号化してサーバーに転送していることが確認できました。

パススルー

DNSサーバーで「wwwlab01.home.local」のAレコードを「192.168.7.170」として登録しておきます。

C:\>nslookup wwwlab01.home.local
サーバー:  cent32.home.local
Address:  192.168.1.32

名前:    wwwlab01.home.local
Address:  192.168.7.170

C:\>

ChromeおよびFirefoxから「https://wwwlab01.home.local」に接続し、ブラウザーの警告エラーもなく、正常にページが表示されることが確認できました。

また、VSのログからも、フロントのVS経由で443通信をパススルーして、バックエンドのVSに転送していることも確認できました。