개발서버 분리를 위해 VPN 환경에서만 접근 가능한 내부 망을 구성한다.
서론
과거에는 너무 엄격하게 한 나머지, DNS 쿼리를 해도 내부망에 접근 못하게 구성했다.
VPN으로 접근된 트래픽을 Squid 를 통해 Proxy를 구성하고, HTTPS를 MITM시켜 구성했다.
그런데 네이버, 구름 등 대기업들도 이렇게까진 하지 않더라...
이전에 정리한 게시글(https://leestana01.tistory.com/6)이 있는데, 너무 과거 회고에 가깝다.
그래서 내부망 구성 방식을 보기좋게 다시 고안하고 정리한다.
설계 목표
- 인가되지 않은 외부인의 개발 리소스 접근을 일체 금지한다.
- 내부 리소스의 모든 접근은 VPN을 이용해 접근해야한다.
하단에 기술할 구성 방법은 본인이 직접 구상하여 설계한 것으로,
더 좋은 실무적 방법이 있는 경우 공유해주시면 감사할 듯 하다.
방법 1 - Ingress에서 차단하기
결론적으로 이 방식을 사용중이다. 매우 간단한데, 매우 확실하다.
개인적인 우려가 있다면 굳이 ingress까지 트래픽이 한 번 타고 가야한다는 점이다.
externalTrafficPolicy 변경
우선, 사용자가 VPN 환경에서 접속했는지 Client-IP를 확인해야한다.
그러나 기존 `externalTrafficPolicy: Cluster`에서는 ingress-nginx가 실제 클라이언트 IP를 볼 수 없다.
→ 모든 트래픽이 kube-proxy를 거쳐 노드 IP로 변환되기 때문
조금 더 상세히 설명하면 다음과 같이 SNAT이 발생하여, Client-IP가 유실된다.
Client → Node A → (kube-proxy) → Node B의 Pod
다음과 같이 Local로 변경 가능하다.
(주의 : kubectl 직접 패치이므로 ingress-nginx Helm 재설치 시 재적용 필요!)
kubectl patch svc ingress-nginx-controller -n ingress-nginx \
-p '{"spec":{"externalTrafficPolicy":"Local"}}'
환경 분석
VPN 환경이 다음과 같다고 가정하자.
- VPN: WireGuard (wg-easy)
- 클라이언트 서브넷: `10.8.0.0/24`
- VPN pod IP: `10.0.10.51` (node 10.0.10.220)
트래픽 경로는 다음과 같을 것이다.
externalTrafficPolicy: Cluster 라면 어떻게 되나요?
VPN 클라이언트 (10.8.0.x)
→ WireGuard 터널
→ VPN pod (MASQUERADE → 10.0.*.*)
→ NAT Gateway (SNAT → 152.69.*.*)
→ OCI LB (168.107.*.*)
→ kube-proxy (SNAT → 노드 IP)
→ ingress-nginx (sees: 노드 IP)
VPN 클라이언트 (10.8.0.x)
→ WireGuard 터널
→ VPN pod (MASQUERADE → 10.0.*.*)
→ 목적지: dev.notinoty.kr = 168.107.*.* (OCI LB)
→ OCI 내부 라우팅 (같은 VCN이므로 NAT Gateway 미경유, SNAT 없음)
→ OCI LB (168.107.*.*)
→ ingress-nginx (sees: 10.0.*.*) ← VPN Pod IP 그대로 보존
즉, VPN 트래픽의 source IP = VPN pod (10.0.*.*) 이다.
Ingress 수정
이후 각 프로젝트의 gitops(kustomization.yaml)의 기존 patches에 overlay로 다음을 추가한다.
(혹시 몰라 SNAT을 고려하여 NAT 주소까지 추가했다.)
patches:
# 기존 patches에 추가
- patch: |-
- op: add
path: /metadata/annotations/nginx.ingress.kubernetes.io~1whitelist-source-range
value: "10.0.*.*/32,152.69.*.*/32"
target:
kind: Ingress
gitops가 아닌 자체 배포를 사용중이라면, ingress에 annotaion을 직접 추가하면 된다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress이름
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.*.*/32,152.69.*.*/32"
spec:
...(생략)...
방법 2 - DNS에서 차단하기
역시나 매우 간단하다. k8s의 해당 Service주소를 DNS로 가리키면 된다.
다만, DNS-01 방식을 통해 인증해야한다는 점이 치명적인 단점이다.
DNS-01은 txt 기반으로 인증된다.
DNS Provider API가 없다면 인증서를 매번 수동 갱신해야한다. (네임서버에서 txt 직접 수정해야함)
DNS Provider API는 보통 다음을 지원한다.
- Cloudflare
- Route53
- Google DNS
필자는 호스팅케이알을 이용중이므로, 적합하지 않다고 판단했다.
지원되는 환경이라면 와일드카드 지원을 포함하여 꽤 유용하다고 생각한다.
심지어 트래픽을 DNS 수준에서 걸러버릴 수 있다.
간단해서 여기에 방법은 기재하지 않는다.
방법 3 - 외부에서 존재조차 모르게 차단하기
방법이 너무 복잡하므로, 아래 이미지로 갈음한다.
과거에 직접 구성했던 VPN 환경을 이미지로 표현한 것이다.
사실상 필요한 내용이 모두 담겨있다.
다만, Squid 설정이 인터넷에도 없고 AI도 제대로 구성 못한다. 부딪히면서 공부하는게 답이다.

'인프라 > 자유' 카테고리의 다른 글
| JCasC에서 Jenkins 계정 관리 방법 (0) | 2026.03.14 |
|---|---|
| NFS를 통해 다중 노드 스토리지 공유하기 (0) | 2026.03.12 |
| PVC 설정 없이 Wireguard VPN 세팅하기 (0) | 2026.03.09 |
| VPN을 통해 사내망을 구축해보자 (0) | 2026.03.09 |
| Path MTU Discovery(PMTUD)가 뭘까? (0) | 2026.03.09 |