V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
Bac2
V2EX  ›  NGINX

请教一个 nginx rewrite 问题,www->non-www 强制 https

  •  
  •   Bac2 · 2016-02-07 10:24:01 +08:00 via Android · 5190 次点击
    这是一个创建于 3241 天前的主题,其中的信息可能已经有所发展或是发生改变。
    跳转需求是这样的
    强制所有连接走 https
    且带 www301 到不带 www
    我的配置
    server {
    listen 80;
    server_name abc.com www.abc.com;
    return 301 https://abc.com$request_uri;
    }
    server {
    listen 443 ssl;
    server_name abc.com;
    ssl_certificate ***;
    ssl_certificate_key ***;
    *****
    }

    现在的状态是
    http://www.abc.com
    http://abc.com
    跳转到 https://abc.com
    可是 https://www.abc.com 不跳转
    第一个 server 内加 listen 443 ssl;出错(ノ=Д=)ノ┻━┻
    第 1 条附言  ·  2016-02-07 10:58:35 +08:00
    (ノ=Д=)ノ┻━┻我还是去直接 CNAME 吧
    哪位大大能想出来啊啊(虽然很简单,但是我还是不会-_-||)
    第 2 条附言  ·  2016-02-07 11:47:12 +08:00
    感谢 @imlonghao 现在全部正常跳转到 https://abc.com
    配置:
    server {
    listen 80;
    server_name abc.com www.abc.com;
    return 301 https://abc.com$request_uri;
    }
    server {
    listen 443 ssl;
    server_name www.abc.com;
    ssl__certificate ***;
    ssl_certificate_key ***;
    ***;
    return 301 https://abc.com$request_uri;
    }
    server {
    listen 443 ssl;
    server_name abc.com;
    ssl__certificate ***;
    ssl_certificate_key ***;
    ***;
    }
    搞不懂为啥两个 443 server 块合在一起就会出错。。。
    28 条回复    2016-02-09 07:26:56 +08:00
    rainy3636
        1
    rainy3636  
       2016-02-07 10:29:06 +08:00 via Android
    DNS 里把 www cname 到 abc.com
    Bac2
        2
    Bac2  
    OP
       2016-02-07 10:35:09 +08:00 via Android
    @rainy3636 让我冷静一下(#゚Д゚)我把 DNS 这事忘了,从昨天折腾到现在了→_→
    现在的问题是如何用 nginx rewrite 实现,毕竟都折腾那么长时间了≥﹏≤
    secondwtq
        3
    secondwtq  
       2016-02-07 10:36:44 +08:00
    server {
    listen 80;
    listen 443 ssl;

    server_name www.abc.com;
    ssl_certificate ***;
    ssl_certificate_key ***;

    return 301 https://abc.com$request_uri;
    }
    server {
    listen 80;

    server_name abc.com

    return 301 https://abc.com$request_uri;
    }

    这样试试呢
    babytomas
        4
    babytomas  
       2016-02-07 10:42:24 +08:00 via Android
    给你一个思路啊,在 nginx.conf 最底部加一个 listen 80 ,但是不加 server_name ,把这个层全部重定向 https://abc.com

    然后不要把 www.abc.com 加入到其他配置的 server_name
    Bac2
        5
    Bac2  
    OP
       2016-02-07 10:48:49 +08:00 via Android
    @secondwtq 还是不行→_→
    ys0290
        6
    ys0290  
       2016-02-07 10:51:14 +08:00 via iPhone
    你缺一个监听 443 www 的
    Bac2
        7
    Bac2  
    OP
       2016-02-07 10:51:57 +08:00 via Android
    @babytomas https://www.*依旧不跳转 @_@
    Bac2
        8
    Bac2  
    OP
       2016-02-07 10:56:06 +08:00 via Android
    @ys0290 网页可能暂时无法连接,或者它已永久性地移动到了新网址。
    ys0290
        9
    ys0290  
       2016-02-07 10:59:02 +08:00 via iPhone
    看 log 呢?
    jalena
        10
    jalena  
       2016-02-07 11:01:13 +08:00
    ```sh
    if ($host != 'www.abc.com.cn' ) {
    rewrite ^/(.*)$ https://www.abc.com.cn/$1 permanent;
    }
    ```
    imlonghao
        11
    imlonghao  
       2016-02-07 11:11:58 +08:00 via Android
    @rainy3636 说 CNAME 的你真的是认真的么?
    imlonghao
        12
    imlonghao  
       2016-02-07 11:13:50 +08:00 via Android
    独立做一个 www.abc.com 的跳转到 abc.com
    imlonghao
        13
    imlonghao  
       2016-02-07 11:15:21 +08:00 via Android   ❤️ 1
    server {
    listen 80;
    server_name abc.com www.abc.com;
    return 301 https://abc.com$request_uri;
    }
    server {
    listen 443 ssl;
    server_name www.abc.com;
    ssl_certificate ***;
    ssl_certificate_key ***;
    *****
    return 301 xxxxxxxxxx;
    }
    server {
    listen 443 ssl;
    server_name abc.com;
    ssl_certificate ***;
    ssl_certificate_key ***;
    *****
    }

    大概就是这个样子了...
    printempw
        14
    printempw  
       2016-02-07 11:16:38 +08:00 via Android
    if host name = www.xx 啊,等下贴配置
    printempw
        15
    printempw  
       2016-02-07 11:18:10 +08:00 via Android
    if ($host = www.prinzeugen.net) {
    rewrite ^/(.*)$ $scheme://prinzeugen.net/$1 permanent;
    }
    放 443 server 块里
    imlonghao
        16
    imlonghao  
       2016-02-07 11:22:08 +08:00 via Android
    winterbells
        17
    winterbells  
       2016-02-07 11:23:43 +08:00
    @rainy3636 应该是显性 DNS 转发吧,相当于直接 301 转发。 cnname 是解析到 ip 上
    Bac2
        18
    Bac2  
    OP
       2016-02-07 11:40:19 +08:00
    @imlonghao 在 www 的 server 块里加上完整的 ssl 配置成功了。。。
    shyling
        19
    shyling  
       2016-02-07 12:00:25 +08:00 via iPad
    表示我是借助 if 实现的:人访问强制 301 到 https ,蜘蛛访问强制 302 到 http
    shyling
        20
    shyling  
       2016-02-07 12:02:43 +08:00 via iPad
    try_files 在 core_module,if 在 rewrite_module 。并不是特别需要在意
    Andy1999
        21
    Andy1999  
       2016-02-07 15:00:53 +08:00
    https 301 先验证证书可信否 可信才会跳转 因此单独写一个 server
    Return2legacy
        22
    Return2legacy  
       2016-02-07 15:41:07 +08:00 via Android
    这两天刚好也在弄这个,但是在做 ssl 检测的时候不知道为什么会出很多问题,评分只有 C ,最后还是只做了 2 个 serve , 80 的 301 重定向,以及主 server 监听 443 ,回到 A+。
    just1
        23
    just1  
       2016-02-07 16:08:34 +08:00 via Android
    这不是最基本的 nginx 配置吗,上面你们在干嘛。。
    aprikyblue
        24
    aprikyblue  
       2016-02-07 16:33:29 +08:00
    @shyling
    咱只配了 HSTS ,发起 HTTP 仍然正常返回内容,但是包含 HSTS 头。
    识别出 HSTS 的浏览器 /蜘蛛,自己就转 HTTPS 了。
    不支持的继续 HTTP 也正常
    aprikyblue
        25
    aprikyblue  
       2016-02-07 16:38:37 +08:00
    > 第一个 server 内加 listen 443 ssl;
    如果这样,对于 SSL+abc.com ,它是要第一个 server 还是第二个 server 。。。

    > 搞不懂为啥两个 443 server 块合在一起就会出错。。。
    有个 301 呢。。怎么能合。。合起来 https://abc.com 不就无限 301 到自身了吗。。


    @just1
    1L 还来了一个 CNAME 也是醉。、。、
    shyling
        26
    shyling  
       2016-02-07 17:54:37 +08:00 via Android   ❤️ 1
    @aprikyblue hsts 仅仅在 https 连接时有效。我的意思是收到 http 请求里的 hsts 头会被忽视
    aprikyblue
        27
    aprikyblue  
       2016-02-07 19:37:19 +08:00
    @shyling 目前咱 http 和 https 都返回了 hsts 头,查了下的确是要在 https 里返回 ORZ 。。
    TaMud
        28
    TaMud  
       2016-02-09 07:26:56 +08:00
    nginx( https) -> pass -> nginx( http)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4985 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 01:20 · PVG 09:20 · LAX 17:20 · JFK 20:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.