วันจันทร์, มกราคม 18, 2559

สร้าง https ใน localhost พร้อมกุญแจเขียว บน OS X

เรื่องมันเริ่มจากว่าเห็น 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

https-with-green-padlock-on-localhost-poster

สิ่งที่ต้องมีก่อนจะเริ่มทำ

  • 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 ดู

red padlock

ได้แล้ว แต่เราจะมาทำให้มันไม่ขึ้นเตือนแบบนี้ และกลายเป็น 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 ...เย้! ไม่มีคำเตือนแล้ว

green padlock

reference:

  1. https://certsimple.com/blog/obsolete-cipher-suite-and-things-web-developers-should-know-about-ssl
  2. https://gist.github.com/jonathantneal/774e4b0b3d4d739cbc53
  3. https://www.sslshopper.com/ssl-converter.html
  4. http://www.area536.com/projects/be-your-own-certificate-authority-with-openssl/

ไม่มีความคิดเห็น :