Privacy & Security

วิธีตั้งค่า HSTS โดยไม่ทำให้ตัวเองถูกล็อกออก

แผนการปล่อยใช้งาน Strict-Transport-Security แบบเป็นขั้นตอนและย้อนกลับได้ ที่ช่วยเพิ่มความเป็นส่วนตัวโดยไม่ทำให้ใบรับรองที่ผิดพลาดเพียงใบเดียวกลายเป็นเหตุขัดข้องทั้งระบบ

The Wux Webtools Team The Wux Webtools Team 20 อ่านขั้นต่ำ ช่วยโดย AI, ตรวจสอบโดยมนุษย์
Illustration of a secure browser connection with redirect arrows and subdomain warning markers.
สารบัญ
  1. HSTS นั้นเรียบง่าย จนกระทั่งมันไม่เรียบง่าย
  2. HSTS header ทำอะไรจริง ๆ
  3. สถานการณ์ล็อกเอาต์ที่ควรหลีกเลี่ยง
  4. 1. subdomain ที่ถูกลืมยังไม่พร้อมสำหรับ HTTPS
  5. 2. ใบรับรองหมดอายุ
  6. 3. เครื่องมือ staging หรือเครื่องมือภายในอยู่ภายใต้ production domain
  7. 4. preload ถูกมองเป็น checkbox ตามปกติ
  8. แผนการปล่อยใช้งานที่ปลอดภัย
  9. Step 1: ตรวจสอบทุก hostname ที่คุณควบคุม
  10. Step 2: แก้ HTTPS ให้เรียบร้อยก่อนเพิ่ม HSTS
  11. Step 3: เริ่มด้วย max-age ที่สั้นมาก
  12. Step 4: เพิ่มขึ้นทีละขั้น
  13. Step 5: เพิ่ม includeSubDomains เฉพาะหลังจาก audit จริงจังแล้ว
  14. Step 6: มอง preload เป็นโครงการแยกต่างหาก
  15. ตัวอย่างการตั้งค่า
  16. Nginx
  17. Apache
  18. CDN หรือ edge platform
  19. วิธีถอน HSTS อย่างปลอดภัย
  20. Checklist การทดสอบก่อน ship
  21. เหตุผลด้านความเป็นส่วนตัวของ HSTS

HSTS นั้นเรียบง่าย จนกระทั่งมันไม่เรียบง่าย

HTTP Strict Transport Security ซึ่งมักย่อว่า HSTS บอกเบราว์เซอร์ว่า “สำหรับไซต์นี้ ให้ใช้ HTTPS เสมอ” เมื่อเบราว์เซอร์ได้รับ header นี้ผ่านการเชื่อมต่อ HTTPS ที่ถูกต้องแล้ว เบราว์เซอร์จะจดจำกฎนี้ตามระยะเวลาที่คุณกำหนด

สิ่งนี้มีประโยชน์ เพราะช่วยป้องกันการโจมตีแบบลดระดับโปรโตคอล ลดคำขอที่ไม่ปลอดภัยโดยไม่ตั้งใจ และหลีกเลี่ยงช่วงเวลาน่าอึดอัดที่ผู้ใช้พิมพ์ example.com แล้วแตะ plain HTTP ชั่วครู่ก่อนถูก redirect

แต่มันก็ติดแน่นเช่นกัน หากคุณเผยแพร่นโยบาย HSTS ที่ผิด เบราว์เซอร์อาจยังบังคับใช้นโยบายนั้นต่อไปนานหลังจากคุณเอา header ออกจากเซิร์ฟเวอร์แล้ว นี่คือวิธีที่ทีมต่าง ๆ ทำให้ตัวเองถูกล็อกออก ไม่ได้ล็อกจากแผงผู้ดูแลของตัวเองโดยตรง แต่ล็อกจากเบราว์เซอร์ของผู้ใช้, subdomain, ระบบ staging, endpoint เก่า และบริการที่ถูกลืมซึ่งยังไม่พร้อมสำหรับการบังคับใช้ HTTPS

เป้าหมายไม่ใช่การหลีกเลี่ยง HSTS เป้าหมายคือการ deploy มันเหมือนการ migration ไม่ใช่เหมือนสวิตช์เปิดปิด

HSTS header ทำอะไรจริง ๆ

HSTS header โดยทั่วไปหน้าตาเป็นแบบนี้:

Strict-Transport-Security: max-age=31536000; includeSubDomains

มันมีส่วนสำคัญสามส่วน:

  • max-age: ระยะเวลาเป็นวินาทีที่เบราว์เซอร์ควรบังคับใช้ HTTPS สำหรับ host นี้
  • includeSubDomains: กฎนี้จะมีผลกับทุก subdomain ด้วยหรือไม่
  • preload: สัญญาณว่าคุณต้องการให้ domain ถูกรวมอยู่ใน preload list ของเบราว์เซอร์

เบราว์เซอร์จะเชื่อถือ header นี้เฉพาะเมื่อได้รับผ่าน HTTPS ที่ถูกต้องเท่านั้น หากใบรับรองไม่ถูกต้อง หมดอายุ หรือไม่ตรงกัน เบราว์เซอร์ไม่ควรรับนโยบาย HSTS ใหม่จาก response นั้น

เมื่อนโยบายถูกบันทึกไว้แล้ว ความพยายามในอนาคตที่จะเข้า http://example.com จะถูกเบราว์เซอร์อัปเกรดเป็น https://example.com ก่อนส่งคำขอออกไป นี่คือประโยชน์ด้านความเป็นส่วนตัว: คำขอที่ไม่ปลอดภัยจะไม่ออกจากอุปกรณ์เลย

สถานการณ์ล็อกเอาต์ที่ควรหลีกเลี่ยง

ความล้มเหลวของ HSTS ส่วนใหญ่ไม่ได้เกิดจากเว็บไซต์หลัก แต่มักเกิดที่ขอบระบบ

1. subdomain ที่ถูกลืมยังไม่พร้อมสำหรับ HTTPS

includeSubDomains ฟังดูเป็นระเบียบ แต่มีผลแบบเด็ดขาด หากคุณตั้งไว้บน example.com มันจะมีผลกับ:

  • www.example.com
  • api.example.com
  • old-crm.example.com
  • printer-setup.example.com
  • staging.example.com
  • สิ่งอื่นใดก็ตามที่อยู่ภายใต้ domain นั้น

หาก host ใดในกลุ่มนี้ไม่สามารถให้บริการ HTTPS ที่ถูกต้องได้ ผู้ใช้ที่มีนโยบาย HSTS cache ไว้จะไม่สามารถเข้าถึง host เหล่านั้นผ่าน HTTP ได้

2. ใบรับรองหมดอายุ

เมื่อไม่มี HSTS บางครั้งผู้ใช้ก็คลิกผ่านคำเตือนใบรับรอง แม้นั่นจะไม่ใช่แนวปฏิบัติด้านความปลอดภัยที่ดี แต่ก็เกิดขึ้นจริง

เมื่อมี HSTS เบราว์เซอร์สมัยใหม่จะไม่อนุญาตให้ข้ามข้อผิดพลาดของใบรับรองสำหรับ host นั้นได้ง่าย ๆ นี่คือประเด็นสำคัญ และยังหมายความว่าการต่ออายุใบรับรองต้องเป็นเรื่องธรรมดา มีการ monitor และผ่านการทดสอบ

3. เครื่องมือ staging หรือเครื่องมือภายในอยู่ภายใต้ production domain

การวางเครื่องมือภายในไว้ใต้ *.example.com อาจกลายเป็นเรื่องเจ็บปวดเมื่อ parent domain ใช้ includeSubDomains หากเครื่องมือเหล่านั้นใช้ใบรับรอง self-signed, private certificate authorities, การตั้งค่า TLS เก่า หรือไม่มี HTTPS เลย HSTS จะทำให้ทางลัดนั้นถูกเปิดเผย

นี่เป็นเหตุผลหนึ่งที่หลายทีมเก็บระบบภายในและระบบทดลองไว้ภายใต้ domain แยกต่างหากซึ่งมีนโยบายความปลอดภัยของตัวเอง

4. preload ถูกมองเป็น checkbox ตามปกติ

HSTS preload ไม่ใช่เพียง directive อีกตัวหนึ่ง แต่มันหมายความว่า domain ของคุณสามารถถูกบรรจุอยู่ในเบราว์เซอร์ในฐานะ HTTPS-only ก่อนที่ผู้ใช้คนใดจะเคยเข้าชมไซต์ของคุณ

สิ่งนี้ปิดช่องว่างของ “การเข้าชมครั้งแรก” แต่ย้อนกลับได้ยากกว่ามาก การนำออกจาก preload list อาจใช้เวลาหลายสัปดาห์หรือหลายเดือนกว่าจะถึงผู้ใช้ ขึ้นอยู่กับรอบการปล่อยเวอร์ชันของเบราว์เซอร์ preload เหมาะกับ domain ที่เสถียรและเติบโตเต็มที่ ไม่เหมาะกับไซต์ที่ยังอยู่ระหว่างค้นหาว่ามี subdomain อะไรบ้าง

แผนการปล่อยใช้งานที่ปลอดภัย

Step 1: ตรวจสอบทุก hostname ที่คุณควบคุม

ก่อนตั้ง includeSubDomains ให้ทำรายการ hostname ทั้งหมดภายใต้ domain นั้น DNS records เป็นจุดเริ่มต้น แต่ไม่ใช่ทั้งหมด ตรวจสอบการตั้งค่า CDN, hosting dashboards, hostname ที่เกี่ยวข้องกับอีเมล, เครื่องมือการตลาดเก่า, storage buckets และเอกสารภายใน

สำหรับแต่ละ hostname ให้ตอบคำถาม:

  • ให้บริการ HTTP, HTTPS หรือทั้งสองอย่าง?
  • ใบรับรอง HTTPS ถูกต้องและต่ออายุอัตโนมัติหรือไม่?
  • redirect จาก HTTP ไป HTTPS ได้เรียบร้อยหรือไม่?
  • ตั้งใจให้เป็น public หรือไม่?
  • ยังจำเป็นอยู่หรือไม่?

หากทีมของคุณมีนิสัย debug production header อยู่แล้ว งานนี้จะเข้ากันได้ดีกับการตรวจ redirect และ header เราเคยอธิบาย workflow นั้นไว้ใน ชุดเครื่องมือขนาดเล็กสำหรับ debug redirects และ HTTP headers ใน production

Step 2: แก้ HTTPS ให้เรียบร้อยก่อนเพิ่ม HSTS

HSTS ไม่ได้ทำให้การตั้งค่า HTTPS ที่พังกลายเป็นสิ่งปลอดภัย มันเพียงทำให้ HTTPS เป็นข้อบังคับ

ก่อนเปิดใช้งาน ให้ตรวจสอบว่า:

  • TLS certificates ครอบคลุม hostname ที่ถูกต้อง
  • Certificates ต่ออายุอัตโนมัติ
  • HTTP redirect ไป HTTPS ด้วย hop เดียวที่สะอาดเมื่อเป็นไปได้
  • Canonical host redirects สอดคล้องกัน เช่น จาก non-www ไป www หรือในทางกลับกัน
  • Application assets ไม่พึ่งพา URL แบบ http:// ที่ไม่ปลอดภัย

Mixed content พบได้น้อยกว่าในอดีต แต่ยังคงปรากฏใน CMS themes เก่า, analytics snippets, embedded media และ image paths ที่ hard-code ไว้

Step 3: เริ่มด้วย max-age ที่สั้นมาก

อย่าเริ่มด้วยหนึ่งปี ให้เริ่มด้วยห้านาที:

Strict-Transport-Security: max-age=300

Deploy เฉพาะบน hostname ที่คุณกำลังทดสอบ โดยปกติคือเว็บไซต์ production แบบ canonical ยังไม่ต้องใส่ includeSubDomains

จากนั้นทดสอบในเบราว์เซอร์จริงและด้วยคำสั่ง command-line:

curl -I https://example.com

คุณควรเห็น Strict-Transport-Security header เพียงรายการเดียวพอดี HSTS headers ที่ซ้ำกันจาก app server และ CDN เป็นแหล่งความสับสนที่พบได้บ่อย โดยทั่วไปเบราว์เซอร์จะใช้นโยบายที่มีผลจริง แต่คนที่กำลัง debug incident ไม่จำเป็นต้องเจอกับความคลุมเครือ

Step 4: เพิ่มขึ้นทีละขั้น

หากไม่มีอะไรพัง ให้เพิ่มระยะเวลาเป็นขั้น ๆ:

Strict-Transport-Security: max-age=86400

จากนั้น:

Strict-Transport-Security: max-age=604800

แล้วอาจเป็น:

Strict-Transport-Security: max-age=2592000

ตารางเวลาที่ใช้งานได้จริงคือ:

  • 5 นาที
  • 1 วัน
  • 1 สัปดาห์
  • 1 เดือน
  • 6 เดือน หรือ 1 ปี

ไม่มีรางวัลสำหรับความรีบร้อน จุดประสงค์ทั้งหมดของ staged rollout คือการให้ monitoring, support inbox และ edge cases มีเวลาบอกคุณว่าสิ่งใดที่ checklist ของคุณพลาดไป

Step 5: เพิ่ม includeSubDomains เฉพาะหลังจาก audit จริงจังแล้ว

เมื่อ public subdomain ทุกตัวพร้อมสำหรับ HTTPS แล้ว คุณจึงพิจารณาได้ว่า:

Strict-Transport-Security: max-age=31536000; includeSubDomains

นี่คือช่วงเวลาที่ควรระมัดระวัง หาก legacy service หนึ่งยังต้องใช้ HTTP อย่าเพิ่ม includeSubDomains ลงใน parent domain ให้ migrate service นั้น ย้ายไป domain อื่น หรือยอมรับว่านโยบาย HSTS ของคุณต้องแคบกว่านี้ไปก่อน

Security headers ควรสะท้อนความเป็นจริง ไม่ควรถูกใช้เป็นโปสเตอร์สร้างแรงบันดาลใจสำหรับ infrastructure ที่คุณหวังว่าจะมีในภายหลัง

Step 6: มอง preload เป็นโครงการแยกต่างหาก

พิจารณา preload เฉพาะเมื่อทุกข้อต่อไปนี้เป็นจริง:

  • domain และ subdomain ทั้งหมดรองรับ HTTPS ที่ถูกต้อง
  • HTTP redirect ไป HTTPS
  • HSTS header ใช้ max-age อย่างน้อย 31536000 วินาที
  • header มี includeSubDomains
  • header มี preload
  • คุณมั่นใจว่าจะไม่ต้องใช้ plain HTTP ที่ใดก็ตามภายใต้ domain นี้

header ที่พร้อมสำหรับ preload หน้าตาเป็นแบบนี้:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

การ submit เข้าสู่ preload list คือพันธะระยะยาว หากไซต์เป็น campaign microsite, product domain ชั่วคราว หรือ domain ที่ขอบเขตความเป็นเจ้าของยังไม่ชัดเจน ให้ข้ามไป

ตัวอย่างการตั้งค่า

Nginx

ใช้ always เพื่อให้ส่ง header ใน error responses ด้วย:

add_header Strict-Transport-Security "max-age=300" always;

หลังจาก rollout เสถียรแล้ว:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Apache

เมื่อเปิดใช้ mod_headers แล้ว:

Header always set Strict-Transport-Security "max-age=300"

ต่อมา:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

CDN หรือ edge platform

หาก CDN ของคุณตั้ง response headers ให้จัดการ HSTS ในที่เดียวจะดีกว่า อย่าตั้งนโยบายหนึ่งที่ origin และอีกนโยบายหนึ่งที่ edge เว้นแต่คุณมีเหตุผลที่ชัดเจนมาก

ตรวจสอบด้วยว่า CDN ใช้ headers กับ redirects, cached errors และ custom error pages หรือไม่ เว็บไซต์ production ไม่ได้มีแค่ response 200 OK เท่านั้น

วิธีถอน HSTS อย่างปลอดภัย

หากคุณต้องปิดใช้ HSTS ให้ส่ง:

Strict-Transport-Security: max-age=0

แต่มีเงื่อนไขสำคัญ: เบราว์เซอร์ต้องเข้าถึงไซต์ผ่าน HTTPS ที่ถูกต้องได้สำเร็จเพื่อรับ header นั้น หาก HTTPS เองพัง ผู้ใช้ที่มีนโยบาย HSTS cache ไว้จะไม่สามารถดึงคำสั่งที่จะล้างนโยบายได้

ดังนั้นลำดับการกู้คืนโดยทั่วไปคือ:

  1. กู้คืน HTTPS ที่ถูกต้อง
  2. เสิร์ฟ Strict-Transport-Security: max-age=0
  3. คงไว้ให้นานพอให้ผู้ใช้ที่กลับมาได้รับ header นี้
  4. ลบหรือแทนที่ header หลังจาก incident ได้รับการแก้ไขแล้ว

หาก domain อยู่ใน preload แล้ว การเสิร์ฟ max-age=0 ไม่เพียงพอสำหรับ browser profiles ใหม่ คุณต้องขอให้นำออกจาก preload list และรอให้การเปลี่ยนแปลงนั้นถูกส่งผ่าน browser updates ด้วย

Checklist การทดสอบก่อน ship

ใช้ checklist นี้ก่อนเพิ่ม max-age หรือเพิ่ม includeSubDomains:

  • Canonical HTTPS URL ส่งคืนใบรับรองที่ถูกต้อง
  • HTTP redirect ไป HTTPS
  • มี HSTS header เพียงรายการเดียว
  • header ปรากฏบน redirects และ error responses เมื่อเหมาะสม
  • public subdomain ทั้งหมดมี HTTPS ที่ถูกต้อง
  • มีการ monitor การต่ออายุใบรับรอง
  • ไม่มีระบบภายในที่สำคัญพึ่งพา HTTP ภายใต้ parent domain เดียวกัน
  • มีการหารือเรื่อง preload อย่างชัดเจน ไม่ใช่เพิ่มตามความเคยชิน

Lighthouse อาจเตือนเรื่อง security headers ที่ขาดหายหรืออ่อนแอในบางบริบทได้เช่นกัน แต่ไม่ควรเป็นวิธีตรวจสอบเพียงอย่างเดียวของคุณ หากคุณใช้มันเป็นส่วนหนึ่งของการ review ที่กว้างกว่า ให้อ่านผลลัพธ์เป็นสัญญาณมากกว่าคำตัดสิน แนวคิดเดียวกันนี้ใช้ได้เมื่อคุณ อ่าน Lighthouse report โดยไม่ตื่นตระหนก

<!-- tool-cta:start -->

💡 ลองทำสิ่งนี้: ก่อนและหลังการเปลี่ยนแปลง HSTS แต่ละครั้ง ให้ตรวจสอบ Strict-Transport-Security response ด้วย Get Headers เพื่อยืนยันว่า max-age, includeSubDomains และ preload เป็นไปตามที่คุณคาดไว้

<!-- tool-cta:end -->

เหตุผลด้านความเป็นส่วนตัวของ HSTS

HSTS มักถูกมองว่าเป็น security header และมันก็เป็นเช่นนั้นจริง นอกจากนี้ยังมีประโยชน์ด้านความเป็นส่วนตัว: มันลดโอกาสที่คำขอแรกของผู้ใช้จะรั่วผ่าน plain HTTP บนเครือข่ายที่ไม่น่าเชื่อถือ

เรื่องนี้สำคัญบน Wi-Fi สนามบิน, เครือข่ายโรงแรม, เครือข่าย guest ขององค์กร และทุกที่ที่ทราฟฟิกของผู้ใช้อาจถูกสังเกตหรือแก้ไขได้ คำขอ plain HTTP อาจเปิดเผย hostname, path, cookies ที่ไม่มี Secure flag และรายละเอียดคำขออื่น ๆ HTTPS ไม่ใช่เวทมนตร์ แต่การบังคับใช้อย่างสม่ำเสมอจะตัดการรั่วไหลทั้งประเภทที่หลีกเลี่ยงได้ออกไป

การ deploy HSTS ที่ดีที่สุดคือแบบไม่น่าสนใจ มันถูกปล่อยใช้งานอย่างช้า ๆ มีใบรับรองที่เชื่อถือได้รองรับ และน่าเบื่อพอที่ไม่มีใครสังเกตเห็น นั่นคือสิ่งที่คุณต้องการจาก header ที่โหมดความล้มเหลวอาจรุนแรงได้

คำถามที่พบบ่อย

HSTS header แรกที่ปลอดภัยควรเป็นอะไร?
เริ่มด้วย `Strict-Transport-Security: max-age=300` นั่นให้เบราว์เซอร์มีนโยบายห้านาที ซึ่งยาวพอสำหรับทดสอบพฤติกรรม แต่สั้นพอให้กู้คืนจากความผิดพลาดส่วนใหญ่ได้อย่างรวดเร็ว
ทุกไซต์ควรใช้ includeSubDomains หรือไม่?
ไม่ ควรใช้ `includeSubDomains` เฉพาะเมื่อ subdomain ทุกตัวภายใต้ parent domain รองรับ HTTPS ที่ถูกต้องและจะทำเช่นนั้นต่อไป host legacy ที่ถูกลืมเพียงตัวเดียวอาจเข้าถึงไม่ได้สำหรับผู้ใช้ที่มีนโยบาย cache ไว้
HSTS preload จำเป็นหรือไม่?
ไม่จำเป็นสำหรับไซต์ขนาดเล็กหรือขนาดกลางส่วนใหญ่ preload ปกป้องการเข้าชมครั้งแรกจริง ๆ แต่ย้อนกลับได้ยากและต้องให้ namespace ทั้งหมดของ domain พร้อมสำหรับ HTTPS ควรพิจารณาหลังจาก rollout HSTS ที่เสถียรแล้วเท่านั้น
ฉันลบ HSTS ได้ด้วยการลบ header หรือไม่?
การลบ header จะหยุดการตั้งนโยบายใหม่ แต่ไม่ได้ล้างนโยบายที่เบราว์เซอร์ cache ไว้แล้ว หากต้องการล้าง HSTS ให้เสิร์ฟ `Strict-Transport-Security: max-age=0` ผ่าน HTTPS ที่ถูกต้อง
HSTS แก้ mixed content ได้หรือไม่?
ไม่ได้ HSTS บังคับให้การเชื่อมต่อของไซต์ระดับบนสุดเป็น HTTPS คุณยังต้องแก้ URL ของ asset ที่ไม่ปลอดภัย, embedded content และ reference `http://` เก่าที่ hard-code ไว้แยกต่างหาก

แหล่งข้อมูล & การอ่านเพิ่มเติม

  1. MDN Web Docs: Strict-Transport-Security
  2. OWASP HTTP Strict Transport Security Cheat Sheet
  3. HSTS Preload Submission Requirements
  4. RFC 6797: HTTP Strict Transport Security
เกี่ยวกับผู้เขียน
The Wux Webtools Team

อัปเดตล่าสุด:

อ่านต่อ

Privacy & Security

หัวข้อ Permissions-Policy สามารถล็อกสิ่งใดได้จริง

Permissions-Policy สามารถลดการเข้าถึงฟีเจอร์ของเบราว์เซอร์ได้ โดยเฉพาะใน iframe มีประโยชน์ แต่ขอบเขตแคบกว่าที่หลายทีมคาดไว้

20 อ่านขั้นต่ำ
Privacy & Security

การแฮชรหัสผ่านปกป้องคุณจากอะไรกันแน่

การแฮชรหัสผ่านช่วยปกป้องผู้ใช้หลังฐานข้อมูลรั่วไหล แต่ไม่ได้หยุดฟิชชิง การยัดข้อมูลรับรอง หรือความปลอดภัยของเซสชันที่แย่

31 อ่านขั้นต่ำ
Privacy & Security

วิธีลบเมทาดาทา EXIF ก่อนแชร์รูปภาพออนไลน์

เมทาดาทา EXIF ฝังตำแหน่ง ข้อมูลอุปกรณ์ และเวลาไว้ในทุกภาพ นี่คือวิธีลบออกอย่างน่าเชื่อถือก่อนแชร์รูปภาพออนไลน์

22 อ่านขั้นต่ำ