트러블슈팅 - VSCode Remote SSH에서 localhost3000 안됨
개요
집에 있는 RHEL 서버로 원격 개발하다가 정말 이상한 현상을 만났다. DDNS로는 웹 서비스가 잘 뜨는데, VSCode Remote에서 localhost:3000으로 접속하면 무한 로딩에 빠지는 이상한 현상. 그냥 포트 하나 다른 걸로 바꾸면 해결될 문제 같은데, 왜 하필 3000번만 이런 문제가 발생하는지 파고들었던 과정을 기록해본다. 결론부터 말하자면 해결했다.
1. 처음 만난 이상한 현상들
집에 셋업한 RHEL 서버(192.168.0.2)를 외부에서 WireGuard로 터널링해서 사용 중이었다. React 개발 서버를 켜고 테스트하려는데 이상한 현상이 발생했다:
- DDNS를 통한 접속(dododombti.iptime.org:3000)은 멀쩡히 됨
- VSCode Remote SSH 접속 후
localhost:3000접속 시 무한 로딩 - VSCode Remote SSH 접속 후
192.168.0.2:3000접속 시 연결 거부
"어? 뭐지?" 당연히 작동해야 할 것 같은 상황인데 작동하지 않아서 의아했다. 먼저 서버에서 3000번 포트가 열려있는지 확인부터 했다.
sudo lsof -i :3000
sudo netstat -tulpn | grep :3000당연히 아무 결과도 없었다. 아, 그런데 재밌는 건 pnpm dev --port 3001처럼 다른 포트로 실행하면 멀쩡하게 작동한다는 점이었다. 3000번 포트에 무슨 저주라도 걸린 건가?
2. 분석: 방화벽, SELinux, 바인딩은 다 괜찮더라
확인해볼 것들을 하나씩 살펴봤다.
방화벽 설정
sudo firewall-cmd --list-all출력결과를 보니 방화벽에는 이미 3000번 포트가 열려있었다. 다른 포트들도 잘 열려 있었고.
ports: 3000/tcp 3001/tcp 3002/tcp ... 기타등등
SELinux 정책
sudo semanage port -l | grep 3000ntop_port_t tcp 3000-3001
ntop_port_t udp 3000-3001
tcs_port_t tcp 30003
흥미로운 발견! 3000-3001 포트가 ntop_port_t로 설정되어 있었다. 이게 문제인가 싶어 SELinux를 비활성화해보기도 했지만, 여전히 같은 문제가 발생했다.
다양한 시도
솔직히 이쯤 되니 좀 짜증이 났다. 다음과 같은 것들을 시도해봤다:
# 호스트 바인딩 변경 시도
HOST=0.0.0.0 npm start
# 또는
pnpm dev --host 0.0.0.0근데 더 황당한 현상이 발생했다:
PORT=3002 HOST=0.0.0.0 npm start→ localhost:3002는 접속 가능, 192.168.0.2:3002는 접속 불가- SELinux를 완전히 꺼도 동일한 현상
"진짜 이거 뭐지?" 라는 생각이 들기 시작했다.
3. 깨달음: WireGuard 터널링 설정이 문제였다
몇 시간 삽질 끝에 문제의 진짜 원인이 WireGuard VPN 터널과 관련되어 있다는 걸 깨달았다. 사실 생각해보면 당연한 건데, 당시에는 머리가 멍해서 그런지 이걸 놓쳤던 것 같다.
WireGuard 인터페이스가 올바른 방화벽 Zone에 없었음
sudo firewall-cmd --get-active-zones
# public: interfaces: enp5s0
# (wg0 없음)아하! WireGuard 인터페이스(wg0)가 방화벽 Zone에 추가되지 않았다. 이러니 VPN을 통한 트래픽이 제대로 처리되지 않았던 거다.
서버 내 IP 테스트로 확인해보기
# 물리 LAN IP
curl -v http://192.168.0.2:3000/ # 200 OK
# wg0 인터페이스 IP
ip addr show wg0
# inet 192.168.2.1/24 scope global wg0
curl -v http://192.168.2.1:3000/ # 200 OK흥미롭게도 서버 내에서는 두 IP 모두에서 정상 응답을 받았다. 그런데 왜 클라이언트에서는 안 되는 걸까?
클라이언트 AllowedIPs 설정이 불완전했음
[Interface]
Address = 192.168.2.2/32
[Peer]
AllowedIPs = 192.168.0.0/24 # LAN 대역만 지정여기서 큰 실수를 발견했다. AllowedIPs에 터널 IP 대역(192.168.2.0/24)이 포함되지 않았다. 이러니 클라이언트가 WireGuard IP(192.168.2.1)로 패킷을 보낼 때 터널을 타지 않고 일반 라우팅을 타게 된 것이다. 정신승리 하듯 "아, 이건 당연히 안 되는 거였어!"라고 생각했다(물론 나중에 알게 된 거지만).
4. 최종 해결책: 세 가지 설정 조합
결국 문제는 세 가지 설정의 불일치였다:
방화벽 Zone에 WireGuard 인터페이스 추가
sudo firewall-cmd --zone=public --add-interface=wg0 --permanent
sudo firewall-cmd --reload클라이언트 AllowedIPs 수정
[Peer]
AllowedIPs = 192.168.0.0/24, 192.168.2.1/32VSCode SSH 설정을 WireGuard IP로 변경
Host rhel-wireguard
HostName 192.168.2.1 # wg0 인터페이스 IP
User leedo
ServerAliveInterval 60
ServerAliveCountMax 3
이 세 가지를 모두 조합하니 드디어 VSCode Remote에서 localhost:3000 접속이 정상적으로 작동했다!
5. 양심 고백과 교훈
사실 이 문제, 네트워크에 대한 이해가 제대로 되어 있었다면 훨씬 빨리 해결했을 거다. 내가 왜 이렇게 삽질을 했을까 생각해보니:
- 방화벽 Zone 설정의 중요성을 간과했다 - VPN 인터페이스도 방화벽 zone에 명시적으로 등록해야 한다는 사실
- WireGuard AllowedIPs의 의미를 잘못 이해했다 - 이건 "허용된 IP"가 아니라 "이 IP들로 가는 패킷은 터널을 타게 해라"라는 의미였다
- SSH HostName 설정의 중요성 - VSCode Remote는 이 값 그대로 연결을 시도하기 때문에 터널 IP를 사용하는 게 훨씬 효율적이었다
결론적으로, 네트워크는 단순히 "연결된다/안 된다"의 문제가 아니라 라우팅과 보안 정책의 조합이라는 것을 다시 한번 깨달았다. 이런 삽질이 싫다면 네트워크에 대한 이해도를 높이는 게 중요하다고 생각한다.
그리고 제발, 다음부터는 포트 3000만 안 된다고 해서 몇 시간씩 삽질하지 말고, 다른 포트 써보고 안 되면 그때 파고들자. 시간은 소중하니까.
WireGuard MTU 설정으로 인한 SSH 연결 불안정 문제는 [[KnowledgeBase/Blog/WireGuard VPN에서 VS Code 원격 SSH 연결 문제 해결 가이드]]에서 다룬다.
댓글
첫 번째 댓글을 남겨보세요.