เมื่อพัฒนาเว็บหรือ API ใน Local Environment หรือ Staging Server นักพัฒนาหลายคนต้องการทดสอบฟีเจอร์ที่ต้องการ HTTPS เช่น Service Worker, Geolocation API, Mixed Content Policy หรือ HTTP/2 แต่ยังไม่อยากติดตั้ง SSL Certificate จริงในขั้นนี้ Self-Signed SSL Certificate ที่สร้างด้วย OpenSSL คือทางออกที่เร็วและฟรีที่สุด บทความนี้อธิบายวิธีสร้าง Self-Signed SSL ทุกขั้นตอนพร้อมตัวอย่างคำสั่งจริง ทั้งสำหรับ Linux, macOS และ Windows รวมถึงวิธีกำหนดค่า Web Server ให้ใช้งาน Certificate ที่สร้างขึ้น
Self-Signed SSL Certificate คืออะไร และใช้เมื่อไหร่
Self-Signed SSL Certificate คือใบรับรองความปลอดภัยแบบ X.509 ที่สร้างและลงนามโดยตัวเองโดยไม่ผ่าน Certificate Authority (CA) ภายนอกเช่น DigiCert, Sectigo หรือ Let's Encrypt ซึ่งหมายความว่า Browser และ OS จะไม่รู้จัก CA ผู้ออกใบรับรอง จึงแสดงคำเตือน "Your connection is not private" หรือ "NET::ERR_CERT_AUTHORITY_INVALID" เสมอ
อย่างไรก็ตาม Self-Signed SSL มีประโยชน์มากในหลายสถานการณ์:
- Local Development — ทดสอบฟีเจอร์ที่ต้องการ HTTPS เช่น Service Worker, Camera API, Clipboard API, WebCrypto บน localhost
- Staging/UAT Environment — ใช้บน Server ที่ทีมงานเข้าถึงเท่านั้น ไม่เปิดให้สาธารณะ
- Internal Tools — API Gateway หรือ Dashboard ที่ใช้ภายในองค์กรที่สามารถกำหนด Trust Policy ได้
- Testing SSL Configuration — ทดสอบการกำหนดค่า TLS Protocol, Cipher Suite, HSTS บน Web Server ก่อน Deploy Production
- Docker/Container Networks — Communication ระหว่าง Service ใน Internal Network ที่ต้องการ Mutual TLS (mTLS)
ข้อควรจำ: ห้ามใช้ Self-Signed SSL บน Production Server ที่ผู้ใช้ทั่วไปเข้าถึง เพราะจะทำให้ผู้ใช้เห็นหน้าเตือน "Not Secure" ซึ่งสร้างความไม่น่าเชื่อถือและอาจทำให้ผู้ใช้ออกจากเว็บได้ สำหรับ Production ควรใช้ SSL Certificate จาก CA ที่ Browser เชื่อถือ
ทำความเข้าใจโครงสร้าง SSL Certificate ก่อนเริ่ม
ก่อนสร้าง Certificate ควรเข้าใจว่าไฟล์แต่ละประเภทคืออะไร เพื่อให้ใช้งานได้ถูกต้อง:
| ไฟล์/นามสกุล | ความหมาย | ใช้กับ |
|---|---|---|
server.key |
Private Key — กุญแจส่วนตัว ห้ามเผยแพร่ | Web Server (Apache/Nginx) |
server.csr |
Certificate Signing Request — คำขอรับใบรับรอง | ส่งให้ CA (ใน Self-Signed ใช้ Sign เอง) |
server.crt |
Certificate — ใบรับรองที่ใช้งาน (PEM format) | Web Server + ติดตั้งใน Browser Trust Store |
server.pem |
PEM format — เหมือน .crt แต่บางระบบต้องการนามสกุลนี้ | Linux CA Store, Docker, Node.js |
server.pfx / .p12 |
PKCS#12 — รวม Key + Cert ในไฟล์เดียว | Windows IIS, .NET, Java KeyStore |
สำหรับ Linux/Apache/Nginx ในบทความนี้จะทำงานกับไฟล์ .key และ .crt เป็นหลัก ซึ่งใช้ PEM format (ข้อความ Base64 ที่ขึ้นต้นด้วย -----BEGIN CERTIFICATE-----)
ตรวจสอบ OpenSSL และเตรียม Environment
OpenSSL มักติดตั้งมาพร้อมกับ Linux และ macOS ส่วน Windows ต้องติดตั้งเพิ่มเติม ตรวจสอบว่ามี OpenSSL อยู่แล้วด้วยคำสั่ง:
openssl version
ผลลัพธ์ที่ควรได้:
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
ถ้ายังไม่มี OpenSSL ให้ติดตั้งตามระบบปฏิบัติการ:
# Ubuntu/Debian sudo apt-get update && sudo apt-get install -y openssl # CentOS/RHEL/Rocky Linux sudo dnf install -y openssl # macOS (ผ่าน Homebrew) brew install openssl # Windows — ดาวน์โหลด Win32/Win64 OpenSSL จาก https://slproweb.com/products/Win32OpenSSL.html # หรือใช้ WSL (Windows Subsystem for Linux) แล้วรันคำสั่ง Linux ปกติ
หลังจากนั้นสร้างโฟลเดอร์เก็บไฟล์ Certificate:
mkdir -p ~/ssl-certs && cd ~/ssl-certs
วิธีที่ 1 — สร้าง Self-Signed SSL แบบ Quick (1 คำสั่ง)
วิธีเร็วที่สุดคือสร้าง Private Key และ Certificate พร้อมกันในคำสั่งเดียว เหมาะสำหรับ Dev ที่ต้องการใช้งานทันที:
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt \ -days 365 -nodes \ -subj "/C=TH/ST=Bangkok/L=Bangkok/O=MyCompany Dev/OU=Development/CN=localhost"
อธิบายพารามิเตอร์แต่ละตัว:
req -x509— สร้าง Self-Signed Certificate (ข้าม CA ไปเลย)-newkey rsa:4096— สร้าง RSA Private Key ขนาด 4096 bits (ปลอดภัยกว่า 2048)-keyout server.key— บันทึก Private Key ลงไฟล์ชื่อ server.key-out server.crt— บันทึก Certificate ลงไฟล์ชื่อ server.crt-days 365— กำหนดอายุ Certificate 365 วัน-nodes— ไม่เข้ารหัส Private Key (ย่อมาจาก "no DES") ทำให้ Web Server ไม่ต้องถามรหัสผ่านตอน Start-subj— กำหนดข้อมูล Subject โดยไม่ต้องตอบคำถาม Interactive
หลังรันคำสั่งจะได้ไฟล์ 2 ไฟล์: server.key (Private Key) และ server.crt (Certificate) พร้อมใช้งานกับ Web Server ได้ทันที
วิธีที่ 2 — สร้าง SSL พร้อม Subject Alternative Names (SAN)
Browser สมัยใหม่ต้องการให้ Certificate มี Subject Alternative Names (SAN) ไม่เช่นนั้นจะแสดงเตือน "Subject Alternative Name Missing" แม้จะยอมรับ Certificate แล้วก็ตาม วิธีนี้สร้าง Certificate ที่ครอบคลุมหลาย hostname:
# สร้างไฟล์ config สำหรับ SAN cat > san.cnf << 'EOF' [req] default_bits = 4096 prompt = no default_md = sha256 distinguished_name = dn x509_extensions = v3_req [dn] C = TH ST = Bangkok L = Bangkok O = MyCompany Development CN = localhost [v3_req] subjectAltName = @alt_names keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [alt_names] DNS.1 = localhost DNS.2 = *.localhost DNS.3 = dev.local DNS.4 = *.dev.local DNS.5 = staging.myapp.com IP.1 = 127.0.0.1 IP.2 = 192.168.1.100 EOF # สร้าง Certificate จาก config ไฟล์ openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt \ -days 365 -nodes -config san.cnf
ด้วยวิธีนี้ Certificate เดียวจะครอบคลุม localhost, *.localhost, dev.local, *.dev.local, staging.myapp.com รวมถึง IP Address ที่กำหนด ทำให้ใช้ในสภาพแวดล้อม Dev ที่มีหลาย Domain ได้โดยไม่ต้องสร้าง Certificate หลายใบ
วิธีที่ 3 — สร้างแบบแยกขั้นตอน (สำหรับผู้ที่ต้องการความยืดหยุ่น)
ถ้าต้องการควบคุมทุกขั้นตอน หรือต้องการเก็บ CSR ไว้สำหรับใช้ในอนาคต สามารถแยกเป็น 3 ขั้นตอน:
ขั้นตอนที่ 1: สร้าง Private Key
# RSA 4096-bit (แนะนำ) openssl genrsa -out server.key 4096 # หรือ ECDSA P-256 (เร็วกว่า RSA ทั้ง Gen และ Handshake) openssl ecparam -genkey -name prime256v1 -out server.key
ขั้นตอนที่ 2: สร้าง CSR (Certificate Signing Request)
openssl req -new -key server.key -out server.csr \ -subj "/C=TH/ST=Bangkok/L=Bangkok/O=MyOrg/CN=localhost"
ขั้นตอนที่ 3: Sign Certificate ด้วย Private Key ของตัวเอง
openssl x509 -req -in server.csr -signkey server.key \ -out server.crt -days 365 \ -extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1")
การแยกขั้นตอนช่วยให้คุณเก็บ server.csr ไว้ได้ ซึ่งมีประโยชน์ถ้าต้องการส่งไปให้ Internal CA ขององค์กรลงนามแทนการ Self-Sign
ตรวจสอบ Certificate ที่สร้างขึ้น
หลังสร้าง Certificate แล้ว ควรตรวจสอบข้อมูลเพื่อให้แน่ใจว่าถูกต้องก่อนนำไปใช้งาน:
# ดูข้อมูล Certificate ทั้งหมด openssl x509 -in server.crt -text -noout # ดูแค่ Subject, Issuer, Validity openssl x509 -in server.crt -subject -issuer -dates -noout # ตรวจสอบว่า Private Key ตรงกับ Certificate openssl x509 -noout -modulus -in server.crt | md5sum openssl rsa -noout -modulus -in server.key | md5sum # ถ้า md5 ตรงกัน แสดงว่า key กับ cert เป็น pair เดียวกัน # ตรวจสอบ SAN openssl x509 -in server.crt -text -noout | grep -A2 "Subject Alternative Name"
ผลลัพธ์จาก openssl x509 -text ที่ควรตรวจสอบ:
- Validity — วันที่เริ่มและหมดอายุถูกต้อง
- Subject — ชื่อ CN ตรงกับ Domain ที่ใช้งาน
- X509v3 Subject Alternative Name — มีรายการ DNS/IP ที่ต้องการ
- Public Key Algorithm — RSA 4096 หรือ EC prime256v1
กำหนดค่า Web Server ให้ใช้งาน Self-Signed SSL
หลังสร้าง Certificate แล้ว ขั้นตอนต่อไปคือกำหนดค่า Web Server เพื่อเปิดใช้ HTTPS สมมติว่าเก็บไฟล์ Certificate ไว้ที่ /etc/ssl/self-signed/:
# คัดลอก Certificate ไปยังตำแหน่งมาตรฐาน sudo mkdir -p /etc/ssl/self-signed sudo cp server.key /etc/ssl/self-signed/server.key sudo cp server.crt /etc/ssl/self-signed/server.crt # กำหนดสิทธิ์ให้ Private Key อ่านได้เฉพาะ root sudo chmod 600 /etc/ssl/self-signed/server.key sudo chmod 644 /etc/ssl/self-signed/server.crt
กำหนดค่า Nginx
server {
listen 80;
server_name localhost dev.local;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name localhost dev.local;
ssl_certificate /etc/ssl/self-signed/server.crt;
ssl_certificate_key /etc/ssl/self-signed/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
root /var/www/html;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
กำหนดค่า Apache
<VirtualHost *:443>
ServerName localhost
ServerAlias dev.local
SSLEngine on
SSLCertificateFile /etc/ssl/self-signed/server.crt
SSLCertificateKeyFile /etc/ssl/self-signed/server.key
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
DocumentRoot /var/www/html
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# บังคับ HTTPS
<VirtualHost *:80>
ServerName localhost
Redirect permanent / https://localhost/
</VirtualHost>
หลังแก้ไข Config ให้ Reload Web Server:
# Nginx sudo nginx -t && sudo systemctl reload nginx # Apache sudo apachectl configtest && sudo systemctl reload apache2
ติดตั้ง Certificate ใน Browser Trust Store
เพื่อให้ Browser ไม่แสดงคำเตือน "Not Secure" ใน Dev Environment ต้อง Import Certificate เข้า Trust Store ของแต่ละระบบปฏิบัติการ:
macOS
# วิธีที่ 1: ผ่าน Command Line sudo security add-trusted-cert -d -r trustRoot \ -k /Library/Keychains/System.keychain server.crt # วิธีที่ 2: ผ่าน Keychain Access GUI # 1. ดับเบิลคลิกไฟล์ server.crt # 2. เปิด Keychain Access → ค้นหา CN ของ Certificate # 3. ดับเบิลคลิก → Trust → "When using this certificate" → Always Trust
Linux (Ubuntu/Debian)
sudo cp server.crt /usr/local/share/ca-certificates/dev-localhost.crt sudo update-ca-certificates # ผลลัพธ์: 1 added, 0 removed; done.
Windows
# รัน PowerShell ในฐานะ Administrator Import-Certificate -FilePath "C:\path\to\server.crt" ` -CertStoreLocation Cert:\LocalMachine\Root # หรือผ่าน GUI: # 1. ดับเบิลคลิก server.crt → Install Certificate # 2. Store Location: Local Machine → Next # 3. Place all certificates in the following store → Browse # 4. เลือก Trusted Root Certification Authorities → OK → Finish
เคล็ดลับ mkcert — เครื่องมือสร้าง Self-Signed SSL ที่ง่ายกว่า OpenSSL: ถ้าใช้บ่อยมาก ลองใช้ mkcert (github.com/FiloSottile/mkcert) ซึ่งสร้าง Local CA อัตโนมัติและติดตั้งเข้า System Trust Store ทุกระบบในคำสั่งเดียว: mkcert -install แล้วสร้าง Certificate ด้วย mkcert localhost 127.0.0.1 ::1 ได้เลยโดยไม่ต้องจัดการ OpenSSL config ซับซ้อน
สร้าง Self-Signed SSL สำหรับ Docker และ Node.js
นักพัฒนาที่ใช้ Docker หรือ Node.js มักต้องการ Self-Signed SSL สำหรับสร้าง HTTPS Server ภายใน Container หรือ Development Server ดังนี้:
Node.js HTTPS Server
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/path/to/server.key'),
cert: fs.readFileSync('/path/to/server.crt'),
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello HTTPS World!\n');
}).listen(443, () => {
console.log('HTTPS Server running on port 443');
});
Docker Compose กับ Nginx + SSL
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "443:443"
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./ssl/server.crt:/etc/ssl/certs/server.crt:ro
- ./ssl/server.key:/etc/ssl/private/server.key:ro
- ./html:/usr/share/nginx/html:ro
ปิดการตรวจสอบ SSL ใน Development Tools
บาง Tool ปฏิเสธ Self-Signed SSL โดยค่าเริ่มต้น สามารถปิดชั่วคราวได้:
# curl: ใช้ -k หรือ --insecure
curl -k https://localhost/api/health
# wget
wget --no-check-certificate https://localhost/file.zip
# Python requests
import requests
response = requests.get('https://localhost', verify=False)
# Node.js / npm (ตั้งค่า env var)
export NODE_TLS_REJECT_UNAUTHORIZED=0
node app.js
# Git
git config --global http.sslVerify false # ⚠️ ควรตั้งเฉพาะ repo ไม่ใช่ global
คำเตือน: ปิดการตรวจสอบ SSL ใน Development เท่านั้น อย่าลืมเปิดกลับใน Production เพราะจะทำให้ Man-in-the-Middle Attack ทำได้ง่าย
สร้าง Certificate Authority (CA) ส่วนตัว สำหรับ Team Development
ถ้าทำงานเป็น Team และต้องการให้ทุกคนเชื่อถือ Certificate เดียวกันโดยไม่ต้อง Import ทีละเครื่อง วิธีที่ดีกว่าคือสร้าง Root CA ส่วนตัวแล้วแจกจ่าย CA Certificate ให้ทีมติดตั้งครั้งเดียว หลังจากนั้น Certificate ใหม่ที่ Sign โดย CA นี้จะได้รับความเชื่อถืออัตโนมัติ:
# ขั้นตอนที่ 1: สร้าง Root CA Private Key openssl genrsa -out ca.key 4096 # ขั้นตอนที่ 2: สร้าง Root CA Certificate (อายุ 10 ปี) openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \ -out ca.crt \ -subj "/C=TH/ST=Bangkok/O=MyCompany Dev CA/CN=MyCompany Development Root CA" # ขั้นตอนที่ 3: สร้าง Private Key สำหรับ Server openssl genrsa -out server.key 4096 # ขั้นตอนที่ 4: สร้าง CSR openssl req -new -key server.key -out server.csr \ -subj "/C=TH/ST=Bangkok/O=MyCompany/CN=dev.mycompany.local" # ขั้นตอนที่ 5: Sign CSR ด้วย CA openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 365 -sha256 \ -extfile <(printf "subjectAltName=DNS:dev.mycompany.local,DNS:*.dev.mycompany.local,IP:192.168.1.100")
แจกจ่าย ca.crt ให้สมาชิก Team ติดตั้งเข้า Trust Store แต่ละเครื่องครั้งเดียว จากนั้นทุก Server Certificate ที่ Sign ด้วย CA นี้จะเชื่อถือโดยอัตโนมัติ โดยไม่ต้อง Import ทีละใบ
Renew Self-Signed SSL Certificate
เมื่อ Certificate ใกล้หมดอายุ สร้างใหม่แทนการ Renew เพราะ Self-Signed ไม่มีกระบวนการ Renewal จาก CA:
# ตรวจสอบวันหมดอายุ openssl x509 -in server.crt -noout -enddate # ผลลัพธ์: notAfter=Jun 9 00:00:00 2027 GMT # สร้างใหม่ด้วย config เดิม (ถ้าเก็บ san.cnf ไว้) openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt \ -days 365 -nodes -config san.cnf # หรือถ้ามี Shell Script สำหรับ Automation cat > renew-ssl.sh << 'EOF' #!/bin/bash openssl req -x509 -newkey rsa:4096 \ -keyout /etc/ssl/self-signed/server.key \ -out /etc/ssl/self-signed/server.crt \ -days 365 -nodes -config /etc/ssl/san.cnf systemctl reload nginx echo "SSL Certificate renewed: $(date)" EOF chmod +x renew-ssl.sh
สามารถตั้ง Cron Job เพื่อ Renew อัตโนมัติก่อนหมดอายุ 30 วัน หรือใช้ Script ตรวจสอบและแจ้งเตือนผ่าน Email เมื่อ Certificate ใกล้หมดอายุ
คำถามที่พบบ่อย (FAQ)
Self-Signed SSL กับ SSL Certificate จาก CA ต่างกันอย่างไร
Self-Signed SSL คือใบรับรองที่คุณออกให้ตัวเองโดยใช้ OpenSSL ไม่ผ่าน Certificate Authority (CA) ดังนั้น Browser จึงไม่เชื่อถือและแสดงคำเตือน "Your connection is not private" ส่วน SSL จาก CA เช่น DigiCert, GlobalSign ได้รับความเชื่อถือจาก Browser และระบบปฏิบัติการทั่วโลก Self-Signed SSL เหมาะใช้เฉพาะ Dev/Staging/Internal ที่ควบคุมผู้ใช้งานได้ ไม่ควรใช้บน Production Server ที่ผู้ใช้ภายนอกเข้าถึง
Self-Signed SSL ใช้บน Production ได้ไหม
ไม่แนะนำอย่างยิ่ง เพราะ Browser ทุกตัว (Chrome, Firefox, Safari, Edge) จะแสดงหน้าเตือน "Not Secure" ก่อนที่ผู้ใช้จะเข้าถึงเว็บไซต์ ทำให้ผู้ใช้ทั่วไปรู้สึกไม่ปลอดภัยและอาจออกจากเว็บทันที สำหรับ Production ควรใช้ SSL Certificate จาก CA ที่ได้รับการรับรอง
วิธีทำให้ Browser เชื่อถือ Self-Signed SSL Certificate ทำอย่างไร
ต้อง Import Certificate (.crt หรือ .pem) เข้า Trust Store ของระบบปฏิบัติการหรือ Browser โดยตรง บน Windows ใช้ certmgr.msc → Trusted Root Certification Authorities → Import บน macOS ใช้ Keychain Access → Certificates → ลาก .crt เข้า → เปลี่ยน Trust เป็น Always Trust บน Linux (Ubuntu/Debian) คัดลอกไฟล์ .crt ไปที่ /usr/local/share/ca-certificates/ แล้วรัน sudo update-ca-certificates
Self-Signed SSL Certificate มีอายุนานแค่ไหน และต้อง Renew บ่อยไหม
คุณกำหนดอายุได้เองเมื่อสร้างด้วยพารามิเตอร์ -days เช่น -days 365 (1 ปี) หรือ -days 3650 (10 ปี) สำหรับ Dev/Staging นิยมตั้ง 365-3650 วัน เพื่อไม่ต้อง Renew บ่อย แต่ Browser ใหม่อาจมีปัญหากับ Certificate อายุยาวกว่า 825 วัน ควรสร้างใหม่เป็นประจำทุกปีหรือเมื่อข้อมูลใน Certificate เปลี่ยน
SSL Certificate ทุกประเภทที่ AsiaGB
DV OV EV Wildcard SSL เริ่มต้น 1,000 บาท/ปี พร้อม Installation Support
ดู SSL Certificate