사설 사이트와 인터넷 사이에는 세 가지 독립적인 결정이 있습니다. 어느 소켓이 연결을 받아들이는지, 어느 경로가 그것을 전달할 수 있는지, 선택한 서버가 어느 HTTP 클라이언트에 응답하는지입니다. 서버 블록은 첫 번째 결정만 내립니다. 나머지 둘을 별도의 통제로 다루지 않으면 사이트는 사설처럼 보이지만 오래된 입구는 열린 채로 남습니다. VPN 전용 NGINX 실패의 대부분은 첫 번째 계층만 테스트하는 데서 옵니다.

예제는 tun0의 10.90.0.1에 있는 Linux OpenVPN 게이트웨이, 10.90.0.0/24의 클라이언트, 보존된 소스, 그리고 이 입구용으로 예약된 TCP 8443을 사용합니다. 값을 조정하되 계층은 유지하십시오.

호스트 이름이 아니라 소켓에서 시작하십시오

HTTPS 리스너를 터널 주소와 전용 포트에 바인딩하십시오. 특정 주소는 와일드카드 소켓에 이름 검사를 더한 것보다 생각하기 쉽습니다. 커널이 그 포트를 다른 로컬 주소에 넘기지 않기 때문입니다.

server {
    listen 10.90.0.1:8443 ssl;
    server_name admin.corp.example;

    ssl_certificate     /etc/nginx/tls/admin-fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/admin-key.pem;

    root /srv/private-site;

    allow 10.90.0.0/24;
    deny all;

    location / {
        try_files $uri $uri/ =404;
    }
}

인증서에는 클라이언트가 입력하는 서비스 호스트 이름이 있어야 하고, 사설 DNS 뷰는 그 호스트를 바인딩된 주소로 확인해야 합니다. server_name은 가상 호스트를 고를 뿐 누구도 인증하지 않습니다. DNS 항목이 없으면 TLS 장애처럼 보이는 인증서 오류가 발생합니다. 인증서를 교체하기 전에 이름을 확인하십시오.

파일을 추가하기 전에 실제 구성을 읽으십시오. 포함과 와일드카드 리스너가 같은 루트를 다른 곳에서 제공할 수 있고, 기본 서버가 새 블록이 보지 못하는 요청에 응답할 수 있습니다.

그 콘텐츠에 대한 다른 모든 리스너를 닫으십시오

listen 지시문을 나열하고 그것들이 제공하는 루트를 비교하십시오. 다른 애플리케이션을 위해 추가한 블록이 같은 업스트림으로 프록시할 수 있고, 오래된 기본 서버가 새것을 배치한 뒤에도 계속 응답할 수 있습니다. 그 출력이 실제 목록이며 방금 편집한 파일이 아닙니다. 같은 콘텐츠를 제공하는 모든 루트를 비교하십시오.

sudo nginx -T | grep -n "listen\|server_name\|root\|proxy_pass"

두 주소 체계를 모두 확인하십시오. IPv4 바인딩은 IPv6 소켓을 그대로 두고, 새 A 레코드는 여전히 공개 경로를 가리키는 오래된 AAAA 응답을 철회하지 않습니다.

오래된 가상 호스트를 별도 변경으로 폐기하십시오. 새 블록의 공개 쌍둥이를 제거하는 것이 실제로 입구를 닫는 단계입니다. 사설 리스너는 의도한 입구만 추가합니다.

호스트에서 들어오는 경로의 범위를 정하십시오

수신 주소는 소켓을 제한할 뿐 인그레스 인터페이스를 제한하지 않습니다. 다른 곳에서 그 주소로 라우팅된 패킷도 여전히 로컬 입력으로 도착하므로, 호스트 방화벽에는 연결이 어디서 올 수 있는지에 대한 자체 선언이 필요합니다. 그래서 바인딩만으로는 감사를 충족하기 어렵습니다.

기본 거부 인바운드 정책이 있고 이 서비스에 더 넓은 허용이 없다면, 범위가 정해진 규칙이 터널, 소스 범위, 목적지, 포트를 함께 지정합니다.

sudo ufw allow in on tun0 proto tcp from 10.90.0.0/24 to 10.90.0.1 port 8443

적용하기 전에 실제 방화벽 순서를 읽으십시오. 이전의 넓은 허용이 제한을 무력화할 수 있고, 이전의 최종 드롭이 이 허용에 도달하지 못하게 할 수 있습니다. 예제에 맞추려고 관련 없는 규칙을 비우거나 방화벽을 끄지 마십시오.

그 규칙은 호스트 입력이며 다른 LAN 머신으로 가는 경로가 아닙니다. 게이트웨이의 외부 OpenVPN 리스너는 별도 서비스로 남습니다. 사이트가 이전에 공개였다면 오래된 입구를 어떻게 폐기하고 기존 세션을 어떻게 처리할지 계획하십시오.

위치가 바뀌어도 HTTP 목록을 손상되지 않게 유지하십시오

NGINX는 allow와 deny 항목을 순서대로 평가하며, 위의 서버 수준 목록은 최종 deny 전에 선언된 풀을 허용합니다. 액세스 모듈은 또한 액세스 항목을 정의하는 위치가 상위 목록 대신 자체 목록을 사용한다고 기록합니다. 순서는 항목 자체만큼 중요합니다.

그 초기화가 흔한 회귀입니다. 항목을 하나 추가하는 새 업로드, API 또는 상태 위치가 서버 수준 제한을 조용히 대체하고, 사이트는 가장 최근에 추가된 경로에서 더 넓어집니다.

모든 위치, 별칭, 대체 블록을 같은 정책의 일부로 검토하십시오. IP 검사가 NGINX 인증과 결합되면 satisfy를 이해하십시오. any 설정은 한 메커니즘으로 클라이언트를 통과시키면서 다른 메커니즘은 아직 통과하지 않은 상태일 수 있습니다. 액세스 목록을 위치 검토 체크리스트에 넣으십시오.

HTTP 거부는 TCP 연결이 NGINX에 도달한 뒤에 일어납니다. 그것은 네트워크 제한을 보완하며, 애플리케이션 자체의 권한 부여는 각 사용자에게 계속 적용됩니다.

실제 경로와 실패 사례를 검증하십시오

구성 파서를 실행하고 수신 중인 소켓을 검사한 다음, 의도한 클라이언트에서 새 이름 지정 요청을 하십시오. 인증서가 검증되고, DNS 이름이 바인딩된 주소로 확인되며, 응답이 예상 루트에서 오는지 확인하십시오.

다음으로 제외된 소스와 대체 입구를 테스트하십시오. 작동하는 허용 요청은 닫으려던 경로에 대해 아무것도 말해 주지 않으며, 제외 테스트에서 남은 리스너나 넓은 방화벽 허용이 드러납니다.

부팅 또는 VPN 복구 사례를 반복하십시오. 터널 주소가 존재하기 전에 NGINX가 시작되면 완벽한 파일이라도 바인딩이 실패할 수 있습니다. 주소 준비를 조정하고 공유 웹 서버를 변경하기 전에 로컬 복구 경로를 유지하십시오.

통과한 소켓, 포트, 소스 범위, HTTP 목록을 기록하십시오. 다음 VPN 또는 DNS 변경이 그중 어느 것이든 움직일 수 있으며, 네 개의 이름 있는 값을 작동하는 브라우저 탭보다 비교하기 쉽습니다.

관련 글