WordPress多站点HTTP/HTTPS子域名访问异常问题
问题描述
Ubuntu服务器新手,在Nginx环境下搭建了WordPress多站点,通过Let's Encrypt安装了免费SSL证书。主站HTTP访问可正常跳转至HTTPS,但子域名HTTP访问时显示Apache默认页面,无法定位问题。各域名访问情况:
- http://friendflue.com:自动跳转至https://friendflue.com
- http://www.friendflue.com:返回Apache默认页面
- http://demo.friendflue.com:返回Apache默认页面
- https://www.friendflue.com:跳转至https://friendflue.com
- https://demo.friendflue.com:正常访问对应站点
用户提供的Nginx配置:
################################## # WORDPRESS NGINX CONFIGURATIONS ################################## server { listen 80; root /var/www/mywebsite; server_name mywebsite.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; root /var/www/mywebsite; access_log /var/log/nginx/wp_client_access.log; error_log /var/log/nginx/wp_client_error.log; server_name mywebsite.com; ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem; # Attempt to rewrite wordpress in sub directory rewrite ^/wp/([_0-9a-zA-Z-]+)/(xmlrpc\.php|wp-[0-9a-z-]+\.php) /wp/$2; rewrite ^/wp/([_0-9a-zA-Z-]+)/(wp-(admin|content|includes).*) /wp/$2; location / { index index.php index.html; try_files $uri $uri/ /index.php?$args; } ############# # Specify a charset ############ charset utf-8; ############ # GZIP ########### gzip off; ############# # Add trailing slash to */wp-admin requests. ############ rewrite /wp-admin$ $scheme://$host$uri/ permanent; ############ # this prevents hidden files (beginning with a period) from being served ############ location ~ /\. { access_log off; log_not_found off; deny all; } ########### # SEND EXPIRES HEADERS AND TURN OFF 404 LOGGING ########### location ~* ^.+.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { access_log off; log_not_found off; expires max; } ############ # Pass uploaded files to wp-includes/ms-files.php. ############ # rewrite /files/$ /index.php last; if ($uri !~ wp-content/plugins) { rewrite /files/(.+)$ /wp-includes/ms-files.php?file=$1 last; } # Rewrite multisite in a subdirectory '.../wp-.*' and '.../*.php'. # if (!-e $request_filename) { # rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last; # rewrite ^/[_0-9a-zA-Z-]+.*(/wp-admin/.*\.php)$ $1 last; # rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last; #} # Rewrite multisite '.../wp-.*' and '.../*.php'. if (!-e $request_filename) { rewrite /wp-admin$ $scheme://$host$uri/ permanent; rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) /wp$1 last; rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ /wp$1 last; } ############ # Pass all .php files onto a php-fpm or php-cgi server ############ location ~ \.php$ { # Try the files specified in order. In our case, try the requested URI and if # that fails, try (successfully) to pass a 404 error. # zero day exploit defense try_files $uri =404; # Include the fastcgi_params defaults provided by nginx include /etc/nginx/fastcgi_params; # The amount of time for upstream to wait for a fastcgi process to send data. # We keep this *extremely* high so that one can be lazy when remote debugging. fastcgi_read_timeout 3600s; # Buffer size for reading the header of the backend FastCGI process. # This defaults to the value of a single fastcgi_buffers, so does not # need to be specified in our case, but it's good to be explicit. fastcgi_buffer_size 128k; # The number and size of the buffers into which the reply from the FastCGI # process in the backend is read. # # 4 buffers at 128k means that any reply by FastCGI greater than 512k goes # to disk and replies under 512k are handled directly in memory. fastcgi_buffers 4 128k; # SCRIPT_FILENAME is a required parameter for things to work properly, # but was missing in the default fastcgi_params on upgrade to nginx 1.4. # We define it here to be sure that it exists. fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # Use the upstream for php7.0-fpm that we defined in nginx.conf fastcgi_pass unix:/run/php/php-fpm.sock; #fastcgi_pass 127.0.0.1:9000; # And get to serving the file! fastcgi_index index.php; } ############ # ROBOTS ########### location = /robots.txt { allow all; log_not_found off; access_log off; } ############ # RESTRICTIONS ############ # Deny access to any files with a .php extension in the uploads directory # Works in sub-directory installs and also in multisite network # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban) location ~* /(?:uploads|files)/.*\.php$ { deny all; } }
问题分析与解决步骤
核心原因
- Nginx未覆盖子域名的HTTP请求:当前80端口的server块仅配置了
server_name mywebsite.com(应为friendflue.com的笔误),未包含www.friendflue.com和demo.friendflue.com,导致这些子域名的HTTP请求未被Nginx处理。 - Apache抢占未处理的80端口请求:Apache服务仍在运行,当Nginx没有匹配到对应server块时,Apache会接管80端口的请求,返回默认页面。
解决步骤
1. 修正Nginx的HTTP跳转配置
修改监听80端口的server块,将所有需要处理的域名加入server_name,确保所有HTTP请求都被Nginx捕获并跳转到HTTPS:
server { listen 80; root /var/www/mywebsite; server_name friendflue.com www.friendflue.com demo.friendflue.com; # 使用$host保留原访问域名,避免统一跳转到主域名 return 301 https://$host$request_uri; }
2. 停止并禁用Apache服务
既然使用Nginx作为Web服务器,无需Apache运行,执行以下命令彻底关闭并禁用:
sudo systemctl stop apache2 sudo systemctl disable apache2 # 确认状态,显示inactive则成功 sudo systemctl status apache2
3. 验证Nginx配置并重启
修改配置后先验证合法性,再重启Nginx生效:
# 检查配置是否有语法错误 sudo nginx -t # 重启Nginx sudo systemctl restart nginx
4. 确认SSL证书覆盖所有子域名
确保Let's Encrypt证书包含所有需要的子域名,若当初仅申请了主域名,重新申请包含子域名的证书:
sudo certbot --nginx -d friendflue.com -d www.friendflue.com -d demo.friendflue.com
内容的提问来源于stack exchange,提问作者Mohammad Sohanur Rahman
相关产品推荐
相关产品推荐

