[英]Wordpress Permalinks return 404 when using NGINX as a reverse proxy to apache
我正在嘗試讓 NGINX 反向代理並為在 Apache 上運行的 WordPress 站點提供 SSL 終止,端口為 8086。我希望 NGINX 處理靜態文件,並且只代理對 Apache 的 PHP 請求。
我已經成功地使用標准鏈接讓它工作。 (即https://example.com/?post=274工作正常)
當我啟用任何類型的永久鏈接時,主頁將加載,wp-admin 也會加載,但https://example.com/what-we-do/失敗。
查看 NGINX 日志,我看到了
2018/05/23 09:36:40 [error] 7472#0: *1 "/var/www/example.com/live_site/what-we-do/index.php" is not found (2: No such file or directory), client: xxx.xxx.xxx.xxx, server: example.com, request: "GET /what-we-do/ HTTP/2.0", host: "example.com", referrer: "https://example.com/?post=274"
所以 NGINX 試圖尋找 /permalink/index.php 作為靜態路徑/文件,而不是傳遞給 apache。 關於如何讓它發揮作用的任何想法?
我的 NGINX 配置看起來像:
upstream example_apache {
ip_hash;
server 127.0.0.1:8086;
}
server {
# HTTP/HTTPS Server Block
# General Config
listen [::]:80;
listen 80;
listen [::]:443 http2 ssl;
listen 443 http2 ssl;
server_name example.com
www.example.com;
root /var/www/example.com/live_site;
access_log /var/log/nginx/access-example.com.log main;
error_log /var/log/nginx/error-example.com.log;
index index.php;
#SSL Cert Configuration
# Check SSL config at https://www.ssllabs.com/ssltest/
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305 ECDHE-RSA-CHACHA20-POLY1305 EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH DHE-RSA-CHACHA20-POLY1305 EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4 !SEED !CAMELLIA";
ssl_session_cache shared:SSL:100m;
ssl_session_timeout 180m;
ssl_dhparam /var/www/certs/dh4096.pem;
ssl_certificate /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.fullchain.secp384r1.cer;
ssl_certificate_key /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.secp384r1.key;
ssl_certificate /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.fullchain.rsa4096.cer;
ssl_certificate_key /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.rsa4096.key;
# Enable HSTS #Deploy in stages to prevent extended loss to site.
add_header Strict-Transport-Security "max-age=300; includeSubdomains;"; #300s-5min TTL Testing
#add_header Strict-Transport-Security "max-age=604800; includeSubdomains;"; #1week TTL Testing
#add_header Strict-Transport-Security "max-age=2592000; includeSubdomains;"; #1month TTL Testing
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; #10886400s-126days Min for Preload
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; #63072000s-2years Production Value
# OCSP Configuration
ssl_trusted_certificate /var/www/certs/lets_encrypt/web01.example.com/web01.example.com.fullchain.secp384r1.cer;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
# LetEncrypt webroot alias
location /.well-known/acme-challenge/ {
alias /var/www/le_root/.well-known/acme-challenge/;
}
# www to non-www rewrite
# Redirect to the correct place, if needed
set $https_redirect 0;
if ($server_port = 80) { set $https_redirect 1; }
if ($host ~ '^www\.') { set $https_redirect 1; }
if ($https_redirect = 1) {
return 301 https://example.com$request_uri;
}
# Wordpress entry point
location / {
#Try file dir index.php else 404
try_files $uri $uri/ /index.php?$args =404;
#All Files except for *.php
location ~ .+(?<!\.php)$ {
location ~ ^[^.]+\.[^.]+$ {
expires max;
add_header Cache-Control public;
break;
}
}
#Only *.php files
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass_header Set-Cookie;
proxy_set_header SSL_PROTOCOL $ssl_protocol;
proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;
proxy_set_header SSL_CLIENT_VERIFY $ssl_client_verify;
proxy_set_header SSL_SERVER_S_DN $ssl_client_s_dn;
proxy_pass http://example_apache;
}
}
}
由於這個問題甚至沒有涉及代理通行證部分,而且似乎與 NGINX 嚴格相關(我可以說),因此以下內容不適用。 但是有人會想知道,或者它可能會幫助其他在這個問題上絆倒的人也了解 apache 配置方面。
我的 apache 有一個 .htaccess 文件,其中包含:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
我的 wp-config.php 有:
// If WordPress is behind reverse proxy
// which proxies https to http
if ( (!empty( $_SERVER['HTTP_X_FORWARDED_HOST'])) ||
(!empty( $_SERVER['HTTP_X_FORWARDED_FOR'])) ) {
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['HTTPS'] = 'on';
}
我的 apache 配置有:
<VirtualHost *:8086>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/example.com/live_site
ServerName example.com
ServerAlias www.example.com
ErrorLog ${APACHE_LOG_DIR}/example.com.error.log
CustomLog ${APACHE_LOG_DIR}/example.com.access.log combined
Alias "/.well-known/acme-challenge/" "/var/www/le_root/.well-known/acme-challenge/"
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/example.com/live_site>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
</VirtualHost>
我還應該注意,當我直接連接到 Apache 時,我可以正確地看到所有頁面的永久鏈接。 (即http://127.0.0.1:8086/what-we-do/工作正常)
NGINX 版本 1.13.9
阿帕奇 2.4.33 mpm_prefork
PHP 版本 7.1
任何想法或幫助讓 NGINX 正確代理到 apache 的永久鏈接將不勝感激!
啟用或檢查是否使用此命令啟用了 mod_rewrite
sudo a2enmod 重寫
當我使用 NGINX 將我的 Prod 環境遷移到 Docker 時,我收到了同樣的錯誤,但我沒有為 Apache 進行反向代理。 不過,我的錯誤是一樣的。
原因是我必須更改wp_options
以匹配我的新本地端口和 URL。
SELECT * FROM wp_options WHERE option_name='siteurl' OR option_name='home';
將顯示您的 WordPress 配置嘗試導航到的當前 URL。 但是由於您已經創建了一個代理並且現在您的 WordPress 站點位於不同的端口或 URL 后面,您可能需要更改這些值。
當您執行該命令時,您將收到您的站點用作前綴的兩個 URL 的列表。 如果它顯示代理的 URL,這可能不起作用。
然后我修改了 URL 以匹配新后端 URL + 端口的位置。 在您的情況下,您可能必須更改它以匹配代理后面的端口和 url,而不是代理本身的 URL。
在我的wp-config.php
中修改這些值不起作用。 例如
define('WP_HOME','http://local.www.greenhousetreatment.com:8080');
define('WP_SITEURL','http://local.www.greenhousetreatment.com:8080');
這對我不起作用。
我必須在 SQL 中手動使用上面的命令,然后更新這些值以匹配 PORT 和網站的 URL。 通常在反向代理中,您將輸入代理 URL,然后它將訪問您的服務 IP 和端口。 您的服務 IP 和 PORT 完成了它需要做的事情,因為它根本不關心代理。 它甚至不知道代理。
你確定你的wp_options
匹配實際的服務 URL 和端口,而不是代理 URL?
我希望這可以提供一些啟示。
我今天遇到了同樣的問題,我的設置和你的一樣,我做了什么來解決這個問題;
修改 nginx 配置,只需將index index.php
從服務器塊添加/移動到location /
塊。
這是我在服務器塊中評論index index.php
然后將其添加到位置塊中的示例。
server {
...
root /var/www/example.com/live_site;
access_log /var/log/nginx/access-example.com.log main;
error_log /var/log/nginx/error-example.com.log;
#index index.php; ##REMOVE THIS ONE
...
# Wordpress entry point
location / {
index index.php index.html ##THEN ADD HERE
#Try file dir index.php else 404
try_files $uri $uri/ /index.php?$args =404;
...
}
也不要忘記檢查.htaccess
確保它適用於 WordPress 永久鏈接,或者可以轉到 wordpress 設置然后將永久鏈接設置保存到Post name 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.