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.com
www.rss.example.com
答案2
Nginx 确实对包含虚拟主机的文件进行排序。因为这样使用起来更方便,也更容易理解选择默认文件的逻辑——按字母顺序排序时,这将是第一个 vhost 包含文件。
实际上你正在寻找指令default
的选项listen
,用于终止所有其他网站server_name
与你所提及的块不匹配server {}
。
将选项添加到虚拟主机的指令default
中,如果没有匹配的请求,则终止所有请求。listen
server_name