리눅스 서버와 SSH 터널로 만드는 웹 프록시 서버

필자도 종종 IP 주소를 외부에 노출하지 않기 위하여 오라클 클라우드의 미국 산호세 리전에 Wireguard를 설치한 VPN 서버를 구축하여 SSL VPN을 사용하고 있다.

하지만 큰 단점이 있는데 SSL-VPN을 연결하면 모든 트래픽이 VPN 서버를 통해 전송된다는 점이다. 하지만 IP를 노출하지 않고자 하는 서비스는 그다지 많지 않다. 종종 방문하는 디씨인사이드, 보배드림, 뽐뿌, 클리앙과 같은 커뮤니티와 페이스북, 인스타그램, X(구 트위터), 레딧, 스레드 등 SNS에 글을 쓰거나 댓글을 작성할 때 뿐이다.

VPN 연결 시 스플릿 터널링을 적용하면 필요한 IP만 터널을 통해 접속하도록 할 수 있지만 대부분의 웹사이트들이 IP가 하나가 아닌데다 IP는 종종 바뀐다. 그래서 매우 불편하다.

그래서 새롭게 찾은 방법이 바로 웹 프록시였다. Shdowsock 이라는 프록시 서버를 리눅스 서버와 PC에 설치하고 PC의 프록시 설정과 브라우저의 프록시 설정을 맞춰주면 특정 URL(도메인주소)만 프록시를 통해 접속하도록 할 수 있다. 하지만 이 방법은 설치가 복잡하고 오류가 발생했을 때 원인을 찾기가 너무 힘들었다.

더 단순한 웹 프록시 서버 구성 방법을 찾다가 SSH의 암호화된 터널과 SSH 서버에서 제공하는 포트포워딩 기능을 이용해 Proxy로 사용하는 방법이 있다는 사실을 떠올렸다. 지금까지는 웹 서핑을 위해 매번 SSH 터미널 프로그램을 실행하고 접속하는 과정이 번거로워 사용할 생각을 하지 않았다. 하지만 마땅한 방법이 없어 SSH 터널을 Windows에 로그인할 때 자동으로 생성하도록 하면 되지 않을까 라는 아이디어를 떠올리고 시도해보기로 했다.

결과적으로 다양한 보안기능이나 편리한 기능을 제공하지는 않지만 인터넷 접속이 가능한 리눅스 서버만 있으면 SSH 서버에서 제공하는 포트포워딩 기능을 사용해 아주 손쉽게 나만의 웹 프록시 서버를 구축할 수 있었다.

SSH 터널 기반의 프록시 서버 구성

이 구성에서 필요한 것은 리눅스 서버다. 리눅스 서버에 다른 그 어떤 SW도 추가로 설치하지 않는다. 리눅스 서버에 SSH 접속이 가능하고 리눅스 서버에서 인터넷 접속만 가능하면 된다.

먼저 PC에 다음과 같은 코드를 포함하는 배치파일(.bat)을 적당한 폴더에 작성한다.

@echo off
chcp 65001 > nul
TITLE SSH Proxy Tunnel

setlocal

:: --- 설정 부분 --- 
SET KEY_PATH="리눅스 서버에 SSH 접속 시 사용되는 개인키 또는 PEM 키 파일경로와 파일명" 
SET SSH_PORT=리눅스 서버의 SSH 포트번호 
SET SOCKS_PORT=1080   :: PC의 Proxy 포트 번호
SET USER_HOST=계정ID@리눅스서버IP

:: 현재 bat 파일이 위치한 경로 확인
set SCRIPT_DIR=%~dp0

:: Windows의 Startup 폴더 경로 가져오기
set STARTUP_DIR=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\

:: 경로 비교
if /I "%SCRIPT_DIR%"=="%STARTUP_DIR%" (
   :: [연결 체크] 이미 1080 포트가 열려있다면 조용히 종료
   netstat -ano | findstr :1080 | findstr LISTENING > nul
   if %errorlevel% equ 0 exit
)
:: [관리자 권한 확인 및 요청 로직]
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' NEQ '0' (
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs"
    "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
    pushd "%CD%"
    CD /D "%~dp0"

:: [자동 실행 체크 로직]
:: 실행 시 포트가 닫혀 있으면 자동으로 연결 섹션으로 점프합니다.
netstat -ano | findstr :%SOCKS_PORT% | findstr LISTENING > nul
if %errorlevel% neq 0 (
    echo [자동 실행] 터널이 꺼져 있어 자동으로 연결을 시작합니다...
    goto AUTO_START
)

:MENU
cls
echo ======================================================
echo       SSH Proxy 터널 관리자 (관리자 권한)
echo ======================================================
echo  현재 상태: ▶ [연결됨] 터널이 이미 활성화 상태입니다.
echo ------------------------------------------------------
echo  1. 터널 연결 시작 (현재 연결 중)
echo  2. 터널 연결 종료
echo  3. 연결 상태 확인
echo  4. 종료
echo ======================================================
set /p conn="번호를 선택하세요: "

if "%conn%"=="1" goto START_TUNNEL
if "%conn%"=="2" goto STOP_TUNNEL
if "%conn%"=="3" goto CHECK_STATUS
if "%conn%"=="4" goto EXIT
goto MENU

:AUTO_START
:: 사용자 개입 없이 연결 후 바로 종료하는 섹션
start "SSH Proxy Tunnel" /min ssh -i %KEY_PATH% -D %SOCKS_PORT% -N -p %SSH_PORT% %USER_HOST%
echo [완료] 터널 연결 명령을 보냈습니다.
echo 3초 후 이 창을 닫습니다...
timeout /t 3 > nul
exit

:START_TUNNEL
cls
echo [정보] 터널 연결을 시도 중입니다...
netstat -ano | findstr :%SOCKS_PORT% | findstr LISTENING > nul
if %errorlevel% equ 0 (
    echo [오류] 이미 %SOCKS_PORT% 포트가 사용 중입니다!
    pause
    goto MENU
)
start "SSH Proxy Tunnel" /min ssh -i %KEY_PATH% -D %SOCKS_PORT% -N -p %SSH_PORT% %USER_HOST%
echo [완료] 터널이 백그라운드에서 실행되었습니다.
timeout /t 3 > nul
goto MENU

:STOP_TUNNEL
cls
echo [정보] 모든 SSH 터널 프로세스를 종료합니다...
for /f "tokens=5" %%a in ('netstat -aon ^| findstr :%SOCKS_PORT% ^| findstr LISTENING') do taskkill /f /pid %%a > nul 2>&1
echo [완료] 연결이 정상적으로 종료되었습니다.
pause
goto MENU

:CHECK_STATUS
cls
echo [정보] 현재 터널 활성화 상태를 점검합니다...
echo ------------------------------------------------------
netstat -ano | findstr :%SOCKS_PORT% | findstr LISTENING > nul
if %errorlevel% equ 0 (
    echo 상태: ▶ [연결됨] 미국 IP로 웹서핑이 가능합니다.
) else (
    echo 상태: ■ [연결끊김] 현재 일반 IP 상태입니다.
)
echo ------------------------------------------------------
pause
goto MENU

:EXIT
exit

이 배치파일은 프록시 서버로 사용할 리눅스 서버에 SSH 연결을 하는데 프롬프트(# 또는 $)를 얻는 것이 아니라 연결 후 SOCKS 소켓을 만들고 %SOCKS_PORT%로 지정한 포트를 사용하는 프록시를 만들게 된다. PC에 설치된 브라우저 또는 다른 응용프로그램들은 SSH 터널을 사용해 만든 PC의 프록시를 통해 외부의 서버와 통신을 하게 되는 것이다.

코드 앞부분의 “설정 부분”의 IP, SSH 포트, ID와 인증용 개인키 또는 PEM키 등 정보만 수정해주고 bat 파일을 생성한 다음 실행하면 SSH 연결 시 생성하는 터널 기반의 프록시 서버가 구성된다. 단, 이 파일은 VSCode와 같은 전문 코딩 툴을 이용해 UTF8로 저장해야 한다 .그렇지 않으면 한글이 깨지는 등 문제가 발생할 수 있다.


Windows 키와 r 키를 동시에 누르면 표시되는 “실행” 창에서 shell:startup 입력하고 엔터키를 누르면 나오는 “시작프로그램”에 이 배치파일의 “바로가기”를 만들어 두면 Windows를 부팅하고 로그인 하면 자동으로 실행되도록 할 수 있다.

부팅하고 처음 실행하면 관리자 권한을 요구하는 창이 보이고 승인해주고 나면 다음과 같이 데몬 프로세스가 하나 생성된다.

SSH Proxy Server
SSH Proxy Server

그리고 이 창은 최소화된 상태로 실행된다. SSH 프록시의 정상 실행 여부는 다른 도스창에서 netstat -an | findstr 1080 을 실행하면 된다. 1080은 “설정 부분”에서 언급된 포트 번호(%SOCKS_PORT%)다.

만약 다른 CMD 창을 열고 netstat -an | grep 1080 명령을 실행하면 다음과 같이 LISTEN 상태로 보여야 한다.

SSH 터널 기반 프록시 서버가 실행된 모습
SSH 터널 기반 프록시 서버가 실행된 모습

혹시 이렇게 실행중인 상태에서 .bat 파일을 실행하면 이미 SSH 프록시 터널이 서버와 이미 연결되어 있다고 표시해주고 다음과 같이 어떤 작업을 할 것인지를 묻는다.

이미 SSH 프록시 터널이 실행된 상태에서 실행했을 때
이미 SSH 프록시 터널이 실행된 상태에서 실행했을 때

서버에 대한 작업은 모두 끝났다. 이제 브라우저에서 플러그인 하나를 설치한다.

브라우저에 Switchyomega 플러그인 설치

브라우저의 스토어에서 proxy switchyomega를 다음과 같이 검색한다. 다음 화면엔 엣지 브라우저다. 구글 검색에서 엣지 브라우저 플러그인 또는 크롬 브라우저 플러그인 등 키워드를 검색하면 해당 브라우저의 스토어로 연결된다.

연결 후에는 다음과 같이 proxy switchomega를 검색한다.

엣지 브라우저 익스텐션 검색
엣지 브라우저 익스텐션 검색

Proxy와 관련된 여러 플러그인과 확장앱들이 보이는데 필자는 Proxy SwitchyOmega MV3 버전을 설치했다.

엣지 브라우저에 설치할 proxy switchyomega 플러그인
엣지 브라우저에 설치할 proxy switchyomega 플러그인

로컬 프록시 서버 등록

설치한 SwitchyOmegaMV3 확장의 설정화면에 가서 New Profile을 클릭한 후 표시되는 Profile의 유형 선택 화면에서 “Proxy Profile”을 선택한다. 그리고 다음 화면과 같이 로컬 PC의 프록시 서버를 등록해준다.

로컬 PC의 Proxy 서버 등록
로컬 PC의 Proxy 서버 등록

이 프록시 서버의 정보는 앞에서 작성한 .bat 파일이 실행되면서 구동되는 SSH 클라이언트가 오픈하고 대기하는 SSH 터널 기반의 프록시 서버다.

스위치 프로파일 생성

등록된 프록시 프로파일이 잘 보인다면 이제 스위치 프로파일을 작성해야 한다. 왼쪽 화면에서 New Profile을 클릭한 다음 표시되는 화면에서 Switch Profile을 선택한다.

다음 화면과 같이 프록시를 통해 접속할 사이트와 등록된 사이트 외 모든 사이트에 적용될 Default 정책을 만들어 준다.

Switch profile 등록 화면
Switch profile 등록 화면

컨디션 타입은 “Host wildcard”를 선택한다. 호스트네임(도메인 이름 포함)까지 Full Name으로 적어줘도 되고 위에서 처럼 호스트네임 자리에는 *을 쓰고 도메인 기반으로 등록해도 된다. 이 사이트는 앞에서 등록한 프록시 서버를 통해 접속하도록 한다는 의미다.

그리고 마지막에 Default는 Direct로 접속하라고 알려주어야 한다. 즉 위에 등록된 사이트들은 SSH2HTTP-Proxy 프로파일에 등록된 프록시 서버를 통해 접속하고 그 외의 사이트들은 프록시 서버를 거치지 않고 직접 접속한다는 의미다.

그리고 다음과 같이 프록시 관리 플러그인을 브라우저의 툴바에 고정시켜 준다. 그래야 편하다.

엣지 브라우저 툴바에 플러그인을 고정
엣지 브라우저 툴바에 플러그인을 고정

브라우저의 툴바에 SwitchyOmega Proxy 관리자 아이콘이 표시되는데 클릭한 다음 앞에서 등록한 스위치 프로파일이 보인다. 그 프로파일을 선택해준다.

프로파일 중에서 스위치 프로파일을 선택
프로파일 중에서 스위치 프로파일을 선택

이 때부터 스위치 프로파일에 등록한 웹사이트에 접속하게 되면 트래픽은 SSH 연결로 생성한 SOCKS 프록시 터널을 타고 리눅스 서버로 간 다음 리눅스 서버의 IP를 달고 해당 사이트에 접속하게 된다.

#웹프록시 #SSH프록시 #switchyomega #vpn대체 #SOCKS5

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다