Лак и скипидар

9

Я обнаружил, что всякий раз, когда я перезагружаю Varnish на моем сервере, я теряю сеансы для своих пользователей.

Это очередь заставляет моих клиентов терять свои тележки.

Это нормальное поведение для Varnish или мой VCL виноват? Казалось бы, это не


Дальнейшая информация

При дальнейшем исследовании выясняется, что эта проблема связана с проблемой № 725 на GitHub.

Моя установка Magento - версия 1.9.1.0. Следует также сказать, что весь мой интерфейс работает под https. Я использую Pound перед Varnish для прекращения SSL.

Похоже, что поведение Magento по умолчанию в этой версии заключается в создании вторичного файла cookie внешнего интерфейса, обычно называемого «frontend_cid», в попытке протестировать атаки MITM.

Похоже, что сгенерированный VCL-файл скипидаром не передает этот cookie, что приводит к недействительным сеансам.

Кто-нибудь может объяснить, как файл VCL передает файлы cookie, которые Magento создает для Клиента?


Я сузил это, чтобы Varnish не генерировал требуемые куки.

Начиная с Magento 1.9.1.0, cookie-файл frontend_cid был введен для блокировки MITM-атак.

Это можно найти в Mage_Core_Model_Session_Abstract_Varienклассе, в строке 135

if (Mage::app()->getFrontController()->getRequest()->isSecure() && empty($cookieParams['secure'])) {
    // secure cookie check to prevent MITM attack
    $secureCookieName = $sessionName . '_cid';
    if (isset($_SESSION[self::SECURE_COOKIE_CHECK_KEY])
        && $_SESSION[self::SECURE_COOKIE_CHECK_KEY] !== md5($cookie->get($secureCookieName))
    ) {
        session_regenerate_id(false);
        $sessionHosts = $this->getSessionHosts();
        $currentCookieDomain = $cookie->getDomain();
        foreach (array_keys($sessionHosts) as $host) {
            // Delete cookies with the same name for parent domains
            if (strpos($currentCookieDomain, $host) > 0) {
                $cookie->delete($this->getSessionName(), null, $host);
            }
        }
        $_SESSION = array();
    }
    if (!isset($_SESSION[self::SECURE_COOKIE_CHECK_KEY])) {
        $checkId = Mage::helper('core')->getRandomString(16);
        $cookie->set($secureCookieName, $checkId, null, null, null, true);
        $_SESSION[self::SECURE_COOKIE_CHECK_KEY] = md5($checkId);
    }
}

Чтобы обеспечить безопасные соединения для клиентов, Varnish должен сгенерировать «внешний» файл cookie, который впоследствии будет использоваться Magento для идентификации конкретного клиента. До сих пор, похоже, это просто отлично. Тем не менее, похоже на Magento 1.9.1.0, теперь ему также необходимо сгенерировать файл cookie frontend_cid.

Varnish должен сделать это, потому что, кэшируя ответ, он также кэширует заголовок ответа, который содержит куки «внешнего интерфейса».

Поэтому по умолчанию Varnish уничтожает все файлы cookie, на которые сервер отвечает, когда обрабатывает условия «поиска» или «прохождения». Это делает это, чтобы несколько пользователей не получали один и тот же кэшированный файл cookie внешнего интерфейса (что могло бы скомпрометировать сеансы пользователей).

В любое время, когда лак обрабатывает запрос с помощью «pipe», Magento может создать необходимые файлы cookie и прикрепить их к браузеру пользователя. Это приводит к тому, что система не проходит первоначальную проверку, но затем предоставляет новый сеанс пользователю. Этот симптом проявляется в потере корзины или невозможности добавить товары в корзину.

Скипидарный VCL будет «передавать» любой запрос, который НЕ имеет тип метода GET или HEAD, как видно из этого кода в vcl_recvфункции:

// We only deal with GET and HEAD by default
// we test this here instead of inside the url base regex section
// so we can disable caching for the entire site if needed
if (!true || req.http.Authorization ||
    req.request !~ "^(GET|HEAD)$" ||
    req.http.Cookie ~ "varnish_bypass=1") {
    return (pipe);
}

Таким образом, этот симптом наиболее заметен, когда пользователь пытается добавить товар в корзину или пытается оформить заказ в первый раз.


Как исправить?

Я полагаю, что решение этой проблемы состоит в том, чтобы Turpentine VCL также создал cookie-файл «frontend_cid» для входящих посетителей, а затем модуль скипидара добавил этот cookie-файл в текущий сеанс, как это делается сейчас для cookie-файла «frontend».

Итак ... как мы это реализуем?

Предостережение: я могу ошибаться, я очень плохо знаком с Varnish, но я потратил много часов на это сейчас, и это то, что я вижу, любая поддержка прямо сейчас будет принята с благодарностью.

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ И МОЙ ИЗБРАННЫЙ ФИКС - 2015 10 30

Невозможно создать cookie-файл «frontend_cid» на лаке, так как он случайно создается на сервере Magento и сохраняется в виде хеша MD5 в сеансе клиентов. Это мешает вам создавать внешне вне сеанса клиентов.

Лучшее решение, которое я придумал по этому вопросу, - это вместо этого переписать способ, которым Magento обрабатывает сессии клиентов.

В настоящее время Magento обрабатывает недопустимые сеансы, например:

IF
    The requested session by the customer is flagged as invalid
THEN
    Stop processing request
    Redirect to the appropriate page

Моя новая логика выглядит следующим образом:

IF
    The requested session by the customer is flagged as invalid
THEN
    Create a new session
    Complete the requested task
    Redirect to the appropriate page

Мой новый подход позволяет лакированно реагировать на запросы клиентов даже при первом посещении. Что не так, как работает последняя реализация скипидара.


My Issue, Issue # 829 - / nexcess / magento-turpentine / Issues / 829 на GitHub. Копию моего VCL можно найти здесь.


Моя проблема на GitHub была закрыта, так как это дубликат гораздо более старой проблемы, найденной здесь:

Выпуск № 345

Петр А
источник
1
Я видел, вы только что открыли проблему на GitHub, я проверю это завтра утром. Тем временем вы можете проверить github.com/nexcess/magento-turpentine/issues/90 и github.com/nexcess/magento-turpentine/issues/92 .
mbalparda
это невозможно, сеансы хранятся в magento и браузере пользователя, лак не имеет к этому никакого отношения. что-то, вероятно, настроено неправильно.

Ответы:

4

Это может быть вызвано неправильной настройкой пути к файлам cookie.

Попробуйте установить настройки cookie, Admin->Configuration->Web->Session Cookie Managementесли это еще не сделано.

В качестве альтернативы это может быть ошибка в лаке.

performadigital
источник
Спасибо @performadigital, я провел дополнительное расследование и обновляю свой вопрос.
Питер А
1

Я подозреваю, что ваша проблема будет решена недавним обновлением скипидара: https://github.com/nexcess/magento-turpentine/commit/66615b7cc987854e8671911ab6c3aa22afb808a2

Удалено создание сеансов. Исправлены проблемы # 806, # 345 и многих других, связанных с дополнительными сеансами, пустыми корзинами и т. Д.

Заставляет Varnish обходиться при загрузке первой страницы для новых сеансов.

Поэтому Varnish больше не нужно пытаться подделать cookie-файл сеанса (за счет невозможности ответить из кэша на запрос первой страницы)

Мы обнаружили, что это изменение решило эту проблему для ряда наших клиентов Magento (мы запускаем www.section.io ).

mattnthat
источник
1
Спасибо @mattnthat, я знаю о предлагаемом решении, но не нахожу его приемлемым. В итоге я реализовал другое решение. Я заставил Magento проверить, был ли сеанс действительным, и, если это не так, вместо завершения сценария, я заставил его инициализировать новый сеанс и завершить запрос.
Питер A