적절한 HAProxy SNI 기반 라우팅을 위해 "tcp-request content accept" 프런트엔드 지침이 필요한 이유는 무엇입니까?

적절한 HAProxy SNI 기반 라우팅을 위해 "tcp-request content accept" 프런트엔드 지침이 필요한 이유는 무엇입니까?

최근 mongodb 프로토콜 연결을 위해 HAProxy에서 SNI 기반 라우팅을 설정하려고 했습니다 mongodb+srv.

작동하게 만들었지만 넣기 전까지는 그렇지 않았습니다.

tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }

내 프런트엔드 구성에서 제대로 작동하기 시작했습니다.

이것들이 없으면 (또는하나만으로이 중) 요청의 약 70%에 대해 산발적인 연결 재설정이 계속 발생했습니다. 때때로 연결이 설정되었습니다.

에 따르면http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#4-tcp-request%20content

콘텐츠 기반 규칙은 정확한 선언 순서에 따라 평가됩니다. 일치하는 규칙이 없거나 규칙이 없는 경우 기본 작업은 내용을 수락하는 것입니다. 삽입할 수 있는 규칙 수에는 특별한 제한이 없습니다.

따라서 기본적으로 작동했어야 합니다.

기본적인 TCP 개념이나 특정 Mongo 연결 세부 정보가 누락되었습니다. 그러나 나는 거의 모든 사람들이 SNI 기반 라우팅을 선택할 때 정의된 동일한 규칙을 가지고 있으므로 대부분의 사람들에게 이해가 될 것입니다.

HAProxy 구성 작동:

    frontend fe_mongo-nonprod
      bind :27017
      tcp-request inspect-delay 5s
      tcp-request content accept if { req_ssl_hello_type 1 }

      acl mongoAtlas-01 req_ssl_sni -i host1.mongodb.net
      acl mongoAtlas-02 req_ssl_sni -i host2.mongodb.net
      acl mongoAtlas-03 req_ssl_sni -i host3.mongodb.net
      use_backend be_mongo-nonprod if mongoAtlas-01 || mongoAtlas-02 || mongoAtlas-03

    backend be_mongo-nonprod
      mode tcp

      acl mongoAtlas-01 req_ssl_sni -i host1.mongodb.net
      acl mongoAtlas-02 req_ssl_sni -i host2.mongodb.net
      acl mongoAtlas-03 req_ssl_sni -i host3.mongodb.net

      use-server server-01 if mongoAtlas-01
      use-server server-02 if mongoAtlas-02
      use-server server-03 if mongoAtlas-03

      server server-01 host1.mongodb.net:27017
      server server-02 host2.mongodb.net:27017
      server server-03 host3.mongodb.net:27017

HAProxy는 Kubernetes(GCP의 Google 관리형 클러스터)에 배포되고 istio-사이드카가 있으며 내부 LoadBalancer k8s 서비스를 통해 노출된다는 점도 언급할 가치가 있습니다.

언급한 바와 같이 위의 구성은 완벽하게 잘 작동합니다. 내가 관심 있는 것은 왜 tcp-request content accept절대적으로 필요하고 여기에서는 연결이 기본적으로 [항상] 허용되지 않는지입니다.

답변1

나는 내 자신의 질문에 대해 좀 생각해 본 후에 대답하려고 노력할 것입니다.

따라서 HAProxy 문서에는 다음과 같은 언급도 있습니다. http://cbonte.github.io/haproxy-dconv/2.0/configuration.html

콘텐츠 전환이 필요한 경우 아래 예와 같이 먼저 완전한 클라이언트 hello(유형 1)를 기다리는 것이 좋습니다.

이제 SNI 데이터는 요청의 Client Hello 섹션에도 포함되어 있으므로(https://www.rfc-editor.org/rfc/rfc6066#page-6) 내 가정은 다음과 같습니다.

Client Hello가 여러 TCP 패킷에 분산되어 있고 no 경우 tcp-request content accept is configured첫 번째 패킷을 수신하면 HAProxy가 이를 라우팅하려고 시도하고 두 가지 중 하나가 발생합니다.

  1. 기본 백엔드가 구성된 경우 패킷은 이 백엔드로 전달됩니다.
  2. 기본 백엔드가 구성되지 않은 경우(필자의 경우) 패킷이 삭제되고 연결이 재설정됩니다.

또한 설명된 첫 번째 경우에도 백엔드 섹션에 있는 서버 HAProxy 지점에는 SNI가 필요할 수도 있습니다. 따라서 SNI 표시 없이 불완전한 요청을 전달하면 연결이 재설정됩니다.

관련 정보