Harden SSL/TLS บน Ubuntu ให้ปลอดภัยขึ้น

Harden SSL/TLS บน Ubuntu ให้ปลอดภัยขึ้น

ทำไมติดตั้ง SSL แล้ว ยังไม่พอ

หลายคนติดตั้ง SSL Certificate ด้วย Let’s Encrypt แล้วเห็นรูปแม่กุญแจบน Browser ก็คิดว่าเว็บไซต์ปลอดภัยแล้ว แต่ในมุมของ SysAdmin คำว่า “เปิด HTTPS ได้” กับ “ตั้งค่า HTTPS ให้ปลอดภัย” เป็นคนละเรื่องกันครับ

ถ้า Web Server ยังเปิด TLS เวอร์ชันเก่า เช่น TLS 1.0 หรือ TLS 1.1, ใช้ Cipher Suite ที่ล้าสมัย, ไม่เปิด HSTS หรือไม่มีการตรวจสอบ Chain/OCSP ที่เหมาะสม เว็บไซต์อาจยังถูกจัดเกรดต่ำจากเครื่องมือตรวจสอบ เช่น SSL Labs และยังมีความเสี่ยงจากการโจมตีที่อาศัยการ Downgrade หรือ Protocol เก่าได้

บทความนี้จะพา Harden SSL/TLS บน Ubuntu Server 26.04 ทั้งฝั่ง Nginx และ Apache แบบใช้งานจริง โดยเน้นค่าที่เหมาะกับเว็บไซต์ทั่วไปในปี 2026 คือรองรับ TLS 1.2 และ TLS 1.3 ตามแนวทาง Intermediate Configuration ของ Mozilla SSL Configuration Generator ซึ่งออกแบบมาสำหรับ Server ที่ต้องรองรับ Client หลากหลายประเภท


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

บทความนี้ทดสอบบนสภาพแวดล้อมดังนี้

  • OS: Ubuntu Server 26.04 LTS

  • Web Server: Nginx หรือ Apache จาก Ubuntu Repository

  • Certificate: Let’s Encrypt ผ่าน Certbot

  • OpenSSL: ใช้เวอร์ชันจาก Ubuntu Repository โดย Ubuntu 26.04 มีแพ็กเกจ OpenSSL 3.5.5 ใน repository สาย resolute/security

  • Domain: มี DNS ชี้มายัง Server แล้ว

  • Firewall: เปิด Port 80 และ 443

ตรวจสอบเวอร์ชันระบบก่อนเริ่ม

# ตรวจสอบ Ubuntu version
lsb_release -a

# ตรวจสอบ OpenSSL version
openssl version

# ตรวจสอบ Nginx version
nginx -v

# ตรวจสอบ Apache version
apache2 -v

หากใช้ Certbot แบบ HTTP challenge เว็บไซต์ควรเข้าถึงได้ทาง Port 80 ก่อน เพราะ Certbot สำหรับ Nginx/Apache ต้องการเว็บที่ Online และเข้าถึงจาก Internet ได้ทาง HTTP ตามเอกสารของ Certbot


แนวคิดสำคัญของ SSL/TLS Hardening

การ Harden SSL/TLS คือการปรับค่าความปลอดภัยของ HTTPS ให้เหมาะสมขึ้น เช่น

  • ปิด Protocol เก่า เช่น SSLv2, SSLv3, TLS 1.0, TLS 1.1

  • เปิดเฉพาะ TLS 1.2 และ TLS 1.3

  • ใช้ Cipher Suite ที่รองรับ Forward Secrecy และ AEAD

  • ปิด Session Ticket หากไม่ต้องการความเสี่ยงจาก Key Reuse

  • เปิด HSTS เพื่อบังคับให้ Browser ใช้ HTTPS

  • เปิด OCSP Stapling เพื่อช่วยตรวจสอบสถานะ Certificate

  • ตรวจสอบผลด้วย SSL Labs

ตั้งแต่ SSL Labs Rating Guide รุ่นใหม่ หาก Server ยังไม่รองรับ TLS 1.3 จะมี Warning และคะแนนอาจถูกจำกัดไว้ที่ A- ขณะที่ HSTS ที่ปิดหรือไม่ถูกต้องก็ทำให้มี Warning และคะแนนถูกตั้งไว้ที่ A- ได้เช่นกัน


สำรองไฟล์ก่อนแก้ไข

ก่อนแก้ไข Production Server ควร Backup configuration เดิมเสมอ

สำหรับ Nginx

# สำรอง config ทั้งโฟลเดอร์ nginx
sudo cp -a /etc/nginx /etc/nginx.backup.$(date +%F-%H%M)

สำหรับ Apache

# สำรอง config ทั้งโฟลเดอร์ apache2
sudo cp -a /etc/apache2 /etc/apache2.backup.$(date +%F-%H%M)

⚠️ คำเตือน: อย่าแก้ไฟล์ SSL/TLS บน Production Server โดยไม่ Backup และไม่ทดสอบ Syntax เพราะหากพิมพ์ผิดเพียงบรรทัดเดียว Web Server อาจ Reload ไม่ขึ้นทันที


วิธีที่ 1: Harden SSL/TLS บน Nginx

สมมติว่าเว็บไซต์ใช้โดเมน

example.com
www.example.com

และ Certificate อยู่ที่

/etc/letsencrypt/live/example.com/fullchain.pem
/etc/letsencrypt/live/example.com/privkey.pem

สร้างไฟล์ SSL Hardening Snippet

# สร้างไฟล์ snippet สำหรับรวมค่า SSL/TLS hardening
sudo nano /etc/nginx/snippets/ssl-hardening.conf

ใส่ค่าต่อไปนี้

# เปิดเฉพาะ TLS 1.2 และ TLS 1.3
ssl_protocols TLSv1.2 TLSv1.3;

# Cipher Suite สำหรับ TLS 1.2
# TLS 1.3 จะใช้ Cipher ที่จัดการโดย OpenSSL/Server เอง
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';

# ให้ Client เลือก Cipher ที่เหมาะสม
ssl_prefer_server_ciphers off;

# Session Cache ช่วยลดภาระ TLS Handshake
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;

# ปิด Session Tickets เพื่อลดความเสี่ยงจากการใช้ Key ซ้ำ
ssl_session_tickets off;

# Elliptic Curves ที่เหมาะกับการใช้งานทั่วไป
ssl_ecdh_curve X25519:prime256v1:secp384r1;

# เปิด OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;

# Resolver สำหรับตรวจสอบ OCSP
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;

# Security Headers พื้นฐาน
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

เพิ่ม HSTS อย่างระมัดระวัง

HSTS ช่วยบังคับให้ Browser เข้าผ่าน HTTPS เสมอ แต่ต้องระวังมาก โดยเฉพาะตัวเลือก includeSubDomains และ preload

เริ่มจากค่าปลอดภัยก่อน

# เริ่มต้น HSTS แบบระยะสั้นก่อน
add_header Strict-Transport-Security "max-age=300" always;

เมื่อทดสอบแล้วว่า HTTPS ใช้งานได้ครบทุกหน้า ค่อยเพิ่มเป็น

# ใช้เมื่อมั่นใจว่าเว็บหลักและ subdomain พร้อมใช้ HTTPS แล้ว
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;

⚠️ คำเตือน: อย่าใส่ preload หากยังไม่มั่นใจว่า Domain และ Subdomain ทั้งหมดรองรับ HTTPS ครบแล้ว เพราะเมื่อ Browser จำค่า HSTS แล้ว ผู้ใช้จะไม่สามารถเข้าเว็บผ่าน HTTP ได้อีกในช่วงเวลาที่กำหนด


นำ Snippet ไปใช้กับ Nginx Server Block

แก้ไฟล์ Virtual Host

sudo nano /etc/nginx/sites-available/example.com

ตัวอย่าง configuration

server {
    listen 80;
    server_name example.com www.example.com;

    # Redirect HTTP ไป HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com www.example.com;

    root /var/www/example.com/html;
    index index.html index.htm index.php;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # เรียกใช้ SSL/TLS hardening snippet
    include snippets/ssl-hardening.conf;

    location / {
        try_files $uri $uri/ =404;
    }
}

ทดสอบ Syntax และ Reload

# ทดสอบ config nginx
sudo nginx -t

# หากไม่มี error ให้ reload
sudo systemctl reload nginx

แนะนำ Screenshot:

  • ภาพ nginx -t แสดงผล successful

  • ภาพเว็บไซต์เปิดผ่าน HTTPS

  • ภาพผลทดสอบจาก SSL Labs


วิธีที่ 2: Harden SSL/TLS บน Apache

สำหรับ Apache ให้เปิด Module ที่จำเป็นก่อน

# เปิด SSL module
sudo a2enmod ssl

# เปิด Headers module สำหรับ Security Headers
sudo a2enmod headers

# เปิด HTTP/2 หากต้องการใช้งาน
sudo a2enmod http2

# เปิด module สำหรับ SSL Stapling Cache
sudo a2enmod socache_shmcb

จากนั้นสร้างไฟล์ Hardening Config

sudo nano /etc/apache2/conf-available/ssl-hardening.conf

ใส่ค่าต่อไปนี้

# เปิดเฉพาะ TLS 1.2 และ TLS 1.3
SSLProtocol -all +TLSv1.2 +TLSv1.3

# Cipher Suite สำหรับ TLS 1.2
SSLCipherSuite 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

# ให้ Client เลือก Cipher ที่เหมาะสม
SSLHonorCipherOrder off

# ปิด Session Ticket
SSLSessionTickets off

# เปิด OCSP Stapling
SSLUseStapling on
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

# Security Headers พื้นฐาน
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"

# เริ่มต้น HSTS แบบระยะสั้นก่อน
Header always set Strict-Transport-Security "max-age=300"

เปิดใช้งาน Config

# Enable ssl-hardening config
sudo a2enconf ssl-hardening

# ทดสอบ config apache
sudo apachectl configtest

# หากขึ้น Syntax OK ให้ reload
sudo systemctl reload apache2

ตัวอย่าง Apache VirtualHost

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com

    # Redirect HTTP ไป HTTPS
    Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com

    DocumentRoot /var/www/example.com/html

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    <Directory /var/www/example.com/html>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

ตรวจสอบว่า TLS 1.0 และ TLS 1.1 ถูกปิดแล้วหรือไม่

ใช้ OpenSSL ทดสอบจากเครื่อง Client หรือจาก Server เองก็ได้

# ทดสอบ TLS 1.0 ควรเชื่อมต่อไม่สำเร็จ
openssl s_client -connect example.com:443 -tls1

# ทดสอบ TLS 1.1 ควรเชื่อมต่อไม่สำเร็จ
openssl s_client -connect example.com:443 -tls1_1

# ทดสอบ TLS 1.2 ควรเชื่อมต่อสำเร็จ
openssl s_client -connect example.com:443 -tls1_2

# ทดสอบ TLS 1.3 ควรเชื่อมต่อสำเร็จ
openssl s_client -connect example.com:443 -tls1_3

ผลที่ต้องการคือ TLS 1.0 และ TLS 1.1 ต้องไม่สามารถเชื่อมต่อได้ ส่วน TLS 1.2 และ TLS 1.3 ต้องเชื่อมต่อสำเร็จ


ตรวจสอบ Certificate และวันหมดอายุ

# ตรวจสอบ Certificate chain และวันหมดอายุ
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -issuer -subject -dates

ตัวอย่างผลลัพธ์

issuer=C = US, O = Let's Encrypt, CN = E7
subject=CN = example.com
notBefore=Jul  1 00:00:00 2026 GMT
notAfter=Sep 29 23:59:59 2026 GMT

หากใช้ Certbot ควรทดสอบระบบต่ออายุอัตโนมัติด้วย

# ทดสอบต่ออายุ certificate แบบ dry-run
sudo certbot renew --dry-run

Certbot ระบุว่าสามารถทดสอบ Automatic Renewal ได้ด้วยคำสั่ง certbot renew --dry-run และระบบจะใช้ cron job หรือ systemd timer ในการต่ออายุ Certificate อัตโนมัติเมื่อถึงเวลา


ตรวจสอบด้วย SSL Labs

หลัง Reload Web Server แล้ว ให้ใช้ SSL Labs SSL Server Test ตรวจสอบ Domain ของเรา เครื่องมือนี้เป็นบริการฟรีสำหรับวิเคราะห์ SSL Web Server แบบละเอียด

สิ่งที่ควรตรวจสอบในผลลัพธ์:

  • Certificate Chain ต้องถูกต้อง

  • Protocol ควรเหลือ TLS 1.2 และ TLS 1.3

  • ไม่ควรมี TLS 1.0 / TLS 1.1

  • Cipher Suite ไม่ควรมี RC4, 3DES, CBC เก่า หรือ SHA-1

  • Forward Secrecy ต้องรองรับ

  • HSTS ควรเปิดหลังทดสอบระบบครบแล้ว

  • คะแนนควรอยู่ระดับ A หรือ A+

ถ้าคะแนนยังไม่ขึ้น A/A+ ให้ดูรายละเอียดในส่วน Protocol Support, Key Exchange, Cipher Strength และ HTTP Strict Transport Security


Checklist สำหรับ Harden SSL/TLS

ใช้รายการนี้ตรวจสอบก่อนปิดงาน

[ ] ใช้ Certificate ที่ถูกต้องและไม่หมดอายุ
[ ] เปิด HTTPS บน Port 443
[ ] Redirect HTTP ไป HTTPS
[ ] ปิด SSLv2, SSLv3, TLS 1.0, TLS 1.1
[ ] เปิด TLS 1.2 และ TLS 1.3
[ ] ใช้ Cipher Suite ที่ปลอดภัย
[ ] เปิด Forward Secrecy
[ ] ปิด Session Tickets หากไม่จำเป็น
[ ] เปิด OCSP Stapling
[ ] เปิด Security Headers พื้นฐาน
[ ] เปิด HSTS หลังทดสอบครบ
[ ] ทดสอบด้วย SSL Labs
[ ] ทดสอบ Certbot Renewal
[ ] มี Backup config ก่อนแก้ไข

Troubleshooting ที่พบบ่อย

1. Nginx Reload ไม่ขึ้น

ตรวจสอบ Syntax

sudo nginx -t

ดู Log เพิ่มเติม

sudo journalctl -u nginx --no-pager -n 50

ปัญหาที่พบบ่อยคือใส่ directive ซ้ำ เช่น ssl_protocols ถูกกำหนดทั้งในไฟล์ Virtual Host และไฟล์ที่ Certbot สร้างไว้ ให้ตรวจสอบไฟล์เหล่านี้

grep -R "ssl_protocols" /etc/nginx/
grep -R "ssl_ciphers" /etc/nginx/

2. Apache ขึ้น Syntax Error

sudo apachectl configtest
sudo journalctl -u apache2 --no-pager -n 50

ถ้าเจอปัญหาเกี่ยวกับ SSLStaplingCache ให้ตรวจสอบว่าเปิด module แล้วหรือยัง

sudo a2enmod socache_shmcb
sudo systemctl reload apache2

3. เปิด HSTS แล้วบาง Subdomain เข้าไม่ได้

หากตั้งค่า includeSubDomains แล้ว Subdomain บางตัวไม่มี HTTPS ผู้ใช้จะเข้า Subdomain นั้นไม่ได้ผ่าน Browser สมัยใหม่ วิธีแก้คือทำ HTTPS ให้ครบทุก Subdomain ก่อนเปิด includeSubDomains

4. SSL Labs ยังเตือน HSTS

เริ่มจากเพิ่ม max-age ให้สูงขึ้นหลังทดสอบครบ เช่น

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

หรือฝั่ง Apache

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

ควรใช้ Modern หรือ Intermediate TLS Profile?

ถ้าเป็นเว็บไซต์ทั่วไป แนะนำใช้ Intermediate Profile เพราะยังรองรับ Client ที่หลากหลาย เช่น Browser รุ่นเก่าบางรุ่น, อุปกรณ์มือถือบางกลุ่ม หรือระบบองค์กรที่ยังใช้ TLS 1.2 อยู่

ถ้าเป็นระบบภายในองค์กรที่ควบคุม Client ได้ทั้งหมด เช่น Internal API, Dashboard, Monitoring System หรือระบบที่กำหนด Browser/Client ชัดเจน อาจพิจารณา Modern Profile ที่รองรับเฉพาะ TLS 1.3 ได้ แต่ต้องทดสอบ Compatibility ก่อนเสมอ Mozilla SSL Configuration Generator แบ่งแนวทางเป็น Modern สำหรับ Client ที่รองรับ TLS 1.3 และ Intermediate สำหรับ Server ที่ต้องรองรับ Client หลากหลาย


สรุป

การ Harden SSL/TLS เป็นงานพื้นฐานที่ SysAdmin ไม่ควรมองข้าม เพราะการมี Certificate เพียงอย่างเดียวไม่ได้หมายความว่าเว็บไซต์ปลอดภัยที่สุด สิ่งที่ต้องทำต่อคือปิด Protocol เก่า เลือก Cipher Suite ที่เหมาะสม เปิด TLS 1.3 เปิด HSTS อย่างระมัดระวัง และตรวจสอบผลด้วยเครื่องมือภายนอก เช่น SSL Labs

สำหรับเว็บไซต์ทั่วไปบน Ubuntu Server 26.04 แนะนำให้ใช้แนวทาง Intermediate คือเปิด TLS 1.2 และ TLS 1.3 พร้อมปิด TLS 1.0/1.1 ทั้งหมด วิธีนี้ให้สมดุลที่ดีระหว่างความปลอดภัยและความเข้ากันได้กับผู้ใช้งานจริง

Next Steps: หลังจาก Harden SSL/TLS แล้ว ควรทำ Security Headers เพิ่มเติม เช่น Content-Security-Policy, Rate Limiting, Fail2ban, Web Application Firewall และระบบ Monitoring Certificate Expiry เพื่อให้เว็บไซต์ปลอดภัยครบวงจรมากขึ้น



Write by Dr.Arnut Ruttanatirakul
SysAdmin Knowledge
https://www.sysadmin.in.th
July 2, 2026