Nginx SSL 사전 읽기가 서버 이름이 추출되지 않은 요청을 산발적으로 가져옴

Nginx SSL 사전 읽기가 서버 이름이 추출되지 않은 요청을 산발적으로 가져옴

나는nginx 스트림 모듈s3 앞에서 nginx를 TCP 역방향 프록시로 활용합니다. 최근에는 추가적인 업스트림을 수용하기 위해 로직을 추가해야 했습니다. 이를 위해 저는 $ssl_preread_server_name 맵 변수를 통해 조건부 논리를 사용하기로 결정했습니다.SSL_prereadnginx는 SSL을 종료하지 않고 ClientHello 메시지에서 서버 이름을 추출할 수 있습니다. 아래 논리를 볼 수 있습니다.

map $ssl_preread_server_name $https_cname {
    s3.amazonaws.com https_s3_backend;
    aws-service-2.amazonaws.com aws-service-2-backend;
}
upstream https_s3_backend {
    server s3.amazonaws.com:443;
}
upstream aws_service_2_backend {
    server aws-service-2.amazonaws.com:443;
}

server {
    listen       443;
    proxy_pass $https_cname;
    ssl_preread on;
}

서버 이름이 s3.amazonaws.com인 요청이 들어오면 해당 요청은 s3으로 전송됩니다. 서버 이름이 aws-service-2.amazonaws.com인 요청이 들어오면 해당 요청은 aws-service-2로 전송됩니다.

이것은 대부분의 경우 작동합니다. 그러나 때때로 요청이 서버 이름 없이 포트 443의 nginx 서버에 도달하고 있음을 나타내는 오류가 오류 로그에 있습니다.

[error] ... no host in upstream "", client: x.x.x.x, server: 0.0.0.0:443

맵 로직에 기본 문을 추가하면 이러한 오류가 사라집니다. 서버 이름이 추출되지 않은 채 들어오는 일부 s3 요청에 대한 가능한 설명은 무엇입니까? 현재 요청이 이러한 nginx 상자에 도달할 수 있는 유일한 방법은 누군가가 s3 작업을 수행하는 경우입니다.

답변1

저는 Amazon S3 자체에 익숙하지 않지만 서버 이름을 설정하지 않고 요청이 생성되는 것이 문제라고 생각합니다 (참조서버 이름 표시).

유사한 설정에서 매우 동일한 문제가 발생했으며 예를 들어 OpenSSL v1.0.2p에서 servername 매개변수를 명시적으로 설정하지 않고 연결하여 이 문제를 재현할 수 있었습니다.

openssl s_client -connect <mydomain>:<some_port> -showcerts

이 요청은 기본 서버의 인증서만 제공할 뿐이며 URL에 제공한 도메인 이름은 존중하지 않습니다. 반면에 servername 매개변수를 지정하는 경우:

openssl s_client -connect <mydomain>:<some_port> -showcerts -servername <mydomain>

.. 요청이 올바른 도메인으로 전송되고 올바른 인증서가 반환됩니다.

컬을 사용하거나 웹 브라우저를 통해 동일한 웹 서버에 액세스할 때 이 문제를 관찰하지 못했습니다. 웹 브라우저 및 컬의 구현이 백그라운드의 URL에서 서버 이름을 추출하여 서버 이름을 설정하는 것으로 의심됩니다. openssl은 이를 선택적 매개변수로 처리합니다.

따라서 귀하의 경우에는 다음을 수행해야 한다고 생각합니다.

  • 요청이 생성된 위치를 확인하세요.
  • 서버 이름을 설정하는 옵션이 있는지 확인하세요.

관련 정보