codingstairs
노트에듀라이프연락
⌕검색⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

연락하기

로그인 없이도 보낼 수 있어요. 답변이 필요하면 이메일을 함께 적어 주세요.

  • 익명 폼으로 의견 남기기 →
  • ✉ warragon112@gmail.com
  • 카카오톡 오픈채팅 ↗

© 2026 codingstairs

  • 노트
  • 에듀
  • 검색
  • 라이프
  • 연락
  • 약관
  • RSS
  • GitHub
노트›infra

로컬 HTTPS — mkcert 와 자체 CA

2026-04-28 게시· 2026-05-18 갱신·0회 조회

로컬 HTTPS — mkcert 와 자체 CA

요즘 웹 기능 중 일부는 HTTP 에서는 동작하지 않습니다. Service Worker · WebAuthn · 일부 미디어 API · Cookie SameSite=None 의 Secure 플래그가 그렇습니다. 운영에서는 자연스럽게 HTTPS 가 깔리지만, 로컬 개발에서는 별도 설정이 필요. 이 글은 로컬 HTTPS 가 필요한 자리 · mkcert 의 모델 · OS 별 트러스트 스토어 · 다른 길 (openssl · ngrok · Caddy local CA) · HSTS preload 와의 충돌 같은 미묘한 자리.

1. 로컬 HTTPS 가 필요한 자리

브라우저 보안 모델이 점점 강해지면서 https:// 또는 http://localhost 만 허용되는 기능이 늘어남.

기능 HTTP localhost HTTP 다른 호스트 HTTPS
Service Worker · PWA 가능 불가 가능
WebAuthn 가능 불가 가능
getUserMedia (카메라 · 마이크) 일부 가능 불가 가능
SameSite=None Cookie Secure 강제 Secure 강제 가능
Cross-origin Cookie · CORS 제한 제한 자연스러움

localhost 자체는 보안 컨텍스트로 취급되어 일부 기능이 동작. 다음 자리에서 로컬 HTTPS 가 필요해집니다.

  • 가상 호스트 (app.test · myapp.local) 를 쓸 때.
  • Cookie 의 SameSite=None Secure 시험.
  • 프로덕션과 동일한 흐름 (HSTS · 리다이렉트 · 쿠키 동작) 검증.
  • WebRTC · 카메라 · 마이크 등을 IP 기반 접근에서 시험.

2. mkcert 에 대한 이야기

Filippo Valsorda 가 2018 에 공개한 로컬 CA 발급 도구. Go 로 작성된 단일 바이너리.

흐름:

  1. 첫 실행 시 로컬 머신에만 신뢰되는 자체 CA (루트 인증서) 생성.
  2. 만든 CA 를 OS 와 브라우저의 트러스트 스토어에 등록.
  3. 도메인 인증서를 그 CA 로 서명해 발급.
# Mac
brew install mkcert nss   # nss 는 Firefox 트러스트용
mkcert -install
mkcert localhost 127.0.0.1 ::1 myapp.local "*.myapp.local"

# Linux
sudo apt install libnss3-tools mkcert
mkcert -install
mkcert localhost 127.0.0.1 myapp.local

# Windows (PowerShell, scoop 또는 chocolatey)
scoop install mkcert
mkcert -install
mkcert localhost 127.0.0.1 myapp.local

결과로 myapp.local+3.pem (인증서) 과 myapp.local+3-key.pem (개인키) 두 파일. 개발 서버에 이 두 파일을 지정.

3. Vite · Next · 일반 Node 서버

// Vite
import fs from 'node:fs';
export default {
  server: {
    https: {
      cert: fs.readFileSync('./myapp.local+3.pem'),
      key:  fs.readFileSync('./myapp.local+3-key.pem'),
    },
  },
};
// Node http2
import http2 from 'node:http2';
http2.createSecureServer({
  cert: fs.readFileSync('./myapp.local+3.pem'),
  key:  fs.readFileSync('./myapp.local+3-key.pem'),
}, app).listen(8443);

4. OS 트러스트 스토어

mkcert -install 이 자동 처리하지만 내부 동작은 OS 마다 다름.

OS 저장소 도구
macOS System Keychain security add-trusted-cert
Windows Trusted Root Certification Authorities certmgr.msc 또는 certutil
Linux (Debian / Ubuntu) /usr/local/share/ca-certificates/ + update-ca-certificates ca-certificates 패키지
Linux (Fedora / RHEL) /etc/pki/ca-trust/source/anchors/ + update-ca-trust ca-certificates

브라우저:

  • Chrome · Edge · Safari — OS 트러스트 스토어 그대로 사용.
  • Firefox — 별도 NSS 데이터베이스. mkcert 는 nss 도구로 자동 등록.

5. 다른 길

openssl 자체 서명 — 일회성 · 서버 간 통신 · 로컬 단일 사용에 충분 (CA 미트러스트라 매번 경고):

openssl req -x509 -newkey rsa:4096 -nodes \
  -keyout key.pem -out cert.pem \
  -days 365 -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

ngrok · localhost.run · cloudflared tunnel — 로컬 서버를 외부 HTTPS URL 로 노출:

도구 메모
ngrok (2013) 가장 오래됨. 무료 + 유료 정적 도메인.
Cloudflare Tunnel Cloudflare 계정 + 도메인 결합. 무료 티어 폭 넓음.
localhost.run 가입 없이 SSH 만으로 노출.
Tailscale Funnel Tailnet 도메인 노출.

장점은 자체 CA 가 필요 없음 (이미 신뢰된 인증서). 단점은 외부 서비스 의존.

6. Caddy 의 자체 local CA

Caddy 는 첫 실행 시 자체 local CA 를 만들고 OS 트러스트 스토어에 등록 가능. mkcert 와 모델은 같지만 Caddy 의 리버스 프록시 흐름과 자연스럽게 결합.

{
  local_certs
}

myapp.local {
  reverse_proxy 127.0.0.1:3000
}

이 한 자리만 돼도 https://myapp.local 이 신뢰된 인증서로 동작. mkcert 별도 설치 없이.

7. 빌트인 옵션

일부 프레임워크는 자체적으로 HTTPS 옵션:

  • next dev --experimental-https (Next 13.5 ~).
  • Vite server.https = true 만 두면 자동 자체 서명 (브라우저 경고 발생).

빌트인은 빠르지만 트러스트 안 된 인증서. 실 시험은 mkcert · Caddy 가 권장되는 흐름.

8. hosts 파일 + mkcert

localhost 가 아닌 가상 호스트로 시험하려면 hosts 파일 매핑:

# Mac / Linux: /etc/hosts
# Windows: C:\Windows\System32\drivers\etc\hosts
127.0.0.1 myapp.local
127.0.0.1 api.myapp.local
mkcert myapp.local "*.myapp.local"

*.myapp.local 로 와일드카드를 두면 서브도메인이 늘어나도 같은 인증서 재사용.

9. 팀 공유는 권장 안 됨

mkcert 의 CA 는 한 머신에만 신뢰되어야 안전. 팀이 같은 CA 를 공유하는 흐름은 권장 안 됨 — 그 CA 가 유출되면 팀의 모든 머신이 위협. 각자 mkcert -install 후 자기 머신에서 발급.

CI 에서 HTTPS 시험은 자체 서명 + NODE_TLS_REJECT_UNAUTHORIZED=0 조합 또는 testcontainers 같은 격리 환경. mkcert 를 CI 머신에 설치하면 매번 새 CA 가 만들어져 혼선.

10. 자주 걸리는 자리

Firefox 미인식 — NSS 라이브러리 (libnss3-tools · nss) 없으면 Firefox 트러스트 스토어에 자동 등록 안 됨. mkcert 가 경고 출력.

HSTS preload 충돌 — .dev · .app · .test 일부 TLD 가 HSTS preload 에 포함되어 HTTP 가 강제로 HTTPS 로 리다이렉트됨. .local 또는 .localhost 가 비교적 안전.

mkcert 미설치 머신에서 인증서 사용 — 다른 사람의 머신에서 같은 인증서를 쓰면 OS 가 CA 를 모르므로 경고. 머신마다 새로 발급해야 함.

포트 80 / 443 권한 — 일반 사용자는 1024 미만 포트 바인딩이 권한 필요 (Linux). 8443 같은 고포트 사용 또는 setcap / 포트 포워딩.

인증서 SAN 누락 — CN 만 두면 최근 브라우저가 거부. subjectAltName 에 모든 호스트 · IP 포함.

유효 기간 — mkcert 도메인 인증서는 825 일 기본. 만료 후 재발급.

트러스트 스토어 재설치 — OS 재설치 · 로그인 사용자 변경 시 CA 가 사라짐. mkcert -install 다시 실행.

하고픈 말

대부분의 로컬 개발은 http://localhost 보안 컨텍스트로 충분합니다. PWA · WebAuthn 같은 운영 흐름을 그대로 시험해야 할 때만 mkcert (단일 머신) 또는 Caddy local_certs (리버스 프록시 결합) 를 도입할 만한 자리. CI 에는 testcontainers 가 더 깔끔.

Next

  • cloud-emulator-stack
  • (infra 끝)

mkcert GitHub · Caddy Local Certs · openssl x509 docs · ngrok 공식 · Cloudflare Tunnel · Tailscale Funnel · MDN Secure Contexts · HSTS Preload 를 참고합니다.

infra 카테고리의 다른 글

카테고리 전체 보기 →
  • 클라우드 에뮬레이터 스택 — 4번째 환경의 설계
  • 단일 서버 운영의 자리
  • 루프백 바인딩과 SSH 터널
  • Caddy 와 nginx — 비교의 자리
  • Docker Compose 패턴
  • Docker 기초