NGINX: localhost가 _로 리디렉션 중입니다.

NGINX: localhost가 _로 리디렉션 중입니다.

nginx 버전/1.18.0(Ubuntu) — Ubuntu 22.04.01 LTS x86_64 커널 6.0.8


호스트 이름이 여러 개 있고 nginx를 실행 중이며 모든 것이 작동하는 서버(위 설치 사양)가 있습니다(nginx 포함, http:에서 https:로 리디렉션).

실제로 기본 서버에서 이 작업을 수행하는 방법은 다음과 같습니다.

listen 80 default_server;

listen 443 default_server ssl;
# force https-redirects
if ($scheme = http) {
  return 301 https://$host$request_uri;
}

server_name _;

이상한 동작은 다음과 같습니다.

URL 다음으로 리디렉션 노트
http://mumblefrotz/ https://mumblefrotz/ (예상대로 작동함)
http://mumblefrotz.fullyqualified.com/ https://mumblefrotz.fullyqualified.com/ (예상대로 작동함)
http://127.0.0.1/ https://127.0.0.1/ (예상대로 작동함)
http://localhost/ https://_ 실패

왜 이러는 걸까요? 나는 그것이 뭔가 관련이 있다고 의심한다.server_name지시문은 문자 그대로 받아들여지지만 왜 localhost.

바라보면서이 스택 오버플로 제안, 나는 다음 두 가지를 모두 시도했지만 여전히 놀라운 밑줄을 얻었습니다.

  • server_name ~.;
  • server_name ~^(.+)$;

내 기대는 그 $host거다HTTP 요청에 전달된 호스트 이름, 정의된 경우 가상 호스트가 이를 선택하고 그렇지 않은 경우 기본 서버 정의로 대체합니다.

내가 알 수 있는 것은 http://localhost/제대로 해결되지 않는 유일한 것입니다. 나는 그것을 고치고 싶습니다.

답변1

요청을 하는 데 어떤 클라이언트가 사용되었는지에 대한 정보가 없습니다. 에 쓰여진대로nginx 문서, $host변수에는 다음이 포함됩니다.

우선 순위는 다음과 같습니다: 요청 라인의 호스트 이름, "Host" 요청 헤더 필드의 호스트 이름, 또는 요청과 일치하는 서버 이름

여기서 "요청 라인"은 GETHTTP 요청에서 동사 뒤의 호스트 이름을 의미합니다.

두 번째는 Host헤더 필드를 의미합니다.

세 번째는 에 구성된 이름을 의미합니다 server_name.

귀하의 경우에는 테스트 클라이언트가 Host헤더가 포함되지 않은 요청을 한 것 같습니다. 따라서 nginx는 변수 server_name내용에 대한 구성을 사용했습니다 $host.

개인적으로 저는 Ansible로 nginx 구성을 관리하기 때문에 모든 가상 서버에 대해 HTTP -> HTTPS 전달 블록을 생성합니다. 그렇게 하면 return 404내가 관심이 없는 다른 모든 호스트 이름에 대해 가상 호스트를 가질 수 있습니다.

그러나 리디렉션을 위해 공통 가상 호스트를 구현해야 하는 경우 다음 접근 방식을 사용할 수 있습니다.

map $http_host $redirect_host {
    ~ (^.+$) $http_host;
    default  example.com;
}

server {
    listen 80 default_server;
    ...

    if ($scheme = http) {
        return 301 https://$redirect_host$request_uri;
    }
}

헤더 가 없는 경우를 제외하고 항상 리디렉션 대상에 HTTP 호스트 헤더를 사용합니다 Host. 이 경우 example.com리디렉션 대상으로 사용됩니다. 예를 들어 기본 도메인 이름을 리디렉션 대상으로 할당할 수 있습니다.

관련 정보