我是Amazon Web Services的新手,并且一直在尝试在EC2实例上安装SSL证书。我尝试使用AWS文档,但发现它令人费解。然后我按照http://www.robertbrewitz.com/2014/09/aws-and-setting-up-a-custom-ssl-certificate/的指南进行了操作。
我用Go Daddy购买了SSL证书,并使用openssl生成了2个文件:
server.key
server.csr
导游说我应该期待3张证书:
DigiCertCA.crt
TrustedRoot.crt
star_yourdomain_com.crt
相反,我很容易收到2个名为的文件:
f6f65901b1708ae5.crt
gd_bundle-g2-g1.crt
我认为f6f65901b1708ae5.crt
是我的域名证书(但我不确定)。无论如何,指南说我需要一个Elastic Load Balancer来安装SSL证书,所以我创建了一个。
我用以下内容生成了私钥:
openssl rsa -in server.key -text
和公钥认证:
openssl x509 -inform PEM -in f6f65901b1708ae5.crt
我还被要求进入证书链。我不确定这是什么以及如何获得它,所以我猜到了命令:
openssl x509 -inform PEM -in gd_bundle-g2-g1.crt
并输入以“----- BEGIN CERTIFICATE -----”
开头的结果证书密钥指南继续说,然后我需要设置Cloudfront。我安装了aws命令行工具,为了生成我运行的PEM:
openssl rsa -in server.key -text > aws_private.pem
openssl x509 -inform PEM -in f6f65901b1708ae5.crt > aws_public.pem
openssl x509 -inform PEM -in gd_bundle-g2-g1.crt > aws_public.pem
我上传了SSL证书:
aws iam upload-server-certificate --server-certificate-name mydomain_com \
--certificate-body file://aws_public.pem --private-key file://aws_private.pem \
--certificate-chain file://aws_chain.pem --path /cloudfront/mydomain_com/
这很成功。
然后,我必须创建一个Cloudfront分发版,我选择了SSL证书。
但是,当我转到我的https网址(https://www.example.org/)时,它无效。 http://www.example.org/但确实有效。
由于安装SSL证书的步骤非常多,我怀疑在此过程中我犯了一个错误。问题是,我不知道在哪里。有没有人指点?
此外,是否有更简单的方法来安装SSL证书?对于这么常见的事情来说,这似乎是非常复杂的。我愿意付钱给专家为我做这件事(我是一个软件开发人员,几乎不知道任何与SSL相关的知识),但是很难找到任何人完成这样的任务(并且有必要的问题)交出登录详细信息等)。任何帮助非常感谢。
修改
以下建议是我应该使用AWS Certificate Manager。我看了一眼,这似乎是一个更加轻松的选择。但是,我确实在Go Daddy的SSL证书上花了86欧元,所以我更愿意,如果这不浪费。我的任何工作都可以挽救吗?是否有意转售SSL证书?
修改
我还没有找到真正的解决方案。为了澄清,我有一个非常小众的网站,访客很少。我在EC2实例上有该站点。我按照上面的网站建议使用Load Balancer和Cloudfront来加密SSL。然而,它不起作用,无论如何它可能是矫枉过正的。谁能帮我这个?我想使用我支付的SSL证书,但如果没有,我应该使用像Lets Encrypt这样的东西吗?
答案 0 :(得分:5)
你提到指南要说3个文件,包括" DigiCertCA.crt"文件;听起来它是用DigiCert作为您的证书提供者而不是GoDaddy编写的。
首先,要确保" f6f65901b1708ae5.crt"包含您要求的证书(并留下任何疑问)。为此,您可以比较" server.csr"中的数据(例如公共名称(CN),DNS主题备用名称(SAN)等)。文件(即证书签名请求)中包含的内容" f6f65901b1708ae5.crt"文件:
$ openssl req -noout -text < server.csr
这应该在CSR文件中显示有关域的详细信息的人类可读文本。与之相比:
$ openssl x509 -noout -text < f6f65901b1708ae5.crt
这应该显示类似的人类可读文本,填写更多细节/字段。但它们应该大致符合您的期望。 注意如果您发现类似的错误:
51299:error:0906D06C:PEM routines:PEM_read_bio:no start line:/SourceCache/OpenSSL098/OpenSSL098-52.40.1/src/crypto/pem/pem_lib.c:648:Expecting: TRUSTED CERTIFICATE
然后它表明你的&#34; f6f65901b1708ae5.crt&#34;文件是DER格式,而不是PEM格式。如果没有,那么您已经有了一个PEM文件,这是AWS ELB所期望的。如果您有DER格式的证书,则可以使用以下方法轻松转换为PEM格式:
$ openssl x509 -in f6f65901b1708ae5.crt -inform DER -out f6f65901b1708ae5.pem -outform PEM
我只是希望通过提及这部分来彻底。
现在假设我们知道那&#34; f6f65901b1708ae5.crt&#34;包含您域名的PEM格式证书,我们已准备好处理&#34;证书链&#34;一部分。
我看了GoDaddy的online certificate repository,看看&#34; gd_bundle-g2-g1.crt&#34;你提到的文件就在那里,它就是。 (这些文件可以公开获取,因为它们包含供任何人/每个人使用的公共证书。)查看该gd_bundle-g2-g1.crt文件,我发现它包含多个证书。这很重要。
参见&#34;证书链&#34;是一个提供信任路径(或&#34;链&#34;)的文件列表,来自&#34; f6f65901b1708ae5.crt&#34;证书您必须拥有受信任的根GoDaddy CA证书。每个证书都有一个主题(它是发给的人)和一个发行者(发布它的人)。这意味着您可以从证书到发行人的证书,向后走&#34;到该证书的发行人证书等。向后走是证书链&#34;。
&#34; gd_bundle-g2-g1.crt&#34;文件包含多个证书意味着该文件包含您需要的证书链。这也意味着你不想要这样做:
$ openssl x509 -inform PEM -in gd_bundle-g2-g1.crt > aws_public.pem
因为openssl x509
只读取指定文件中的第一个证书,并且您需要所有。
考虑到上述所有情况,您可能只需要以下内容(以确保您的私钥是PEM格式化的):
$ openssl rsa -in server.key -text > aws_private.pem
然后,因为我们假设&#34; f6f65901b1708ae5.crt&#34;已经是PEM格式(如果没有,你知道如何在上面进行转换),我们知道那&#34; gd_bundle-g2-g1.crt&#34;已经进行了PEM格式化,我们现在可以将这些内容上传到AWS ELB。
要上传证书和密钥以供ELB使用,请使用以下内容:
$ aws iam upload-server-certificate \
--server-certificate-name redmatterapp_com2 \
--certificate-body file://f6f65901b1708ae5.crt \
--private-key file://aws_private.pem \
--certificate-chain file://gd_bundle-g2-g1.crt \
--path /cloudfront/redmatterapp_com/
注意我使用了不同的--server-certificate-name
,只是为了确保它不会覆盖/与您现有的配置冲突。作为建议,您可以包括创建上载证书的日期(或者,更好的是,当它将到期时),作为名称的一部分,作为您未来自我的暗示该证书已添加,例如&#34; redmatterapp_com-2016-02-18&#34;。
同样注意如果您不使用CloudFront,那么您应该不使用--path
选项。如果 使用CloudFront然后将其删除,我强烈建议您再次执行上述aws iam upload-server-certificate
命令,仅使用不同的--server-certificate-name
而不是--path
选项(并删除以前的名称)。这可能意味着重新配置任何现有的ELB HTTPS侦听器以使用新的证书名称,但可能有必要,因为--path
会影响SSL处理。
完成上述操作后,使用例如 AWS控制台,您应该能够配置您的AWS ELB,并在&#34; Listeners&#34;选项卡,单击&#34;编辑&#34;。为&#34; https&#34;添加一个监听器例如。添加任何支持SSL的侦听器时,您将看到&#34;更改&#34;链接显示在&#34; SSL证书&#34;列/选项卡。单击&#34;更改&#34;,然后选择&#34;现有证书&#34;按钮。在&#34;证书名称&#34;然后,您应该看到上面使用的--server-certificate-name
字符串/标签的条目。选择该条目,然后单击&#34;保存&#34;。现在,应在AWS ELB上为该侦听器建立连接,以便为浏览器信任的SSL / TLS连接进行正确配置。
因此,HTTPS Listener配置看起来像:
--server-certificate-name
名称)请注意,您不也希望将端口443用于实例端口;如果你这样做,那就说你想要从ELB到实例的HTTPS ,这通常不需要 。 (一些安全站点需要这个,但这是一个不同的主题/存储。)因此,上面配置ELB来处理SSL终止;对于实例上的Node.js服务器,它只在端口80上接收纯HTTP请求:
client ---> HTTP ---> ELB port 80 ---> HTTP ---> server port 80
client ---> HTTPS --> ELB port 443 --> HTTP ---> server port 80
如果您的服务器需要知道原始请求是HTTP还是HTTPS,请查找AWS ELB将automatically add to the request的X-Forwarded-For
(以及其他请求标头)。
现在,一旦配置了ELB,它就是验证它是否正常工作的一个很好的步骤。首先,您可以使用openssl s_client
来验证SSL握手是否有效:
$ openssl s_client -connect example.com:443
CONNECTED(00000003)
depth=3 /C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=redmatterapp.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
3 s:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/CN=example.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
---
No client certificate CA names sent
---
SSL handshake has read 4929 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
...
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
以上显示我们成功完成了SSL握手,您可以看到它显示带有GoDaddy名称的证书链; &#34;服务器证书&#34;部分应匹配&#34; f6f65901b1708ae5.crt&#34;你加载的PEM文件。
现在测试 HTTPS 部分;为此,我喜欢使用curl
,就像这样:
$ curl -kv https://example.com/
-v
选项显示更多信息,特别是证书是否与DNS名称匹配; -k
告诉curl
忽略任何证书不匹配/问题,以便我们可以看到有关事情的详细信息。
这是需要更多配置的地方。 如果您在curl
命令(或浏览器)中使用自动生成的ELB DNS名称,那么您很可能会看到安全警告/问题。为什么?由于HTTPS的一部分正在验证您在URL 中使用的DNS名称与服务器证书中的域/主机名匹配,因此要么作为证书中的公用名(CN),或< / em>作为DNS主题备用名称(SAN)之一。您可能没有在GoDaddy的证书签名请求(CSR)中包含ELB DNS名称。
这意味着,下一步是配置指向AWS ELB名称的DNS CNAME记录,例如:
www.example.com CNAME to aws-elb-1.elb.amazonaws.com
如果您正在使用AWS进行DNS,那么您可以使用例如 Route 53执行此操作。然后您重试curl
命令(或浏览器):
curl -kv https://www.example.com/
要注意的另一个重要事项(您可以在curl -v
输出中看到这一点)是Host
请求标头的内容。一些HTTP服务器(即在后端实例上运行的服务器)对那里的值非常挑剔;他们希望Host
标题与其配置中的内容匹配,如果没有,则可能会拒绝该请求。
另一个常见的问题是:
如果您从ELB获得此响应,通常意味着您的后端服务器没有响应或无法响应ELB healtcheck。仔细检查用于ELB healtcheck的端口和路径/ URL是否正确,和,任何防火墙或AWS安全组都允许从ELB连接到您的实例。
所以,现在你应该有一个ELB,它将端口80(HTTP)和端口443(HTTPS)转发到你的后端实例。并且您有&#34; www.example.com&#34;的CNAME记录。在DNS中指向该ELB名称。剩下的是什么?
我高度建议您将HTTP服务器配置为始终重定向到相同网址的HTTPS等效项。为什么呢?
为了确保客户端与服务器之间的数据安全,现在需要使用SSL / TLS。以至于越来越多的浏览器首先自动尝试HTTPS,并且只是不情愿地使用HTTP作为后备。像Chrome(和其他人)这样的浏览器希望避免这种HTTP回退,以至于他们引入了HTTP Strict Transport Security这样的机制:您的网站告诉浏览器只能使用HTTPS的方式网站,永远不会HTTP 。此外,它总是一个更好的营销故事;事实上,如果您不使用HTTPS,您可能会受到客户/用户的负面反应。
使用HTTPS为您的所有网站流量提供的另一件事是保护您免受:其他人使用其DNS名称和您的ELB。您有&#34; www.example.com&#34;的CNAME记录指向&#34; aws-elb-1.elb.amazonaws.com&#34;。但是,如果我也为&#34; www.evilco.com&#34;创建我自己的CNAME,它指向相同的&#34; aws-elb-1.elb.amazonaws.com& #34 ;?人们前往&#34; www.evilco.com&#34;会看到您的网站,并认为它是我的网站!
通过强制您网站的所有流量为HTTPS,您强制所有HTTPS客户端验证服务器提供的证书即您的&#34 ; f6f65901b1708ae5.crt&#34; file)包含公共名称(CN)或DNS主题备用名称(SAN),匹配客户端在其URL中使用的域名。显然,您的证书不包含CN或DNS SAN,因为验证过程会失败 - 最终用户会看到有些东西是可疑的。但是,如果你的网站也允许HTTP流量,这种现象可能会发生 - 你看着你网站的日志,就永远不会知道!
我自己没有使用过AWS证书管理器或CloudFront(因此我无法对它们发表评论),但我 多次使用上述过程,适用于多个域的多种证书配置。
希望这有帮助!