2026년 11월 13일 금요일

포트 하나 안 열고 홈 서버 운영하기 (3) 관리 화면 잠그기

홈서버-따라하기 시리즈 3편. 터널로 공개한 서비스 중 나만 써야 하는 것(관리 화면, 개인 대시보드)을 로그인 뒤로 숨긴다. 앱에 로그인 기능을 만들지 않고 Cloudflare Access 를 앞에 세운다.

Access 가 하는 일

요청이 서버에 닿기 전에 Cloudflare 엣지에서 "이 사람이 들어와도 되는가"를 확인한다. 통과하지 못한 요청은 서버까지 오지 않는다. 앱은 로그인 화면도, 비밀번호 저장도 필요 없다.

설정 순서

  1. Zero Trust 대시보드에서 로그인 수단에 One-time PIN(이메일 일회용 코드)을 추가한다. 기본 수단만 있으면 이메일 입력란이 나오지 않는다.
  2. Access → Applications 에서 Self-hosted 애플리케이션을 만들고 보호할 주소(admin.example.com)를 넣는다.
  3. 로그인 수단은 One-time PIN 하나만 선택하고 Instant authentication 을 켠다.
  4. 정책을 만든다. Action 은 Allow, Include 는 Emails 에 내 메일 주소.

이제 그 주소로 들어가면 메일 주소를 묻고, 허용한 주소로만 코드가 간다.

같은 사이트의 일부만 잠그기

공개 사이트의 관리 화면만 잠그고 싶다면 호스트 이름을 나누는 편이 깔끔하다. 같은 컨테이너를 www.example.com 과 admin.example.com 두 이름으로 터널에 연결하고, Access 는 admin 쪽에만 건다. 앱은 Host 헤더를 보고 관리 경로를 admin 호스트에서만 응답한다.

오리진을 직접 못 두드리게

Access 는 엣지에서만 막는다. 서버 안에서는 Host 헤더만 맞추면 인증 없이 응답이 온다.

curl -H 'Host: admin.example.com' http://127.0.0.1:8081/

배포 직후 점검에는 편하지만, 이 포트가 LAN 이나 인터넷에 열려 있다면 누구나 같은 방법으로 우회할 수 있다는 뜻이다. 그래서 두 가지를 지킨다.

  • 컨테이너 포트는 127.0.0.1 에만 바인딩한다(2편).
  • 민감한 앱은 Access 가 요청에 붙여 주는 JWT(Cf-Access-Jwt-Assertion 헤더)를 서버에서 검증한다. 서명 키는 팀 도메인의 공개 인증서 주소에서 받고, 대상(aud) 값이 내 애플리케이션의 것인지 확인한다. 이렇게 하면 터널을 거치지 않은 요청은 앱이 스스로 거절한다.

서비스가 많아지면

사용자가 여럿이거나 앱마다 권한이 달라야 하면 자체 SSO(나는 Authentik)를 두는 방법도 있다. 프록시 방식으로 앱 앞에 세우면 앱을 고치지 않고 로그인을 붙일 수 있다. 다만 혼자 쓰는 서비스 몇 개라면 Access 의 이메일 코드로 충분했다.

설정 중에 막혔던 부분은 Cloudflare 라벨의 글에 따로 적었다. 다음 편은 백업과 정기 정비다. 시리즈 전체 목록은 여기.

댓글 없음:

댓글 쓰기

반도체 주식을 보기 전에 그려 두는 지도 — 설계, 파운드리, 메모리, 장비, 소재, 후공정

"반도체주"라고 한 묶음으로 부르지만, 그 안의 회사들은 하는 일도 돈 버는 방식도 전혀 다르다. 같은 뉴스에 어떤 회사는 오르고 어떤 회사는 내리는 이유가 여기에 있다. 종목을 들여다보기 전에 머릿속에 그려 두면 좋은 지도를 정리한...