- Published on
ssh 터널링 툴 기초 정리
- Authors

- Name
- Indo Yoon
ssh 터널링 툴은 SSH 연결 안에 다른 네트워크 트래픽을 실어 보내는 도구를 말해요. 대부분의 기본 요구는 OpenSSH 클라이언트의 포워딩 옵션으로 해결할 수 있고, 연결이 자주 끊기거나 여러 호스트를 네트워크 단위로 다뤄야 할 때 autossh나 sshuttle 같은 보조 도구를 검토해요. 이 글은 서버 운영과 배포를 하는 백엔드 개발자가 터널링 방식을 고르고 안전하게 운영할 수 있도록 개념과 선택 기준을 정리해요.
한눈에 보기
ssh 터널링 툴을 고를 때 먼저 정할 것은 어느 쪽에서 포트를 열고, 어디까지 전달할지예요. 내 컴퓨터에서 시작해 원격의 특정 대상으로 보내면 로컬 포워딩이고, SSH 서버 쪽에서 포트를 열어 내 쪽으로 보내면 원격 포워딩이에요. 대상이 여러 개라서 포트마다 설정을 추가하기 어렵다면 동적 포워딩이나 네트워크 단위 도구를 검토해요.
리눅스 서버를 다루는 환경이라면 OpenSSH 클라이언트가 이미 있는 경우가 많아요. 그래서 처음에는 ssh 명령의 -L, -R, -D, -J 옵션으로 필요한 연결을 직접 만들어 보고, 운영 자동화가 필요해질 때 보조 도구를 붙이는 순서가 좋아요. 터널은 SSH 서버의 포워딩 정책과 방화벽 정책 안에서만 동작한다는 점도 함께 기억해야 해요.
터널링 방식 비교 표
| 방식·도구 | 주 용도 | 핵심 옵션 | 서버 쪽 확인 |
|---|---|---|---|
| OpenSSH 로컬 포워딩 | 내 컴퓨터의 포트를 원격 내부 대상으로 연결 | -L | AllowTcpForwarding |
| OpenSSH 원격 포워딩 | SSH 서버 쪽 포트를 내 쪽 대상으로 연결 | -R | GatewayPorts, 방화벽 |
| OpenSSH 동적 포워딩 | 로컬 SOCKS 프록시로 여러 대상 접근 | -D | AllowTcpForwarding |
| ProxyJump | 점프 호스트를 거쳐 최종 서버 접속 | -J, ProxyJump | 중간 서버의 SSH 허용 |
| autossh | SSH 세션을 감시하고 끊기면 재시작 | autossh 실행 옵션 | SSH 접속 정책 |
| sshuttle | SSH를 통한 네트워크 단위 트래픽 전달 | sshuttle 실행 옵션 | 로컬 권한, 원격 환경 |
표에서 알 수 있듯이 단일 포트만 필요하면 OpenSSH 옵션으로 충분한 경우가 많아요. 반면 터널을 오래 유지해야 하거나 여러 서브넷을 함께 다뤄야 하면 별도 도구의 도움이 필요해요.
OpenSSH로 로컬·원격·동적 포워딩 구성하기
OpenSSH의 포워딩은 SSH 서버를 경유해 TCP 연결을 대신 열어 주는 방식이에요. 명령줄에서 -L, -R, -D를 붙이면 되고, 같은 설정을 ~/.ssh/config의 LocalForward, RemoteForward, DynamicForward로 관리할 수 있어요. 설정 파일에 두면 배포 스크립트나 개발 도구에서 같은 터널 구성을 재사용하기 쉬워요.
로컬 포워딩
로컬 포워딩은 내 컴퓨터의 특정 주소와 포트로 들어온 연결을 SSH 서버 너머의 대상 호스트와 포트로 보내요. 예를 들어 ssh -L 15432:db.internal:5432 user@bastion은 로컬의 15432 포트를 bastion에서 본 db.internal의 5432 포트로 연결해요. 내 PC에서는 DB 클라이언트를 쓰지만 DB는 사설망에만 있을 때 유용해요.
바인딩 주소를 생략하면 기본적으로 루프백에만 열려요. 다른 호스트에서도 접근해야 하는 구성이라면 -g 옵션과 SSH 서버의 정책을 함께 확인해야 하고, 보안상 가급적 루프백 사용을 권장해요. 로컬 포워딩은 내 쪽 포트가 실제로 열리는 방식이므로, 이미 사용 중인 포트와 충돌하지 않는지도 확인해야 해요.
원격 포워딩
원격 포워딩은 SSH 서버 쪽에서 포트를 열고, 그 연결을 내 쪽 또는 내가 접근할 수 있는 대상으로 보내요. ssh -R 8080:localhost:3000 user@remote는 remote 서버의 8080 포트를 내 로컬의 3000 포트로 연결해요. 외부에서 사내 개발 서버의 서비스에 접근해야 할 때 쓰지만, 서버의 GatewayPorts와 방화벽 설정을 확인해야 해요.
원격 포워딩은 특히 바인딩 주소를 주의해야 해요. 기본 설정에서는 원격 서버의 루프백에만 열릴 수 있으므로, 외부 인터페이스에 노출해야 한다면 서버 관리자와 정책을 맞춰야 해요. 또한 원격 포워딩으로 연 포트는 SSH 세션이 유지되는 동안만 동작하므로, 세션 종료와 재시작 정책도 함께 설계해야 해요.
동적 포워딩
동적 포워딩은 SSH 연결을 SOCKS 프록시로 노출해요. ssh -D 1080 user@bastion을 실행하면 로컬의 1080 포트에 SOCKS 프록시가 열리고, 브라우저나 도구가 이 프록시를 통해 여러 대상에 접속할 수 있어요. 대상마다 -L을 추가하기 번거로울 때 편리해요.
다만 동적 포워딩은 애플리케이션이 SOCKS 프록시를 지원해야 하고, 프록시 사용 범위를 명확히 해야 해요. 모든 트래픽을 자동으로 터널에 넣는 방식이 아니므로, 브라우저 설정이나 CLI 도구의 프록시 옵션을 각각 확인해야 해요. 운영 환경에서는 어떤 목적의 프록시인지와 접근 가능한 대상 범위를 문서화하는 편이 좋아요.
점프 호스트와 ProxyJump 사용하기
점프 호스트는 사설망 앞단의 SSH 서버를 거쳐 최종 서버에 접속하는 구성이에요. OpenSSH에서는 -J 또는 ssh_config의 ProxyJump로 중간 호스트를 지정할 수 있어요. 예를 들어 ssh -J user@bastion user@app.internal은 bastion을 거쳐 app.internal에 접속해요.
이때 최종 대상의 호스트 키와 점프 호스트의 호스트 키를 각각 확인해야 해요. ~/.ssh/config에 Host 블록으로 분리하면 배포 스크립트에서도 재사용하기 쉬워요. 예전 구성에서는 ProxyCommand와 별도 도구를 조합하기도 하지만, 최근 OpenSSH에서는 ProxyJump가 읽기 쉽고 관리하기 편해요.
점프 호스트를 운영할 때는 중간 서버의 계정 권한을 최소화하는 것이 중요해요. 점프 호스트에 접속한 사용자가 최종 서버까지 자유롭게 이동할 수 있는지, SSH 에이전트 전달을 허용할지도 정책으로 정해야 해요. 편의를 위해 에이전트 전달을 켜면 키가 중간 서버에 노출될 수 있으므로 주의해야 해요.
연결 유지와 네트워크 라우팅 도구
장시간 유지되는 터널은 네트워크 순단이나 서버 재시작으로 끊길 수 있어요. OpenSSH 자체의 ServerAliveInterval, ServerAliveCountMax, ExitOnForwardFailure 같은 옵션으로 끊김을 감지하고 실패 시 종료하게 만들 수 있어요. 배포 스크립트에서 터널을 백그라운드로 띄울 때는 포워딩 실패를 조용히 넘기지 않도록 ExitOnForwardFailure를 확인하는 편이 좋아요.
autossh는 SSH 프로세스를 감시하다가 세션이 끊기면 다시 실행하는 보조 도구예요. 공식 사이트에서도 SSH 세션을 시작하고 감시하며 필요할 때 재시작하는 용도로 소개해요. 상시 유지가 필요한 터널이라면 systemd 같은 서비스 관리자와 함께 사용해 로그와 재시작 정책을 관리할 수 있어요.
sshuttle은 SSH 연결을 통해 트래픽을 전달하는 도구로, 개별 포트보다 네트워크 단위 라우팅이 필요할 때 검토해요. 공식 문서에서는 SSH를 통한 투명 프록시 성격의 도구로 설명해요. 다만 로컬 권한과 방화벽 규칙, 원격 환경의 요구 사항을 확인해야 하므로, 단순한 포트 포워딩으로 충분한지 먼저 판단하는 것이 좋아요.
상황별 선택 기준
사내 DB나 내부 웹처럼 단일 대상 포트만 필요하면 -L 로컬 포워딩이 가장 단순해요. 외부에서 내부 서비스로 역방향 노출이 필요하면 -R을 검토하되, 원격 서버의 바인딩 주소와 방화벽을 먼저 확인해야 해요.
대상이 자주 바뀌고 브라우저나 CLI 도구가 SOCKS를 지원하면 -D 동적 포워딩이 편해요. 중간 서버를 거쳐야 하는 보안망이라면 -J와 ProxyJump로 접속 경로를 정리하는 편이 좋아요.
터널이 자주 끊겨 자동 재시작이 필요하면 autossh를 검토해요. 여러 호스트와 서브넷을 한 번에 다뤄야 하면 sshuttle이 후보가 될 수 있지만, 로컬 권한과 네트워크 정책을 함께 확인해야 해요. 어떤 도구든 운영 환경에서는 전용 계정과 키, 최소 권한, 로그 수집을 기본으로 두는 것이 안전해요.
주의할 점
터널은 편리하지만 SSH 서버의 포워딩 정책을 우회하는 용도로 쓰이면 안 돼요. 서버 관리자는 AllowTcpForwarding, PermitOpen, GatewayPorts 같은 설정을 확인해 어떤 포워딩을 허용할지 정해야 해요. 개발 환경에서 열어 둔 터널이 운영 서버에 그대로 적용되지 않도록 환경별 설정을 분리하는 것도 중요해요.
원격 포워딩으로 포트를 열 때는 바인딩 주소와 방화벽을 반드시 확인해요. 기본적으로 루프백에만 열리는지, 외부 인터페이스에 열리는지에 따라 노출 범위가 크게 달라져요. 터널 프로세스가 죽었는지 확인할 수 있도록 로그와 헬스 체크를 남기고, 재시작만 반복하기보다 끊김 원인을 먼저 확인하는 편이 좋아요.
자주 묻는 질문
ssh 터널링 툴은 OpenSSH만으로 충분한가요?
단일 포트 포워딩과 점프 호스트 정도라면 OpenSSH만으로 충분해요. 연결이 자주 끊겨 자동 재시작이 필요하거나 네트워크 단위 라우팅이 필요할 때 autossh나 sshuttle을 추가로 검토해요. 다만 도구를 늘리기 전에 서버의 포워딩 정책과 방화벽부터 확인하는 편이 좋아요.
로컬 포워딩과 원격 포워딩은 어떻게 구분하나요?
연결을 여는 쪽이 내 컴퓨터면 로컬 포워딩이고, SSH 서버 쪽이면 원격 포워딩이에요. -L은 내 포트에서 원격 대상으로, -R은 원격 포트에서 내 쪽 대상으로 연결해요. 어느 쪽 포트가 실제로 열리는지 확인하면 헷갈리지 않아요.
동적 포워딩은 언제 쓰나요?
대상 호스트가 여러 개이고 애플리케이션이 SOCKS 프록시를 지원할 때 유용해요. -D로 로컬 SOCKS 프록시를 열고 브라우저나 CLI 도구가 그 프록시를 사용하게 해요. 모든 트래픽을 자동으로 보내는 방식은 아니므로 애플리케이션별 프록시 설정을 확인해야 해요.
터널이 자주 끊기면 어떻게 해야 하나요?
먼저 SSH의 keepalive 옵션과 네트워크 장비의 유휴 연결 정책을 확인해요. 그다음 필요하면 autossh나 서비스 관리자의 재시작 정책을 조합해요. 재시작만 반복하면 원인을 놓칠 수 있으니 로그에서 끊김 지점을 확인하는 것이 먼저예요.
출처
- OpenSSH ssh 매뉴얼: https://man.openbsd.org/ssh
- OpenSSH ssh_config 매뉴얼: https://man.openbsd.org/ssh_config
- OpenSSH sshd_config 매뉴얼: https://man.openbsd.org/sshd_config
- autossh 공식 사이트: https://www.harding.motd.ca/autossh/
- sshuttle 공식 문서: https://sshuttle.readthedocs.io/
터널을 운영 환경에 붙일 때는 접속 계정, 키 관리, 로그, 장애 대응까지 함께 보게 돼요. 관련해서 Linux 서버 운영과 배포 체크리스트도 함께 읽어 보세요.