Nginx 根据配置文件的字母顺序优先考虑子域名

Nginx 根据配置文件的字母顺序优先考虑子域名

TLDR:Nginx 按照配置文件的字母顺序优先处理子域名,我想知道如何防止这种情况发生。这是相似的问题,但我更感兴趣的是改进我的系统。

我的服务器上有两个部分:一个用于静态网站,另一个用于我的 dokuwiki 实例。我希望当有人访问 example.com 时加载 dokuwiki,当有人访问 static.example.com 时加载静态网站。最后,我希望 wiki.example.com 始终指向 dokuwiki,以防默认设置发生变化。

为了实现这一点,我在 /etc/nginx/sites-available 中创建了两个文件。

多库维基(这只是一个运行 certbot 的常见 dokuwiki 配置)

server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = wiki.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen               80;
    listen                   [::]:80;
    server_name          wiki.example.com example.com www.example.com;
    return 301 https://$server_name$request_uri;
}
 
server {
    listen [::]:443 ssl;
    listen 443 ssl;
 
    server_name example.com www.example.com wiki.example.com;
 
    # Maximum file upload size is 4MB - change accordingly if needed
    client_max_body_size 4M;
    client_body_buffer_size 128k;
 
    root /dokuwiki/dokuwiki-2020-07-29;
    index doku.php;
 
    #Remember to comment the below out when you're installing, and uncomment it when done.
    location ~ /(conf/|bin/|inc/|install.php) { deny all; }
 
    #Support for X-Accel-Redirect
    location ~ ^/data/ { internal ; }
 
    location ~ ^/lib.*\.(js|css|gif|png|ico|jpg|jpeg)$ {
        expires 365d;
    }
 
    location / { try_files $uri $uri/ @dokuwiki; }
 
    location @dokuwiki {
        # rewrites "doku.php/" out of the URLs if you set the userwrite setting to .htaccess in dokuwiki config page
        rewrite ^/_media/(.*) /lib/exe/fetch.php?media=$1 last;
        rewrite ^/_detail/(.*) /lib/exe/detail.php?media=$1 last;
        rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last;
        rewrite ^/(.*) /doku.php?id=$1&$args last;
    }
 
    location ~ \.php$ {
        try_files $uri $uri/ /doku.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param REDIRECT_STATUS 200;
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
        # fastcgi_pass unix:/var/run/php5-fpm.sock; #old php version
    }
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
}

静止的

server {
    root /var/www/example;
    index index.html index.htm index.nginx-debian.html;
    server_name static.example.com;
    location / {
        try_files $uri $uri/ =404;
    }

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

这个系统完全按照我的预期运行。但是,我随后将 commafeed 添加到我的服务器。我的目标是通过 rss.example.com 访问 commafeed。Commafeed 在端口 8082 上运行,因此我在此文件中对 example.com/8082 执行了 proxy_pass

逗号输入

server {
    listen 443;
    listen [::]:443;
    
    root /var/www/commafeed;
    index index.html index.htm index.nginx-debian.html;
    server_name rss.example.com www.rss.example.com;
    location / {
        proxy_pass http://example.com:8082/;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

当我这样做时,我的浏览器重置了连接全部example.com 域,并记录此错误消息

example:/etc/nginx/sites-available# tail -f /var/log/nginx/error.log -n 0
2021/09/28 03:10:36 [error] 32479#32479: *2317 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: <my ipv6 address>, server: [::]:443
2021/09/28 03:10:36 [error] 32479#32479: *2318 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: <my ipv6 address>, server: [::]:443

但是,当我将文件重命名为“zcommafeed”时,一切都按预期工作。也就是说,所有旧子域名都像以前一样工作,以及指向 commafeed 的 rss.example.com。

现在,虽然这种方法可行,但这似乎意味着还有更好的方法,不需要关注文件的字母顺序。我是 NGINX 新手,所以非常感谢您的帮助!!

答案1

错误消息明确指出配置缺少 的 TLS 证书。为和rss.example.com创建适当的证书/密钥对,然后配置将正常工作。rss.example.comwww.rss.example.com

答案2

Nginx 确实对包含虚拟主机的文件进行排序。因为这样使用起来更方便,也更容易理解选择默认文件的逻辑——按字母顺序排序时,这将是第一个 vhost 包含文件。

实际上你正在寻找指令default的选项listen,用于终止所有其他网站server_name与你所提及的块不匹配server {}

将选项添加到虚拟主机的指令default中,如果没有匹配的请求,则终止所有请求。listenserver_name

相关内容