ปัญหาที่ HTTPS แก้
ถ้าใช้ HTTP ธรรมดา — ทุก request และ response ส่งเป็น plain text ใครที่อยู่ระหว่างทาง (ISP, router ใน café, government) อ่านได้หมด
ลองนึกภาพ: ใช้ Wi-Fi ในร้านกาแฟ ส่ง password ไป login HTTP ใครก็ดักอ่านได้
HTTPS = HTTP + TLS — encrypt ข้อมูลทั้งทาง
3 อย่างที่ TLS รับประกัน:
- Encryption — ข้อมูลที่ส่งคนระหว่างทางอ่านไม่ออก
- Integrity — ข้อมูลถ้าถูกแก้ระหว่างทาง จะ detect ได้
- Authentication — รู้ว่าเชื่อม server ที่ถูกตัวจริงๆ ไม่ใช่ phishing
TLS Handshake ทำอะไร
ตอนเปิด https://example.com ครั้งแรก ใช้เวลา 100-300ms ก่อนข้อมูลจะเริ่มไหล — นั่นคือ handshake
ขั้นตอน (เวอร์ชัน TLS 1.3 ที่ใช้กัน):
Browser Server
|---- ClientHello ------------>|
| (รายการ cipher ที่รองรับ)|
| |
|<--- ServerHello -------------|
| + Certificate |
| + Public key |
| |
|---- ตรวจ certificate ----> |
| + แลก key เพื่อ encrypt |
| |
|<--- เริ่ม encrypted data ----|
หลัง handshake — ทั้ง browser และ server ใช้ key เดียวกัน encrypt/decrypt ทุกข้อความที่ส่ง (symmetric encryption เพราะเร็วกว่า)
ลำดับ key:
- ตอน handshake ใช้ asymmetric (public/private key) เพื่อแลก session key
- หลัง handshake ใช้ symmetric (เร็วกว่ามาก)
TLS 1.3 ลด round trip จาก 2 → 1 → handshake เร็วกว่ารุ่นเก่า
Certificate คืออะไร
Certificate = ไฟล์ที่บอก "domain นี้เป็นของผู้ถือ private key ตัวนี้" + ออกโดย CA ที่ browser เชื่อถือ
ใน cert มีข้อมูล:
- Subject: domain ที่ใช้ได้ (
example.com,*.example.com) - Issuer: ใครออก cert นี้
- Validity: ใช้ได้ถึงเมื่อไหร่
- Public key
- Signature ของ CA
Chain of Trust
Browser ไม่ได้เชื่อ cert ของ example.com ตรงๆ — เชื่อเพราะ cert นั้นถูก sign โดย "CA ที่เชื่อถือ"
Chain ทั่วไป:
Root CA (อยู่ใน browser)
↓ sign
Intermediate CA
↓ sign
Your domain cert (example.com)
Browser ตรวจ chain ทั้งหมด — ถ้าตัวไหนไม่ valid (หมดอายุ, signature ไม่ตรง, ไม่อยู่ใน trust list) — ขึ้น error
Let's Encrypt — SSL ฟรี
ก่อนปี 2015 — cert ราคา $50-200/ปี ตอนนี้ — Let's Encrypt ออก cert ฟรีอัตโนมัติ ผ่าน protocol ACME
ขั้นตอน (ผ่าน Certbot):
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot จะ:
- สร้าง challenge file ใน server
- ขอให้ Let's Encrypt verify ว่าคุณเป็นเจ้าของ domain (HTTP-01 หรือ DNS-01)
- Let's Encrypt ออก cert
- Certbot ติดตั้งใน Nginx
- ตั้ง systemd timer ให้ renew อัตโนมัติทุก 60 วัน
Cert ของ Let's Encrypt อายุ 90 วัน — สั้นกว่า paid CA แต่ renew อัตโนมัติเลยไม่เป็นปัญหา
ดู cert ของ domain
# ดู cert จาก server โดยตรง
openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>/dev/null | openssl x509 -text
# ตรวจ chain
curl -vI https://example.com 2>&1 | grep -A 5 "Server certificate"
# ใช้ tool online ที่เห็นภาพชัด
# https://www.ssllabs.com/ssltest/
# https://crt.sh ← ดู cert history ของ domain
ssllabs.com SSL Test = เครื่องมือดีที่สุดเช็ค config ปัญหาทุกแง่มุม
Best Practice สำหรับ Server
1. ตั้ง Nginx ให้ปลอดภัย
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
ปิด TLS 1.0/1.1 ที่เก่า — TLS 1.2 ขั้นต่ำ
2. HSTS — บังคับใช้ HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
หลัง browser เห็น header นี้ครั้งแรก — ทุก request ถัดไปจะไป HTTPS โดยไม่ผ่าน HTTP เลย
3. Redirect HTTP → HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
4. ตั้ง renewal monitoring
ตั้ง Uptime Kuma เตือนล่วงหน้า 14 วันถ้า cert จะหมด
ปัญหาที่เจอบ่อย
SSL_ERROR_NO_CYPHER_OVERLAP = client กับ server ไม่มี cipher ตรงกัน
- ตรวจ TLS version ที่เปิด
- ดู
ssl_ciphersใน config
NET::ERR_CERT_AUTHORITY_INVALID = chain ไม่สมบูรณ์
- ใส่
fullchain.pemไม่ใช่cert.pemใน Nginx config (fullchain มี intermediate)
Cert หมดอายุ = --dry-run ทดสอบ renew เป็นระยะ
sudo certbot renew --dry-run
Mixed content = หน้า HTTPS แต่ load resource HTTP — browser block
- เปลี่ยน URL ใน code ให้ใช้
//(relative protocol) หรือhttps:// - Nginx:
add_header Content-Security-Policy "upgrade-insecure-requests";
HTTP/2 ไม่ทำงาน = HTTP/2 ต้องเปิด TLS
listen 443 ssl http2;
mTLS — TLS 2 ทาง
ปกติ TLS — server พิสูจน์ตัวตนกับ client mTLS (mutual TLS) — ทั้ง 2 ฝั่งพิสูจน์ตัวตนกัน
ใช้ใน:
- Internal API ระหว่าง microservice
- B2B integration ที่ต้อง security เข้ม
- Zero-trust networking
ใน Nginx:
ssl_client_certificate /etc/nginx/ca.pem;
ssl_verify_client on;
client ต้องส่ง cert มาด้วย ไม่งั้น 403
Certificate Transparency
ทุก cert ที่ออกใหม่ ถูกบันทึกใน public log (Certificate Transparency)
ใครก็ search ได้ที่ crt.sh ดู cert ทั้งหมดที่เคยออกให้ domain
ใช้ตรวจ:
- เคยมีใครออก cert phishing ของ domain เราไหม
- subdomain อะไรบ้างที่ออก cert (อาจเจอ subdomain ที่ลืม)
ทางเลือกแทน Let's Encrypt
- ZeroSSL — ฟรี ออก cert อายุยาวกว่า (90 วันเหมือนกัน)
- Cloudflare Origin Cert — ฟรี อายุ 15 ปี ใช้ได้เฉพาะหลัง Cloudflare proxy
- AWS Certificate Manager — ฟรี ใช้ได้เฉพาะกับ AWS service (ALB, CloudFront)
สรุป
HTTPS ไม่ใช่ feature เสริม — ทุกเว็บปี 2026 ต้องมี
เข้าใจ:
- TLS handshake ขั้นตอนคร่าวๆ
- Certificate chain — ทำไม intermediate สำคัญ
- Let's Encrypt + Certbot — ฟรีและอัตโนมัติ
- HSTS + redirect HTTP → HTTPS
= debug ปัญหา cert ได้เร็วขึ้น 10 เท่า เวลามีปัญหา renewal/chain/mixed content จริง
อ่านเพิ่ม: Nginx Reverse Proxy — config SSL บน Nginx step-by-step