Я добавил Varnish перед nginx. Когда я пытаюсь войти в WordPress, я перехожу на domain.com/wp-admin, но теперь меня перенаправляют на domain.com:8080/wp-admin. Я могу вручную удалить порт и функции администратора, как и должно.
Моя конфигурация Varnish:
backend origin {
.host = "localhost";
.port = "8080";
.connect_timeout = 60s;
.first_byte_timeout = 60s;
.between_bytes_timeout = 60s;
}
acl purge {
"localhost";
}
sub vcl_recv {
set req.backend = origin;
set req.http.X-Forwarded-For = client.ip;
if(req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_") {
return (pass);
}
if(req.url ~ "/xmlrpc.php") {
return(pass);
}
if( req.url ~ "\?s=" ){
return (pass);
}
if (req.request == "BAN") {
if(!client.ip ~ purge) {
error 405 "Not allowed.";
}
ban("req.url ~ "+req.url+" && req.http.host == "+req.http.host);
error 200 "Banned.";
}
if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") {
return (pipe);
}
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
unset req.http.Cookie;
return (lookup);
}
sub vcl_hit {
if (req.request == "PURGE") { purge; }
return (deliver);
}
sub vcl_miss {
if (req.request == "PURGE") { purge; }
return (fetch);
}
sub vcl_fetch {
unset beresp.http.Server;
unset beresp.http.X-Powered-By;
if (beresp.status == 404) {
set beresp.ttl = 0m;
return(hit_for_pass);
}
if( beresp.http.Set-Cookie && req.url !~ "^/wp-(login|admin)" ){
unset beresp.http.Set-Cookie;
}
if ( req.request == "POST" || req.http.Authorization ) {
return (hit_for_pass);
}
if ( beresp.status != 200 ) {
return (hit_for_pass);
}
if( req.url ~ "\?s=" ){
return (hit_for_pass);
}
set beresp.ttl = 5m;
return (deliver);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
unset resp.http.Via;
unset resp.http.X-Varnish;
}
sub vcl_error {
if (obj.status == 503 && req.restarts < 2) {
set obj.http.X-Restarts = req.restarts;
return(restart);
}
if (obj.status == 301) {
set obj.http.Location = req.url;
set obj.status = 301;
return(deliver);
}
if (obj.status == 750) {
set obj.http.Location = obj.response;
set obj.status = 302;
return (deliver);
}
}
Я думаю, вы ошибаетесь, что перенаправление только добавляет порт, не добавляя косую черту в конец URL-адреса.
После обнаружения этой проблемы становится ясно, что это внутреннее перенаправление, которое выполняется nginx, когда он обнаруживает, что доступ к каталогу осуществляется без завершающей косой черты.
Вы бы использовали http://nginx.org/en/docs/http/ngx_http_core_module.html#port_in_redirect чтобы отключить добавление порта:
port_in_redirect off;
Это решение будет отлично работать до тех пор, пока вы не будете полагаться на такие перенаправления при попытке доступа к nginx напрямую через порт 8080, и пока Host
имена совпадают между лаком и nginx.
Не уверен, что все эти разговоры об авторе «лгут», поскольку ложь означает «ложное заявление с намерением обмануть». Автор явно не намерен вводить пользователей в заблуждение, он просто не понимал, что это работает с косой чертой, и, в конечном счете, человек просто хочет знать, как заставить его работать без косой черты.
Чтобы решить эту проблему, я бы рекомендовал добавить следующее в ваш серверный блок nginx:
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
Это было, когда вы переходите на example.com/wp-admin, он переходит на example.com/wp-admin, а не на example.com:8080/wp-admin/, и, например, если вы используете CloudFlare DNS, он скажет сайт не работает.
Я использую Ubuntu, Nginx и Varnish, и теперь это отлично работает, а не отключает port_in_redirect.
Чтобы добавить, обязательно перезапустите nginx после:
sudo service nginx restart
В "Настройки -> Общие" установите "Адрес WordPress (URL)" на "http://yourdomain.com:80/"
Обновление: я обнаружил, что это решение действительно работает только в самых простых сценариях. Любой вид кеша или плагина CDN, который смотрит на эту переменную, будет добавлять ': 80', вызывая всевозможные неприятные проблемы. В конце концов, вместо этого мой клиент просто указал на «/wp-login.php». ;)