Skip to content

HTTPS证书

1. 概述

HTTPS(Hypertext Transfer Protocol Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS 通过在 HTTP 下加入 SSL/TLS 层来保证数据传输的安全性。本文档介绍如何为梵医云系统配置 HTTPS 证书。

2. HTTPS 基础知识

2.1 什么是 HTTPS

HTTPS 是 HTTP 协议的安全版本,通过 SSL/TLS 协议加密数据传输,确保:

  • 机密性:防止数据被窃取
  • 完整性:防止数据被篡改
  • 身份认证:验证服务器身份

2.2 SSL/TLS 协议

SSL/TLS 是 HTTPS 的基础协议,包括:

  • SSL 2.0:已废弃
  • SSL 3.0:已废弃
  • TLS 1.0:已废弃
  • TLS 1.1:已废弃
  • TLS 1.2:推荐使用
  • TLS 1.3:最新版本,推荐使用

2.3 证书类型

类型说明适用场景
DV 证书域名验证个人网站、博客
OV 证书组织验证企业网站、电商平台
EV 证书扩展验证金融、支付等高安全需求
通配符证书支持子域名多子域名网站
多域名证书支持多个域名多域名网站

3. 证书获取方式

3.1 免费证书

3.1.1 Let's Encrypt

Let's Encrypt 是一个免费、自动化、开放的证书颁发机构(CA)。

优点

  • 完全免费
  • 自动化申请和续期
  • 广泛支持

缺点

  • 仅提供 DV 证书
  • 有效期短(90 天)

3.1.2 其他免费证书

  • ZeroSSL
  • Cloudflare SSL
  • 阿里云免费证书
  • 腾讯云免费证书

3.2 付费证书

3.2.1 商业 CA

  • DigiCert
  • GlobalSign
  • Sectigo
  • GeoTrust

优点

  • 提供多种证书类型
  • 有效期长(1-3 年)
  • 提供保险和赔偿

缺点

  • 需要付费
  • 申请流程复杂

4. 使用 Let's Encrypt 申请证书

4.1 安装 Certbot

Certbot 是 Let's Encrypt 的官方客户端。

4.1.1 CentOS 安装 Certbot

bash
# 安装 EPEL 仓库
sudo yum install -y epel-release

# 安装 Certbot
sudo yum install -y certbot

4.1.2 Ubuntu 安装 Certbot

bash
# 更新软件包列表
sudo apt update

# 安装 Certbot
sudo apt install -y certbot

4.2 申请证书

4.2.1 Standalone 模式

适用于没有 Web 服务器的场景。

bash
# 申请证书
sudo certbot certonly --standalone -d fanyi.example.com -d www.fanyi.example.com

# 查看证书
sudo certbot certificates

4.2.2 Webroot 模式

适用于已有 Web 服务器的场景。

bash
# 申请证书
sudo certbot certonly --webroot -w /var/www/html -d fanyi.example.com -d www.fanyi.example.com

# 查看证书
sudo certbot certificates

4.2.3 Nginx 模式

适用于使用 Nginx 的场景。

bash
# 安装 Certbot Nginx 插件
sudo yum install -y python3-certbot-nginx

# 申请证书
sudo certbot --nginx -d fanyi.example.com -d www.fanyi.example.com

# 查看证书
sudo certbot certificates

4.2.4 Apache 模式

适用于使用 Apache 的场景。

bash
# 安装 Certbot Apache 插件
sudo yum install -y python3-certbot-apache

# 申请证书
sudo certbot --apache -d fanyi.example.com -d www.fanyi.example.com

# 查看证书
sudo certbot certificates

4.3 证书位置

Let's Encrypt 证书默认保存在:

/etc/letsencrypt/live/fanyi.example.com/
├── cert.pem       # 服务器证书
├── chain.pem      # 中间证书
├── fullchain.pem  # 完整证书链
└── privkey.pem    # 私钥

4.4 自动续期

Let's Encrypt 证书有效期为 90 天,需要定期续期。

4.4.1 手动续期

bash
# 测试续期
sudo certbot renew --dry-run

# 续期证书
sudo certbot renew

4.4.2 自动续期

Certbot 会自动创建续期任务,也可以手动配置:

bash
# 添加定时任务
sudo crontab -e

# 添加以下内容(每天凌晨 2 点检查续期)
0 2 * * * certbot renew --quiet --post-hook "systemctl reload nginx"

5. 使用云服务商证书

5.1 阿里云证书

5.1.1 申请证书

  1. 登录阿里云控制台
  2. 进入"SSL 证书"服务
  3. 点击"购买证书"
  4. 选择"免费证书"(DV)
  5. 填写域名信息
  6. 选择验证方式(DNS 验证或文件验证)
  7. 完成验证
  8. 下载证书

5.1.2 部署证书

下载证书后,解压得到以下文件:

fanyi.example.com.zip
├── fanyi.example.com.key    # 私钥
├── fanyi.example.com.pem     # 证书
└── fanyi.example.com_chain.pem  # 证书链

5.2 腾讯云证书

5.2.1 申请证书

  1. 登录腾讯云控制台
  2. 进入"SSL 证书"服务
  3. 点击"申请免费证书"
  4. 填写域名信息
  5. 选择验证方式
  6. 完成验证
  7. 下载证书

5.2.2 部署证书

下载证书后,解压得到以下文件:

fanyi.example.com.zip
├── fanyi.example.com.key    # 私钥
├── fanyi.example.com.crt     # 证书
└── fanyi.example.com_bundle.crt  # 证书链

6. Nginx 配置 HTTPS

6.1 安装 Nginx

bash
# CentOS
sudo yum install -y nginx

# Ubuntu
sudo apt install -y nginx

6.2 配置 HTTPS

编辑 Nginx 配置文件 /etc/nginx/conf.d/fanyi.conf

nginx
server {
    listen 80;
    server_name fanyi.example.com www.fanyi.example.com;
    
    # 重定向到 HTTPS
    return 301 https://$server_name$request_uri;
}

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

    # 证书配置
    ssl_certificate /etc/letsencrypt/live/fanyi.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/fanyi.example.com/privkey.pem;

    # SSL 协议配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # SSL 会话缓存
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # 安全头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # 日志配置
    access_log /var/log/nginx/fanyi_access.log;
    error_log /var/log/nginx/fanyi_error.log;

    # 反向代理配置
    location / {
        proxy_pass http://127.0.0.1:48080;
        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;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
    }

    # WebSocket 支持
    location /ws {
        proxy_pass http://127.0.0.1:48080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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;
    }
}

6.3 测试配置

bash
# 测试 Nginx 配置
sudo nginx -t

# 重启 Nginx
sudo systemctl restart nginx

6.4 验证 HTTPS

访问 https://fanyi.example.com,查看浏览器地址栏是否显示锁图标。

7. Apache 配置 HTTPS

7.1 安装 Apache

bash
# CentOS
sudo yum install -y httpd mod_ssl

# Ubuntu
sudo apt install -y apache2

7.2 配置 HTTPS

编辑 Apache 配置文件 /etc/httpd/conf.d/ssl.conf

apache
<VirtualHost *:80>
    ServerName fanyi.example.com
    ServerAlias www.fanyi.example.com
    
    # 重定向到 HTTPS
    Redirect permanent / https://fanyi.example.com/
</VirtualHost>

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

    # 证书配置
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/fanyi.example.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/fanyi.example.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/fanyi.example.com/chain.pem

    # SSL 协议配置
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite HIGH:!aNULL:!MD5
    SSLHonorCipherOrder on

    # HSTS
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

    # 安全头
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-XSS-Protection "1; mode=block"

    # 日志配置
    ErrorLog /var/log/httpd/fanyi_error.log
    CustomLog /var/log/httpd/fanyi_access.log combined

    # 反向代理配置
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:48080/
    ProxyPassReverse / http://127.0.0.1:48080/
</VirtualHost>

7.3 测试配置

bash
# 测试 Apache 配置
sudo apachectl configtest

# 重启 Apache
sudo systemctl restart httpd

7.4 验证 HTTPS

访问 https://fanyi.example.com,查看浏览器地址栏是否显示锁图标。

8. 宝塔面板配置 HTTPS

8.1 申请证书

  1. 登录宝塔面板
  2. 进入"网站"
  3. 找到要配置的网站
  4. 点击"设置"
  5. 选择"SSL"
  6. 选择证书类型:
    • Let's Encrypt(免费)
    • 其他证书(上传)
  7. 填写域名和邮箱
  8. 点击"申请"

8.2 上传证书

  1. 进入"网站"
  2. 找到要配置的网站
  3. 点击"设置"
  4. 选择"SSL"
  5. 选择"其他证书"
  6. 填写证书信息:
    • 证书(KEY):粘贴私钥内容
    • 证书(PEM 格式):粘贴证书内容
  7. 点击"保存"

8.3 强制 HTTPS

  1. 进入"网站"
  2. 找到要配置的网站
  3. 点击"设置"
  4. 选择"SSL"
  5. 勾选"强制 HTTPS"
  6. 点击"保存"

9. Docker 配置 HTTPS

9.1 挂载证书

bash
# 创建证书目录
sudo mkdir -p /etc/nginx/ssl

# 复制证书
sudo cp /etc/letsencrypt/live/fanyi.example.com/fullchain.pem /etc/nginx/ssl/
sudo cp /etc/letsencrypt/live/fanyi.example.com/privkey.pem /etc/nginx/ssl/

# 设置权限
sudo chmod 644 /etc/nginx/ssl/fullchain.pem
sudo chmod 600 /etc/nginx/ssl/privkey.pem

9.2 Docker Compose 配置

编辑 docker-compose.yml

yaml
version: '3.6'

services:
  nginx:
    image: nginx:alpine
    container_name: fanyi-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - /etc/nginx/ssl:/etc/nginx/ssl:ro
    restart: always
    networks:
      - fanyiyun_default

networks:
  fanyiyun_default:
    external: true

9.3 Nginx 配置

编辑 nginx.conf

nginx
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    sendfile on;
    keepalive_timeout 65;

    # HTTPS 配置
    server {
        listen 80;
        server_name fanyi.example.com www.fanyi.example.com;
        
        # 重定向到 HTTPS
        return 301 https://$server_name$request_uri;
    }

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

        # 证书配置
        ssl_certificate /etc/nginx/ssl/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/privkey.pem;

        # SSL 协议配置
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        # SSL 会话缓存
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;

        # HSTS
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

        # 安全头
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;

        # 反向代理配置
        location / {
            proxy_pass http://fanyi-gateway:48080;
            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;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Port $server_port;
        }
    }
}

9.4 启动容器

bash
# 启动容器
docker-compose up -d

# 查看日志
docker-compose logs -f nginx

10. Spring Boot 配置 HTTPS

10.1 生成自签名证书

bash
# 生成证书
keytool -genkeypair -alias fanyi -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore fanyi.p12 -validity 365

# 查看证书
keytool -list -v -keystore fanyi.p12 -storetype PKCS12

10.2 配置 application.yml

编辑 application.yml

yaml
server:
  port: 48080
  ssl:
    enabled: true
    key-store: classpath:fanyi.p12
    key-store-password: your-password
    key-store-type: PKCS12
    key-alias: fanyi

10.3 配置 HTTP 重定向到 HTTPS

创建配置类:

java
@Configuration
public class HttpsConfig {

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(redirectConnector());
        return tomcat;
    }

    private Connector redirectConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8080);
        connector.setSecure(false);
        connector.setRedirectPort(48080);
        return connector;
    }
}

11. 证书管理

11.1 查看证书信息

bash
# 查看证书详细信息
openssl x509 -in /etc/letsencrypt/live/fanyi.example.com/cert.pem -text -noout

# 查看证书有效期
openssl x509 -in /etc/letsencrypt/live/fanyi.example.com/cert.pem -noout -dates

# 查看证书颁发者
openssl x509 -in /etc/letsencrypt/live/fanyi.example.com/cert.pem -noout -issuer

11.2 验证证书

bash
# 验证证书链
openssl s_client -connect fanyi.example.com:443 -showcerts

# 验证证书和私钥是否匹配
openssl x509 -noout -modulus -in /etc/letsencrypt/live/fanyi.example.com/cert.pem | openssl md5
openssl rsa -noout -modulus -in /etc/letsencrypt/live/fanyi.example.com/privkey.pem | openssl md5

11.3 导出证书

bash
# 导出证书为 PEM 格式
openssl x509 -in /etc/letsencrypt/live/fanyi.example.com/cert.pem -out fanyi.crt

# 导出证书为 DER 格式
openssl x509 -in /etc/letsencrypt/live/fanyi.example.com/cert.pem -outform DER -out fanyi.der

11.4 转换证书格式

bash
# PEM 转 PKCS12
openssl pkcs12 -export -out fanyi.p12 -inkey privkey.pem -in cert.pem -certfile chain.pem

# PKCS12 转 PEM
openssl pkcs12 -in fanyi.p12 -out fanyi.pem -nodes

# DER 转 PEM
openssl x509 -inform der -in fanyi.der -out fanyi.pem

12. 安全最佳实践

12.1 使用强加密套件

nginx
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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';

12.2 启用 HSTS

nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

12.3 配置安全头

nginx
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;

12.4 禁用弱协议

nginx
ssl_protocols TLSv1.2 TLSv1.3;

12.5 保护私钥

bash
# 设置私钥权限
chmod 600 /etc/letsencrypt/live/fanyi.example.com/privkey.pem

# 设置证书目录权限
chmod 755 /etc/letsencrypt/live/fanyi.example.com

13. 常见问题

13.1 证书验证失败

问题:浏览器提示证书无效

解决方案

  1. 检查证书是否过期
  2. 检查域名是否匹配
  3. 检查证书链是否完整
  4. 检查系统时间是否正确

13.2 混合内容警告

问题:HTTPS 页面包含 HTTP 资源

解决方案

  1. 将所有 HTTP 资源改为 HTTPS
  2. 使用相对路径
  3. 使用 CSP 策略

13.3 证书续期失败

问题:Let's Encrypt 证书续期失败

解决方案

  1. 检查域名解析是否正确
  2. 检查防火墙是否开放 80 端口
  3. 检查 Web 服务器是否正常运行
  4. 手动测试续期:certbot renew --dry-run

13.4 性能问题

问题:HTTPS 访问速度慢

解决方案

  1. 启用 HTTP/2
  2. 启用 SSL 会话缓存
  3. 使用 OCSP Stapling
  4. 优化证书链

13.5 兼容性问题

问题:旧浏览器无法访问

解决方案

  1. 启用 TLS 1.2 和 TLS 1.3
  2. 使用兼容的加密套件
  3. 更新浏览器或系统

14. 性能优化

14.1 启用 HTTP/2

nginx
listen 443 ssl http2;

14.2 配置 SSL 会话缓存

nginx
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

14.3 启用 OCSP Stapling

nginx
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/fanyi.example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

14.4 优化证书链

nginx
ssl_certificate /etc/letsencrypt/live/fanyi.example.com/fullchain.pem;

15. 监控和告警

15.1 证书过期监控

bash
# 检查证书过期时间
echo | openssl s_client -servername fanyi.example.com -connect fanyi.example.com:443 2>/dev/null | openssl x509 -noout -dates

15.2 配置告警

使用监控工具(如 Zabbix、Prometheus)监控证书过期时间,提前告警。

16. 注意事项

  1. 证书有效期:Let's Encrypt 证书有效期为 90 天,需要定期续期
  2. 私钥保护:妥善保管私钥,不要泄露
  3. 备份证书:定期备份证书和私钥
  4. 测试续期:定期测试证书续期
  5. 监控过期:监控证书过期时间,提前续期
  6. 安全配置:使用强加密套件,禁用弱协议
  7. 性能优化:启用 HTTP/2、SSL 会话缓存等优化
  8. 兼容性:考虑旧浏览器兼容性

17. 相关文档