如何设置Nginx的HSTS?

Nginx

1 基础知识

1.1 HTTPS的概念

– HTTPS是保护网站流量的重要措施(使用SSL或TLS加密HTTP)
– HTTPS使攻击者很难拦截、修改或伪造用户与Web服务器之间的流量

1.2 HSTS的概念

– 当用户用不带“https://”Web域名或用带“http://”的连接时,网络使用非加密连接
– 即使网站立即回发重定向用户到HTTPS连接,但优越的攻击者可以发起中间人(MITM)攻击来拦截HTTP请求
– HSTS能通过指示浏览器只能使用HTTPS访问域来避免潜在的威胁
– 浏览器收到HSTS声明后,即使用户使用HTTP连接也会被升级为HTTPS连接

1.3 HSTS的工作原理

Web站点通过发送如下HTTP响应头发布HSTS声明,

Strict-Transport-Security: max-age=31536000

– 浏览器取得该声明后,知悉该域只能使用HTTPS(SSL或TLS)建立连接
– 浏览器将根据max-age设定的时间内缓存该声明(通常为3153600秒,大约一年)
– 如果以下可选项开启,则声明子域也同样适用,声明范例如下,

Strict-Transport-Security: max-age=31536000; includeSubDomains

例如,在以下域名下声明HSTS,

https://example.com

则以下域名也同样生效,

https://www.example.com

1.4 HSTS网站无保护的情况

– 从未访问过该网站
– 最近重新安装过操作系统
– 最近重新安装过浏览器
– 切换到新的浏览器
– 切换到新的设备(例如手机或平板)
– 删除浏览器的缓存
– 最近没有访问网站并且max-age声明的时间已过期
注:HSTS并非完美解决方案,以上情况仍然容易受到攻击

1.5 Nginx的HSTS配置

server {
    listen 443 ssl;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    #...
    location /servlet {
        add_header X-Served-By "My Servlet Handler";
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        proxy_pass http://localhost:8080;
    }
}

需要注意的是,
– Nginx 1.7.5或Nginx Plus R5以下版本不支持“always”参数
– 如果局部“location”声明“add_header”指令,则“server”部分的声明会被覆盖
– HSTS很难撤销,首次声明建议先配置非常短的“max-age”超时声明先试用没有问题后再设置长时间的声明
另外,更加建议配合强制HTTP强制到HTTPS的方式强化HSTS声明,范例如下,

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    # Discourage deep links by using a permanent redirect to home page of HTTPS site
    return 301 https://$host;

    # Alternatively, redirect all HTTP links to the matching HTTPS page 
    # return 301 https://$host$request_uri;
}

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

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

2 最佳实践

2.1 WordPress基础配置

笔者环境配置如下,

如何用Nginx反向代理WordPress?

2.2 HTTP强制HTTPS

cat /etc/nginx/conf.d/www.cmdschool.org_80.conf

加入如下配置,

server {
    listen       80;
    server_name  www.cmdschool.org;
    #...
    return 301 https://$host$request_uri;
}

2.3 HTTPS中声明HSTS配置

vim /etc/nginx/conf.d/www.cmdschool.org_443.conf

加入如下配置,

server {
    listen 443 ssl;
    proxy_hide_header Strict-Transport-Security;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    #...
}

配置文件修改后,使用如下命令重载使配置生效,

systemctl reload nginx.service

2.4 确认配置生效


如上图所示,
按下【F12】
选择【Network】->【All】->【www.cmdschool.org】->【Headers】->【Strict-Transport-security】即可看到设置

参阅文档
==================
https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/

没有评论

发表回复

Nginx
如何解决https请求不安全http页被阻止问题?

1 前言 一个问题,一篇文章,一出故事。 笔者最近代理公司应用,发现https的页面有请求不安全的h …

Nginx
如何Nginx代理上游的子项目或文件夹?

1 前言 一个问题,一篇文章,一出故事。 笔者接到任务需要把Tomcat的其中一个应用号使用Ngin …

Nginx
如何安装部署RHEL 9 Nignx?

1 前言 一个问题,一篇文章,一出故事。 笔者需要基于RHEL 9部署Nginx环境,于是整理此文。 …