랩톱에서는 응답하고 다른 곳에서는 전혀 응답하지 않는 개발 서버는 보통 잘못된 주소에 바인딩되어 있습니다. 연결은 받아들이지만 페이지를 거부하는 서버는 보통 호스트 이름 검사에서 실패합니다. 이는 서로 다른 결함이며 수정 방법도 다르고, 올바른 구성을 선택하는 것은 누가 작업 공간에 도달해야 하는지와 어떻게 도달하는지에 달려 있습니다.

세 가지 질문이 답을 결정합니다. 누가 연결하는지, 어떤 주소에 도달할 수 있는지, 그리고 그 사람에게 라이브 리로드가 동작해야 하는지입니다.

구성 파일이 아니라 소켓부터 시작하십시오

실행 중인 프로세스가 실제로 무엇에 바인딩되었는지, 그것을 시작한 동일한 네트워크 컨텍스트 안에서 읽으십시오. 컨테이너나 이름 공간은 호스트 셸이 볼 수 없는 소켓을 소유할 수 있기 때문입니다. 수신 열은 첫 번째 질문에 답합니다. 로컬 경로만인지, 특정 인터페이스 하나인지, 아니면 모든 인터페이스인지입니다.

ss -ltn '( sport = :8080 )'
ss -ltnp | grep node

루프백 주소는 안전한 기본값이며 원격 클라이언트에게는 쓸모가 없습니다. 와일드카드 바인드는 편리하고 경로가 있는 모든 인터페이스에 포트를 노출하며, 이는 터널도 함께 가진 머신에서 대부분의 사람이 의도하는 것보다 넓습니다. 특정 주소는 중간 선택지이며, 소켓이 생성되는 순간에 인터페이스가 그 주소를 소유한 경우에만 동작합니다. 이 구분이 중요한 이유는 세 가지 바인드 중 두 가지가 브라우저에서는 동일해 보이지만 두 번째 인터페이스가 생기는 순간 완전히 다르게 동작하기 때문입니다.

경로나 방화벽 규칙을 건드리기 전에 그 관찰에 맞추십시오. 프로세스가 잘못된 주소에서 수신하고 있다면 어떤 정책 라우팅도 클라이언트를 그곳에 도달시키지 못합니다.

누가 도달해야 하는지에 따라 바인드 주소를 선택하십시오

이 머신에서 본인만 페이지가 필요하다면 루프백 바인드를 유지하고 멈추십시오. 같은 터널의 동료 한 명이 필요로 한다면 터널 인터페이스 주소를 바인드하고 방화벽이 그 출처만 허용하게 하십시오.개발 서버를 실제로 테스트하는 사람들 너머로 게시하는 것은 결국 작업 공간을 인터넷에 노출시키는 습관입니다.

컨테이너 내부의 브라우저가 서버에 도달해야 한다면 바인드 주소는 컨테이너의 네트워크가 라우팅할 수 있는 주소여야 하며, 그것은 대개 호스트가 자신을 위해 해석하는 주소가 아닙니다. 구성을 편집하기 전에 경우를 결정하십시오. 세 경우는 세 가지 다른 값을 낳고 그중 하나만 맞습니다. 여기서 추측하면 설정의 다른 어느 부분보다 시간을 더 낭비합니다.

그다음 런처가 실제로 읽는 형식으로 주소를 설정하십시오. 구성 파일과 서버를 프로그래밍 방식으로 구성하는 스크립트는 같은 옵션을 사용하지 않습니다.

devServer: {
  host: "10.77.0.20",
  port: 8080,
  allowedHosts: ["dev.corp.example"],
}

그 조각의 주소는 예시이며 호스트가 소유한 VPN 주소를 나타냅니다. 프로젝트가 서버를 new WebpackDevServer(options, compiler)로 구성한다면 대신 생성자 인수로 옵션을 전달하십시오. webpack 구성의 별도 devServer 속성은 그 경로에서 참조되지 않기 때문입니다. 구성 파일과 Node API 사이의 이 차이는 절대 읽지 않는 프로젝트에 조각을 복사하는 사람을 잡아냅니다.dev-server 문서는 두 시작 방식을 구분하며 사용 중인 버전과 대조해야 할 참조입니다.

호스트 이름 검사를 승인하는 이름에 맞추십시오

호스트 이름 검사는 공격자가 제어하는 이름에서 제공된 페이지가 브라우저를 통해 개발 서버와 대화하지 못하게 하기 위해 존재합니다. 이를 allowedHosts: "all"로 비활성화하면 그 보호가 사라지고, 내부 서비스에 도달할 수 있는 머신에서는 그 편리함이 거의 값을 하지 못합니다. 브라우저가 어떤 이름을 보낼지 알면 검사를 올바르게 충족하는 것은 저렴합니다.

사용할 정확한 이름을 터널 주소로 해석되는 사설 이름을 포함해 나열하십시오. 클라이언트가 이름을 바인드한 주소와 다른 주소로 해석하면 서버 구성 문제가 아니라 이름 해석 문제이며, 허용 목록에 이름을 추가해도 해결되지 않습니다. 해석은 서버가 아니라 클라이언트에서 확인하십시오.

세 가지 제어를 머릿속에서 분리해 두십시오. 바인드 주소는 어떤 인터페이스가 연결을 받아들이는지 결정하고, 허용 목록은 어떤 Host 헤더가 허용되는지 결정하며, 인증은 누구를 들여보낼지 결정합니다. 세 번째만이 접근 제어이며 개발 서버에는 보통 아무것도 없습니다. 터널 주소도 인증 메커니즘이 아닙니다. 그곳으로 라우팅할 수 있는 사람은 이미 당신이 의지하던 경계 안에 있기 때문입니다.

페이지와 라이브 리로드 소켓을 함께 확인하십시오

의도한 클라이언트에서 구성된 스킴으로 새 요청을 불러오고 캐시가 아니라 결과를 읽으십시오. HTTPS의 경우 예상 호스트 이름과 인증서 유효성 검사를 유지하십시오. 브라우저 경고는 성공적인 수용 테스트가 아니기 때문입니다. 라이브 리로드가 조용히 실패하는 동안 페이지가 렌더링되는 것이 여기서 가장 흔한 부분 성공이며, 빠른 점검 중에는 놓치기 쉽습니다.

curl -sS -o /dev/null -w "%{http_code} %{remote_ip}\n" http://dev.corp.example:8080/
curl -sS -i http://10.77.0.20:8080/ | head -n 5

그다음 브라우저의 네트워크 진단을 열고 WebSocket 연결을 관찰하십시오. 페이지는 하나의 호스트 이름, 포트, 스킴으로 로드되는 동안 리로드 소켓은 다른 것을 사용할 수 있으므로 둘을 따로 확인해야 합니다. 문서화된 클라이언트 URL은 배포된 경로가 정말 다른 값을 필요로 할 때만 구성하고, 클라이언트에 우회 방법을 가르치기보다 경로를 고치는 편을 택하십시오.

수신 주소, 허용된 이름, 허용된 출처, 그리고 두 결과를 프로젝트 노트에 기록하십시오. 그 기록은 다음 사람이 작업 공간을 시작하고 페이지는 로드되지만 절대 새로 고쳐지지 않는 이유를 궁금해할 때 남아 있습니다.

관련 글