Amazon EC2 Instance Express API配置HTTPS

最近在做一個API的項目,放在Amazon EC2上跑,爲了提高安全性想把鏈接搞成HTTPS的。API放在Express上,GoDaddy上面沒有Node Server配置的教程,搜到很多教程都是通過AWS Load Balancer來配置的,所以自己把各教程綜合了一下,完成了配置。


第一步:買一個SSL證書

我看很多人都是自己簽發證書。但是我因爲有折扣,打完折之後$3/年,很便宜,就直接從GoDaddy買了。 


第二步:生成CSR

買完證書之後,在賬戶裏進行配置的時候發現GoDaddy要求輸入CSR。生成CSR這一部分需要在EC2 Instance裏面完成。主要是根據Creating And Installing A SSL Certificate On Amazon EC2 裏面第1-6步來做的。

1. 生成私鑰(private key)

$ openssl genrsa -des3 -out host.key 2048
Generating RSA private key, 2048 bit long modulus
..................................................+++
...............................+++
e is 65537 (0x10001)
Enter pass phrase for host.key:
Verifying - Enter pass phrase for host.key:

注意:(1) EC2裏openssl是裝好可以直接用的。

            (2) pass phrase要記住,後面還要用

2. 用私鑰生成certificate signing request,也就是前面所提到的CSR。

$ openssl req -new -key host.key -out host.csr

輸入這個命令之後openssl會讓你輸入上一步裏提到的pass phrase,然後在輸入若干跟你的網站和公司有關的信息如下。其中Organizational Unit Name和Common Name是最重要的,要輸入你的網站的域名,其他可以隨便填。

Enter pass phrase for host.key:
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) [AU]:US
State or Province Name (full name) [Some-State]:Missouri
Locality Name (eg, city) []:Saint Louis
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:www.mycompany.com
Common Name (e.g. server FQDN or YOUR name) []:www.mycompany.com
Email Address []:[email protected]

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


第三步:提交CSR

1. 上面的命令完成後會生成一個host.csr,用vi打開這個csr文件,會看到:

-----BEGIN CERTIFICATE REQUEST-----
[encoded text here]
-----END CERTIFICATE REQUEST-----
把這個文件的內容(包括“BEGIN CERTIFICATE REQUEST”和“END CERTIFICATE REQUEST”這兩行)複製黏貼(:%y+)到GoDaddy的CSR request form裏,提交,等待GoDaddy驗證審批完成。
2. 審批完成之後,GoDaddy會生成一個壓縮包,裏面有兩個crt文件(一個隨機命名的crt文件和一個gd_bundle.crt文件)。

第四步:上傳.crt文件

我的筆記本是windows系統,所以需要下載一個WinSCP,通過這個軟件把crt文件上傳到EC2。

這個軟件跟Putty很類似,用法跟通過putty ssh到ec2一樣,用過putty ssh ec2的筒子們應該都很熟悉。主機名就是你的ec2主機名,ec2-xx-xx-xxx-xxx.us-west-x.compute.amazonaws.com,端口22也就是ssh,協議sftp,用戶名ubuntu(我的ec2是ubuntu),密碼空置。

唯一需要注意的是,要點擊“編輯” ==〉“高級”  ==〉“SSH” ==〉“驗證” ==〉“密鑰文件”,把你的ec2的私鑰(.ppk)文件的路徑輸進去。

具體的詳細步驟請見 http://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/putty.html#Transfer_WinSCP 

ssh連接建立好後就可以很方便的把本地的crt文件上傳的ec2了。


第五步:生成pem格式的私鑰

之前的私鑰host.key並不是pem格式,需要通過下面的命令把.key轉成.pem

openssl rsa -in host.key -out newkey.pem && mv newkey.pem key.pem
否則你會看到錯誤
mgechev → MinBook Pro ~/Desktop/test Thu Apr 30 11:56:03
 $ node index.js
_tls_common.js:67
      c.context.setKey(options.key);
                ^
Error: error:0906A068:PEM routines:PEM_do_header:bad password read
    at Error (native)
    at Object.createSecureContext (_tls_common.js:67:17)
    at Server (_tls_wrap.js:595:25)
    at new Server (https.js:36:14)
    at Object.exports.createServer (https.js:56:10)
    at Object.<anonymous> (/Users/mgechev/Desktop/test/index.js:6:11)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:349:32)
    at Function.Module._load (module.js:305:12)
以上步驟來自http://blog.mgechev.com/2014/02/19/create-https-tls-ssl-application-with-express-nodejs/。


第六步:更改代碼

證書和密鑰設置好了,下一步需要更改代碼以監聽443端口。直接上代碼

var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');

// This line is from the Node.js HTTPS documentation.
var options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.cert') //此處.cert文件實際是從godaddy下載下來的那個隨機命名的.cert文件
};

// Create a service (the app object is just a callback).
var app = express();

// Create an HTTP service.
http.createServer(app).listen(80);
// Create an HTTPS service identical to the HTTP service.
https.createServer(options, app).listen(443);
以上代碼來自http://stackoverflow.com/a/14272874/2177408

第七步:運行

運行服務器之後,可能會發現程序報錯

$ node server.js
events.js:154
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES 0.0.0.0:80
這個Error可能是80端口也可能是443端口,取決於你監聽哪個端口。

這是因爲我們沒有權限來監聽這兩個端口。所以需要用sudo

sudo node server.js
http://stackoverflow.com/a/39320632/2177408

完成這些步驟之後,我們就可以通過https來訪問跑在ec2上的API了。

最後友情提醒一下,不要忘記在aws ec2 security group上打開443和80端口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章