SSH 포트 포워딩 심층 분석: 로컬, 원격, 동적 터널의 모든 것
데이터베이스, 웹 앱 및 SOCKS 프록시를 위한 실용적인 명령어와 함께 로컬, 원격 및 동적 SSH 포트 포워딩을 배웁니다.
SSH 포트 포워딩 이해하기: 로컬, 원격, 동적 터널 설명
SSH 포트 포워딩을 사용하면 네트워크 서비스를 직접 노출하는 대신 암호화된 SSH 연결을 통해 해당 서비스에 접근할 수 있습니다. 일반적으로 데이터베이스, 대시보드 또는 개발 서버가 SSH 호스트에서는 접근 가능하지만 노트북에서는 접근할 수 없을 때 사용합니다.
세 가지 일반적인 형태는 로컬 포워딩, 원격 포워딩 및 동적 포워딩입니다. 이들은 유사한 구문을 사용하지만 수신 포트의 위치가 다릅니다.
SSH 포트 포워딩의 역할
SSH 포트 포워딩(SSH 터널링이라고도 함)은 SSH 세션을 통해 한 호스트와 포트에서 다른 호스트와 포트로 트래픽을 리디렉션합니다. 대상은 최종 연결을 설정하는 쪽에서 확인됩니다. 로컬 포워딩의 경우 SSH 서버가 대상에 연결합니다. 원격 포워딩의 경우 SSH 클라이언트가 대상에 연결합니다.
이를 통해 다음과 같은 여러 이점이 있습니다:
- 보안: 클라이언트와 대상 서비스 간에 암호화되지 않은 트래픽을 암호화합니다.
- 액세스 제어: 현재 위치에서 직접 접근할 수 없는 개인 네트워크나 방화벽 뒤에서 실행되는 서비스에 대한 액세스를 허용합니다.
- 네트워크 연결: 서로 다른 네트워크 세그먼트를 안전하게 연결합니다.
로컬 포트 포워딩 (-L)
로컬 포트 포워딩은 가장 일반적인 유형입니다. 이를 통해 로컬 머신의 포트에서 SSH 서버를 통해 원격 머신의 포트로 연결을 전달할 수 있습니다. 기본적으로 원격 네트워크에서 실행되는 서비스를 로컬 머신에서 실행되는 것처럼 보이게 합니다.
작동 방식:
- 로컬 머신에서 SSH 클라이언트를 시작합니다.
- SSH가 수신할 로컬 포트(
local_port)를 지정합니다. - 로컬 머신의
local_port로 들어오는 모든 연결은 SSH 연결을 통해remote_host및remote_port로 전달됩니다.
구문:
ssh -L [local_bind_address:]local_port:remote_host:remote_port [user@]ssh_server_host
local_bind_address: (선택 사항) 로컬 머신에서 바인딩할 주소입니다. 생략하면 OpenSSH는 일반적으로 클라이언트 구성에서 달리 지정하지 않는 한 루프백 주소에 바인딩됩니다.local_port: SSH가 수신할 로컬 머신의 포트입니다.remote_host: SSH 서버가 연결할 대상 머신의 호스트 이름 또는 IP 주소입니다.remote_port: 트래픽이 전달될remote_host의 포트입니다.user@ssh_server_host: 연결할 SSH 서버의 사용자 이름과 호스트 이름/IP 주소입니다.
실용적인 사용 사례: 원격 서버의 개인 IP 주소에서 실행되는 데이터베이스 서버에 액세스합니다.
회사 내부 네트워크에서만 액세스할 수 있는 데이터베이스 서버(예: 192.168.1.100:5432의 PostgreSQL)가 있다고 가정해 보겠습니다. 로컬 포트 포워딩을 사용하여 집에 있는 노트북에서 액세스할 수 있습니다:
ssh -L 5433:192.168.1.100:5432 your_user@your_ssh_server.com
- 이 명령은
your_ssh_server.com에 연결합니다. - 로컬 머신(기본적으로
localhost)에서 포트5433을 엽니다. localhost:5433에 대한 모든 연결은your_ssh_server.com을 통해192.168.1.100:5432로 전달됩니다.
이제 로컬 데이터베이스 클라이언트를 localhost:5433에 연결하도록 구성할 수 있으며, 트래픽은 원격 데이터베이스 서버로 안전하게 터널링됩니다.
팁: ssh -N을 사용하여 원격 명령을 실행하지 않고 터널을 생성합니다. 이는 백그라운드 터널에 유용합니다.
ssh -N -L 5433:192.168.1.100:5432 your_user@your_ssh_server.com
원격 포트 포워딩 (-R)
원격 포트 포워딩을 사용하면 원격 SSH 서버의 포트에서 로컬 머신 또는 로컬 머신에서 액세스할 수 있는 다른 머신의 포트로 연결을 전달할 수 있습니다. 이는 로컬 머신에서 실행되는 서비스를 원격 서버 또는 해당 네트워크에서 액세스할 수 있도록 하는 데 유용합니다.
작동 방식:
- 로컬 머신에서 SSH 클라이언트를 시작합니다.
- SSH가 수신할 SSH 서버의 원격 포트(
remote_port)를 지정합니다. - SSH 서버의
remote_port로 들어오는 모든 연결은 SSH 연결을 통해 로컬 머신으로 다시 전달된 다음 지정된destination_host및destination_port로 전달됩니다.
구문:
ssh -R [remote_bind_address:]remote_port:destination_host:destination_port [user@]ssh_server_host
remote_bind_address: (선택 사항) 수신 포트를 바인딩할 SSH 서버의 주소입니다. 기본값은localhost입니다(SSH 서버 자체만 이 포트에 연결할 수 있음을 의미).0.0.0.0또는*을 사용하여 원격 네트워크의 다른 머신이 연결할 수 있도록 허용합니다.remote_port: SSH가 수신할 SSH 서버의 포트입니다.destination_host: SSH 클라이언트가 연결할 대상 머신의 호스트 이름 또는 IP 주소입니다(서비스가 로컬 머신에 있는 경우 종종localhost).destination_port: 트래픽이 전달될destination_host의 포트입니다.user@ssh_server_host: 연결할 SSH 서버의 사용자 이름과 호스트 이름/IP 주소입니다.
실용적인 사용 사례: 로컬 웹 서버를 원격 네트워크에 노출합니다.
노트북에서 웹 애플리케이션을 개발 중이고 회사 내부 네트워크에만 액세스할 수 있는 동료에게 시연하고 싶다고 가정해 보겠습니다. 해당 네트워크에서 액세스할 수 있는 SSH 서버(your_ssh_server.com)가 있습니다.
노트북에서 다음을 실행합니다:
ssh -R 8080:localhost:3000 your_user@your_ssh_server.com
- 이 명령은
your_ssh_server.com에 연결합니다. your_ssh_server.com에 포트8080에서 수신하도록 지시합니다.your_ssh_server.com:8080에 대한 모든 연결은 SSH 터널을 통해 노트북(localhost)의 포트3000(웹 서버가 실행 중인 포트)으로 다시 전달됩니다.
이제 동료는 브라우저에서 http://your_ssh_server.com:8080으로 이동하여 웹 애플리케이션에 액세스할 수 있습니다. 트래픽은 브라우저에서 SSH 서버로, 터널을 통해 노트북으로, 그런 다음 웹 서버로 이동합니다.
경고: 일반적인 OpenSSH 구성에서 remote_port는 SSH 서버 자체에서만 연결할 수 있습니다. 원격 네트워크의 다른 머신이 전달된 포트에 액세스할 수 있도록 하려면 remote_bind_address를 명시적으로 0.0.0.0 또는 *으로 설정하고 SSH 서버가 GatewayPorts 설정(예: clientspecified 또는 yes)을 통해 이를 허용하는지 확인하십시오.
ssh -R 0.0.0.0:8080:localhost:3000 your_user@your_ssh_server.com
동적 포트 포워딩 (-D)
동적 포트 포워딩은 로컬 머신에 SOCKS 프록시를 생성합니다. 이는 가장 유연한 유형으로, SOCKS 프록시를 지원하는 모든 애플리케이션을 SSH 연결을 통해 터널링할 수 있습니다. 특정 포트를 전달하는 대신 SSH는 로컬 포트에서 수신하고 SOCKS 프록시 서버 역할을 합니다.
작동 방식:
- 로컬 머신에서 SSH 클라이언트를 시작합니다.
- SSH가 SOCKS 프록시로 수신할 로컬 포트(
local_port)를 지정합니다. - 애플리케이션(웹 브라우저 등)을 구성하여 SOCKS 프록시로
localhost:local_port를 사용하도록 합니다. - 애플리케이션이 이 프록시를 통해 요청을 하면 SSH는 트래픽을 SSH 서버로 전달하고, SSH 서버는 애플리케이션을 대신하여 최종 대상에 연결합니다.
구문:
ssh -D [local_bind_address:]local_port [user@]ssh_server_host
local_bind_address: (선택 사항) 수신 SOCKS 프록시 포트를 바인딩할 로컬 머신의 주소입니다. 기본값은localhost입니다.local_port: SSH가 SOCKS 프록시로 수신할 로컬 머신의 포트입니다.user@ssh_server_host: 연결할 SSH 서버의 사용자 이름과 호스트 이름/IP 주소입니다.
실용적인 사용 사례: 공용 Wi-Fi에서 안전하게 웹 브라우징.
신뢰할 수 없는 공용 Wi-Fi 네트워크에 연결되면 트래픽이 취약해집니다. 동적 포트 포워딩을 사용하여 모든 웹 브라우징 트래픽을 암호화된 SSH 연결을 통해 신뢰할 수 있는 서버로 터널링할 수 있습니다.
노트북에서 다음을 실행합니다:
ssh -D 1080 your_user@your_trusted_server.com
- 이 명령은
your_trusted_server.com에 연결합니다. - 로컬 머신에서 포트
1080을 열어 SOCKS 프록시 역할을 합니다.
그런 다음 웹 브라우저 또는 다른 애플리케이션을 구성하여 localhost의 포트 1080에서 SOCKS 프록시를 사용하도록 합니다. 애플리케이션에 SOCKS5 원격 DNS 옵션이 있는 경우 로컬 네트워크에서 DNS 조회가 발생하지 않도록 하려면 이 옵션을 사용하십시오.
브라우저 트래픽은 SSH 서버로 전송된 다음 대상 사이트에 연결됩니다. HTTPS는 여전히 중요합니다. SSH 터널은 SSH 서버까지의 경로를 보호하며, 그 이후의 모든 홉을 보호하지는 않습니다.
팁: -D를 -C와 결합하여 압축을 사용할 수 있으며, 이는 느린 네트워크 링크에서 유용할 수 있습니다.
ssh -C -D 1080 your_user@your_trusted_server.com
고급 고려 사항 및 모범 사례
- SSH 서버 구성 (
sshd_config): 일부 포워딩 기능은 서버 측 권한이 필요합니다. 터널이 어디에서나 수신하거나 연결할 수 있다고 가정하기 전에AllowTcpForwarding,PermitOpen,PermitListen및GatewayPorts를 확인하십시오. - 방화벽: 클라이언트, 서버 또는 중간 네트워크의 방화벽이 SSH 연결 또는 포워딩에 사용되는 포트를 차단할 수 있습니다. 필요한 포트(일반적으로 SSH 자체의 경우 22)가 열려 있는지 확인하십시오.
- 보안: 포트 포워딩은 트래픽을 암호화하지만 터널의 보안은 SSH 서버의 보안에 따라 달라집니다. 강력한 SSH 키를 사용하고, 비밀번호 인증을 비활성화하고, SSH 서버를 최신 상태로 유지하십시오.
- 안정성: 스크립트의 경우
-o ExitOnForwardFailure=yes를 추가하여 SSH가 요청된 포워드를 생성할 수 없으면 종료되도록 합니다. 장기 실행 터널의 경우autossh또는 감독 서비스를 고려하십시오.
요점
노트북이 개인 원격 서비스에 연결해야 하는 경우 -L을 사용하십시오. 원격 호스트가 노트북 근처의 항목에 연결해야 하는 경우 -R을 사용하십시오. 신뢰할 수 있는 SSH 서버를 통해 SOCKS 프록시가 필요한 경우 -D를 사용하십시오. 바인딩을 엄격하게 유지하고, 서버 정책을 확인하며, 모든 터널을 임시 네트워크 개방으로 취급하십시오.