13 10 月 2026

装了 SSL 证书只是第一步。真正安全的 HTTPS 站点还要做三件事:HTTP 强制跳转 HTTPS、全站 HSTS、配齐安全响应头。

这篇把这几项配置一次讲清,全部 Nginx 配置可直接抄。改完用安全检测工具一测,评分从 C 到 A+。

需要云服务器可以看看财富云计算:NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,一键开服面板,主流游戏快速部署。

一、先确认证书装好了

本文假设你已经用 Let's Encrypt 或厂商证书装好了 HTTPS(没装的看SSL 证书与 HTTPS 部署)。

验证:

# 看证书是否有效
curl -vI https://你的域名 2>&1 | grep -E "subject:|expire|SSL connection"

# 在线检测(目标 A 以上)
# www.ssllabs.com/ssltest

能看到证书信息、没有过期警告,继续往下。

二、HTTP 强制跳转 HTTPS

用户访问 http://你的域名,必须 301 跳到 https://你的域名。否则:

  • 用户可能停在 HTTP 明文站点,传输内容裸奔
  • SEO 上 http 和 https 会被当成两个站,权重分散

Nginx 配置

# 方案1: 独立 server 块(推荐,清晰)
server {
    listen 80;
    listen [::]:80;
    server_name 你的域名 www.你的域名;
    
    # ACME 证书续期验证要放行(如果用 Let's Encrypt)
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    
    # 其余全部跳转
    location / {
        return 301 https://$host$request_uri;
    }
}

# 方案2: 在 HTTPS server 块里加(适合只有一个站点)
# if 写法性能略差,能用方案1 就别用
# if ($scheme = http) { return 301 https://$host$request_uri; }

$host 和 $server_name 的区别:$host 用请求里的域名(适配多域名),$server_name 用配置里的。跳转场景用 $host 更稳。

301 还是 302:用 301(永久跳转),浏览器会记住,之后直接访问 HTTPS,SEO 权重也能传递。

验证

curl -I http://你的域名
# 应返回: HTTP/1.1 301 Moved Permanently
#         Location: https://你的域名/

三、HSTS:让浏览器只认 HTTPS

HSTS(HTTP Strict Transport Security)是响应头,告诉浏览器「这个站以后只准用 HTTPS,别试 HTTP 了」。好处:彻底杜绝 SSL 剥离攻击,用户输错 http:// 也会被浏览器内部转成 HTTPS。

配置

server {
    listen 443 ssl http2;
    server_name 你的域名;
    
    # HSTS: 一年,含子域名,允许预加载
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    
    # ... 其余 SSL 配置
}

参数说明:

参数作用
max-age=31536000一年内浏览器强制 HTTPS
includeSubDomains所有子域名也生效
preload申请加入浏览器内置 HSTS 列表

always 不能漏:Nginx 的 add_header 默认只在 2xx/3xx 响应添加,4xx/5xx 会丢。加 always 保证所有响应都带。

提交预加载列表(可选但推荐)

去 hstspreload.org 填域名提交。加入后 Chrome/Firefox 内置列表,首次访问就是 HTTPS,连第一次明文请求都不会发。

⚠️ 警告:preload 基本不可逆(从列表移除要几个月)。确定全站(含所有子域名)永远支持 HTTPS 再提交。

HSTS 的风险

配了 HSTS 后,如果证书过期或配置错误,用户浏览器会直接拒绝访问,连「不安全继续访问」的选项都没有。所以:

  • 证书续期必须可靠(用自动续期)
  • 先在短 max-age(如 300 秒)测试,稳定了再加到一年
  • 子域名如果还跑 HTTP,别加 includeSubDomains

四、安全响应头全家桶

现代浏览器支持一堆安全响应头,配上后安全评分飙升:

server {
    listen 443 ssl http2;
    server_name 你的域名;

    # ===== 安全响应头 =====
    
    # HSTS(上面讲过)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    # 防止点击劫持: 只允许同源 iframe 嵌入
    add_header X-Frame-Options "SAMEORIGIN" always;
    
    # 防止 MIME 类型嗅探
    add_header X-Content-Type-Options "nosniff" always;
    
    # XSS 过滤器(老浏览器)
    add_header X-XSS-Protection "1; mode=block" always;
    
    # 引荐来源: 跨站不传完整 URL,保护隐私
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # 权限策略: 禁掉用不到的能力
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()" always;
    
    # 内容安全策略(见下文,按站点调整)
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:" always;
    
    # 隐藏版本信息
    server_tokens off;
    
    # ... SSL 配置和 location
}

逐个说明

X-Frame-Options:防点击劫持。你的网页不能被别人用 iframe 嵌进去做钓鱼。需要被合法嵌入(如分享卡片)的用 ALLOW-FROM uri 或 CSP 的 frame-ancestors。

X-Content-Type-Options: nosniff:防浏览器猜测文件类型。没这个头,浏览器可能把上传的文本当 HTML 执行,是 XSS 的温床。

Referrer-Policy:控制跳转时泄露多少来源信息。strict-origin-when-cross-origin 是现代默认值,同源传完整、跨站只传域名。

Permissions-Policy:禁用摄像头、麦克风、定位等。博客用不到全禁,省得被恶意脚本利用。

CSP(内容安全策略):最强但也最容易配错的一个。它规定页面能加载哪些资源:

default-src 'self'                    # 默认只许同源
script-src 'self' 'unsafe-inline'     # 脚本:同源 + 内联
style-src 'self' 'unsafe-inline'      # 样式:同源 + 内联
img-src 'self' data: https:           # 图片:同源 + dataURI + 任意HTTPS
font-src 'self' data:                 # 字体
connect-src 'self'                    # XHR/fetch
frame-ancestors 'none'                # 禁止被嵌入(替代X-Frame-Options)

上线 CSP 的正确姿势:先用 Content-Security-Policy-Report-Only 头跑几天,看浏览器控制台报哪些违规,把合法资源加进白名单,确认不误伤后再改成强制。

# 报告模式:只记录不拦截
add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report" always;

五、SSL 配置也要跟上

响应头之外,SSL 参数本身要过硬:

server {
    listen 443 ssl http2;
    server_name 你的域名;

    ssl_certificate     /etc/letsencrypt/live/你的域名/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/你的域名/privkey.pem;
    
    # 只用 TLS 1.2+(1.0/1.1 已废弃)
    ssl_protocols TLSv1.2 TLSv1.3;
    
    # 加密套件:TLS1.3 和 TLS1.2 分开配
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;    # TLS1.3 推荐 off,让客户端选
    
    # 会话复用,减少握手
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;          # 除非配好轮换,否则关
    
    # OCSP Stapling:加速证书验证
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/你的域名/chain.pem;
    resolver 8.8.8.8 223.5.5.5 valid=300s;
    resolver_timeout 5s;
}

改完必须重载并测试,SSL 配错直接全站打不开:

nginx -t && systemctl reload nginx

六、验收:用工具打分

# 1. 响应头检查
curl -sI https://你的域名 | grep -iE "strict-transport|x-frame|x-content|referrer|content-security"

# 2. 在线评分(目标 A+)
# - SSL Labs:  www.ssllabs.com/ssltest
# - 安全头:    securityheaders.com
# - 综合:      observatory.mozilla.org

必须全绿的项:

  • HTTP 有 301 跳转
  • HSTS 头存在且 max-age ≥ 6 个月
  • X-Frame-Options 或 CSP frame-ancestors
  • X-Content-Type-Options: nosniff
  • Referrer-Policy 存在
  • TLS 1.2+ only,无弱套件

七、常见问题

Q:加了 HSTS 后本地测试打不开了?
Chrome 地址栏输 chrome://net-internals/#hsts,拉到最下 Delete 掉域名再访问。

Q:CSP 把统计脚本/广告拦了?
把脚本域名加进 script-src,比如 script-src 'self' 'unsafe-inline' https://www.google-analytics.com。先用 Report-Only 模式收集违规再配。

Q:add_header 在 location 里失效了?
Nginx 的 add_header 会继承覆盖——location 里新加一个,server 级的全丢。把安全头抽出来写进单独文件,每个 location include:

# /etc/nginx/snippets/security-headers.conf
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
# ... 其余头

# server 和 location 里都 include
include snippets/security-headers.conf;

Q:HTTP/2 要单独开吗?
Nginx 1.25+ 用 http2 on; 指令,老版本写在 listen 443 ssl http2;。确认已编译 http_v2 模块。

Q:HTTP/3 要上吗?
Nginx 1.25+ 编译 quic 后可以开 listen 443 quic reuseport;,弱网环境下提升明显。生产上先小流量试,别当第一个吃螃蟹的。

小结

HTTPS 安全配置三步走:301 强制跳转 → HSTS 锁定 → 安全响应头全家桶。配置文件就几十行,半小时搞定,之后安全评分 A+,再也不用管用户输的是 http 还是 https。

更多网站安全内容见财富云计算知识库:防火墙配置、Web 漏洞防护、安全基线、被入侵应急全系列。需要云服务器可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上。

延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:企业邮箱与邮件发送服务搭建:SMTP 配置与防垃圾箱
  2. 下一篇:Nginx 限速与 CC 防护进阶配置:不买高防也能扛
发表评论 5