Cloudflare SSL Full(Strict) ง่ายกว่าที่คิด
หลายๆ คนที่ใช้บริการของ CloudFlare คงจะได้ใช้ Feature สุดฮอตฮิตของมัน อย่างการเซ็ต SSL
ในความเป็นจริง คงมีคนจำนวนไม่น้อยที่ย้ายจาก DNS เจ้าเก่าๆ มาใช้ Cloudflare เพราะต้องการเซ็ต SSL ง่ายๆ เลยด้วยซ้ำ
ฟีเจอร์นี้เอาไว้ทำอะไร? เอาแบบรวบรัดเลยคือ มันทำให้เว็บเรากลายเป็น HTTPS แบบง่ายๆ แค่กดจาก Dashboard ของ CloudFlare
เพียงแค่ Setup Domain เรากับ CloudFlare ปรับค่า DNS จนครบ และปรับตรง Crypto SSL ให้เป็น Flexible
เพียงแค่เซ็ตแค่นี้ เว็บเราก็กลายเป็น HTTPS เลย โดยที่ไม่ต้องเซ็ตอัพอะไรในฝั่ง Server เราแม้แต่น้อย
ย้ำอีกครั้ง เราไม่ต้องเซ็ตอัพอะไรใน Server เราเลย เว็บเราก็กลายเป็น https แล้ว!!
ด้วยเซ็ตอัพที่ง่ายขนาดนี้ ทำให้ฟีเจอร์นี้เป็นที่นิยมมาก เอาจริง เซ็ต HTTPS ที่เดี๋ยวนี้เราใช้ Self-signed แบบ Lets Encrypt ได้ว่าง่ายแล้ว อันนี้ง่ายกว่าแยะ
เห้ย แล้ว CloudFlare มันทำให้เราได้ยังไง??
เนื่องจาก CloudFlare มันเป็น DNS เวลาเรา connect ไปที่โดเมนเนมเรา request จะไปที่ Cloudflare ก่อน ตรงจุดนี้เอง Cloudflare จะรับ request ที่เข้ารหัส SSL จาก Browser แล้วถอดรหัสมันส่งไปที่ server เราแบบ http ธรรมดา
จากรูปจะเห็นว่า แบบ Flexible นี้ไม่ใช่แบบที่ CloudFlare แนะนำ ถ้าเรามีการส่งข้อมูล sensitive data นะค้าบบบ
เพราะถึงแม้เว็บเราจะขึ้นว่า HTTPS แต่ request ของเราไม่ได้ถูกเข้ารหัสตลอด ข้อมูลของเราไม่ปลอดภัย!
แต่ก็นะ เนื่องด้วยความง่ายของมัน หลายๆ คนคงจะเซ็ตอัพ กะว่าเอาแบบนี้ไปก่อน อย่างน้อย HTTPS ใช้ได้ รัน app ให้ได้ไปก่อนละกัน
ผ่านไปเป็นปี แอพรันไปได้ มี user หลายร้อยคนแล้ว อ้าวแล้ว sensitive data ที่วิ่งอยู่ในเน็ตเวิร์คแบบ unencrypted จะเป็นยังไงกัน
ซวยแล้ว!!
งั้น วันนี้เรามาเซ็ตอัพ SSL จาก Cloudflare ให้เป็นแบบ Full (Strict) กันเถอะ
Set Up Cloudflare SSL Full (Strict) บน Kubernetes Cluster ที่ใช้ Ingress Nginx
ในบทความนี้จะยกตัวอย่างการเซ็ตอัพบน Kubernetes ที่ใช้ NGINX Ingress controller ละกันนะฮะ แต่ถ้าเป็น stack แบบอื่นก็ลองอ่านดูได้ การเซ็ตอัพน่าจะคล้ายๆ กัน
แบบ Full (Strict) เซ็ตอัพ ตัว CloudFlare จะบังคับว่า connection ระหว่าง Cloudflare กับ server เราต้องเป็นแบบ secure https ผ่าน port 443 และ certificate ที่ใช้ encrypt ต้องเป็น valid certificate จาก CloudFlare ด้วย
ถ้าเซ็ตอัพเป็นแบบนี้ เราค่อนข้างมั่นใจได้ว่า connection ของเรา secure และมีการเช็ค authority ของการเข้ารหัสอีกรอบนึงด้วยเพื่อยืนยันว่า Request ที่เข้ารหัสนั้นมาจาก server ที่มี certificate ของเราจริงๆ
ข้อสังเกตอย่างนึงคือ วิธีนี้จะต่างจากการเซ็ตอัพ https แบบเดิมๆ คือ Cloudflare จะมีการเปลี่ยน certificate ระหว่าง Cloudflare — Server กับ ระหว่าง User — Cloudflare ซึ่งในส่วนของ Certificate ระหว่าง User — CloudFlare ตรงนี้จะเป็น cer ที่เราสามารถ manage ได้ใน dashboard ของ CloudFlare และมี Option ต่างๆ ให้เลือกหลายแบบ อย่างไรก็ดี การเซ็ตอัพแบบนี้ ถึงแม้จะไม่ใช่เป็น certificate เดียวทุก connection เราก็ยังมั่นใจได้ว่า connection แต่ละจุดถูกเข้ารหัสและยืนยันได้ไว้แล้ว
อะไปลุยเซ็ตอัพเลยดีกว่า
สร้าง Origin Certificate จาก Cloudflare
ขั้นตอนแรก เราต้องไปเอา Origin Certificate จาก Cloudflare ก่อน ตัวนี้เองเราจำเป็นต้องเอาจาก CloudFlare มันถึงจะผ่าน Validation ที่เป็น Full (Strict)
ในแถบ Crypto เลื่อลงมาจนเจอ Origin Certificates กด Create Certificates ได้เลย
ในขั้นตอนนี้เราจะสามารถเลือก Private key Type และ Hostnames List ที่จะใช้ Certificate นี้ได้
พอกได้ออกมา เราจะได้ Certificate ให้เลือก PEM (Default) Format แล้วก๊อป Certificate กับ Key เก็บไว้ก่อน ในกรณีนี้ก็อาจจะเซฟไฟล์ Origin Certificate ไว้ในชื่อ cloudflare.cert
และเซฟ key ไว้ในชื่อ cloudflare.key
ติดตั้ง Certificate บนเว็บเซิร์ฟเวอร์ของเรา
วิธีนี้จะแตกต่างกันไป แล้วแต่ เว็บเซิร์ฟเวอร์ของเราเลย แต่สำหรับ Kubernetes ที่ใช้ Ingress บน NGINX ingress controller ก็จะง่ายหน่อย เราสามารถทำผ่าน Kubectl ได้เลย
ขั้นตอนแรก อัพโหลด certificate ที่ดาวน์โหลดมาขึ้น Kube ให้เป็น secret
$ kubectl create secret tls {SECRET_NAME} --key ./{KEY_FILE}.key --cert ./{CERT_FILE}.cert
ตรงส่วนนี้เราสามาถตั้งชื่อ SECRET_NAME
ของเราเอาเองได้เลย ในที่นี้ก็ขอใช้ชื่อว่า cloudflare
ละกัน
$ kubectl create secret tls cloudflare --key ./cloudflare.key --cert ./cloudflare.cert
เมื่ออัพโหลดแล้วก็จะเจอ secret ใหม่ขึ้นใน cluster ของเรา
$ kubectl get secret cloudflare
--> NAME TYPE DATA AGEcloudflare kubernetes.io/tls 2 3h
เมื่ออัพโหลดได้แล้ว เราก็ต้องไปแก้ไฟล์ ingress ให้มัน serve https ด้วย certificate ที่พึ่งอัพโหลดขึ้นไป
---apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: rentspree-dashboard
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- www.rentspree.com
secretName: cloudflare
rules:
- host: www.rentspree.com
http:
paths:
- path: /
backend:
serviceName: rentspree-web
servicePort: 80
อันนี้จาก Ingress ปกติที่เราใช้ เพิ่ม section ที่เป็น tls:
ลงไปใน spec
โดยกำหนด hosts ที่จะให้เข้ารหัส SSL
ในส่วนของ secretName
คือชื่อของ Secret ที่เราพึ่งอัพโหลดขึ้นไปนั่นเอง
เท่านี้ Nginx Ingress ของเราก็จะเริ่ม serve ด้วย https แล้ว ถ้าลองเข้าเว็บตอนนี้ก็จะเจอว่า เว็บเข้าไม่ได้เพราะติด Redirect Loop
ไม่ต้องตกใจ ถ้าเจอแบบนี้แสดงว่าเซ็ตอัพของเราจะใช้การได้ละ เหลือขั้นตอนต่อไปอีกนิด
สำหรับเว็บเซิร์ฟเวอร์แบบอื่น ลองดูวิธีการเซ็ต SSL ได้ที่นี่เลย
เปลี่ยน SSL Mode ใน Cloudflare
ขั้นตอนสุดท้าย เราแค่เปลี่ยน SSL Mode ให้เป็น Full (Strict)
เท่านี้ก็เรียบร้อย เราจะได้ Connection ที่เข้ารหัสเว็บเราอย่างปลอดภัย เพื่อป้องกัน Sensitive data ของเราได้แล้วหละ
จะเห็นว่า Secure Connection ผ่าน CloudFlare SSL Full (Strict) นั้นเซ็ตอัพได้ง่ายจริงๆ