ติดตั้ง Let's Encrypt SSL บน VPS ด้วย Certbot

Let's Encrypt คือ Certificate Authority ที่ออก SSL Certificate ฟรี โดยใช้ Certbot เป็น client tool ในการขอและต่ออายุ Certificate อัตโนมัติ บทความนี้จะติดตั้งบน Ubuntu VPS สำหรับทั้ง Nginx และ Apache

ก่อนเริ่ม: สิ่งที่ต้องมี

ติดตั้ง Certbot

sudo apt update
sudo apt install snapd -y
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

ขอ Certificate สำหรับ Nginx

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot จะแก้ไข Nginx config อัตโนมัติและเพิ่มการ redirect HTTP → HTTPS ให้

ถ้าต้องการควบคุมการ config เองให้ใช้ mode certonly:

sudo certbot certonly --nginx -d yourdomain.com

ขอ Certificate สำหรับ Apache

sudo apt install python3-certbot-apache -y
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com

เปรียบเทียบ Let's Encrypt กับ SSL แบบเสียเงิน

Let's Encrypt เหมาะกับเว็บไซต์ส่วนใหญ่ที่ต้องการ HTTPS พื้นฐาน แต่มีกรณีที่ SSL แบบเสียเงินให้ประโยชน์เพิ่มเติมที่คุ้มค่า การเปรียบเทียบนี้จะช่วยให้ตัดสินใจได้ถูกต้อง

คุณสมบัติ Let's Encrypt SSL แบบเสียเงิน (OV/EV)
ราคา ฟรี เริ่มต้น 1,000+ บาท/ปี
ประเภท DV เท่านั้น DV / OV / EV / Wildcard
อายุ certificate 90 วัน (ต่ออายุอัตโนมัติ) 1 ปี หรือ 3 ปี
การยืนยันตัวตน โดเมนเท่านั้น OV: องค์กร / EV: ยืนยันเข้มข้น
Wildcard รองรับผ่าน DNS challenge รองรับครบ ไม่ต้อง DNS challenge
Warranty ไม่มี มี (ขึ้นอยู่กับผู้ออก)
เหมาะกับ Personal site, blog, dev server, startup E-Commerce, ธนาคาร, องค์กร, หลาย subdomain

สรุป: ถ้าเว็บไซต์เป็น WordPress, portfolio, blog หรือ web app ที่ไม่ได้รับข้อมูล payment โดยตรง Let's Encrypt ก็เพียงพอ แต่ถ้าเป็น e-commerce หรือต้องการ Wildcard สำหรับหลาย subdomain SSL แบบเสียเงินน่าพิจารณา

ตรวจสอบการทำงาน

sudo certbot certificates
# แสดงรายการ Certificate ทั้งหมดที่มี

ทดสอบ renewal ว่าทำงานได้:

sudo certbot renew --dry-run

Auto-Renewal อัตโนมัติ

Certbot ติดตั้ง systemd timer อัตโนมัติเพื่อ renew certificate ทุกวัน ตรวจสอบได้:

sudo systemctl status certbot.timer

ถ้าต้องการเพิ่ม hook หลัง renew (เช่น reload Nginx):

sudo nano /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh

การตั้งค่า HTTPS Redirect และ HSTS สำหรับความปลอดภัยสูงสุด

หลังจากติดตั้ง SSL แล้ว ขั้นตอนต่อไปที่สำคัญคือบังคับให้ทุก request ใช้ HTTPS และเพิ่ม HTTP Strict Transport Security (HSTS) header เพื่อบอก browser ว่าต้องเชื่อมต่อแบบ HTTPS เท่านั้น ซึ่งป้องกันการโจมตีแบบ downgrade attacks ได้

Nginx: ตั้งค่า HTTPS Redirect และ HSTS

# /etc/nginx/sites-available/yourdomain.com

# HTTP → HTTPS redirect
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$host$request_uri;
}

# HTTPS server block
server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # HSTS header (max-age 1 ปี)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
}

Apache: ตั้งค่า HTTPS Redirect และ HSTS

# /etc/apache2/sites-available/yourdomain.com.conf

# HTTP → HTTPS redirect
<VirtualHost *:80>
    ServerName yourdomain.com
    Redirect permanent / https://yourdomain.com/
</VirtualHost>

# HTTPS VirtualHost
<VirtualHost *:443>
    ServerName yourdomain.com
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>

หลังแก้ config ต้อง restart web server:

# Nginx
sudo nginx -t && sudo systemctl reload nginx

# Apache
sudo apachectl configtest && sudo systemctl reload apache2

ทดสอบ SSL configuration ที่ SSL Labs (ssllabs.com/ssltest/) เพื่อดู grade และคำแนะนำการปรับปรุงเพิ่มเติม เป้าหมายควรได้เกรด A ขึ้นไป

การตรวจสอบและ Monitor Certificate Expiry อัตโนมัติ

แม้ Certbot จะต่ออายุอัตโนมัติ แต่ควรมีระบบ monitoring เพิ่มเติมเพื่อแจ้งเตือนก่อน certificate จะหมดอายุ โดยเฉพาะในกรณีที่ Certbot ทำงานผิดพลาดหรือ DNS มีปัญหา

ตรวจสอบวันหมดอายุด้วย openssl:

echo | openssl s_client -servername yourdomain.com \
  -connect yourdomain.com:443 2>/dev/null \
  | openssl x509 -noout -dates

สร้าง script เตือนอัตโนมัติเมื่อ certificate เหลือน้อยกว่า 30 วัน:

#!/bin/bash
# /usr/local/bin/check-cert-expiry.sh
DOMAIN="yourdomain.com"
DAYS_WARN=30
EXPIRY=$(echo | openssl s_client -servername $DOMAIN \
  -connect $DOMAIN:443 2>/dev/null \
  | openssl x509 -noout -enddate \
  | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))

if [ $DAYS_LEFT -le $DAYS_WARN ]; then
  echo "WARNING: Certificate for $DOMAIN expires in $DAYS_LEFT days!"
  # เพิ่มคำสั่งส่ง email ที่นี่
fi

เพิ่ม script นี้ใน cron job รันทุกวัน:

# รัน check ทุกวัน 09:00 น.
0 9 * * * /usr/local/bin/check-cert-expiry.sh

อีกทางเลือกคือใช้บริการ monitoring ภายนอกเช่น Uptime Kuma ที่มี certificate monitoring ในตัว หรือ external service อื่นๆ ที่แจ้งเตือนผ่าน email/webhook เมื่อ certificate ใกล้หมดอายุ

แก้ปัญหาที่พบบ่อย

Port 80 ถูก Block

sudo ufw allow 80/tcp && sudo ufw allow 443/tcp

DNS ยังไม่ propagate

ตรวจสอบด้วย: dig +short yourdomain.com ต้องได้ IP ของ VPS

Certificate หมดอายุแล้วและ renew ไม่ได้

sudo certbot renew --force-renewal -d yourdomain.com

แนวทางปฏิบัติ SSL ที่ดีบน VPS และ Checklist ก่อน Deploy

ก่อน deploy website ไปยัง production ควรตรวจสอบว่า SSL configuration ครบถ้วนและปลอดภัย รายการต่อไปนี้เป็น checklist ที่แนะนำ

SSL Installation Checklist

ปัญหาที่พบบ่อยและวิธีแก้

นอกจากปัญหาที่กล่าวถึงข้างต้นแล้ว ยังมีปัญหาอื่นที่อาจเจอได้บ่อยในการใช้ Let's Encrypt บน VPS

ตรวจสอบ TLS protocol version

ควรปิด TLS เวอร์ชันเก่า (TLS 1.0 และ 1.1) และเปิดเฉพาะ TLS 1.2 และ 1.3 สำหรับ Nginx ตรวจสอบในไฟล์ /etc/letsencrypt/options-ssl-nginx.conf และตรวจสอบว่ามีบรรทัดนี้:

ssl_protocols TLSv1.2 TLSv1.3;

สำหรับ Apache ตรวจสอบใน ssl.conf:

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

การปิด TLS เก่าจะช่วยหลีกเลี่ยงช่องโหว่อย่าง POODLE และ BEAST และทำให้ได้เกรดสูงขึ้นจาก SSL Labs

Multi-domain Certificate (SAN)

ถ้ามีหลาย domain บน VPS เดียวกัน สามารถขอ certificate ครอบคลุมหลาย domain ในครั้งเดียว:

sudo certbot --nginx \
  -d domain1.com -d www.domain1.com \
  -d domain2.com -d www.domain2.com \
  -d domain3.com

Let's Encrypt รองรับสูงสุด 100 domain ต่อ certificate (SAN) แต่ในทางปฏิบัติควรแยก certificate ตามกลุ่ม application เพื่อจัดการง่ายขึ้น

การตรวจสอบ SSL Grade และการปรับปรุงเพิ่มเติม

หลังติดตั้ง SSL เสร็จแล้วควรทดสอบความแข็งแกร่งของ configuration ด้วยเครื่องมือออนไลน์ เพื่อระบุจุดที่ยังปรับปรุงได้อีก เครื่องมือที่แนะนำ ได้แก่

การปรับปรุง cipher suites เพิ่มเติมสำหรับ Nginx เพื่อให้ได้เกรด A+:

# เพิ่มใน nginx.conf หรือ server block
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;

วิธีจัดการ Certificate สำหรับ Multiple Domains และ Subdomain

เมื่อมีการเพิ่ม domain หรือ subdomain ใหม่บน VPS เดิม ไม่จำเป็นต้องขอ certificate ใหม่ทั้งหมด สามารถขยาย certificate เดิมโดยเพิ่ม domain ได้:

# ขยาย certificate ที่มีอยู่แล้วด้วย --expand
sudo certbot --nginx --expand \
  -d yourdomain.com \
  -d www.yourdomain.com \
  -d newsubdomain.yourdomain.com

หรือถ้าต้องการ Wildcard certificate ที่ครอบคลุม subdomain ทั้งหมด ต้องใช้ DNS-01 challenge:

sudo certbot certonly \
  --manual \
  --preferred-challenges dns \
  -d yourdomain.com \
  -d *.yourdomain.com

Certbot จะแนะนำให้เพิ่ม TXT record ชื่อ _acme-challenge.yourdomain.com ใน DNS zone ของคุณ หลังจากเพิ่ม record แล้วรอให้ DNS propagate (ประมาณ 1-5 นาที) ก่อนกด Enter ต่อ

ความสำคัญของ OCSP Stapling

OCSP (Online Certificate Status Protocol) Stapling คือการที่ web server ดาวน์โหลดและแนบ OCSP response ไว้กับ TLS handshake แทนที่จะให้ browser ไปถาม CA โดยตรงทุกครั้ง ทำให้ connection เร็วขึ้นและเป็นส่วนตัวมากขึ้น เพราะ browser ไม่ต้องส่ง certificate serial number ไปยัง CA server

เปิดใช้ OCSP Stapling ใน Nginx:

server {
    listen 443 ssl http2;
    ...
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.com/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
}

ทดสอบว่า OCSP Stapling ทำงาน:

openssl s_client -connect yourdomain.com:443 \
  -servername yourdomain.com \
  -status 2>/dev/null | grep -i "OCSP"

ถ้าได้ OCSP Response Status: successful แสดงว่า OCSP Stapling ทำงานถูกต้อง

SSL บน VPS กับ WordPress และ Web Application

หลังจากติดตั้ง SSL Certificate บน VPS แล้ว ยังต้องตั้งค่า application ให้รู้จัก HTTPS ด้วย สำหรับ WordPress ต้องอัปเดต URL ใน WordPress admin:

สำหรับ Node.js application ให้ตั้งค่าให้รับรู้ว่าอยู่หลัง reverse proxy:

// ใน Express.js
app.set('trust proxy', 1);

// redirect HTTP → HTTPS
app.use((req, res, next) => {
  if (req.header('x-forwarded-proto') !== 'https') {
    res.redirect('https://' + req.header('host') + req.url);
  } else {
    next();
  }
});

การตั้งค่า trust proxy สำคัญมากเมื่อใช้ Nginx เป็น reverse proxy เพราะ Node.js จะเห็น connection เป็น HTTP แต่ Nginx ส่ง header X-Forwarded-Proto: https มาให้ application รู้ว่า client เชื่อมต่อผ่าน HTTPS จริงๆ

สำหรับ application อื่นๆ เช่น Django, Laravel หรือ Rails ก็มีการตั้งค่าคล้ายกัน คือต้องระบุว่า application อยู่หลัง HTTPS reverse proxy และบังคับให้ generate URL ด้วย https:// เสมอ ซึ่งสำคัญมากสำหรับ redirect URL ที่ถูกต้องและหลีกเลี่ยง mixed content

เมื่อไรควรเปลี่ยนจาก Let's Encrypt มาใช้ SSL แบบเสียเงิน

Let's Encrypt เหมาะมากสำหรับเว็บไซต์ส่วนใหญ่ แต่มีสถานการณ์ที่การลงทุนใน SSL แบบเสียเงินให้ผลคุ้มค่ามากกว่า ได้แก่

AsiaGB มี SSL certificate หลายประเภทให้เลือกตามความต้องการ ตั้งแต่ DV ราคาประหยัดไปจนถึง EV และ Wildcard สำหรับองค์กร ทุก certificate ผ่านการรับรองจาก trusted CA ที่ browser รู้จักทั่วโลก

สรุป: Let's Encrypt ด้วย Certbot เป็น SSL ฟรีที่สะดวกที่สุดสำหรับ VPS ต่ออายุอัตโนมัติทุก 90 วัน ถ้าต้องการ SSL ที่มีเอกสาร OV/EV หรือ Wildcard สำหรับหลาย subdomain AsiaGB มี SSL certificate หลายประเภทให้เลือก

ต้องการ VPS สำหรับ Web Server ของคุณ

AsiaGB VPS Ubuntu มาพร้อม Full Root Access ติดตั้ง Nginx/Apache + SSL ได้ทันที เริ่มต้น 500 บาท/เดือน

ดู VPS Plans