nginx上ssl配置

发布时间 2023-11-09 11:47:17作者: 五官一体即忢

准备

申请证书,取得 ***.crt***.key文件。
在nginx目录下新建ssl.conf文件夹,并将上述两个文件放入。
开放443端口。

ssl配置

server {
    listen 80;
    listen 443 ssl;
    server_name  wiki.test.site;
    
    ssl_certificate ../ssl.conf/***.crt;
    ssl_certificate_key ../ssl.conf/***.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #协议
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
    ssl_prefer_server_ciphers on;
    
    # 其它配置
    ****
    ****
}

以上配置可以同时以http与https两种方式访问站点。

升级到https后,页面内的http请求被浏览器拦截

无论以http还是https访问站点,最终页面上发起的请求都将变成https:

server {
    ***
    add_header Content-Security-Policy upgrade-insecure-requests;
}

只有以https访问时,发起的请求才变成https:

server {
    ***
    location / {
      ****
     # 如果访问的协议是https,响应头中加上下面语句
         if ($scheme = https) {
             add_header Content-Security-Policy upgrade-insecure-requests;
         }
     ****
    }
}

注意,add_header外面有if的情况下不能放在server中,只能放在location区域内。

升级到https后,websocket无法连接

server {
    ****
    location /websocket {
        proxy_pass http://127.0.0.1:8888; #服务转发
        # WebSocket support (nginx 1.4)
        proxy_http_version 1.1; #协议版本1.1
        proxy_set_header Connection "upgrade"; #协议升级
        proxy_set_header Upgrade $http_upgrade; #引用协议升级的类型,也就是这里的websocket协议
        proxy_read_timeout 3m; #读取超时时间设置为3分钟,默认60秒
    }
    ****
}

页面http强制转https

全站转https

server {
    listen 80;
    server_name wiki.test.site;
    rewrite ^(.*) https://$host$1 permanent;
}

server {
    listen 443;
    ssl on;
    server_name wiki.test.site;
    ssl_certificate ../ssl.conf/***.crt;
    ssl_certificate_key ../ssl.conf/***.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #协议
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
    ssl_prefer_server_ciphers on;
  
    add_header Content-Security-Policy upgrade-insecure-requests;  
    ****
    **** 
}

一级域名转https

server {
    ****
    set $rewrite_url "${scheme}://${host}${request_uri}";
    if ($rewrite_url = "https://wiki.test.site/") {
        rewrite ^(.*) https://wiki.test.site break;
    }
    ****
}

指定项目转https

server {
    ****
    location /app {
        ****
        if ($scheme = http) {
        rewrite ^(.*)$ https://$host$1 break;
    }
        ****
    }
    ****
}

指定页面转https

匹配app目录下product/list.html页面和/center/目录下的页面跳转https

server {
    ****
    location /app {
        ****
        # 大小写不敏感
        if ($request_uri ~* (.*)(product/list\.html|/center/).*) {
            rewrite ^(.*)$ https://$host$1 break;
        }
        ****
    }
    ****
}

代理非本站页面转https

server {
    ****
    # 使用virtual虚拟目录 代理a.test.com
    location /virtual/ {
        proxy_set_header Host $proxy_host; 
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://a.test.com/;
        #subs_filter 'a.test.com' 'wiki.test.site';
    }
    set $flag_virtual "0";
    
    # 判断请求是否从 a.test.com/virtual 这个地址发出的
    if ($http_referer ~* "a.test.com/virtual/") {
        set $flag_virtual "${flag_virtual}1";
    }

    # 判断页面是否已经包含 virtual 这个虚拟目录了
    if ($request_uri !~* "virtual/") {
        set $flag_virtual "${flag_virtual}2";
    }

    # 判断请求类型
    if ($request_method != GET) {
        set $flag_virtual "${flag_virtual}3";
    }

    # 将 get 类型的请求指向 virtual 这个虚拟目录
    if ($flag_virtual = "012") {
        rewrite ^(.*) $scheme://$host/virtual$1 break;
    }

    # 状态码307表示请求方法不变,页面会再次以post、delete、put发起请求
    if ($flag_virtual = "0123") {
        return 307 $scheme://$host/virtual$request_uri;
    }
    ****
}

注1:subs_filter指定文本替换,可以将页面返回的非代理域名替换成代理域名。
注2:官网windows版本的nginx是不带subs_filter模块的,需要自行编译或另外找替代版本。

相关问题

证书过期更换依然是老证书的问题: 如果服务器上证书已经是最新的, 检查域名运营商那边CDN云防护是否开启HTTPS的配置,如果开启了要更新CDN上的证书。

资料

1.让页面中的http请求转为https请求