Ubuntu16.04下带SSL的Nginx无法实现www转非www重定向问题
看起来你已经找到了问题的关键——重复的server_name监听导致Nginx优先匹配了默认配置,不过我再帮你梳理完整的解决流程和优化建议:
1. 定位冲突根源
你在错误日志里看到的conflicting server name警告,本质是Nginx加载了多个监听同一端口+域名的server块。最常见的情况是/etc/nginx/sites-available/default这个默认配置文件在搞事情:它可能包含了监听80/443的server块,甚至被误配置成了匹配www.example.org,导致你的自定义重定向规则被忽略,请求被导向了Nginx默认页面。
2. 清理冲突配置
执行命令打开默认配置文件:
sudo nano /etc/nginx/sites-available/default
你会看到类似这样的内容:
server { listen 80 default_server; listen [::]:80 default_server; listen 443 ssl default_server; listen [::]:443 ssl default_server; server_name _; # 也可能被错误设置为www.example.org root /var/www/html; # 默认页面的根目录 ... }
推荐直接移除这个默认配置的软链接(因为它已经干扰了你的自定义配置):
sudo unlink /etc/nginx/sites-enabled/default
如果不想删除,也可以把默认server块的server_name固定为_;(匹配所有未被精确指定的域名),这样Nginx会优先选择你自定义的、精确匹配example.org和www.example.org的server块。
3. 验证配置并重启Nginx
修改完成后,先检查配置是否合法:
sudo nginx -t
如果输出nginx: configuration file /etc/nginx/nginx.conf test is successful,就可以重启Nginx让配置生效:
sudo systemctl restart nginx
4. 优化你的重定向配置
你之前调整后的配置已经很合理,这里补充一个小细节:把ROOT_URL改成HTTPS地址,避免Meteor应用内部生成HTTP链接导致混合内容问题。最终优化后的配置如下:
# 所有HTTP请求统一重定向到HTTPS主域名 server { listen 80; listen [::]:80; server_name example.org www.example.org; return 301 https://example.org$request_uri; } # HTTPS的www域名重定向到主域名 server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.example.org; # 复用SSL证书配置 ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; return 301 https://example.org$request_uri; } # 主站点HTTPS配置 server { listen 443 ssl http2; 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.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Passenger + Meteor 核心配置 root /var/www/example/bundle/public; passenger_enabled on; passenger_app_type node; passenger_startup_file main.js; passenger_env_var MONGO_URL mongodb://localhost:27017/example; passenger_env_var MONGO_OPLOG_URL mongodb://localhost:27017/local; # 这里一定要设置为HTTPS的地址 passenger_env_var ROOT_URL https://example.org; }
为什么之前的配置无效?
Nginx加载sites-enabled目录下的配置是按字母顺序来的,default文件会比你的mysite.conf先被加载。当多个server块监听同一端口和域名时,Nginx会优先选择第一个匹配的规则,所以www域名的请求被默认配置接管,显示了Nginx的默认欢迎页。
内容的提问来源于stack exchange,提问作者Little Brain

