Mar*_*ark 2 ssl https amazon-ec2 ssl-certificate amazon-elb
我是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
Run Code Online (Sandbox Code Playgroud)
指南说我应该期待3个证书:
DigiCertCA.crt
TrustedRoot.crt
star_yourdomain_com.crt
Run Code Online (Sandbox Code Playgroud)
相反,我很容易收到2个名为的文件:
f6f65901b1708ae5.crt
gd_bundle-g2-g1.crt
Run Code Online (Sandbox Code Playgroud)
我假设f6f65901b1708ae5.crt是我的域名证书(但我不确定).无论如何,指南说我需要一个Elastic Load Balancer来安装SSL证书,所以我创建了一个.
我生成了私钥:
openssl rsa -in server.key -text
Run Code Online (Sandbox Code Playgroud)
和公钥认证:
openssl x509 -inform PEM -in f6f65901b1708ae5.crt
Run Code Online (Sandbox Code Playgroud)
我还被要求进入证书链.我不确定这是什么以及如何得到它,所以我猜到了命令:
openssl x509 -inform PEM -in gd_bundle-g2-g1.crt
Run Code Online (Sandbox Code Playgroud)
并输入以"----- 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
Run Code Online (Sandbox Code Playgroud)
我上传了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/
Run Code Online (Sandbox Code Playgroud)
这很成功.
然后,我必须创建一个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这样的东西吗?
您提到指南说要预期3个文件,包括"DigiCertCA.crt"文件; 听起来它是用DigiCert作为您的证书提供商而不是GoDaddy编写的.
首先,要确保"f6f65901b1708ae5.crt"包含您所要求的证书(并在那里放下任何疑问).为此,您可以将"server.csr"文件(即证书签名请求)中的数据(例如,公共名称(CN),DNS主题备用名称(SAN)等)与"f6f65901b1708ae5.crt"中的内容进行比较. "档案:
$ openssl req -noout -text < server.csr
Run Code Online (Sandbox Code Playgroud)
这应该在CSR文件中显示有关域的详细信息的人类可读文本.与之相比:
$ openssl x509 -noout -text < f6f65901b1708ae5.crt
Run Code Online (Sandbox Code Playgroud)
这应该显示类似的人类可读文本,填写更多的细节/字段.但它们应该大致有你期望的. 请注意,如果您看到类似于此的错误:
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
Run Code Online (Sandbox Code Playgroud)
然后它建议你的"f6f65901b1708ae5.crt"文件是DER格式,而不是PEM格式.如果没有,那么您已经有了一个PEM文件,这是AWS ELB所期望的.如果您有DER格式的证书,则可以使用以下方法轻松转换为PEM格式:
$ openssl x509 -in f6f65901b1708ae5.crt -inform DER -out f6f65901b1708ae5.pem -outform PEM
Run Code Online (Sandbox Code Playgroud)
我只想提一下这一部分.
现在假设我们知道 "f6f65901b1708ae5.crt"包含您域名的PEM格式证书,我们已准备好处理"证书链"部分.
我查看了GoDaddy的在线证书库,看看你提到的"gd_bundle-g2-g1.crt"文件是否存在,而且确实如此.(这些文件可以公开获取,因为它们包含供任何人/每个人使用的公共证书.)查看gd_bundle-g2-g1.crt文件,我发现它包含多个证书.这个很重要.
请参阅"证书链"是提供信任路径(或"链")的文件列表,从您拥有的"f6f65901b1708ae5.crt"证书到受信任的根GoDaddy CA证书.每份证书都有一个主题(是谁发出来)和发行人(谁发出它).这意味着您可以"向后"走,从证书到发行人的证书,到证书的发行人证书等.这种向后走的是"证书链".
"gd_bundle-g2-g1.crt"文件包含多个证书这一事实意味着该文件包含您需要的证书链.这也意味着,你不希望这样做:
$ openssl x509 -inform PEM -in gd_bundle-g2-g1.crt > aws_public.pem
Run Code Online (Sandbox Code Playgroud)
因为openssl x509只读取指定文件中的第一个证书,并且您需要所有这些证书.
鉴于上述所有情况,您可能只需要以下内容(以确保您的私钥是PEM格式):
$ openssl rsa -in server.key -text > aws_private.pem
Run Code Online (Sandbox Code Playgroud)
然后,因为我们假设"f6f65901b1708ae5.crt"已经是PEM格式化(如果不是,你知道如何在上面进行转换),我们知道 "gd_bundle-g2-g1.crt"已经是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/
Run Code Online (Sandbox Code Playgroud)
请注意,我使用了不同的--server-certificate-name,只是为了确保它不会覆盖/与现有配置冲突.作为建议,您可以包括创建上载证书的日期(或者,更好,何时到期),作为名称的一部分,作为添加该证书时未来自我的提示,例如 " redmatterapp_com - 2016年2月18"日.
另外请注意,如果你不使用CloudFront的,那么你应该不使用的--path选项.如果您是使用CloudFront的,然后删除它,我会强烈建议做上述aws iam upload-server-certificate再次命令,只能用一个不同的--server-certificate-name,没有--path选项(和删除以前的名字).这可能意味着重新配置任何现有的ELB HTTPS侦听器以使用新的证书名称,但这可能是必要的,因为这--path会影响SSL处理.
完成上述操作后,使用例如 AWS控制台,您应该能够配置AWS ELB,并在"监听器"选项卡下单击"编辑".添加一个监听器,例如 "https".添加任何支持SSL的侦听器时,您会在"SSL证书"列/选项卡下看到"更改"链接.单击"更改",然后选择"现有证书"按钮.在"证书名称"下拉列表中,您应该看到--server-certificate-name上面使用的字符串/标签的条目.选择该条目,然后单击"保存".现在,应在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
Run Code Online (Sandbox Code Playgroud)
如果您的服务器需要知道原始请求是HTTP还是HTTPS,请查找X-Forwarded-ForAWS ELB将自动添加到请求的(以及其他请求标头).
现在,一旦配置了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)
---
Run Code Online (Sandbox Code Playgroud)
以上显示我们成功完成了SSL握手,您可以看到它显示带有GoDaddy名称的证书链; "服务器证书"部分应与您加载的"f6f65901b1708ae5.crt"PEM文件匹配.
现在来测试HTTPS部分; 为此,我喜欢使用curl,像这样:
$ curl -kv https://example.com/
Run Code Online (Sandbox Code Playgroud)
该-v选项显示更多信息,特别是证书是否与DNS名称匹配; 该-k通知curl忽略任何证书不匹配/问题,这样我们就可以看到有关事情的详细信息.
这是需要更多配置的地方. 如果在curl命令(或浏览器)中使用自动生成的ELB DNS名称,则很可能会看到安全警告/问题.为什么?因为HTTPS的一部分正在验证您在URL 中使用的DNS名称是否与服务器证书中的域/主机名匹配,可以是证书中的公用名(CN),也可以是DNS主题备用名称(SAN)之一.你可能没有在您的证书签名请求(CSR)到GoDaddy的包括ELB DNS名称.
这意味着,下一步是配置指向AWS ELB名称的DNS CNAME记录,例如:
www.example.com CNAME to aws-elb-1.elb.amazonaws.com
Run Code Online (Sandbox Code Playgroud)
如果您使用AWS进行DNS,那么您可以使用例如 Route 53 执行此操作.然后您重试curl命令(或浏览器):
curl -kv https://www.example.com/
Run Code Online (Sandbox Code Playgroud)
另一个需要注意的重要事项(您可以在curl -v输出中看到这一点)是Host请求标头的内容.一些HTTP服务器(即在后端实例上运行的服务器)对那里的值非常挑剔; 他们希望Host标题与其配置中的某些内容匹配,如果不匹配,则可能拒绝该请求.
另一个常见的问题是:
如果您从ELB获得此响应,通常意味着您的后端服务器没有响应或未能响应ELB healtcheck.仔细检查用于ELB healtcheck的端口和路径/ URL是否正确,以及任何防火墙或AWS安全组是否允许从ELB连接到您的实例.
所以,现在你应该有一个ELB,它将端口80(HTTP)和端口443(HTTPS)转发到你的后端实例.并且您在DNS中有"www.example.com"的CNAME记录,指向该ELB名称.还剩什么?
我强烈建议您将HTTP服务器配置为始终重定向到相同URL的HTTPS等效项.为什么?
为了确保客户端和服务器之间的数据安全,现在需要使用SSL/TLS.以至于越来越多的浏览器首先自动尝试HTTPS,并且只是不情愿地使用HTTP作为后备.像Chrome(和其他人)这样的浏览器希望避免这种HTTP回退,以便他们引入HTTP严格传输安全性等机制:您的网站告诉浏览器只能为网站使用HTTPS,而不是HTTP.此外,它总是一个更好的营销故事; 事实上,如果您不使用HTTPS ,您可能会得到客户/用户的负面反应.
还有一件事是使用HTTPS来保护您的所有网站流量:保护您:其他人使用他们的DNS名称和您的ELB.您有"www.example.com"的CNAME记录,指向"aws-elb-1.elb.amazonaws.com".但是如果我还为"www.evilco.com"创建了自己的CNAME,它指向相同的"aws-elb-1.elb.amazonaws.com"呢?去"www.evilco.com"的人会看到你的网站,并认为这是我的网站!
通过强制您的站点的所有流量为HTTPS,您强制所有HTTPS客户端验证服务器提供的证书(即您的"f6f65901b1708ae5.crt"文件)包含公用名(CN)或DNS主题备用名称( SAN)匹配客户端在其URL中使用的域名.显然,你的证书并没有包含CN或DNS SAN的"www.evilco.com"的,因而这种验证过程将失败-和最终用户将看到的东西是腥.但是,如果你的网站也允许HTTP流量,这种现象可能会发生 - 你看着你网站的日志就永远不会知道!
我自己没有使用AWS证书管理器或CloudFront(因此我无法对它们发表评论),但我已经多次使用上述过程,在多个作业中对多个域进行各种证书配置.
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
1804 次 |
| 最近记录: |