10초만에 만드는 로컬 프록시 서버

조갱·2025년 8월 24일

이슈 해결

목록 보기
16/17

문제의 발단

사전 배경 : Shopby 서비스는 K8S 환경에서 동작한다.

Shopby는 K8S 환경에서 동작합니다.
따라서, 내부 internal 통신을 위해서는 내부 cluster 통신 을 사용하는데요,

일반적으로 물리 장비나, VPC 에 인스턴스를 띄워

http://10.123.123.123:1234/internal-api

와 같이 VIP (Virtual IP) 나 FIP (Floating IP) 에 직접 통신하는 것에 비해, 클러스터 도메인

http://<service-name>.<service-namespace>.svc.cluster.local/internal-api

을 사용하는 것이 특징입니다.

그래서 동일한 클러스터 내에 위치한게 아니라면, 클러스터 도메인을 사용할 수 없는데요,
이는 로컬 환경 에서 alpha 환경의 인스턴스를 띄워 테스트할 때 제약이 됩니다.

Shopby는 이를 해결하기 위해 FeignClient 의 Interceptor 를 활용합니다.
로컬에서 alpha 환경의 인스턴스를 띄울 때에는 spring profiles 를 보고
internal 통신의 도메인을 http://{Alpha API Gateway}.shopby.co.kr 로 변경시킵니다.

어제까지는 됐는데..

분명 어제까지는 http://{Alpha API Gateway}.shopby.co.kr 로 통신이 됐었거든요?!
근데 오늘부터 갑자기 503 Service Unavailable 에러가 떨어지는거예요.

요청을 잘못 보냈는지 확인해봐도 정상이고, 파드도 정상적으로 떠있었어요.
무엇보다, 로컬 터미널에서 https:// 프로토콜로 요청하면 정상 응답이 됐어요.

데브옵스에 문의를 해봤는데, http 프로토콜은 원래부터 막혀있었대요 (?)
그동안 왜 된건지는 모르겠지만, 아무튼 해결을 해야합니다.

시도했던 것들

이건 첫번째 레슨, https 프로토콜로 요청 하기.

아무튼 로컬 터미널에서 https 로 요청하면 잘 됐으니, feign client 도 https 로 요청하면 잘 될거같았어요. 그러나 결과는 처참하게 실패.

SSL Handshake 관련 에러랑, 인증서 관련 에러가 발생했어요.
어차피 내부 통신이니까 TrustManager 를 통해 인증서를 모두 허용하게 바꿔봤어요.
근데 안되더라구요.

참고로, Spring Cloud Open Feign Client 은 별도의 설정이 없으면 JVM에서 제공하는 HttpUrlConnection 을 사용해요.

HttpUrlConnection를 사용하면 TrustManager 를 설정할 수 없어서,
별도 설정을 통해 구현체를 okhttp, webClient, http Client 로 바꿔서 TrustManager 를 설정해줘야해요.

이제 두번째 레슨, 인증서 등록 하기

TrustManager 로도 인증서 무시가 안됐으니, 직접 인증서를 등록해봤어요.
위에서 로컬 터미널에서는 https 통신이 된다고 했었잖아요?

  • 로컬 터미널 (curl) <> https
    • OS 레벨의 인증서를 사용하여 통신 가능
  • 로컬 어플리케이션 <> https
    • OS 레벨 인증서를 사용하지 않고 자체 인증서를 사용하기 때문에,
      별도로 설정해주지 않으면 통신 불가능

그래서 로컬에서 인증서를 발급받고, 이거를 스프링부트 어플리케이션에 적용해줬는데, 그래도 에러가 동일하게 발생하더라구요.

드디어 세번째 레슨, 로컬 프록시 서버 구현 하기

로컬에서 테스트 할 때마다 로컬 프록시 서버를 켜야만 하는 단점이 있어요.
일단 빠르게 테스트는 해야했기에 그냥 로컬 프록시 서버를 구현하기로 했어요.

로컬 프록시 서버 구현하기

1. Node.js 설치 (node --version 으로 이미 설치되어있다면 패스)

brew install node

2. 프로젝트 생성 및 패키지 설치

mkdir local-proxy
cd local-proxy
npm init -y
npm install http-proxy

3. 코드 작성 (vi proxy.js)

inteconst http = require('http');
const httpProxy = require('http-proxy');

const URI = 'https://alpha-api.domain.com';

// 프록시 서버 생성
const proxy = httpProxy.createProxyServer({
  target: URI,
  changeOrigin: true,
  secure: false, // self-signed SSL 인증서 허용하려면 true → false
});

// HTTP 서버 생성
const server = http.createServer((req, res) => {
  console.log(`Proxying ${req.url} to ${URI}${req.url}`);
  proxy.web(req, res, {});
});

server.listen(9090, () => {
  console.log('Proxy server listening on http://localhost:9090');
});

4. 실행

node proxy.js

5. 마무리

이제

POST http://localhost:9090/internal/order

Content-Type: application/json
Version: 1.0

{"key": "value"}

로 요청하면, 프록시에 의해

POST https://alpha-api.domain.com/internal/order

Content-Type: application/json
Version: 1.0

{"key": "value"}

와 같이 URL 을 제외한 Method, Header, body 가 모두 넘어가게 됩니다.

profile
A fast learner.

0개의 댓글