การต่อ HTTPS กับ GitLab Pages ด้วย Cloudflare​ ให้ได้ SSL Lab เกรด A+

สวัสดีครับ ห่างหายกันไปหลายสัปดาห์​ วันนี้เรากลับมาต่อกันกับการโฮสเว็บไซต์บน GitLab Pages ในเรื่องของการทำ custom domain และทำ HTTPS ด้วย Cloudflare ให้ได้เกรด A+ จาก SSL Labs

สำหรับบทความนี้จะมีทั้งหมด 3 ตอน ดังนี้

  1. ใช้ GitLab Pages โฮส Static Website ฟรีๆ ไม่ต้องตั้ง Server
  2. การต่อ HTTPS กับ GitLab Pages ด้วย Cloudflare​ ให้ได้ SSL Lab เกรด A+
  3. ทำเว็บไซต์แบบเป็นเรื่องเป็นราวบน GitLab Pages ด้วย Hugo

ก่อนที่จะไปกันต่อ ผู้อ่านควรมีความรู้เรื่อง DNS พอสมควรนะครับ ถ้าใครยังงงๆ แนะนำให้ไปอ่านบทความนี้กันก่อน ผมเคยเขียนเล่าไว้แล้วแบบง่ายๆ การตั้งค่า DNS Server ฉบับผู้เริ่มต้น

ต่อมาที่ท่านผู้อ่านจะต้องทำกันก่อนก็คือ จะต้องจด domain name (ใครยังไม่มี domain name แล้วไม่อยากเสียตังจดลองไปจดฟรีที่ dot.tk มาใช้ก่อนก็ได้นะ แต่ไม่แนะนำให้ใช้ถาวรเพราะเวลามีคนเข้าเยอะๆ มันจะยึด domain) หลังจากได้ domain มาแล้วก็ไปสมัคร Cloudflare แล้วเชื่อม domain ให้เรียบร้อย ซึ่งถ้าใครทำไม่เป็นไปอ่านกันที่หนูเนยเคยเขียนเอาไว้ได้ที่นี่

สำหรับตัวอย่างที่จะใช้ในบทความนี้คือเว็บ spicydog.me เป็นหน้า homepage portfolio ส่วนตัวของผมเอง ซึ่งผมจะเชื่อมให้ spicydog.me เป็นเว็บหลัก ส่วน www.spicydog.me ก็เข้าได้เหมือนกัน แต่จะถูก redirect มาที่ spicydog.me (สถานการณ์จะกลับกัน เว็บปรกติที่จะใช้ www เป็นหลัก)

อันนี้คือแผนผังคร่าวๆ ว่าหน้าตา infra และผลลัพธ์​จากการเข้าในแต่ละ URL จะออกมาแบบไหน


ชี้ Domain name มาหา GitLab Pages ด้วย Cloudflare

เข้าไปที่ GitLab Pages แล้วจะเห็น Force domain with SSL ให้เอาออกไป ไม่งั้นเราจะต้องหา cert ssl มาใส่ด้วย (ความจริง Cloudflare ก็ออก ssl cert ได้ แต่ผมจอเริ่มจากง่ายๆ ก่อนละกัน) จากนั้นก็กดปุ่ม New Domain สีเขียวด้านขวาบน เพื่อเพิ่ม custom domain ของเรา

ต่อมาก็ใส่ domain ของเราลงไป ซึ่งของผมก็คือ spicydog.me นั่นเอง ส่วน Certificate กับ Key ไม่ต้องใส่ เพราะทางฝั่งนี้จะเป็น HTTP ธรรมดา เรียบร้อยแล้วกด Create New Domain

เสร็จแล้ว GitLab จะให้เราชี้ CNAME มาให้ถูกและยืนยันความเป็นเจ้าของ domain โดยสิ่งที่ต้องทำมี 2 ก็คือ ไปสร้าง CNAME และ TXT ตามที่ GitLab ให้ทำ

เราก็ไปแก้ไขค่า DNS ที่ Cloudflare แล้วเพิ่ม records ตามที่ GitLab กำหนดให้ลงไป ในรูปเป็นขั้นตอนของการเพิ่ม TXT สำหรับคนที่ยังไม่แม่นเรื่อง DNS ลองสังเกตค่าที่ใส่ไปหน่อยนะครับว่าต้องใส่ยังไง

อันนี้คือผลลัพธ์สุดท้าย (ดูแค่ TXT กับ CNAME พอครับ)

กลับมาที่ GitLab กด verify ถ้าเซทถูกต้องก็จะได้สีเขียวมาเรียบร้อย

Domain ใหม่ที่เพิ่งเพิ่มเข้ามาขึ้นมาให้เห็นแล้ว (ถ้าไม่ได้กดรูปเมฆสีส้มในหน้า dns ของ Cloudflare เอาไว้ ก็จะเข้าแบบ HTTP ธรรมดาได้ละ)


ทำ HTTPS ด้วย Cloudflare

แต่เรากำลังจะทำแบบ HTTPS ดังนั้นเดินหน้าต่อไป แล้วไปกดเมฆสีส้มเอาไว้ด้วย เพราะจะต้องใช้ฟีเจอร์ของ Cloudflare กับ subdomain ที่กำลังทำอยู่

กลับไปที่ Cloudflare เราจะต้องเซทให้ domain ของเราเข้าผ่าน SSL Rule ที่เรียกว่า Flexible มันคือการที่ Client ต่อแบบ HTTPS มาถึง Cloudflare แล้ว Cloudflare ต่อมาหา Origin Server แบบ HTTP แต่เพื่อให้ไม่ไปไปกระทบกับ subdomain อื่น (ที่อาจจะเป็น web app ที่ควรต้องต่อด้วย HTTPS ตลอด) เราจึงควรใช้ Page Rule เฉพาะ subdomain ที่เราต้องการ

ไปที่หน้า Page Rules บน Cloudflare ก็จะเห็นหน้าตาประมาณในรูปข้างบน จากนั้นกด Create Page Rule

ใน popup ที่ช่อง URL matches เป็นชื่อ subdomain ที่เราต้องการลงไปแล้วปิดท้ายด้วย /* ก็คือให้ใช้ rule นี้กับทุก path (สำหรับคนที่จะใช้ www นำหน้าก็ใส่ www. นำไปด้วยล่ะ

ต่อมา Setting ให้เลือก SSL แล้วเลือกเป็น Flexible แล้วก็ Save and Deploy ซะ

รอสักนาทีสองนาที แล้วลองเปิดเว็บด้วย HTTPS ดูก็จะเห็นว่าเข้าได้แล้ว จากภาพจะเห็นว่ารูป logo ไม่ขึ้น ปัญหานี้ถ้าจำกันได้ มันเกิดจาก GitLab กำลัง Deploy เว็บเราใหม่ แล้วมันยังไม่ Propagate resource ทั้งหมดมา เพราะเวลาเราเพิ่ม custom domain ใหม่ มันเหมือนจะไป deploy ใหม่ ก็รอมันหน่อย เดี๋ยวครั้งต่อๆ ไปจะไม่มีปัญหานี้

หลังจากเข้าผ่านทาง spicydog.me ผ่านทาง HTTPS​ ได้แล้ว


Redirect Subdomain รองมาที่เว็บหลัก

ต่อไปเราจะมาทำให้การเข้าผ่านทาง www.spicydog.me ถูก redirect มาที่ spicydog.me แทน เพื่อจะได้เข้าได้จากทั้งสองทาง

วิธีการก็ใส่ CNAME เพิ่มเข้าไปอีกอัน (กรณีของผมคือ www ถ้าจะใช้แบบไม่มี subdomain ให้ใส่ @) แล้วชี้กลับไปที่ไหนก็ได้ กรณีของผมคือผมชี้ไปหา subdomain หลัก แล้วก็เปิดก้อนเมฆสีด้วย

ต่อมาไปเพิ่ม Page rule อันใหม่ โดยตั้งให้รับ URLs ที่เราต้องการ redirect ทั้งหมด แล้วทำการ Forward URL ไปที่ subdomain หลัก แล้วปิดท้ายด้วย /$1 ซึ่งหมายความว่า ให้เอาใดๆ ที่ * ดักไว้มาใส่ที่ตรงนี้ ดังนั้นเวลาเข้าไปที่ path อะไร มันก็จะ forward มาที่ subdomain ใหม่ใน path ที่ต้องการเลย ดูตัวอย่างข้างล่าง

ทดลองว่า redirect ได้ถูกต้องผ่านทางคำสั่ง curl -I จะเห็นใน Location ว่ามันจะพาไปที่ไหน


ทำ HTTPS ให้ได้เกรด A+ จาก SSL Labs

ต่อมาลองเปิดเว็บผ่าน https ดู ถ้าเปิดได้แล้วทีนี้มาเซท https เกรด A+ กัน

ไปที่ tab Crypto แล้วตั้งค่าประมาณนี้

Always use HTTPS ให้เข้าผ่าน https ตลอด ถ้าเข้ามาทาง http มันจะ redirect

HSTS อันนี้บอกว่าให้ใส่ header พิเศษให้ web browser จำว่า เว็บไซต์นี้ให้บริการผ่านทาง HTTPS เท่านั้นนะ จะห้ามเข้าผ่านทาง HTTP ธรรมดา มันจะมีให้ตั้งเวลาว่าจะจำแบบนี้ไปนานเท่าไหร่ ถ้ายังไม่ชัวร์ก็ตั้งสั้นๆ ก่อน ถ้ามั่นใจก็จัดไปเลยสัก 6 เดือน

อ่อ ระวังเรื่องการเซทให้มัน preload กับ subdomain นะครับ ถ้าทั้งแล้ว subdomain ใดๆ จะต้องเข้าผ่านทาง HTTPS ตลอดไปด้วย แนะนำให้ข้ามก่อนดีกว่าถ้ายังไม่แม่นเรื่อง HSTS

Opportunistic Encryption อันนี้ผมอ่านแล้วไม่เคลีย 100% สั้นๆ คือมันเป็น Header ที่มีขึ้นมาใหม่บน HTTP/2 ช่วยให้สื่อสารผ่าน HTTP ธรรมดาบนช่องทางที่เข้ารหัสได้ ช่วยแก้ปัญหาที่บางครั้งเว็บยังแก้เป็น HTTPS ไม่หมด ใครสนใจศึกษาเพิ่มเติมตามไปอ่านที่นี่ Opportunistic Encryption

Automatic HTTPS Rewrites ถ้าเจอ content ที่เป็น HTTP ให้แก้ให้เป็น HTTPS แทนให้หมด กรณี hard code แบบ absolute path ทำให้บาง resource ที่เป็น HTTP จะโดนปัญหา​เรื่อง mixed content

จากนั้นก็ไปทดสอบกันที่ SSL Labs กัน ซึ่งก็จะเห็นสีเขียวสุดตาดังในภาพ 🙂


สำหรับตอนนี้ก็ขอจบไว้เพียงเท่านี้นะครับ การประยุกต์ใช้​งานต่อไปจากนี้ด็ไม่ต่างกันละ สำหรับตอนหน้าผมจะมีแนะนำให้รู้จักกับ Hugo มันคือ static page CMS ที่จะ compile content ของเราออกมาเป็น static files แล้วโฮสบน GitLab Pages กันได้เลย พร้อมกันแล้วก็ไปกันต่อเลยครับที่นี่ ทำเว็บไซต์ด้วย Hugo แล้วโฮสบน GitLab Pages และ Cloudflare