서버에서 Varnish를 다시 시작할 때마다 사용자의 세션을 잃어 가고 있음을 발견했습니다.
이제 고객이 쇼핑 카트를 잃게됩니다.
이 정상적인 동작이 Varnish에 있습니까? 아니면 VCL이 책임이 있습니까? 아닌 것 같습니다
추가 정보.
추가 조사에서이 문제는 GitHub의 문제 # 725 와 관련이있는 것으로 보입니다 .
내 Magento 설치 버전은 1.9.1.0입니다. 또한 전체 프론트 엔드가 https로 실행되고 있다고 말해야합니다. SSL을 종료하기 위해 Varnish 앞에서 Pound를 사용하고 있습니다.
이 버전의 기본 Magento 동작은 MITM 공격을 테스트하기 위해 일반적으로 'frontend_cid'라고하는 보조 프런트 엔드 쿠키를 생성하는 것으로 보입니다.
Turpentine이 생성 한 VCL 파일이이 쿠키를 전달하지 않는 것 같습니다. 이로 인해 유효하지 않은 세션이 발생합니다.
누구든지 VCL 파일이 Magento가 클라이언트에 만드는 쿠키를 어떻게 전달하는지 설명 할 수 있습니까?
필요한 쿠키를 생성하지 않는 니스로 범위를 좁혔습니다.
Magento 1.9.1.0부터 MITM 공격을 차단하기 위해 'frontend_cid'쿠키가 도입되었습니다.
이것은 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는 '프론트 엔드'쿠키를 생성해야합니다.이 쿠키는 나중에 Magento가 해당 특정 고객을 식별하는 데 사용합니다. 지금까지는 잘하는 것처럼 보입니다. 그러나 Magento 1.9.1.0과 같이 보이므로 이제 'frontend_cid'쿠키도 생성해야합니다.
Varnish는 응답을 캐싱하여 '프론트 엔드'쿠키가 포함 된 응답 헤더도 캐시하기 때문에이를 수행해야합니다.
따라서 기본적으로 니스는 '조회'또는 '통과'조건을 처리 할 때 백엔드가 응답하는 쿠키를 모두 제거합니다. 이는 동일한 캐시 된 프론트 엔드 쿠키로 여러 사용자가 발행되는 것을 막기 위해 수행됩니다 (사람 세션을 손상시킬 수 있음).
바니시가 'pipe'로 요청을 처리 할 때마다 Magento는 필요한 쿠키를 생성하여 사용자 브라우저에 연결할 수 있습니다. 이로 인해 시스템이 초기 검증에 실패하지만 사용자에게 새 세션을 제공합니다. 이 증상은 장바구니가 유실되었거나 장바구니에 제품을 추가 할 수없는 것으로 나타납니다.
Turpentine VCL은 vcl_recv
함수 에서이 코드에서 볼 수 있듯이 메소드 유형 GET 또는 HEAD가 아닌 모든 요청을 '파이프'합니다 .
// 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이 들어오는 방문자를위한 'frontend_cid'쿠키를 생성 한 다음 현재 'frontend'쿠키와 마찬가지로 현재 세션에 해당 쿠키를 추가하는 것입니다.
그럼 ... 어떻게 구현할까요?
주의 사항 : 나는 틀릴 수 있고, 나는 바니쉬를 처음 접했지만 지금은 많은 시간을 보냈으며 이것이 내가보고있는 것입니다. 지금 지원하는 사람은 크게 감사하겠습니다.
최종 업데이트 및 내 수정-2015 10 30
쿠키가 Magento에 의해 서버에서 무작위로 생성되고 고객 세션에서 MD5 해시로 저장되므로 니스에서 'frontend_cid'쿠키를 생성 할 수 없습니다. 이렇게하면 고객 세션 외부에서 외부에서 작성하지 못하게됩니다.
이 문제에 관해 내가 생각해 낸 가장 좋은 해결책은 대신 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
내 새로운 접근 방식을 통해 니스는 첫 방문에서도 고객의 대응을 처리 할 수 있습니다. 테레빈의 최신 구현 방식이 아닙니다.
내 문제, 문제 # 829-GitHub의 / nexcess / magento-turpentine / issues / 829. 내 VCL 사본은 여기에서 찾을 수 있습니다.
GitHub에 대한 내 문제는 여기에서 발견 된 훨씬 오래된 문제와 중복되어 종료되었습니다.