본문으로 건너뛰기

정적 파일 및 디렉터리 응답

Host 매핑은 리버스 프록시를 거치지 않고 fn-knock 게이트웨이가 실행되는 파일 시스템의 파일이나 디렉터리로 요청에 직접 응답할 수 있습니다. 다운로드 파일, 정적 문서, 소규모 사이트 또는 읽기 전용 파일 디렉터리를 공개할 때 적합하며 별도의 웹 서버를 실행할 필요가 없습니다.

정적 응답도 완전한 Host 라우트입니다. 로그인 필요, 고급 인증, 게이트웨이 가시성, WAF, 예약 공개, 요청 로그 및 게이트웨이 속도 제한은 파일을 읽기 전에 적용됩니다. 서버 측 재작성이나 단일 페이지 애플리케이션(SPA) 폴백은 제공하지 않습니다. 알 수 없는 모든 경로에서 index.html을 반환해야 한다면 이 기능을 지원하는 업스트림 웹 서버를 계속 사용해야 합니다.

응답 유형 선택

서비스 Host를 추가하거나 편집할 때 응답 유형에서 다음 중 하나를 선택합니다.

응답 유형요청 동작일반적인 용도
리버스 프록시요청을 HTTP, HTTPS 또는 WebSocket Target으로 전달동적 웹 애플리케이션 및 API
단일 파일현재 Host의 루트 경로 /에서만 지정한 파일 반환다운로드 진입점, 안내 파일, 고정 리소스
디렉터리URL 경로를 지정한 디렉터리의 파일과 하위 디렉터리에 매핑정적 사이트, 문서 및 파일 탐색

리버스 프록시에서 정적 응답으로 전환하면 확인 후 프록시에만 해당하는 Target, 경로 응답, 업스트림 Basic Auth, Host 유지 및 대상 경로 모드를 지웁니다. Host의 인증, 가시성, WAF, 이용 가능 시간대, 제목, 아이콘 및 그룹은 유지됩니다. 편집 창을 닫기 전에 리버스 프록시로 다시 전환하면 아직 저장하지 않은 이번 프록시 초안을 복원할 수 있습니다.

정적 매핑은 파일 내용에서 제목이나 아이콘을 자동으로 추출하지 않습니다. 포털, 매핑 목록 또는 북마크에 알아보기 쉬운 이름을 표시하려면 표시 제목을 직접 입력하고 사용자 지정 아이콘을 업로드합니다.

설정 절차

  1. 서브도메인 모드 또는 리버스 프록시 모드 → 서브도메인 매핑을 사용하고 서비스 Host가 fn-knock 게이트웨이로 들어오는지 확인합니다.
  2. 서브도메인 매핑에서 서비스 Host를 추가하거나 편집한 뒤 단일 파일 또는 디렉터리를 선택합니다.
  3. 서버 경로 옆의 찾아보기를 누릅니다. 게이트웨이 서버의 디렉터리를 차례로 탐색하거나 주소 표시줄에 절대 경로를 입력하고 Enter를 눌러 이동할 수 있습니다.
  4. 디렉터리 응답은 대상 디렉터리로 들어간 뒤 현재 폴더 사용을 누릅니다. 단일 파일 응답은 일반 파일을 선택한 뒤 선택한 파일 사용을 누릅니다.
  5. 디렉터리 응답에서는 필요에 따라 기본 문서, 디렉터리 목록 및 README 렌더링을 조정합니다.
  6. 로그인 필요, 게이트웨이 가시성, WAF, 이용 가능 시간대, 제목 및 아이콘을 설정한 뒤 저장합니다.
  7. 실제 접근 경로에서 루트 경로, 파일 하나, 존재하지 않는 경로 하나를 요청하고 요청 분석에서 라우트 유형과 상태 코드를 확인합니다.

서버 경로 탐색

경로 브라우저에는 관리 화면을 연 컴퓨터가 아니라 fn-knock 게이트웨이 프로세스에 보이는 파일 시스템이 표시됩니다. 기존 경로가 있으면 그 위치에서 시작합니다. 경로가 비어 있으면 POSIX 플랫폼은 /에서 시작하고 Windows는 먼저 사용할 수 있는 로컬 드라이브를 표시합니다. 파일 시스템 루트는 탐색에만 사용할 수 있으며 정적 디렉터리로 선택할 수 없습니다. Docker에서는 컨테이너 안에 마운트된 내용만 탐색할 수 있고, 경로 브라우저가 호스트 경로를 읽거나 마운트를 만들고 변경하지는 않습니다.

주소 표시줄에는 절대 경로를 입력할 수 있으며 옆에는 루트 위치, 상위 디렉터리, 이동 경로 및 새로 고침 작업이 있습니다. 목록은 항상 디렉터리를 일반 파일보다 먼저 표시하고 페이지당 최대 100개 항목과 이전·다음 페이지 이동을 제공합니다. 단일 파일 모드에서는 일반 파일만 선택할 수 있고 디렉터리 모드에서는 현재 폴더를 사용합니다. 안전한 스캔 한도 안에서 처리할 수 없을 만큼 항목이 많으면 잘린 목록을 반환해 잘못된 선택을 유도하지 않고 디렉터리 전체를 오류로 표시합니다.

경로 브라우저는 .으로 시작하는 숨김 이름, __으로 시작하는 내부 예약 이름, 특수 파일, 안전하게 열 수 없는 항목, 보호된 경로와 그 하위 항목을 생략합니다. 보호된 경로의 상위 디렉터리는 다른 위치로 이동하는 데 사용할 수 있지만 정적 루트로 선택할 수 없습니다. 심볼릭 링크는 해석한 대상이 현재 탐색 중인 디렉터리 안에 남고 숨김 또는 보호된 위치로 들어가지 않을 때만 표시됩니다.

현재 폴더 사용이나 선택한 파일 사용을 누르면 시스템은 정확한 경로가 여전히 존재하고 읽을 수 있으며 유형이 일치하는지 다시 확인합니다. 확인에 성공해도 경로를 현재 매핑 초안에 채울 뿐이므로 실제 적용하려면 매핑을 저장해야 합니다. 이 검사는 그 시점의 상태만 확인하며 파일이나 마운트 지점을 잠그지 않습니다. 새 정적 매핑을 저장하거나 서버 경로 또는 응답 유형을 변경할 때도 경로를 검사하지만 디렉터리 옵션만 조정하면 다시 검사하지 않습니다. 선택과 저장이 모두 성공했더라도 이후 경로가 삭제·교체되거나 읽기 권한을 잃을 수 있으므로 게이트웨이는 요청마다 다시 열고 검증합니다.

단일 파일 응답

단일 파일 매핑은 Host의 루트 경로에만 응답합니다.

text
download.example.com/        -> /srv/downloads/manual.pdf
download.example.com/other   -> 404

게이트웨이는 서버 파일명의 확장자에 따라 Content-Type을 설정하며 GET, HEAD, 범위 요청 및 일반적인 조건부 캐시 요청을 지원합니다. 파일 내용이 바뀌면 ETag와 수정 시간도 파일 상태에 따라 갱신됩니다. URL에 서버 파일명을 포함할 필요는 없으며 쿼리 매개변수는 선택된 파일을 바꾸지 않습니다.

디렉터리 응답

디렉터리 매핑은 요청 경로의 각 단계를 설정한 루트 디렉터리 아래에 매핑합니다.

text
docs.example.com/                 -> /srv/docs/
docs.example.com/assets/app.css   -> /srv/docs/assets/app.css
docs.example.com/manual/          -> /srv/docs/manual/

요청이 디렉터리에 도달했지만 URL 끝에 /가 없으면 게이트웨이는 쿼리 매개변수를 유지한 채 슬래시가 있는 표준 주소로 영구 리디렉션합니다. 반대로 디렉터리 매핑의 일반 파일 URL 끝에 /가 잘못 붙으면 쿼리 매개변수를 유지한 채 슬래시를 제거한 주소로 영구 리디렉션합니다. 디렉터리에 들어간 뒤에는 설정 순서대로 기본 문서를 찾습니다. 초기 순서는 index.html, index.htm이며 최대 16개까지 설정할 수 있습니다. 이름은 표시 가능한 단일 파일명이어야 하고 경로 구분자를 포함할 수 없습니다. 목록을 비우면 기본 문서 검색이 꺼집니다.

기본 문서를 찾지 못하면 다음과 같이 동작합니다.

  • 디렉터리 목록이 꺼져 있으면 404를 반환합니다.
  • 디렉터리 목록이 켜져 있으면 현재 디렉터리의 파일 목록을 생성합니다.
  • README.md 렌더링은 디렉터리 목록이 켜진 경우에만 사용할 수 있으며 현재 디렉터리의 README.md를 안전하게 렌더링해 목록 아래에 표시합니다.

디렉터리 목록은 기본적으로 이름순으로 정렬하며 항상 일반 파일보다 디렉터리를 먼저 표시합니다. 페이지에서 이름, 크기 또는 수정 시간을 기준으로 오름차순과 내림차순을 전환할 수 있고 이동 경로 탐색, 밝은 테마와 어두운 테마, 이전·다음 페이지 이동을 제공합니다. 페이지당 최대 100개 항목을 표시합니다. 색인 화면의 레이블은 현재 영어로 표시되며 수정 시간은 중국 표준시(UTC+8)로 고정됩니다. 숨겨진 이름, 특수 파일 또는 안전하게 열 수 없는 항목은 표시하지 않습니다.

README는 GitHub 스타일 Markdown을 사용하며 파일 하나의 최대 크기는 1 MiB입니다. 원시 HTML과 안전하지 않은 내용은 필터링됩니다. 이미지는 동일 출처의 상대 주소만 허용하며 외부 링크에는 보안 속성이 추가됩니다. 기본 문서가 없고 실제로 디렉터리 목록을 표시할 때만 README를 렌더링합니다.

디렉터리 응답은 확장자 재작성, 동적 압축, 후행 경로 폴백 또는 SPA History Fallback을 수행하지 않습니다. 정적 대상을 위한 사용자 지정 응답 헤더나 캐시 정책 설정도 제공하지 않습니다. 요청한 파일이 없으면 즉시 404를 반환합니다.

인증, WAF, 로그 및 캐시

정적 Host는 리버스 프록시 Host와 같은 인바운드 정책을 사용합니다.

  • 로그인 필요와 고급 인증은 파일을 읽기 전에 확인합니다. LAN 출처가 local_exempt에 해당할 수도 있으므로 인터넷 정책은 실제 외부 네트워크에서 검증해야 합니다.
  • 게이트웨이 가시성, 일반 차단 목록, 스캔 차단, 리버스 프록시 속도 제한 및 이용 가능 시간대는 계속 적용됩니다.
  • 현재 Host의 WAF 활성화가 켜져 있고 전역 WAF도 활성화되어 있으면 요청은 WAF를 먼저 거친 뒤 정적 콘텐츠를 읽습니다.
  • 요청 로그와 WAF 로그에는 라우트 유형이 각각 정적 파일 또는 정적 디렉터리로 기록되고 업스트림 대상은 비어 있습니다. 서버 파일 시스템 경로는 로그에 기록되지 않습니다.

공개 정적 파일에는 재검증이 필요한 공용 캐시 정책이 적용됩니다. 인증이 필요하거나 이미 인증 결과가 포함된 응답에는 private, no-store를 사용하여 보호된 콘텐츠가 공유 캐시에 들어가지 않게 합니다. 생성된 디렉터리 목록, 리디렉션 및 오류 응답도 공용 캐시에 저장되지 않습니다.

파일 시스템 보안 경계

서버 경로는 절대 경로여야 하며 표시 가능한 일반 파일 또는 디렉터리를 가리켜야 합니다. 게이트웨이는 파일 시스템 루트 디렉터리, 숨겨진 대상, 상위 디렉터리 순회, 제어 문자, Windows UNC 및 장치 네임스페이스, fn-knock 설정·데이터·로그·키 또는 시스템 디렉터리와 겹치는 경로를 거부합니다. 범위가 지나치게 넓어 보호된 디렉터리를 포함하는 상위 디렉터리도 거부됩니다.

파일 시스템 이름은 정확한 철자 그대로 처리됩니다. POSIX 플랫폼(Linux, macOS 등)에서는 경로 구성 요소의 앞뒤 공백을 자동으로 제거하지 않으므로 /srv/docs/srv/docs 는 서로 다른 대상입니다. 입력 전체가 공백으로만 이루어진 경우에만 거부됩니다. 혼동하기 쉬운 이런 이름은 피하고 경로를 복사할 때 실제 문자를 그대로 유지하는 편이 좋습니다. Windows에서는 이름 끝의 공백이나 점, 예약 장치 이름 및 기타 안전하지 않은 이름을 계속 거부합니다.

디렉터리 안에서는 표시 가능한 일반 파일과 하위 디렉터리에만 응답합니다. 점으로 시작하는 파일과 디렉터리, .well-known은 사용할 수 없습니다. 심볼릭 링크는 정적 루트 디렉터리 안의 안전한 대상으로 해석되어야 합니다. 루트를 벗어나거나 숨겨진 위치로 들어가거나 검증 도중 대상이 바뀌면 요청이 실패합니다. FIFO, 소켓, 장치 파일 같은 특수 유형은 다운로드 콘텐츠로 열지 않습니다.

이 제한만으로 서비스 콘텐츠가 공개하기에 적합한지 판단할 수는 없습니다. 사이트마다 독립된 최소 디렉터리를 준비하고 읽기 전용 권한을 사용하며 백업, 환경 변수, 개인 키, 데이터베이스 또는 애플리케이션 설정을 정적 루트 디렉터리에 복사하지 마십시오. 디렉터리 목록을 공개하기 전에 모든 하위 디렉터리와 README의 링크 및 이미지를 점검해야 합니다.

Docker 및 플랫폼 경로

경로는 항상 fn-knock 프로세스의 관점에서 해석됩니다.

  • Docker에서는 먼저 호스트 콘텐츠를 컨테이너에 읽기 전용으로 마운트한 뒤 컨테이너 내부 경로를 입력해야 합니다. 호스트 경로 자체는 직접 사용할 수 없습니다.
  • Linux, macOS, OpenWrt, fnOS FPK / Lite 및 Synology에서는 해당 패키지 계정에 디렉터리 탐색 및 파일 읽기 권한을 부여해야 합니다.
  • Windows에서는 C:\Sites\docs 같은 로컬 드라이브 절대 경로를 사용합니다. 네트워크 공유 경로와 장치 네임스페이스는 지원하지 않습니다.

Docker Compose 예시:

yaml
services:
  fn-knock:
    volumes:
      - /srv/public-site:/srv/public-site:ro

마운트를 변경한 뒤 컨테이너를 다시 만들고 관리 화면에서 찾아보기를 누릅니다. 경로 브라우저에 /srv/public-site가 보여야 합니다. 해당 디렉터리로 들어가 현재 폴더 사용을 누른 뒤 매핑을 저장합니다. 정적 콘텐츠를 읽기 위해 호스트 루트 디렉터리, /etc 또는 fn-knock 데이터 볼륨 전체를 컨테이너에 마운트하지 마십시오.

정적 매핑은 기존 파일만 읽으며 DNS 레코드를 생성하거나 방화벽 포트를 열거나 컨테이너 마운트를 변경하지 않습니다. 외부 접근 가능 여부는 여전히 현재 배포 플랫폼의 게이트웨이 진입점, DNS, 인증서, 라우터 또는 터널에 따라 결정됩니다.

상태 코드 및 문제 해결

현상확인 항목
저장할 때 경로를 사용할 수 없다고 표시됨절대 경로, 파일 / 디렉터리 유형, 읽기 권한, 보호된 경로 및 Docker 마운트
경로 브라우저에 파일이나 디렉터리가 보이지 않음현재 보고 있는 대상이 게이트웨이 / 컨테이너 파일 시스템인지, 이름이 숨김 또는 예약 이름인지, 읽기 권한, 보호된 경로 및 심볼릭 링크 대상 확인
경로 브라우저에 디렉터리 항목이 너무 많다고 표시됨더 작은 전용 콘텐츠 디렉터리를 사용하고 범위가 넓은 공유 디렉터리를 정적 루트로 직접 선택하지 않음
루트 경로에서 503 반환설정한 루트 디렉터리 또는 단일 파일이 현재 존재하지 않거나 읽을 수 없거나 더 이상 안전하지 않음. 응답에 잠시 후 재시도하라는 안내가 포함됨
하위 경로에서 404 반환파일이 없거나 보안 규칙이 이름을 숨겼거나 디렉터리 목록이 꺼져 있거나 단일 파일 매핑에 루트가 아닌 경로로 요청함
405 반환정적 응답은 GETHEAD만 허용함
사이트 홈 대신 디렉터리 목록 표시기본 문서 이름이나 우선순위가 잘못되었거나 해당 파일을 읽을 수 없음
페이지를 새로 고친 뒤 프런트엔드 라우트에서 404정적 디렉터리는 SPA 폴백을 제공하지 않으므로 History Fallback을 지원하는 업스트림 웹 서버 사용
요청 로그에 업스트림 주소가 없음정적 응답은 게이트웨이가 파일을 직접 읽으므로 정상 동작임

문제를 해결할 때 먼저 편집 창에서 찾아보기를 열고 대상을 다시 찾은 뒤 현재 폴더 사용 또는 선택한 파일 사용을 실행합니다. 그다음 fn-knock 실행 환경에서 권한과 마운트를 확인하고 요청 로그에서 Host, 라우트 유형, 인증 결과, WAF 동작 및 상태 코드를 확인합니다. 시스템 디렉터리까지 범위를 넓히거나 불필요한 root 권한을 부여해 경로 검사를 우회하지 마십시오.

관련 설정은 서브도메인 매핑, Docker Compose로 배포, WAF, 보안 경계 및 기준을 참고합니다.

QQ 커뮤니티: 1081609274