haproxy + stunnel + 연결 유지?


10

HTTPS 트래픽을 처리하기 위해 haproxy 1.4 앞에 stunnel을 배치하고 싶습니다. X-Forwarded-For 헤더 를 추가하려면 stunnel이 필요합니다 . 이것은 haproxy 웹 사이트 의 "stunnel-4.xx-xforwarded-for.diff" 패치 를 통해 얻을 수 있습니다 .

그러나 설명은 다음을 언급합니다.

이 패치는 keep-alive와 함께 작동하지 않습니다.

내 질문은 : 이것이 실제로 나에게 어떤 의미가 있는가? 확실하지 않습니다

  1. 이 사이에 연결 유지에 관한 경우
    • 클라이언트와 기절
    • 기절 및 haproxy
    • 또는 haproxy 및 백엔드 서버?
  2. 이것이 성능의 의미 : 웹 페이지에 100 개의 아이콘이있는 경우 브라우저가 100 개의 전체 SSL 연결을 협상해야합니까, 아니면 SSL 연결을 재사용하여 새 TCP 연결 만 만들 수 있습니까?

답변:


12

이것은 HTTP keep-alive에 관한 것으로, 여러 리소스 요청이 단일 TCP 세션 (및 SSL을 사용하여 단일 SSL 세션)을 통과 할 수있게합니다. keep-alive가 없으면 요청 된 각 리소스에 SSL 핸드 셰이크가 필요하므로 SSL 사이트의 성능에 매우 중요합니다.

따라서 여기서의 문제는 클라이언트에서 백엔드 서버까지 하나의 커다란 연결 유지 세션입니다. 성능에있어 중요한 요소이며 최신 HTTP 서버에서는 당연한 것으로 여겨지지만이 패치에서는 지원하지 않습니다. 왜 그런지 살펴 보자 ..


연결 유지 세션은 한 번에 더 많은 요청입니다. 서버가 한 요청에 대한 응답을 완료하면 서버는 FINTCP 세션을 종료하기 위해 패킷을 보내지 않습니다 . 클라이언트는 단순히 다른 배치의 헤더를 보낼 수 있습니다.

해당 패치가 수행하는 작업을 이해하기 위해 연결 유지 대화의 예는 다음과 같습니다.

고객:

GET / HTTP/1.1
Connection: keep-alive
Host: domain.com
...

섬기는 사람:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: Apache
Content-Length: 34
.... (other headers)
<html><head>content!</head></html>

연결 유지가 아닌 연결이 중지되는 위치는 다음과 같습니다. 그러나 keep-alive를 사용하면 클라이언트가 다른 클라이언트를 해고 할 수 있습니다.

GET /images/some/image.on.the.page.jpg HTTP/1.1
Connection: keep-alive
Host: domain.com
...

프록 싱의 클라이언트 ID의 경우 일부 리버스 프록시는 X-Forwarded-For각 클라이언트 요청 의 헤더에 추가 할 수 있습니다 . 이는 역방향 프록시 IP에서 시작하는 모든 요청 대신 요청이 어디에서 오는지 업스트림 서버에 알립니다.

전체 X-Forwarded-For헤더가 매번 전송되므로 keep-alive 연결을 통해 전송되는 모든 클라이언트 리소스 요청에 헤더를 삽입해야합니다. X-Forwarded-For헤더를 처리 하고 "실제"요청 IP로 변환하는 것은 TCP-keep-alive-session이 아닌 요청마다 수행됩니다. 어쩌면 단일 클라이언트 유지 세션을 사용하여 여러 클라이언트의 요청을 처리하는 멋진 리버스 프록시 소프트웨어가있을 수 있습니다.

이 패치가 실패하는 곳입니다.


해당 사이트의 패치는 스트림에서 첫 번째 HTTP 헤더 집합의 끝 부분에 대한 TCP 세션의 버퍼를 감시하고 첫 번째 헤더 집합이 끝나면 스트림에 새 헤더를 삽입합니다. 이 X-Forwarded-For작업이 완료되면 작업이 완료된 것으로 간주하고 새 헤더 집합의 끝 검색을 중지합니다. 이 방법은 후속 요청을 통해 들어오는 모든 미래 헤더를 인식하지 못합니다.

그들을 비난 할 수는 없습니다. stunnel은 스트림의 내용을 처리하고 번역하기 위해 실제로 구축되지 않았습니다.

이것이 시스템에 미치는 영향 은 keep-alive 스트림 의 첫 번째 요청이 X-Forwarded-For헤더를 올바르게 주입하고 모든 후속 요청이 정상적으로 작동하지만 헤더가 없다는 것입니다.

연결 당 여러 클라이언트 요청을 처리 할 수있는 다른 헤더 주입 패치가없는 경우 (또는 스택 오버플로에서 친구의 도움으로이 요청을 조정하지 않은 경우) SSL 종료에 대한 다른 옵션을 검토해야 할 수 있습니다.


1
훌륭한 답변, 감사합니다. 여기에 질문을하는 것이 좋은 이유를 상기시켜줍니다.
Chris Lercher

1
stunnel에서 keep-alive 헤더 삽입을 허용하려면 엄청난 양의 작업이 될 거의 모든 HTTP를 말할 수 있어야합니다. 즉, HAproxy의 헤더를 주입하기 위해 HAproxy의 PROXY 프로토콜 (stunnel 또는 stud 용 패치가 필요함)을 사용할 수도 있습니다 . 자세한 내용 은 문서 를 참조하십시오 (Google 프록시에서 HAproxy 사이트가 ATM을 부분적으로 다운 한 것으로 보입니다)
Holger Just


3

다른 스레드에 게시 한 것과 마찬가지로 HAProxy는 1.5-dev12 이후 양쪽에서 기본 SSL을 지원합니다. 따라서 X-Forwarded-For, HTTP keep-alive 및 서버가 SSL을 통해 연결되었음을 알리는 헤더는 다음과 같이 간단합니다.

listen front
    bind :80
    bind :443 ssl crt /etc/haproxy/haproxy.pem
    mode http
    option http-server-close
    option forwardfor
    reqadd X-Forwarded-Proto:\ https if { is_ssl }
    server srv1 1.1.1.1:80 check ...
    ...

stunnel을 패치하는 것보다 훨씬 쉽고 keep-alive를 삭제하는 것보다 훨씬 낫습니다.


is_ssl 대신 ssl_fc를 사용하고 싶을 수도 있습니다.
josch

2

Shane의 탁월한 답변을 확장하여 Nginx를 HAproxy 앞에서 SSL 종료기로 사용할 수 있습니다. 대기 시간에 가장 민감한 클라이언트와 nginx 간의 연결 유지를 올바르게 처리하고 각 클라이언트 요청에 대해 백엔드에 새로운 연결을 만들어 각 클라이언트에서 X-FORWARDED-FOR을 보냅니다.


1
그러나 웹 소켓이 필요한 경우 nginx가 작동하지 않습니다.
w00t

또한 SSL 세션 캐시를 지원합니다.
3molo September
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.