HTTPS 設定 SOP

AWS EC2 (Ubuntu 22.04) + Apache + Let's Encrypt + GoDaddy DNS
最後更新:2026-10-13

前置條件

1 確認 AWS Security Group 開放 Port 443

到 AWS Console → EC2 → Security Groups,確認 Inbound Rules 包含:

TypeProtocolPortSource
HTTPTCP800.0.0.0/0
HTTPSTCP4430.0.0.0/0

或用 AWS CLI:

# 查看目前規則
aws ec2 describe-security-groups --group-ids sg-xxxxxxxx \
  --query 'SecurityGroups[0].IpPermissions' --output table

# 如果沒有 443,手動加入
aws ec2 authorize-security-group-ingress \
  --group-id sg-xxxxxxxx \
  --protocol tcp --port 443 --cidr 0.0.0.0/0
2 設定 GoDaddy DNS

登入 GoDaddy → My Products → 你的網域 → DNS Management

新增或修改以下 A Records,將 IP 替換為你的 Elastic IP:

TypeNameValueTTL
A@你的 Elastic IP600 秒
Awww你的 Elastic IP600 秒
如果 www 已有 CNAME 記錄指向其他地方,請先刪除再建立 A Record。

驗證 DNS 是否生效(可能需要幾分鐘):

dig +short yourdomain.org A
dig +short www.yourdomain.org A
# 兩個都應該回傳你的 Elastic IP
3 安裝 Apache 並啟用必要模組
# 更新套件庫 & 安裝 Apache
sudo apt-get update
sudo apt-get install -y apache2

# 啟用 SSL 和 Rewrite 模組
sudo a2enmod ssl rewrite

# 重啟 Apache
sudo systemctl restart apache2

# 確認 Apache 正在運行
sudo systemctl status apache2
4 建立網站目錄與 VirtualHost 設定

4a. 建立網站目錄

# 建立網站根目錄(依你需求調整路徑)
sudo mkdir -p /var/www/html

# 建立測試首頁
echo "<h1>Hello from yourdomain.org</h1>" | sudo tee /var/www/html/index.html

4b. 建立 VirtualHost 設定檔

sudo nano /etc/apache2/sites-available/yourdomain.conf

貼入以下內容(把 yourdomain.org 替換成你的網域):

<VirtualHost *:80>
    ServerAdmin webmaster@yourdomain.org
    ServerName yourdomain.org
    ServerAlias www.yourdomain.org
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/yourdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/yourdomain_access.log combined
</VirtualHost>

4c. 啟用網站 & 測試

# 啟用新網站設定
sudo a2ensite yourdomain.conf

# 停用預設網站(可選)
sudo a2dissite 000-default.conf

# 測試設定檔語法
sudo apache2ctl configtest

# 重啟 Apache
sudo systemctl restart apache2

用瀏覽器打開 http://yourdomain.org 確認看到測試頁面。

5 安裝 Certbot(透過 Snap)
不要用 apt install certbot,Ubuntu 22.04 上的 apt 版本與 pyOpenSSL 不相容,會報錯。請用 Snap 安裝。
# 確保 snap 已安裝且更新
sudo snap install core
sudo snap refresh core

# 移除舊版 certbot(如果有的話)
sudo apt-get remove -y certbot python3-certbot-apache 2>/dev/null

# 用 snap 安裝 certbot
sudo snap install --classic certbot

# 建立 symlink 讓 certbot 可直接使用
sudo ln -sf /snap/bin/certbot /usr/bin/certbot

# 確認安裝成功
certbot --version
6 取得 SSL 憑證並自動設定 Apache
執行前請確認 DNS 已經生效(Step 2 的 dig 指令回傳正確 IP),否則 Let's Encrypt 驗證會失敗。

6a. 只有一個網域(先申請)

sudo certbot --apache \
  -d yourdomain.org \
  --non-interactive \
  --agree-tos \
  --email your-email@example.com \
  --redirect

6b. 加入 www 子網域(DNS 生效後擴展)

sudo certbot --apache \
  -d yourdomain.org \
  -d www.yourdomain.org \
  --non-interactive \
  --agree-tos \
  --email your-email@example.com \
  --redirect \
  --expand

參數說明:

7 驗證 HTTPS 是否正常
# 測試 HTTPS 是否回應 200
curl -I https://yourdomain.org
curl -I https://www.yourdomain.org

# 測試 HTTP 是否自動轉址到 HTTPS(應看到 301)
curl -I http://yourdomain.org
curl -I http://www.yourdomain.org

預期結果:

URL預期回應
https://yourdomain.org200 OK
https://www.yourdomain.org200 OK
http://yourdomain.org301 → https://yourdomain.org
http://www.yourdomain.org301 → https://www.yourdomain.org
8 確認自動續期

Let's Encrypt 憑證有效期為 90 天,Certbot 會自動續期。確認排程正常:

# 檢查 certbot 的自動續期排程
sudo systemctl list-timers | grep certbot

# 手動測試續期(不會真的續期,只是模擬)
sudo certbot renew --dry-run
如果 --dry-run 測試失敗,檢查 Apache 是否正在運行、Port 80/443 是否開放。

最終設定檔參考

HTTP VirtualHost(自動轉址)

檔案:/etc/apache2/sites-available/yourdomain.conf

<VirtualHost *:80>
    ServerAdmin webmaster@yourdomain.org
    ServerName yourdomain.org
    ServerAlias www.yourdomain.org
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/yourdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/yourdomain_access.log combined

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =yourdomain.org [OR]
    RewriteCond %{SERVER_NAME} =www.yourdomain.org
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

HTTPS VirtualHost(Certbot 自動產生)

檔案:/etc/apache2/sites-available/yourdomain-le-ssl.conf

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin webmaster@yourdomain.org
    ServerName yourdomain.org
    ServerAlias www.yourdomain.org
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/yourdomain_error.log
    CustomLog ${APACHE_LOG_DIR}/yourdomain_access.log combined

    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.org/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.org/privkey.pem
</VirtualHost>
</IfModule>

常見問題

Q: Certbot 報錯 X509_V_FLAG_NOTIFY_POLICY

這是 Ubuntu 22.04 apt 版本的 pyOpenSSL 不相容問題。

解法:移除 apt 版本,改用 snap 安裝(見 Step 5)。

Q: Let's Encrypt 驗證失敗

常見原因:

Q: 要如何手動續期憑證?

sudo certbot renew

通常不需要,Certbot 會自動處理。