AWSのロードバランサー(ELB)にサーバー証明書(SSL)を適用する

2016年1月18日。

ロードバランサー(ELB)にSSL(サーバー証明書)をつけようとしたらエラーが出たので色々調べて対応した件のまとめ。

 

問題:

AWS管理画面からロードバランサー(SSL付)を作成しようとしたらエラー。

管理画面から簡単にできるような気配を見せておきながら。。。

やることリスト(順番):

  1. AWS管理画面からIAMを作成する
  2. awscliをインストールする
  3. セキュリティシールを発行する
  4. コマンドラインからセキュリティシールをIAMにアップロードする
  5. ロードバランサー(ELB)を作る

セキュリティシールの準備と、IAMの設定が必要と解釈してください。

3は1,2より先にやってもらってもOKです。

1. AWS管理画面からIAMを作成する

参考:【AWS】IAM Roleを使用してインスタンスに操作権限を設定する – TASK NOTES

画面のスクリーンショットが、もう大分変わっているため完全合致とはいかないが要点はこちらのURLで十分。

大事なのは作った後にAttach Role Policy(ポリシーのアタッチ)で「IAMFullAccess」をつけること(FullAccessじゃなくてもいいんだけどとりあえずFullAccessつけとけば目的は達成します)。

IAMに対する権限を与えないと2のawscliの初期設定で「権限がないよ」といわれてコケる。

2. awscliをインストールする

2-1. いろいろインストール

IAMにセキュリティシールをアップロードするために、なんでかコマンドラインツールが必要になります。

(awsの管理画面で作らせろよと思う次第ですが、やり方が悪いのかなんだかわかりませんがとりあえず作れませんでした)

参考:Mac OS X Mavericksでawscliをインストールする – 戦場のプログラマー

brew install python
pip install awscli
brew install jq

pythonをbrewで入れてpipでawscliをインストール。

aws Command Line Interfaceで cli だそうです。

jqは、コマンドラインでぶん投げたものをJSONっぽく見やすくするもので、入れておいた方がいいです。

awscliがインストールできたら、初期設定を行います。

2-2. awscliの初期設定

% aws configure
AWS Access Key ID [None]: アクセスキー
AWS Secret Access Key [None]: シークレットキー
Default region name [None]: ap-northeast-1
Default output format [None]: json

アクセスキー、シークレットキーは、IAM発行したものを使う。アカウント直のものは入れないように。なにやら死ぬらしいw

regionはデフォルトで使うところによって変更する。ap-northeast-1は東京。
参考:region一覧

出力が見づらいのでjq入れたという流れがあるので、outputはjsonで。

~/.aws/
にconfigファイルが出来てるはず。

2-3. 動作確認

次のコマンドが動作すればOK。

% aws ec2 describe-instances | jq '.'

3. セキュリティシールを発行する

3-1. keyファイル(PEM)を作る

openssl genrsa -out ドメイン名.key 2048
(ex: openssl genrsa -out www.cyborg-ninja.com.key 2048)

keyファイルを作成。このへんのファイル名はなんでもいいんですがわかりやすいようにドメイン名にしとくといいと思います。

3-2. csrファイルを作る

openssl req -new -key ドメイン名.key -out ドメイン名.csr
(ex: openssl req -new -key www.cyborg-ninja.com.key -out www.cyborg-ninja.com.csr)
Country Name (2 letter code) [GB]:
State or Province Name (full name) [Berkshire]:
Locality Name (eg, city) [Newbury]:
Organization Name (eg, company) [My Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

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

CSRファイルを作成。Country Nameなど、いちいち聞かれますのでJPとかTokyoとか打っていく。

最後の「A challenge password」は無視してEnterキーを押してパスワードの入力はしないように。
※パスワード入力するとELBに使えないそうです。というか普通パスワード入れないので入れないでOK。

3-3. 申し込む

規定の期間にこのCSRで発行してくれ!と申し込みましょう。

自前のCertificate(オレオレSSL)でやりたい人は以下などを参考に。
参考:オレオレ証明書をopensslで作る(詳細版) – ろば電子が詰まっている

3-4. Certificateファイルを用意する

Certificateファイル群は発行をお願いしたところからくるはずなのでそれを用意。 SSLには全部で4つ必要だと思ってください。

  • key(PEM。鍵ファイル)
  • csr
  • crt(証明書)
  • chain file(中間証明書)

参考だけ載せておきます。 * key(PEM。鍵ファイル)

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA6h4oHS2sLDoUkMtI2fsPo4VvVpBcVFKMezxSaB3NXfdSWfVm
<中略>
IJHIy7Jc+QGE+szAh1cJE1TD2Rwy6DjGncl3s9ghDtPu/yf8gV29Vtg=
-----END RSA PRIVATE KEY-----
  • csr
-----BEGIN CERTIFICATE REQUEST-----
MIIC1DCCAbwCAQAwgY4xCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEUMBIG
<中略>
vGoVdDvx///JaDYYN3Xz0BfFbeamX1AK2FTY7jZio4i/gEHGELGCcQQFyUZZD10R
-----END CERTIFICATE REQUEST-----
  • crt(証明書)
-----BEGIN CERTIFICATE-----
MIIENDCCAxygAwIBAgIDCX/mMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNVBAYTAlVT
<中略>
6XXBzzrs4669fwOt0a8d4Yps5+RdfbEtZ+7It643PQ7lkzkc+k8Zf7OXEVjQjhHM
-----END CERTIFICATE-----

これが中間証明書です。超大事。

  • chain file(中間証明書)
-----BEGIN CERTIFICATE-----
MIIEJTCCAw2gAwIBAgIDAjp3MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT
<中略>
gP8L8mJMcCaY
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
<中略>
b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
-----END CERTIFICATE-----

apache用の中間証明書は、2ファイルくっついてることが多いです。
正確には中間証明書とクロスルート証明書の2つです。これをがっちゃんこして中間証明と言ったりchainファイルと言ったりします。

なお、発行したkeyファイル、CSR、CRTが合致してるのかの確認はコマンドラインツールで

openssl rsa -in ドメイン名.key -modulus -noout | openssl md5
openssl req -in ドメイン名.csr -modulus -noout | openssl md5
openssl x509 -in ドメイン名.crt -modulus -noout | openssl md5

をそれぞれ3つコマンド実行させることで、確認できます。

4. コマンドラインからセキュリティシールをIAMにアップロードする

% aws iam upload-server-certificate --server-certificate-name サービス名 --certificate-body file://ドメイン名.crt --private-key file://ドメイン名.key --certificate-chain file://ドメイン名.chain

のようなコマンドをうちます。

Q. このエラーどうしたらいいの?(PEM format)

A client error (MalformedCertificate) occurred when calling the UploadServerCertificate operation: Unable to parse certificate. Please ensure the certificate is in PEM format.

多分file://がついていない。ファイル名指定箇所にfile://をつけてください。

Q. このエラーどうしたらいいの?(AccessDenied)

A client error (AccessDenied) occurred when calling the UploadServerCertificate operation: User: arn:aws:iam::*******:user/****** is not authorized to perform: 以下略

多分、権限がないです。「1. AWS管理画面からIAMを作成する」(このページ上部)を確認してください。

 

アップロードができると

% aws iam upload-server-certificate --server-certificate-name サービス名 --certificate-body file://ドメイン名.crt --private-key file://ドメイン名.key --certificate-chain file://ドメイン名.chain
{
    "ServerCertificateMetadata": {
        "ServerCertificateId": "*****",
        "ServerCertificateName": "ドメイン名",
        "Expiration": "2017-01-13T06:01:48Z",
        "Path": "/",
        "Arn": "arn:aws:iam::******:server-certificate/******",
        "UploadDate": "2016-01-18T04:39:31.026Z"
    }
}

こんな感じのログが出ます。

これでIAMのアカウントに対して、セキュリティシールがアップロードできたようです。

5. ロードバランサー(ELB)を作る

やっとAWS管理画面からELBを作成します。

現時点ではこちらのサイトに書かれているスクリーンショットでOK。
参考:AWSのELBでSSLの証明書を設定する方法(2015年5月版) | 株式会社LIG

こちらの手順の途中で取得した証明書を設定するところで、

「AWS Identity and Access Management (IAM) から、既存の証明書を選択する」を選択。
※「AWS Identity and Access Management (IAM) に、新規の SSL 証明書をアップロードする」ではないです。

先ほど手作業でアップロードしていますのでそれを選択するということで。

機械忍者

某SEO会社(?)勤務。 多分日本語よりHTMLの方が得意です。 最近はRubyとかいうキラキラな言語も勉強中です。 SEOはもう標準スキルになってきてると思うので正直もうあんまり昔ほどの熱意は感じません。 新たに躍動してる人も多いですしね。 だれか強化骨格コスプレあったら教えてください。