【问题标题】:How should I redirect from non-www to www when https?https时我应该如何从非www重定向到www?
【发布时间】:2022-06-14 18:50:31
【问题描述】:

我在 Nginx 文档中读到,应该创建新的服务器块,而不是使用 IF。

我尝试制作另一个块来监听 443 ssl,只是为了设置 redvi.eu(非 www)然后相应地重定向它。由于重复而失败。

这里如何重定向https非www的正确方法?

server {
    listen 80 default_server;
    server_name www.redvi.eu redvi.eu;
    return 301 https://www.redvi.eu$request_uri;
}

server {

  server_name www.redvi.eu;
  root /home/deploy/redvi/current/public;

  passenger_enabled on;
  passenger_app_env production;

  location /cable {
    passenger_app_group_name redvi_websocket;
    passenger_force_max_concurrent_requests_per_process 0;
  }

  # Allow uploads up to 100MB in size
  client_max_body_size 100m;

  location ~ ^/(assets|packs) {
    expires max;
    gzip_static on;
  }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/www.redvi.eu/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.redvi.eu/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

}

【问题讨论】:

  • 你需要三个服务器块才能做到这一点。 Here 是将 www 重定向到非 www 的示例;你需要做相反的事情。
  • 感谢您的回答。如果我唯一要做的就是重定向,我真的需要在第一个块中定义证书吗?
  • 如果在启用 ssl 的端口上侦听的服务器块没有证书/密钥声明,Nginx 将拒绝启动。

标签: nginx


【解决方案1】:

即使你不想使用“IF”,你也无能为力。

我多年来一直以这种方式使用它,并且效果很好。

server {

    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;

}

server {

    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com www.example.com;
    root /var/www/sites/example.com/public;

    if ($host != 'www.example.com') {
        return 301 https://www.example.com$request_uri;
    }

    # others....

}

【讨论】:

  • 我确信你需要 3 个街区,但是是的,这很有魅力
【解决方案2】:

我想我必须评论接受的答案和我的suggestion 之间的区别。当然,您可以在NGX_HTTP_SERVER_REWRITE 请求处理phase 期间使用两个带有附加字符串比较操作的服务器块。此外,您甚至可以使用单个服务器块,如下所示:

server {

    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name example.com www.example.com;

    # ssl certificate/key/ciphers setup

    if ($https = "") {
        return 301 https://www.example.com$request_uri;
    }

    if ($http_host != www.example.com) {
        return 301 https://www.example.com$request_uri;
    }

    ... # rest of configuration here

}

尽管如此,出于性能考虑,我还是有意给出了使用三个服务器块的建议。这是因为内部 nginx 将为每个子域级别构建一个哈希表,以通过哈希表查找选择正确的服务器块,其复杂性不大于 O(x) 其中x 是最长托管的子域组件的最大数量服务器名称(例如,3 代表 www.example.com)。配置 nginx,尤其是在高负载系统上,您不应该尝试缩短配置以降低性能成本。 Nginx 配置(大部分)是声明性的,它不是脚本或程序代码,Nginx 不是一个优化编译器来以最佳方式处理您的配置。 DRY(不要重复自己)原则在这里不适用,即使你有这样的诱惑。


在某些示例中,您甚至可以看到如下内容:

if ($http_host !~ ^www\.) {
    rewrite ^ https://www.$http_host$request_uri permanent;
}

这个在性能方面是最差的,因为调用了昂贵的 PCRE 库调用(实际上,当在上面的示例中使用 rewrite 指令而不是 return 301 https://www.$http_host$request_uri; 时,甚至两次调用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    相关资源
    最近更新 更多