Back to all posts
DevOps

VPN을 버려라: 홈 네트워크로 연결되는 패킷 손실 없는 개인 터널 구축하기

당신은 지구 반대편의 호텔에 앉아 멈춰버린 터미널을 바라보고 있습니다. 간단한 SSH 명령에 Enter 키를 눌렀지만 커서만 깜박일 뿐입니다. 5분 후: Operation timed out(작업 시간 초과). 회사 VPN을 켜고 다시 시도해 보지만, 이번에는 지역 차단(geo-blocking) 때문에 API 호출이 실패합니다.

솔직해집시다. 상업용 VPN은 개발자를 위한 것이 아닙니다. 유지 관리의 악몽이고, 그들의 IP는 지구상의 모든 방화벽에 의해 표시되며, 표준 국제 라우팅에서 발생하는 패킷 손실은 워크플로우를 파괴할 것입니다.

중요한 것은 이렇습니다. 우리는 바위처럼 단단한 차단 방지 브리지를 구축할 것입니다. 프리미엄 VPS를 사용하여 VIP 인터넷 차선에서 트래픽을 포착하고, 거실에 있는 Raspberry Pi에 직접 구멍을 뚫을 것입니다. 멈추는 터미널도, 지역 차단도 없습니다. 오로지 홈 네트워크에 대한 조작되지 않고 제한 없는 액세스만 있습니다.

심층 분석: 표준 VPN이 실패하는 이유

무작위 클라우드 서버에 WireGuard나 OpenVPN을 배포하기만 하면, 검열이 심한 지역의 심층 패킷 검사(DPI)가 몇 시간 내에 연결을 표시하고 조절할 것입니다.

이를 극복하려면 두 가지가 필요합니다.

  1. 프리미엄 라우팅 (AS9929/AS10099): 이것은 물리적 계층입니다. 혼잡한 공용 네트워크 노드를 통과하는 대신, 지연 시간이 짧은 엘리트 엔터프라이즈 케이블에 있는 VPS를 구매합니다.
  2. VLESS-Reality: 이것은 위장입니다. VLESS-Reality는 프록시 트래픽처럼 보이는 대신, 주요 사이트(예: iCloud 또는 Windows Update)에 접속하는 표준 HTTPS 트래픽과 똑같이 보이게 만듭니다. 방화벽은 개발자가 개인 네트워크로 터널링하는 것이 아니라 단지 자신의 캘린더를 동기화하는 사람만 보게 됩니다.

구축해 봅시다.

개인 터널 시스템 다이어그램


1단계: 엘리트 릴레이(SaltyFish VPS) 확보

패킷 손실 없는 브리지를 구축하려면 인터넷의 "VIP 차선"에 위치한 VPS가 필요합니다. 국제 혼잡을 극복하는 데 필수적인 프리미엄 엔터프라이즈 라우팅(AS9929 및 AS10099)을 전문으로 하는 SaltyFish를 예로 들겠습니다.

1. 등록

portal.saltyfish.io 로 이동하여 계정을 등록합니다. 서버 자격 증명 및 결제에 필요하므로 실제 이메일 주소를 사용하십시오.

2. 올바른 패키지 선택

로그인하고 Services(서비스) -> Order New Services(새 서비스 주문) 로 이동합니다.

  • Location(위치): "San Jose - Premium" 또는 "Frankfurt - Premium"을 찾습니다.
  • Network(네트워크): 설명에 AS9929 또는 AS10099가 언급되어 있는지 확인하십시오. 이것이 핵심입니다. 표준 "BGP" 라우팅은 동일한 안정성을 제공하지 않습니다.
  • Specs(사양): 가장 작은 1vCPU / 1GB RAM 플랜으로도 네트워크 터널에 충분합니다.

3. 결제

운영 체제로 Debian 12를 선택합니다. 강력한 루트 암호를 설정하십시오. 결제를 완료합니다. 상태가 "Active(활성)"으로 바뀌면 **Server IP Address(서버 IP 주소)**를 복사합니다.


2단계: 클라우드 브리지(VPS) 배포

VPS는 우리의 안정적인 릴레이 스테이션 역할을 합니다. 이 프리미엄 케이블에서 우리의 트래픽을 잡아 집으로 전달합니다.

터미널을 열고 새 SaltyFish VPS에 SSH로 접속하여 Docker를 실행합니다. 매우 간단합니다:

# VPS에 로그인하고 비밀번호 입력
ssh root@[IP_ADDRESS]

시스템을 업데이트하고 공식 스크립트를 사용하여 Docker를 설치합니다:

# 패키지 업데이트 및 전제 조건 설치
apt update && apt install -y ufw curl wget nano

# 공식 Docker 설치 스크립트 가져오기
curl -fsSL https://get.docker.com | sh

# Docker 데몬 활성화 및 시작
systemctl enable docker && systemctl start docker

다음으로 방화벽을 잠급니다. 443번 포트(클라이언트용)와 7000번 포트(Pi용)만 필요합니다.

ufw allow ssh
ufw allow 7000/tcp
ufw allow 443/tcp
ufw --force enable

이제 FRP 서버(frps)를 배포합니다. 홈 라우터의 포트 포워딩을 건드릴 필요가 없도록 역방향 프록시 마법을 처리합니다.

mkdir -p /root/frp && cd /root/frp

# Docker를 실행하기 전에 구성 파일을 만듭니다.
nano frps.toml

전문가 팁: Docker 명령을 실행하기 전에 frps.toml 파일을 만드는 것을 건너뛰지 마십시오. 존재하지 않는 파일을 Docker 볼륨 마운트에 전달하면 Docker는 이를 디렉토리로 간주하고 frps.toml이라는 폴더를 만듭니다. 성가신 OCI runtime create failed 오류가 발생하고 rm -rf를 사용해 삭제해야 합니다. 이런 골칫거리를 피하십시오.

frps.toml에 이것을 붙여넣으십시오:

# VPS (예: Saltyfish VPS) 구성
serverAddr = "Your_VPS_Public_IP"
# Raspberry Pi가 연결할 포트
bindPort = 7000
# 추측할 수 없는 비밀번호로 변경하십시오
auth.token = "YOUR_SUPER_SECRET_PASSWORD" 

[[proxies]]
name = "xray-reality"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8443
remotePort = 443

실행합니다:

docker run -d --name frps --restart=always \
  --network host \
  -v /root/frp/frps.toml:/etc/frp/frps.toml \
  snowdreamtech/frps

3단계: 홈 베이스 잠금 (Raspberry Pi)

이제 클라우드를 떠나 집으로 향합니다. Raspberry Pi를 보안 터널의 터미널 역할을 하도록 준비해야 합니다.

3.1 연결 확인

로그인하기 전에 Pi가 로컬 네트워크에서 활성화되어 있는지 확인하십시오. IP 주소(보통 라우터의 관리자 페이지를 통해)를 찾고 핑을 보냅니다:

ping YOUR-PI-IP # 또는 IP를 직접 사용

0.0% packet loss 가 표시되면 준비가 완료된 것입니다.

3.2 Pi에 SSH로 접속

터미널을 열고 Pi로 이동합니다. 처음 접속하는 경우 "호스트의 진위성(authenticity of host)"에 대한 경고가 표시됩니다. yes를 입력하여 known_hosts에 추가합니다.

ssh your_username@YOUR-PI-IP # 로컬 IP 주소 또는 Raspberry Pi의 호스트 이름을 사용합니다.

3.3 "명령어를 찾을 수 없음(Command Not Found)"의 함정

많은 개발자들이 즉시 Docker 명령을 실행하려고 시도하다가 -bash: docker: command not found 오류에 부딪힙니다. 당황하지 마세요. Docker가 아직 설치되지 않았음을 의미할 뿐입니다.

공식 편의 스크립트를 실행하여 엔진을 가동합니다:

curl -fsSL https://get.docker.com | sudo sh

3.4 권한 관리

기본적으로 Docker는 root 권한이 필요합니다. 5초마다 sudo를 입력하는 것을 피하려면 docker 그룹에 사용자를 추가하십시오:

# $USER를 실제 사용자 이름으로 바꿉니다
sudo usermod -aG docker $USER
newgrp docker

3.5 3X-UI 제어 패널 배포

이제 우리는 운영의 두뇌를 배포합니다. 이 패널은 VLESS-Reality 자격 증명을 관리합니다.

docker run -itd \
   -p 2053:2053 \
   -p 8443:8443 \
   --name 3x-ui \
   --restart=always \
   ghcr.io/mhsanaei/3x-ui:latest

3.6 FRP 클라이언트 연결

마지막으로 Pi를 다시 Cloud Bridge(VPS)에 연결해야 합니다.

경로에 대한 전문가 팁: /home/pi/frp와 같이 하드 코딩된 경로를 사용하지 마십시오. 설정에 따라 홈 디렉토리는 사용자 이름(예: /home/elvisli)을 따를 수 있습니다. 홈 폴더를 참조할 때는 항상 ~/ 를 사용하십시오.

mkdir -p ~/frp && cd ~/frp
nano frpc.toml

구성을 붙여넣습니다 (VPS의 토큰과 일치):

serverAddr = "YOUR_VPS_PUBLIC_IP"
serverPort = 7000
auth.token = "YOUR_SUPER_SECRET_PASSWORD"

[[proxies]]
name = "xray-reality"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8443
remotePort = 443 

"붙여넣기 쓰레기(Paste Garbage)" 주의: 터미널에 ^[[200~ 가 나타나면 "대괄호 붙여넣기 모드"가 잘못되었다는 신호입니다. 이는 종종 브라우저에서 터미널로 복사할 때 발생합니다. 명령을 실행하기 전에 백스페이스로 이 추가 문자를 삭제하십시오.

터널 클라이언트를 시작합니다:

docker run -d --name frpc --restart=always \
  --network host \
  -v ~/frp/frpc.toml:/etc/frp/frpc.toml \
  snowdreamtech/frpc

이제 물리적 터널이 설정되었습니다. 이제 홈 Pi가 Cloud VPS에 "보입니다".

4단계: VLESS-Reality 망토(Cloak) 구성

로컬 네트워크의 브라우저에서 http://YOUR_PI_LOCAL_IP:2053 으로 이동합니다. admin / admin 으로 로그인합니다.

  1. Inbounds(인바운드) -> Add Inbound(인바운드 추가) 로 이동합니다.
  2. Protocol(프로토콜)을 vless로, Port(포트)를 8443으로 설정합니다.
  3. Flow(흐름)를 xtls-rprx-vision으로 설정합니다.
  4. Security(보안)를 reality로 설정합니다.
  5. uTLS를 chrome으로 설정하고 Dest/Server Names를 **www.icloud.com:443**으로 설정합니다. (이렇게 하면 터널이 Apple 클라우드 동기화 트래픽과 동일하게 보입니다).
  6. Get New Keys(새 키 가져오기) 및 Generate(생성) (ShortIds 용)를 클릭합니다.
  7. 저장합니다.

새 규칙 옆에 있는 QR 코드 아이콘을 클릭하고 Copy Link(링크 복사) 를 클릭합니다. vless://... 로 시작하는 복잡한 문자열을 얻게 됩니다.

5단계: 클라이언트 설정 (iPhone 및 Mac용 Shadowrocket)

이제 Pi에서 VPS로 터널이 실행 중이므로 휴대폰을 연결해야 합니다.

5.1 노드 내보내기

  1. 3X-UI 패널에 접속합니다.
  2. VLESS 인바운드에서 점 세 개(메뉴)를 클릭합니다.
  3. "Export All URLs(모든 URL 내보내기)" 를 선택합니다. 이렇게 하면 vless:// 링크가 클립보드에 복사됩니다.

5.2 Shadowrocket으로 가져오기

  1. iPhone에서 Shadowrocket을 엽니다.
  2. 클립보드의 링크를 자동으로 감지하고 추가할지 묻는 메시지가 나타납니다. Add(추가) 를 클릭합니다.
  3. 팝업이 나타나지 않으면 + 아이콘을 클릭하고 Type(유형) 을 URI로 설정한 다음 링크를 붙여넣습니다.

5.3 브리지 구성

이것은 가장 중요한 단계입니다. 기본적으로 노드는 Pi의 로컬 IP를 가리킵니다. 이를 Cloud Bridge로 리디렉션해야 합니다.

  1. 새 노드 옆에 있는 (i) 아이콘을 탭합니다.
  2. Address(주소): 로컬 IP를 삭제하고 SaltyFish VPS 퍼블릭 IP를 입력합니다.
  3. Port(포트): 443으로 변경합니다.
  4. Type(유형): VLESS라고 표시되는지 확인합니다.
  5. Save(저장) 를 클릭합니다.

5.4 점화 테스트

외부에서 아키텍처가 작동하는지 증명하려면:

  1. Wi-Fi를 끕니다. 셀룰러 데이터(5G/LTE)를 사용하고 있는지 확인하십시오.
  2. Shadowrocket에서 노드를 선택합니다 (작은 주황색 점이 나타남).
  3. 메인 스위치를 Connected(연결됨) 로 전환합니다.
  4. google.com 을 방문합니다. 로드되면 공용 인터넷에서 홈 네트워크로 터널링하는 데 성공한 것입니다.

6단계: macOS 개발자 설정

개발자에게는 단순히 브라우저 프록시만 있는 것으로는 충분하지 않습니다. 워크스테이션 전체가 터널을 따르도록 해야 합니다.

6.1 설치

Apple Silicon Mac(M1/M2/M3)이 있는 경우 Mac App Store에서 macOS 버전의 Shadowrocket을 직접 설치할 수 있습니다. 이는 타사 래퍼(wrapper)를 사용하는 것보다 훨씬 효율적입니다.

6.2 터미널 프록시

macOS 터미널 앱(Git, npm, curl)은 일반적으로 시스템 VPN 설정을 무시합니다. 이것들을 수동으로 "연결"해야 합니다.

  1. 로컬 포트 확인: Shadowrocket Mac에서 Settings(설정) -> Proxy(프록시) 로 이동합니다. HTTP/SOCKS5 포트(보통 1082)를 메모합니다.

  2. 즉각적인 프록시: 현재 세션을 프록시하려면 터미널에서 다음을 실행합니다:

export http_proxy=http://127.0.0.1:1082
export https_proxy=http://127.0.0.1:1082

테스트: curl -I https://www.google.com. HTTP/2 200 이 표시되면 작동하는 것입니다.

  • 영구 별칭: 우아한 워크플로를 위해 이것을 ~/.zshrc 에 추가하십시오:

  • # 프록시 켜기
    alias proxy="export http_proxy=http://127.0.0.1:1082; export https_proxy=http://127.0.0.1:1082; echo 'Terminal Proxy ON'"
    # 프록시 끄기
    alias unproxy="unset http_proxy https_proxy; echo 'Terminal Proxy OFF'"
    

    source ~/.zshrc 를 실행합니다. 이제 proxy 를 입력하기만 하면 보이지 않게 작동합니다.


    7단계: Git SSH 프록시

    이것은 대부분의 개발자가 빠지는 "함정"입니다. GitHub에 SSH 키(git clone git@github.com...)를 사용하는 경우 SSH 프로토콜을 사용하기 때문에 http_proxy를 완전히 무시합니다.

    이를 해결하려면 SSH 클라이언트 자체가 로컬 터널을 사용하도록 구성해야 합니다.

    1. SSH 구성 편집: nano ~/.ssh/config.
    2. 맨 위에 이 블록 추가:
    Host github.com
        HostName github.com
        User git
        # GitHub SSH 트래픽을 Shadowrocket의 SOCKS5 포트를 통해 강제 전송
        ProxyCommand nc -X 5 -x 127.0.0.1:1082 %h %p
    
  • 저장하고 종료합니다. 이제 어디에 있든 git push 명령이 비공개 터널을 통과하여 날아갈 것입니다.
  • 결론

    더 이상 공용 Wi-Fi나 상업용 VPN 차단에 휘둘릴 필요가 없습니다. 원격 워크스테이션을 홈 베이스에 직접 연결하는 엔터프라이즈급 사설 라우팅 경로가 생겼습니다.

    안전하게 머무르십시오. 빠르게 유지하십시오. 행복한 코딩 되세요.