【问题标题】:Redirect from www to non-www not working in Nginx with ssl on Ubuntu 16.04在 Ubuntu 16.04 上使用 ssl 从 www 重定向到非 www 在 Nginx 中不起作用
【发布时间】:2019-06-04 09:42:05
【问题描述】:

我在 DigitalOcean Ubuntu 16.04 droplet 上有一个 Meteor 1.6 站点,使用 Phusion Passenger 和 Nginx 进行部署。

我已经在我的服务器上设置了 ssl。

http://mysite 重定向到 https://mysite 并且该站点运行良好。

但是http://www.mysite 重定向到https://mysite 并且所有显示的是默认的 Nginx 页面“欢迎使用 nginx!”。

我已经按照教程并尝试了其他论坛帖子中的内容,但我找不到我的设置有什么问题。

DigitalOcean 控制面板中的 DNS 记录:

A   www.mysite.org directs to xxx.xx.xx.xx 3600
A   mysite.org directs to xxx.xx.xx.xx 1800

然后我按照本教程使用 Certbot 和 LetsEncrypt 配置了 ssl: https://www.digitalocean.com/community/tutorials/how-to-set-up-let-s-encrypt-with-nginx-server-blocks-on-ubuntu-16-04

我添加了一个服务器块,按照本教程将 www 重定向到普通域: https://www.digitalocean.com/community/tutorials/how-to-redirect-www-to-non-www-with-nginx-on-ubuntu-14-04

这是我的 nginx 配置:

sudo nano /etc/nginx/sites-enabled/mysite.conf

server {
    server_name mysite.org www.mysite.org;

    ...Meteor app config

    # added by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mysite.org/fullchain.pem$
    ssl_certificate_key /etc/letsencrypt/live/mysite.org/privkey.p$
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

# added by me
server {
    server_name www.mysite.org;
    return 301 $scheme://mysite.org$request_uri;
}

# added by Certbot
server {
    if ($host = mysite.org) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name mysite.org;
    return 404; # managed by Certbot
}

我尝试将此添加到我的服务器重定向块,但没有任何区别:

listen 80;
listen 443 ssl;

任何想法如何让 www.mysite -> mysite 重定向工作?谢谢!

更新:我在不同的应用程序上尝试了 flaixman 的答案,在不同的液滴上尝试了 Django 应用程序,并且成功了。但我仍然无法重定向到我的 Meteor 应用程序上工作。两个站点的 A 和 CNAME 记录配置方式相同。

这是我基于 flaixman 的回答的 Meteor 配置:

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

server {
    listen 443 ssl http2; #https of www*, 301 to right domain.
    server_name www.example.org;

    ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    return 301 https://example.org$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.org;

    ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    # Tell Nginx and Passenger where your app's 'public' directory is
    root /var/www/example/bundle/public;

    # Turn on Passenger
    passenger_enabled on;
    # Tell Passenger that your app is a Meteor app

    passenger_app_type node;
    passenger_startup_file main.js;

    # Tell your app where MongoDB is
    passenger_env_var MONGO_URL mongodb://localhost:27017/example;
    passenger_env_var MONGO_OPLOG_URL mongodb://localhost:27017/local;

    # Tell your app what its root URL is
    passenger_env_var ROOT_URL http://example.org;
}

在我的 nginx 错误日志 /var/log/nginx/error.log 中,我看到了这条消息:

2019/01/17 17:30:52 [warn] 7786#7786: conflicting server name "www.example.org" on 0.0.0.0:80, ignored
2019/01/17 17:30:52 [warn] 7786#7786: conflicting server name "www.example.org" on 0.0.0.0:443, ignored
2019/01/17 17:30:52 [warn] 7789#7789: conflicting server name "www.example.org" on 0.0.0.0:80, ignored
2019/01/17 17:30:52 [warn] 7789#7789: conflicting server name "www.example.org" on 0.0.0.0:443, ignored

我希望这意味着我的 conf 文件中有一个重复的监听指令,但我看不到任何指令?我用 ls -a 检查过,文件夹中没有 conf 文件的第二个副本。

该错误可能与重定向失败有关,但我看不到导致错误的原因?

再次编辑:我终于在 /etc/nginx/sites-available/default 中找到了重复的监听指令。不确定 Certbot 是否插入了它们,或者我在设置服务器时是否将它们放在那里……无论如何,将它们注释掉似乎已经解决了问题。 Phusion Passenger 指令中设置服务器块的内容可能与 LetsEncrypt 指令冲突?无论如何,是 nginx 错误日志!

【问题讨论】:

    标签: ssl nginx redirect


    【解决方案1】:

    Stackoverflow 告诉我 mysite 不是用作示例的正确域,所以我将所有内容都更改为“example”而不是“mysite”

    我想您想要的是将所有内容都重定向到 https example.org,不是吗?你的代码应该是这样的:

    来自http的请求,主机是www*还是没有www并不重要。一切都将被重定向到没有www的主机,并通过https

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

    如果主机是 www* 并且来自 https,则重定向到不带 www 的 https。顺便说一句,在这里您需要使用 www.example.org 的证书,因为没有证书,连接是不安全的。

    server {
        listen 443 ssl http2; #https of www*, 301 to right domain.
        server_name www.example.org;
        #are you sure those 2 paths are right? with the final $.
        ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem$
        ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.p$
        include /etc/letsencrypt/options-ssl-nginx.conf; 
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; 
    
        return 301 https://example.org$request_uri;
    }
    

    最后,如果它配备了正确的方案和正确的主机,那么您可以随心所欲。

    server {
        listen 443 ssl http2;
        server_name example.org;
    
        ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem$
        ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.p$
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    
        #do what you want to do here.
    }
    

    如果您对您的解释有任何疑问或我遗漏了什么,请发表评论,我会尽快修复。

    【讨论】:

    • 感谢您非常详细的回答。不幸的是,它没有用; www.mysite.org 仍然显示 Nginx 页面。我复制了您的三个服务器块并将“example”替换为“mydomainname”,并从现有的 conf 文件中复制了我的证书信息。否则代码与您上面写的完全一样。两个 URL 中的 https 似乎都很好,但是从 www 到普通域的重定向不起作用。
    • 我已经在不同的 droplet 上的不同应用程序上尝试过你的答案并且它有效,但我无法弄清楚为什么它在我原来的 (Meteor) 应用程序上不起作用,并且有一个nginx中的错误消息,但我不明白为什么!如果您有任何想法,我已在问题的末尾添加了详细信息?
    • 您还有其他服务器块吗?我的意思是,在整个 /nginx/sites-enabled 中,您可能有 2 个块用 sae 服务器名称侦听 80,因此它在去哪里冲突。查看您是否有任何隐藏文件或临时文件可能会使您的配置翻倍
    • 我的答案可能与 server_name 和 ip 冲突的唯一方法是因为有另一个服务器块正在监听它,正如我在错误中看到的那样,它完全冲突(所以配置加倍对于 www 和非 www 示例,到 80 和 443 端口。)。
    【解决方案2】:

    检查您的 DNS 设置。 您必须有 CNAME 或 A 条目“www”。

    www A   ip
    

    www CNAME   domain.com
    

    你还需要在你的块中添加监听参数

    listen 443 ssl http2;
    

    编辑:基于 cmets。

    将此添加到您的conf中的顶部

    server {
      server_name mysite.org www.mysite.org;
      if ($server_name ~* \.mysite.org$) {
        return 301 $scheme://mysite.org$request_uri;
      }
      ...Meteor app config    
    }
    

    【讨论】:

    • 查看我的问题中的 DNS 设置:我想我已经有了正确的 A 记录。正如我在问题中所述,我已经尝试将“听”添加到块中。我只是尝试按照您的建议添加“http2”,但没有任何区别。
    • 谢谢,我已经尝试将该代码添加到我的配置中,但没有任何区别。
    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 2016-12-30
    • 2021-09-16
    • 1970-01-01
    • 2016-04-02
    • 2017-01-11
    相关资源
    最近更新 更多