เรื่องมันเริ่มจากว่าเห็น post นี้ของ certsimple What web developers should know about SSL but probably don’t และ กำลังจะเล่น features HTML5 ที่ต้องใช้ https อยู่พอดี ได้เรื่องมาเขียน blog ละ ฮ่าๆ
วิธีต่อไปนี้ทำสำเร็จใน OS X Yosimite ถ้าจะทำใน Linux เช่น ubuntu, centos หรีอ Window platform ไม่แน่ใจนะครับยังไม่ได้ลองหาวิธี ถ้าจะเอาไปใช้ได้ก็จะเป็นส่วนการสร้าง cert แบบ self signed
สิ่งที่ต้องมีก่อนจะเริ่มทำ
- openssl (สั่ง openssl ใน Terminal ได้)
- browser ที่ทันสมัย (Chrome, Safari, Firefox version ล่าสุด)
ต่อไปนี้จะมีหรือไม่มีก็ได้ เอาไว้ทดสอบ(แบบเร็วๆ) cert ที่ได้มา
- nodejs, npm
มาเริ่มกันที่สร้าง root key กันก่อน
Generate root key
$ openssl genrsa -aes256 -out server.key 2048
Generating RSA private key, 2048 bit long modulus
.................................................................................................+++
.............................+++
e is 65537 (0x10001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:
ถ้าไม่ใส่ password มันจะฟ้องว่า
You must type in 4 to 1023 characters
$ openssl genrsa -aes256 -out localhost.key 2048
Generating RSA private key, 2048 bit long modulus
........................................+++
..........+++
e is 65537 (0x10001)
Enter pass phrase for localhost.key:
Verifying - Enter pass phrase for localhost.key:
$ openssl rsa -in localhost.key -out localhost.key.rsa
Enter pass phrase for localhost.key:
writing RSA key
$ ls -l
total 32
-rw-r--r-- 1 siritas_s staff 1766 Jan 15 15:22 localhost.key
-rw-r--r-- 1 siritas_s staff 1679 Jan 15 15:23 localhost.key.rsa
-rw-r--r-- 1 siritas_s staff 1766 Jan 15 15:22 server.key
สร้าง openssl config file localhost.conf
[req]
default_bits = 1024
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = *.localhost
สร้าง Certificate Request (CSR)
$ openssl req -new -key server.key -subj "/C=/ST=/L=/O=/CN/emailAddress=/" -out server.csr
Enter pass phrase for server.key:
No value provided for Subject Attribute C, skipped
No value provided for Subject Attribute ST, skipped
No value provided for Subject Attribute L, skipped
No value provided for Subject Attribute O, skipped
Subject Attribute CN/emailAddress has no known NID, skipped
ตัวที่สองสำหรับ localhost
$ openssl req -new -key localhost.key.rsa -subj "/C=/ST=/L=/O=/CN=localhost/" -out localhost.csr -config localhost.conf
No value provided for Subject Attribute C, skipped
No value provided for Subject Attribute ST, skipped
No value provided for Subject Attribute L, skipped
No value provided for Subject Attribute O, skipped
ตอนนี้จะได้ไฟล์มาแบบนี้
$ ls
localhost.csr localhost.key.rsa server.key
localhost.conf localhost.key server.csr
สร้าง SSL certificate ให้มีอายุ 10 ปีเลย
$ openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
Signature ok
subject=
Getting Private key
Enter pass phrase for server.key:
ของ localhost
$ openssl x509 -req -extensions v3_req -days 3650 -in localhost.csr -signkey localhost.key.rsa -out localhost.crt -extfile localhost.conf
Signature ok
subject=/CN=localhost
Getting Private key
สอบรันบน server
เราจะใช้ nodejs มาทดสอบ มันไวดีครับ ในทางปฎิบัติแล้วของที่เราได้ จะเอาไปใช้กับ apache2 หรือ nginx ก็ได้
sudo npm install -g http-server
เมื่อติดตั้งสำเร็จ ใช้คำสั่งแบบนี้
http-server --ssl --cert /path/to/cert.pem --key /path/to/key.pem
จากที่เราทำมา ก็จะต้องใชคำสั่งแบบนี้ $ http-server --ssl --cert localhost.crt --key localhost.key
อ่าว เห้ย! ใช้ไม่ได้
_tls_common.js:87
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:87:19)
at Server (_tls_wrap.js:754:25)
at new Server (https.js:24:14)
at Object.exports.createServer (https.js:44:10)
at Object.core.createServer (/usr/local/lib/node_modules/http-server/node_modules/union/lib/core.js:93:18)
at new HttpServer (/usr/local/lib/node_modules/http-server/lib/http-server.js:125:23)
at Object.exports.createServer (/usr/local/lib/node_modules/http-server/lib/http-server.js:20:10)
at listen (/usr/local/lib/node_modules/http-server/bin/http-server:113:27)
at /usr/local/lib/node_modules/http-server/bin/http-server:83:5
ถ้าเจอ error แบบนี้ไม่ต้องตกใจ เราจะต้องเอา passpharse ของ key ออกก่อน
เอา passpharse ของ key ออก
เอา passpharse ของ localhost.key ออก ใช้คำสั่งแบบนี้
$ openssl rsa -in localhost.key -out newlocalhost.key
Enter pass phrase for localhost.key:
writing RSA key
มันจะถาม passpharse เป็นครั้งสุดท้าย ใส่เสร็จเราก็เอา newlocalhost.key ไปใช้งานแทน แบบนี้ครับ
$ http-server --ssl --cert localhost.crt --key newlocalhost.key
Starting up http-server, serving ./ through https
Available on:
https:127.0.0.1:8080
https:172.16.22.1:8080
Hit CTRL-C to stop the server
ทดสอบเปิด browser เข้า https://127.0.0.1:8080 ดู
ได้แล้ว แต่เราจะมาทำให้มันไม่ขึ้นเตือนแบบนี้ และกลายเป็น trusted (กุญแจเขียวเลย)
คำสั่งด้านล่างใช้กับ OS X เท่านั้น
กด Ctrl - C หยุด server ก่อน แล้ว ใช้คำสั่งแบบนี้ เป็นการบอกให้ OS X เชื่อใจ certificate ของเราโดยเอา localhost.crt import เข้าไปใน KeyChain และเชื่อใจ trusted ด้วย
$ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain localhost.crt
Password:
ทีนี้ลองใหม่ start server อีกครั้ง ทดสอบกับ browser …เย้! ไม่มีคำเตือนแล้ว
reference: