SSL Certificates & HTTPS: Start full-site encryption with Certbot for 0 cost

📂 Phase: Phase 6 - Online Deployment (Production) 🔗 Related Chapters: Gunicorn 与 Nginx · Docker 部署全流程


1. Why must I enable HTTPS before going online?

Let’s look at the most intuitive scenario first—when a user enters a password on public Wi‑Fi:

HTTP(裸奔模式 😭)
┌─────────────┐  明文传输  ┌──────────────┐  明文截获  ┌─────────────┐
│  用户浏览器  │ ─────────> │  中间节点/WiFi │ ─────────> │  黑客控制台  │
└─────────────┘            └──────────────┘            └─────────────┘
HTTPS(加密保险箱 ✅)
┌─────────────┐  SSL/TLS 加密  ┌──────────────┐  密文转发  ┌─────────────┐
  用户浏览器 ─────────────>  中间节点/WiFi ─────────>  黑客(啥也看不到)
└─────────────┘                 └──────────────┘            └─────────────┘
  只有你的服务器能解密
                        ┌──────────────┐
  你的后端服务器
                        └──────────────┘

In addition to preventing leakage, HTTPS has five irreplaceable advantages in the modern web ecosystem:

  1. Prevent ISP/public Wi‑Fi traffic hijacking and avoid pages being filled with malicious advertisements.
  2. Prevent middlemen from tampering with your HTML/CSS/JS (such as adding phishing links to buttons).
  3. SEO hard threshold: Google and Baidu clearly prioritize HTTPS sites, and pure HTTP sites will even be demoted.
  4. Browser Trust Mark: Chrome/Firefox will mark HTTP sites as “unsafe”, which directly affects the conversion rate.
  5. Prerequisites for turning on HTTP/2: HTTP/2 can increase speed by 30%–50%, but all major browsers require HTTPS.

2. Get a 90-day automatic renewal certificate at zero cost

Many free certificates in China either change once a year, only support a single domain name, or come from small organizations. The world’s most reliable free solution is Let’s Encrypt + Certbot.

2.1 Two roles

  • Let’s Encrypt: A non-profit certificate authority, endorsed by Google, Microsoft, Mozilla and other major manufacturers, trusted by all major browsers, the certificate is permanently free, supports multiple domain names and wildcards, and is valid for 90 days.
  • Certbot: The official automation tool helps you "apply → configure web server → set up automatic renewal", the whole process takes less than 5 minutes.

2.2 Install Certbot

Certbot is very well adapted to all mainstream systems and can be installed directly with the package manager:

# Ubuntu / Debian(最常用)
sudo apt update && sudo apt install -y certbot python3-certbot-nginx

# CentOS 7 / RHEL 7
sudo yum install -y epel-release && sudo yum install -y certbot python3-certbot-nginx

# CentOS 8+ / RHEL 8+ / Rocky Linux
sudo dnf install -y certbot python3-certbot-nginx

# macOS(本地测试)
brew install certbot

2.3 Recommendation for novices: Nginx fully automatic configuration

If you have already configured an HTTP site with Nginx (such as the Gunicorn + Nginx you learned before), you can do it all with just one command:

# 把 daomanpy.com 换成你自己的域名
sudo certbot --nginx -d daomanpy.com -d www.daomanpy.com

Four questions need to be answered during the interaction:

  1. Email address: Used to receive emergency notifications of certificate expiration (only 2‑3 emails will be received in a year).
  2. Agree to the Terms of Service: RequiredA(Agree)。
  3. Whether to share the mailbox with EFF:YorNFeel free (EFF is a nonprofit that promotes online privacy).
  4. Whether to automatically jump to HTTPS: Strongly recommended to select2 (Redirect), forces all HTTP requests to be 301 permanently redirected to HTTPS to avoid mixed content problems.

When finished you will seeCongratulations!tips. Refresh the browser and the website will now be securely locked!

2.4 Advanced version: just get the certificate and match it yourself

If you don't want Certbot to change the existing Nginx configuration, you can also just apply for a certificate and then configure it manually. Choose one of the two according to your verification method:

# 方式 1:Nginx 临时验证(推荐,不动 Nginx 配置)
sudo certbot certonly --nginx -d daomanpy.com -d www.daomanpy.com

# 方式 2:Webroot 验证(假设静态目录为 /var/www/html)
sudo certbot certonly --webroot -w /var/www/html -d daomanpy.com -d www.daomanpy.com

After the application is successful, the certificate will be saved in/etc/letsencrypt/live/你的域名/Next, the path will remain unchanged after renewal. You need to pay attention to two files:

  • fullchain.pem: Certificate chain (sent to browser).
  • privkey.pem:Private key (Never disclose it!).

3. Advanced security Nginx HTTPS configuration

Certbot's auto-generated configuration is already available, but some enhancements are needed if you want an SSL Labs A+ rating (a production-grade security standard). Below is a set of complete configuration templates that have been verified and compatible with mainstream browsers (Chrome 60+, Firefox 55+, Safari 12+):

# /etc/nginx/conf.d/daomanpy.conf
# 记得把所有 daomanpy.com 换成你自己的域名

# --------------------------
# 1. HTTP → HTTPS 强制跳转
# --------------------------
server {
    listen 80;
    listen [::]:80;                      # IPv6 支持
    server_name daomanpy.com www.daomanpy.com;

    # 保留 Let's Encrypt 验证路径(续期必须能访问)
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    # 其余全部 301 跳转
    return 301 https://$host$request_uri;
}

# --------------------------
# 2. HTTPS 主站配置
# --------------------------
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name daomanpy.com www.daomanpy.com;

    root /var/www/daoman;
    index index.html index.htm;

    # ---------- 证书路径 ----------
    ssl_certificate      /etc/letsencrypt/live/daomanpy.com/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/daomanpy.com/privkey.pem;

    # ---------- SSL 协议与加密套件(Mozilla Intermediate 推荐) ----------
    ssl_protocols TLSv1.2 TLSv1.3;       # 禁用不安全的 TLSv1.0 / 1.1
    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;       # 让客户端选择最优加密套件
    ssl_session_cache shared:SSL:10m;    # 会话缓存,减少握手开销
    ssl_session_timeout 1d;
    ssl_session_tickets off;             # 关闭会话票证,降低安全风险

    # ---------- OCSP Stapling(加速证书状态校验) ----------
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # ---------- 安全响应头 ----------
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;   # HSTS
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    # ---------- 反向代理到后端 Gunicorn ----------
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;   # 告知后端当前是 HTTPS
        proxy_redirect off;
        proxy_connect_timeout 60s;
        proxy_read_timeout 60s;
        client_max_body_size 20M;                     # 按需调整上传限制
    }

    # ---------- 静态文件(Nginx 直接服务) ----------
    location /static/ {
        alias /var/www/daoman/static/;
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # ---------- 健康检查端点 ----------
    location /health {
        return 200 "healthy\n";
        add_header Content-Type text/plain;
        access_log off;
    }
}

After the configuration is completed, verify first and then reload to avoid service interruption:

sudo nginx -t                   # 验证语法
sudo systemctl reload nginx     # 平滑重载

4. 90-day automatic renewal: once and for all

Let’s Encrypt certificates are only valid for 90 days to reduce the risk period if the private key is compromised. Certbot comes with renewal capabilities, we just need to ensure that the scheduled tasks work properly.

4.1 Test the renewal process first

Before formal setup, it is strongly recommended to do a test run:

sudo certbot renew --dry-run

SeeCongratulations, all renewals succeededIt means there is no problem with the configuration.

4.2 Configure scheduled renewal

Modern Linux distributions usually come with systemd timer after installing Certbot, just check the status:

sudo systemctl status certbot.timer
# 如果没启动,执行:
sudo systemctl enable --now certbot.timer

# 查看所有 timers 确认 certbot.timer 已就绪
sudo systemctl list-timers

The Timer will be randomly offset for a period of time every morning to perform renewal. After the renewal is successful, Certbot will automatically reload Nginx.

Method 2: crontab (compatible with old systems)

If you don’t have systemd, you can use the root user’s crontab:

sudo crontab -e
# 添加以下行(每天凌晨 3 点检查续期,成功后 reload Nginx)
0 3 * * * certbot renew --quiet --renew-hook "systemctl reload nginx"

5. Check your HTTPS security level

After the deployment is completed, it is recommended to use professional tools to conduct a comprehensive inspection.

Online detection (preferred)

Local quick check

# 测试 SSL 连接
openssl s_client -connect daomanpy.com:443 -servername daomanpy.com

# 查看证书详情(有效期、签发机构等)
openssl x509 -in /etc/letsencrypt/live/daomanpy.com/fullchain.pem -text -noout

6. Pitfall guide: Common HTTPS issues

6.1 Mixed Content (mixed HTTP / HTTPS) warning

⚠️ Symptom: The browser address bar displays "little green lock with an exclamation mark", and the console reportsMixed Contentmistake.

Reason: The page quotedhttp://The opening image, CSS, JS and other resources. Solution: Change all resource links tohttps://or use relative protocol//(Automatically follows the current protocol).

6.2 Certificate renewal failed

⚠️ Symptom: Renewal TimesFailed authorization procedure

Most likely because the verification path of Let’s Encrypt is inaccessible, please check in this order:

  • Is it retained in the Nginx configuration?.well-known/acme-challenge/location block.
  • Whether the firewall has allowed port 80** (renewal must be verified using HTTP).
  • Is the domain name resolution normal (ping 你的域名See if it can be connected).

7. Summary

Full-site HTTPS is already a bottom-line requirement for production projects, and it can be implemented within 10 minutes at zero cost using Let’s Encrypt + Certbot.

Quick review of the deployment process:

  1. Install Certbot and the corresponding Nginx plug-in
  2. Executioncertbot --nginx -d 你的域名Apply and configure with one click
  3. (Optional) Replace with advanced security Nginx configuration and sprint SSL Labs A+
  4. Confirm that automatic renewal (systemd timer or crontab) has taken effect
  5. Use SSL Labs or MySSL to check the security level

💡 Last reminder for production level

  • Be sure to enable HSTS to prevent users from accidentally visiting HTTP sites.
  • Review your security score with SSL Labs every month.
  • Never placeprivkey.pemCommit to a version control system (like Git)!

🔗 Extended reading