HTTPS(HTTP Secure)是HTTP的安全版本,在HTTP的基础上加入了SSL/TLS加密层。使用HTTPS的网站,数据在传输过程中是加密的,第三方无法窃取或篡改,能有效保护用户的隐私和数据安全。

以前,HTTPS主要用于银行、电商、支付等对安全要求高的网站。但近年来,HTTPS已经成为所有网站的标配。原因有几个:

第一,搜索引擎的推动。谷歌从2014年开始把HTTPS作为搜索排名信号,使用HTTPS的网站在搜索排名中有优势。百度也在2015年开始鼓励网站使用HTTPS。

第二,浏览器的推动。Chrome、Firefox等浏览器开始把HTTP网站标记为"不安全",用户看到"不安全"的标记会对网站产生不信任。

第三,安全需求。随着网络安全问题日益严重,用户对隐私和数据安全的要求越来越高。使用HTTPS能保护用户的账号密码、个人信息、交易数据等不被窃取和篡改。

第四,性能优势。HTTP/2协议只支持HTTPS,HTTP/2比HTTP/1.1性能更好,支持多路复用、头部压缩、服务器推送等特性。使用HTTPS可以升级到HTTP/2,提升网站性能。

以前,HTTPS证书很贵,一年要几百到几千块钱,配置也比较复杂,所以很多个人网站和小公司不愿意用。但现在有了免费的Let's Encrypt证书,而且配置工具越来越成熟,HTTPS的门槛已经很低了。今天就来分享从证书申请到Nginx部署的完整流程。

证书类型和选择

在申请证书之前,先了解一下SSL证书的类型。

按验证级别分,SSL证书主要有三种:

  1. DV(Domain Validation,域名验证):只验证域名所有权,不验证组织身份。申请简单,几分钟就能签发,价格便宜(甚至免费),但浏览器地址栏只显示锁图标,不显示组织名称。适合个人网站、博客、小型企业网站。
  1. OV(Organization Validation,组织验证):除了验证域名所有权,还要验证申请组织的真实身份。审核比较严格,需要提供营业执照等证明文件,审核时间几天到几周。浏览器地址栏显示锁图标,点击可以查看组织信息。适合企业网站、电商网站。
  1. EV(Extended Validation,扩展验证):最高级别的验证,审核最严格,需要验证域名所有权、组织身份、经营状况等。审核时间长,价格昂贵。浏览器地址栏会显示绿色的组织名称,信任度最高。适合银行、金融、大型电商等对信任度要求高的网站。

对于个人博客和小型企业网站,DV证书就足够了。Let's Encrypt提供的就是免费的DV证书,完全能满足需求。

按域名数量分,证书还有:

  • 单域名证书:只保护一个域名(如example.com,不包括www.example.com)。
  • 通配符证书:保护一个域名及其所有子域名(如*.example.com,包括www.example.com、blog.example.com等)。
  • 多域名证书:保护多个不同的域名。

Let's Encrypt支持单域名证书和多域名证书(SAN证书),一个证书可以包含多个域名(最多100个)。通配符证书Let's Encrypt也支持(需要用DNS验证方式)。

申请Let's Encrypt证书

Let's Encrypt是一个免费、自动化、开放的证书颁发机构(CA),由互联网安全研究小组(ISRG)运营。它的目标是让所有网站都能免费使用HTTPS。

申请Let's Encrypt证书,推荐使用官方的Certbot工具,它能自动完成证书申请、安装、续期等操作。

首先,安装Certbot。以Ubuntu为例:

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx

然后,用Certbot申请证书并自动配置Nginx:

sudo certbot --nginx -d example.com -d www.example.com

这条命令会做以下事情:

  1. 验证域名所有权(通过在网站根目录放置验证文件,或自动配置Nginx的验证路径)
  2. 申请证书,证书包含example.com和www.example.com两个域名
  3. 自动配置Nginx,添加SSL配置
  4. 设置自动续期(Let's Encrypt证书有效期90天,Certbot会自动续期)

运行命令后,Certbot会问你几个问题:

  • 输入邮箱地址(用于紧急通知和找回密钥)
  • 同意服务条款
  • 是否愿意分享邮箱给电子前沿基金会(可选)
  • 是否将HTTP流量重定向到HTTPS(建议选2,重定向)

完成后,证书就申请好了,Nginx也配置好了。重启Nginx后,网站就可以用HTTPS访问了。

如果不想用Certbot的自动配置,也可以只申请证书,自己手动配置Nginx:

sudo certbot certonly --nginx -d example.com -d www.example.com

这样只会申请证书,不会修改Nginx配置。证书文件会保存在/etc/letsencrypt/live/example.com/目录下,包括:

  • cert.pem:服务器证书
  • chain.pem:中间证书
  • fullchain.pem:服务器证书+中间证书(Nginx用这个)
  • privkey.pem:私钥

Nginx配置HTTPS

如果是手动配置,Nginx的HTTPS配置大概是这样:

# HTTP跳转到HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS配置
server {
    listen 443 ssl;
    server_name example.com www.example.com;

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

    # SSL协议和加密套件
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

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

    # 安全头
    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;

    # 网站根目录和其他配置
    root /var/www/html;
    index index.html index.php;

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

    # PHP处理
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

逐行解释关键配置:

  • listen 443 ssl:监听443端口,开启SSL。
  • sslcertificatesslcertificate_key:指定证书和私钥的路径。
  • ssl_protocols:指定支持的SSL/TLS协议版本。建议禁用SSLv2和SSLv3(有安全漏洞),只支持TLSv1及以上。
  • ssl_ciphers:指定加密套件,禁用不安全的套件(如aNULL、MD5)。
  • sslpreferserver_ciphers on:优先使用服务器端的加密套件,而不是客户端的。
  • sslsessioncachesslsessiontimeout:SSL会话缓存,减少重复握手的开销,提升性能。
  • Strict-Transport-Security(HSTS):告诉浏览器以后都用HTTPS访问这个网站,即使输入的是HTTP也自动转HTTPS。max-age是有效期(秒),includeSubDomains表示包括子域名。
  • X-Frame-Options:防止网站被嵌入到iframe中,避免点击劫持攻击。
  • X-Content-Type-Options:防止浏览器猜测MIME类型,避免某些攻击。

配置完成后,测试Nginx配置是否正确:

sudo nginx -t

如果显示"test is successful",就重启Nginx:

sudo service nginx restart

然后访问https://example.com,看看是否能正常访问,浏览器地址栏是否显示锁图标。

证书续期

Let's Encrypt证书的有效期是90天,需要定期续期。Certbot会自动设置定时任务来续期证书,不需要手动操作。可以用以下命令测试续期是否正常:

sudo certbot renew --dry-run

如果显示成功,说明自动续期配置正常。Certbot会在证书到期前30天自动续期,不需要人工干预。

如果想手动续期,可以运行:

sudo certbot renew

续期后需要重启Nginx才能生效:

sudo service nginx restart

可以把续期和重启命令写到一个脚本里,用cron定时执行:

#!/bin/bash
certbot renew --quiet
service nginx restart

常见问题

第一,证书申请失败。最常见的原因是域名验证失败。Certbot默认用HTTP验证方式,需要能通过HTTP访问到域名。如果域名还没解析到服务器,或者Nginx配置有问题,就会验证失败。解决方法:确保域名已经正确解析到服务器,确保80端口能正常访问,确保网站根目录配置正确。如果HTTP验证不行,可以用DNS验证方式,需要在域名DNS管理处添加一条TXT记录。

第二,混合内容警告。网站升级到HTTPS后,如果页面里有HTTP的资源(如图片、CSS、JS),浏览器会提示"混合内容"警告,地址栏的锁图标可能会变成黄色感叹号。解决方法:把页面里所有HTTP资源的链接改成HTTPS,或者用协议相对路径(//example.com/...)。

第三,性能问题。HTTPS比HTTP多了SSL握手的开销,首次连接会慢一些。但通过SSL会话缓存、OCSP Stapling、HTTP/2等优化,可以把性能影响降到最低。而且现在的服务器性能都很强,HTTPS的性能开销已经很小了,用户几乎感知不到。

第四,证书不被信任。Let's Encrypt的根证书已经被所有主流浏览器和操作系统信任,不会有不被信任的问题。但如果是很老的浏览器或操作系统(如Windows XP的IE),可能会有不被信任的问题。不过这些老系统的用户已经很少了,可以忽略。

总结

HTTPS已经成为网站的标配,而且现在配置HTTPS的门槛已经很低了——免费的Let's Encrypt证书、自动化的Certbot工具、简单的Nginx配置。如果你还在使用HTTP,赶紧升级到HTTPS吧,这不仅是为了安全,也是为了SEO、用户信任和网站性能。

希望这篇教程能帮到正在配置HTTPS的你。