Вопрос или проблема
Я пытаюсь перенаправить все URL-адреса из http на https в файле Varnish vcl
Я использую это правило:
sub vcl_recv {
if (!req.http.X-Forwarded-Proto) {
if(std.port(server.ip) == 443) {
set req.http.X-Forwarded-Proto = "https";
} else {
set req.http.X-Forwarded-Proto = "http";
}
}
if (req.http.X-Forwarded-Proto != "https") {
set req.http.location = "https://" + req.http.host + req.url;
return(synth(301));
}
и ниже это
sub vcl_synth {
if (resp.status == 301 || resp.status == 302) {
set resp.http.location = req.http.location;
set resp.status = 301;
return (deliver);
}
}
Это работает отлично, когда запросы идут с доменным именем. Также это перенаправляет www на non www по мере необходимости
Но это не работает с локальным IP. Все запросы, которые делаются на IP сервера, не перенаправляются на домен.
Nginx присутствует, но перенаправление должно выполняться с Varnish, потому что Varnish работает на порту 80, а TLS-терминация была выполнена с Hitch
Любая помощь, пожалуйста?
Ответ или решение
Вопрос о перенаправлении в Varnish может затруднять работу сетевых администраторов, особенно когда дело касается различных типов запросов, таких как использование локальных IP-адресов. Вы опубликовали ваши правила конфигурации Varnish, которые работают должным образом при запросах с доменом и перенаправлении www на не www, но не с локальными IP-адресами. Давайте разберёмся в причинах данной проблемы и предложим решение.
Проблема с перенаправлением HTTP на HTTPS
На первый взгляд, ваша конфигурация vcl_recv
определяет правильный подход к перенаправлению с использованием заголовка X-Forwarded-Proto
для управления протоколом. Однако, следует обратить внимание на то, как Varnish обрабатывает запросы к локальным IP-адресам.
-
Обработка локальных IP-адресов: Varnish, как правило, не может идентифицировать локальные IP-адреса (например, 192.168.x.x или 10.x.x.x) как валидные адреса для перенаправления, так как запросы к этим адресам игнорируют системную логику работы с заголовком
Host
. Это означает, что когда клиент делает запрос к вашему серверу по локальному IP, Varnish не будет иметь информации о требуемом домен. -
Проблемное условие: Ваше условие
if (req.http.X-Forwarded-Proto != "https")
сработает, но обработкаset req.http.location = "https://" + req.http.host + req.url;
приведет к тому, что значениеreq.http.host
будет указывать на локальный IP-адрес, что и становится основным источником проблемы. При таких сценариях Varnish не знает, как корректно сформировать перенаправление.
Оптимизация конфигурации
Для исправления данной ситуации вы можете внести изменения в свою конфигурацию Varnish. Основная идея заключается в том, чтобы обрабатывать запросы к локальному IP-адресу отдельно, а также добавить проверку на параметры хоста. Вот пример того, как можно изменить вашу конфигурацию:
sub vcl_recv {
if (!req.http.X-Forwarded-Proto) {
if (std.port(server.ip) == 443) {
set req.http.X-Forwarded-Proto = "https";
} else {
set req.http.X-Forwarded-Proto = "http";
}
}
# Проверка на локальный IP
if (req.http.host == "ваш.локальный.ip") {
set req.http.location = "https://домен.вашего.сервера" + req.url;
return (synth(301));
}
if (req.http.X-Forwarded-Proto != "https") {
set req.http.location = "https://" + req.http.host + req.url;
return (synth(301));
}
}
sub vcl_synth {
if (resp.status == 301 || resp.status == 302) {
set resp.http.location = req.http.location;
set resp.status = 301;
return (deliver);
}
}
Заключение
Таким образом, благодаря этой настройке, когда вы отправляете запрос к локальному IP вашему серверу, Varnish будет перенаправлять его на указанный вами домен, обеспечивая корректность перенаправления как для локальных, так и для публичных адресов. Настоятельно рекомендуется провести тестирование конфигурации, чтобы убедиться, что перенаправления работают корректно на всех типах адресов. Поддержание чёткой и грамотной настройки Varnish поможет повысить эффективность работы вашего веб-сервиса и улучшить его безопасность.