소개
SSH(Secure Shell)는 단순한 원격 터미널 접속 도구를 넘어 강력한 네트워크 유틸리티입니다. SSH 터널링(SSH 포트 포워딩이라고도 함)을 사용하면 로컬 네트워크 트래픽을 보안 SSH 연결을 통해 원격 호스트로 라우팅할 수 있습니다.
핵심 개념은 다른 머신의 연결성을 빌려오는 것입니다. 터널 자체가 새로운 네트워크 도달 가능성을 생성하는 것이 아니라, 원격 호스트의 위치와 접근 권한을 재사용하는 방식입니다.
이 기술은 시스템 관리자, 개발자, 보안 전문가들이 엄격한 기업 방화벽을 우회하고, 레거시 애플리케이션 트래픽을 암호화하며, 공개 인터넷에 직접 노출되지 않은 숨겨진 내부 서비스에 액세스하기 위해 널리 사용합니다.
이번 실습에서는 두 가지 주요 SSH 포트 포워딩 유형의 개념과 실제 적용 방법을 배웁니다.
- 로컬 포트 포워딩 (
-L): 로컬 머신의 포트를 원격 대상지로 전달합니다. - 원격 포트 포워딩 (
-R): 원격 서버의 포트를 로컬 머신으로 다시 전달합니다.
네트워크 토폴로지 이해하기
이 단계에서는 실습을 위해 준비된 시뮬레이션 네트워크 환경을 살펴봅니다.
SSH 터널링을 연습하려면 여러 머신이 포함된 시나리오가 필요합니다. 단일 가상 머신 환경에서 작업하고 있으므로, 로컬 시스템(127.0.0.1)의 서로 다른 네트워크 포트를 사용하여 복잡한 네트워크 토폴로지를 시뮬레이션했습니다.
시뮬레이션의 개념적 매핑은 다음과 같습니다. 로컬 머신은 현재 터미널 세션으로 표현됩니다. 배스천 호스트(또는 에지 서버)는 127.0.0.1:2222에서 SSH를 노출하는 Docker 컨테이너를 사용하여 시뮬레이션됩니다. 내부 서비스는 동일한 사설 Docker 네트워크의 172.31.0.20:80에서 실행 중인 웹 서버입니다. 개념적으로 이 서비스는 기업 네트워크 깊숙한 곳에 위치하여 방화벽에 의해 차단되어 있으며, 배스천 호스트를 통해서만 액세스할 수 있다고 가정합니다. 마지막으로 로컬 서비스는 LabEx VM의 8000 포트에서 실행 중인 웹 서버입니다. 이는 인터넷상의 누군가와 공유하고 싶은 개인 노트북에서 실행 중인 개발 서버라고 생각하면 됩니다.
시뮬레이션된 서비스가 실행 중인지 확인해 보겠습니다. URL을 통해 데이터를 전송하는 명령줄 도구인 curl 명령을 사용합니다.
먼저 8000 포트에서 실행 중인 "로컬 서비스"를 확인합니다.
curl http://127.0.0.1:8000
Local Developer Machine Data라는 출력이 표시되어야 합니다.
내부 서비스는 의도적으로 LabEx VM에 직접 노출되지 않았습니다. 다음 단계에서 SSH 터널을 통해 해당 서비스에 도달하게 됩니다.
이어지는 단계에서는 SSH 터널링을 사용하여 이러한 서비스에 액세스하는 방식을 조작하며, 실제 방화벽 우회 시나리오를 시뮬레이션합니다.
로컬 포트 포워딩 구성 (-L)
이 단계에서는 로컬 포트 포워딩을 구성합니다.
집에 있는데 내부 기업 대시보드(172.31.0.20:80 서비스)에 액세스해야 한다고 가정해 봅시다. 방화벽이 외부에서 해당 내부 주소로 직접 액세스하는 것을 차단하고 있습니다. 하지만 방화벽은 특정 에지 서버(배스천 호스트)에 대한 SSH 연결은 허용합니다.
로컬 포트 포워딩을 사용하면 로컬 머신에서 포트를 열 수 있으며, SSH는 해당 로컬 포트로 전송된 모든 트래픽을 SSH 터널을 통해 대상지로 안전하게 전달합니다.
로컬 포트 포워딩의 구문은 다음과 같습니다: ssh -L [local_port]:[destination_host]:[destination_port] [user]@[ssh_server]
로컬 포워딩은 "원격 서비스를 내 로컬처럼 보이게 만들기"로 이해하는 것이 가장 쉽습니다.
시뮬레이션된 SSH 배스천 호스트를 통해 로컬 포트 8080을 내부 서비스(172.31.0.20:80)로 전달합니다. 또한 두 가지 추가 플래그를 사용합니다. -N 플래그는 SSH에게 원격 명령을 실행하지 말라고 지시하며, 포트 포워딩만 수행하려는 경우 유용합니다. -f 플래그는 SSH를 백그라운드에서 실행하도록 하여 터미널을 계속 사용할 수 있게 합니다.
다음 명령을 실행하여 터널을 생성합니다:
ssh -N -f -L 8080:172.31.0.20:80 \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-i ~/project/pivot_key -p 2222 pivot@127.0.0.1
이제 터널이 백그라운드에서 조용히 실행 중입니다.
이제 터널을 테스트해 보겠습니다. 내부 Docker 주소에 직접 액세스하는 대신, 새로 연 로컬 포트 8080에 액세스합니다. SSH 터널이 이 요청을 가로채 암호화한 후 배스천 호스트로 보내고, 배스천 호스트가 이를 172.31.0.20:80으로 전달합니다.
curl http://127.0.0.1:8080
Secret Internal Corporate Data라는 출력이 표시되어야 합니다. 개념적인 방화벽을 성공적으로 우회했습니다!
원격 포트 포워딩 구성 (-R)
이 단계에서는 원격 포트 포워딩을 구성합니다.
로컬 노트북에서 웹 애플리케이션(포트 8000의 서비스)을 개발 중이라고 가정해 봅시다. 클라이언트에게 진행 상황을 보여주고 싶지만, 노트북이 홈 라우터(NAT) 뒤에 있어 공인 IP 주소가 없습니다.
원격 포트 포워딩은 공용 SSH 서버에 연결하여 해당 원격 서버에 포트를 열 수 있게 함으로써 이 문제를 해결합니다. 해당 원격 포트에 도달하는 모든 트래픽은 SSH 터널을 통해 로컬 머신으로 다시 전달됩니다.
원격 포트 포워딩의 구문은 다음과 같습니다: ssh -R [remote_port]:[local_host]:[local_port] [user]@[ssh_server]
원격 포워딩은 관점을 뒤집습니다: "내 로컬 서비스를 원격 측에서 도달 가능하게 만들기".
로컬 서비스(127.0.0.1:8000)를 배스천 호스트의 8081 포트에 노출합니다.
다음 명령을 실행하여 원격 터널을 생성합니다:
ssh -N -f -R 8081:127.0.0.1:8000 \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-i ~/project/pivot_key -p 2222 pivot@127.0.0.1
이제 터널이 백그라운드에 설정되었습니다. 배스천 호스트는 이제 8081 포트에서 대기 중입니다. 누군가 원격 서버의 8081 포트에 액세스하면 트래픽이 로컬 포트 8000으로 다시 전송됩니다.
배스천 호스트 컨테이너를 통해 포워딩된 서비스를 쿼리하여 테스트해 보겠습니다:
docker exec bastion_host curl -s http://127.0.0.1:8081
Local Developer Machine Data라는 출력이 표시되어야 합니다. 로컬 서비스를 원격 서버에 성공적으로 노출했습니다!
내부 웹 서비스 액세스
마지막 단계에서는 생성한 터널을 사용하여 데이터를 다운로드하고 프로젝트 디렉터리의 파일로 저장함으로써 이해도를 높여보겠습니다.
기본 프로젝트 디렉터리에 있는지 확인합니다:
cd ~/project
먼저 로컬 포트 포워딩 터널(포트 8080)을 사용하여 내부 기업 데이터를 가져와 internal_data.txt라는 파일로 저장합니다. curl의 -o 플래그를 사용하여 출력 파일을 지정합니다.
curl http://127.0.0.1:8080 -o internal_data.txt
다음으로 원격 포트 포워딩 터널(포트 8081)을 사용하여 배스천 호스트를 통해 로컬 개발자 데이터를 가져와 remote_data.txt라는 파일로 저장합니다.
docker exec bastion_host curl -s http://127.0.0.1:8081 > remote_data.txt
마지막으로 cat 명령을 사용하여 방금 다운로드한 파일의 내용을 확인합니다:
cat internal_data.txt
cat remote_data.txt
Secret Internal Corporate Data
Local Developer Machine Data
포워딩된 포트를 통해 이 파일들을 성공적으로 다운로드함으로써, SSH 터널이 엔드포인트 간의 트래픽을 안전하게 라우팅하고 있음을 증명했습니다.
요약
축하합니다! SSH 터널링 및 포트 포워딩 실습을 성공적으로 완료했습니다.
이번 실습에서 SSH 터널링의 개념과 이를 사용하여 네트워크 제한을 우회하는 방법을 배웠습니다. 로컬 포트 포워딩(-L)을 구성하여 로컬 트래픽을 배스천 호스트를 통해 라우팅함으로써 숨겨진 내부 서비스에 안전하게 액세스했습니다. 또한 원격 포트 포워딩(-R)을 구성하여 로컬 개발 서비스를 원격 서버에 노출하고, 로컬 NAT 및 방화벽을 성공적으로 우회했습니다. 마지막으로 -N 및 -f 플래그를 사용하여 SSH 터널을 백그라운드에서 조용히 실행하는 방법을 배웠습니다.
이러한 기술은 안전한 시스템 관리, 원격 개발, 그리고 복잡한 네트워크 토폴로지를 안전하게 탐색하는 데 필수적입니다.



