SSH 포워딩은 실제로 어떤 앱 트래픽을 전달하는가?
셸, 로컬 포워드, SOCKS, 터널 장치 모드는 서로 다른 인터페이스를 제공합니다. 라우팅 VPN과 비교하기 전에 앱이 사용할 수 있는 인터페이스가 무엇인지 먼저 밝히세요.
터미널이 연결되고 프롬프트가 나타나면 모두가 SSH 접근이 동작한다고 동의합니다. 그런데 노트북의 데이터베이스 클라이언트는 여전히 사설 호스트에 닿지 못하고, 세션이 비난받습니다. 만들어진 것은 셸이며, 그것은 SSH가 제공할 수 있는 네 가지 매우 다른 인터페이스 중 하나입니다. 먼저 인터페이스를 밝히고, 그다음 앱이 실제로 그것을 사용하는지 시험하십시오. 각 인터페이스는 저마다의 방식으로 실패하기 때문에 순서가 중요합니다.
무엇이든 비교하기 전에 인터페이스를 밝히십시오
OpenSSH 클라이언트 설명서는 서로 혼동하기 쉬운 네 가지 메커니즘을 구분합니다. 셸이나 원격 명령은 SSH 호스트에서 실행됩니다. 로컬 포워드는 클라이언트에서 수신 소켓을 열고 이후 연결은 원격 쪽에서 맺습니다. 원격 포워드는 그 반대로 서버 쪽에서 수신합니다. 동적 포워딩은 사용법을 아는 프로그램에 SOCKS 엔드포인트를 노출합니다.
- 셸: 프로그램은 원격 머신에서 실행되고, 로컬에서는 아무것도 수신하지 않습니다.
- 로컬 포워드: 노트북에 포트가 있고, 원격 호스트가 나가는 연결을 맺습니다.
- 원격 포워드: 원격 쪽에 포트가 있고, 트래픽이 당신 쪽으로 돌아옵니다.
- 동적: 클라이언트의 SOCKS 프록시이며, 프록시를 이해하는 앱만 사용합니다.
이 중 어느 것도 경로를 설치하지 않습니다. 프록시 설정을 무시하거나, UDP로 말하거나, 이름을 스스로 해석하는 프로그램은 활성 SSH 세션의 영향을 받지 않습니다. 이것은 SSH의 결함이 아니라 선택한 인터페이스의 범위입니다.
로컬, 원격, 동적 포워드는 누가 수신하는지에서 다릅니다
대부분의 경우를 결정하는 차이는 수신 소켓을 누가 소유하는가입니다. 로컬 포워드에서는 클라이언트가 수신하고 먼 쪽이 목적지를 호출하므로 목적지 주소는 서버의 관점에서 해석됩니다. 원격 포워드에서는 서버가 수신하고 연결이 당신 쪽으로 되돌아오며, 이렇게 하면 로컬 서비스를 직접 공개하지 않고 노출할 수 있습니다.
ssh -N -L 5432:db.internal.example:5432 [email protected] ssh -N -D 1080 [email protected] ss -ltnp | grep -E '5432|1080'
첫 번째 명령은 노트북에서 포트 5432를 묶고 배스천에서 보이는 대로 데이터베이스로 포워드합니다. 두 번째는 포트 1080에서 SOCKS 프록시를 만듭니다. 세 번째 명령은 어떤 프로세스가 실제로 수신 중인지 확인하며, 포트 충돌로 조용히 실패한 것이 아니라 포워드가 존재한다는 유일한 증거입니다.
동적 포워딩은 그 자체의 경고를 받을 자격이 있습니다: SOCKS를 존중하는 앱만 포괄합니다. 브라우저를 그것으로 향하게 할 수 있고, 명령줄 도구에는 사용하라고 이를 수 있지만, 자체 연결 스택을 가진 데이터베이스 드라이버는 보통 할 수 없습니다. 머신의 모든 프로그램이 이제 터널을 쓴다고 가정하는 것이 이 분야 전체에서 가장 흔한 실수입니다.
터널 장치 모드가 유일한 진짜 네트워크 예외입니다
OpenSSH는 -w 터널 장치 포워딩도 지원하며, TCP 수신자 대신 지점 간 인터페이스를 전달합니다. 그것은 진짜 네트워크 터널이고 의도적으로 구성되며, 셸을 여는 부작용이 아닙니다.
sudo ssh -w 0:0 [email protected] ip addr show tun0
양쪽 끝에서 사용할 수 있는 해당 인터페이스 번호, 서버의 올바른 구성, 장치를 만들기 위한 클라이언트의 충분한 권한이 필요합니다. 또한 어떤 목적지가 그것을 사용해야 하는지에 대한 정책을 순수 인터페이스는 담지 않으므로 주소 지정과 라우팅 계획도 필요합니다.
그래도 터널은 먼 호스트에서 끝납니다. SSH 전송이 제공한 보호는 거기서 끝나고, 이후 연결은 별개의 홉입니다. VPN 게이트웨이도 같은 모양의 경계를 가지므로, 비교는 어느 도구가 더 강한지가 아니라 범위와 종료 지점에 관한 것이어야 합니다. 그 경계를 소리 내어 부르는 것은 분명히 그렇지 않기 때문에 터널이 «모든 것을 암호화하는가»라는 논쟁도 끝냅니다.
당신의 앱이 당신이 만든 인터페이스를 사용하는지 시험하십시오
검증은 세션이 아니라 앱 단위입니다. 동작하는 포워드는 포트가 묶였고 먼 쪽이 호출할 수 있음을 증명하지만, 당신이 신경 쓰는 프로그램이 그것을 통해 연결했다는 것은 증명하지 않습니다.
curl -sS --socks5-hostname 127.0.0.1:1080 -o /dev/null -w '%{http_code}\n' https://app.internal.example/health
psql "host=127.0.0.1 port=5432 dbname=app sslmode=require" -c 'select 1'첫 번째 명령은 호스트 이름을 원격에서 해석하며 SOCKS 엔드포인트를 통해 요청을 보내고, 두 번째는 TLS가 여전히 요구되는 상태에서 포워드된 데이터베이스 포트를 시험합니다. 양쪽 다 통과하는 시험은 터널을 쓰지 않은 것이므로 포워드를 멈춘 상태에서 같은 시험을 실행해 실패하는지 확인하십시오.
그다음 라우팅 VPN과는 중요한 차원에서만 비교하십시오: 어떤 목적지가 포함되는지, 어떤 프로토콜이 동작하는지, 보호가 어디서 끝나는지, 누가 접근을 승인해야 하는지입니다. 단일 서비스 포워드는 더 좁고 더 나은 답이 될 수 있고, 많은 앱이 같은 네트워크 경로를 필요로 할 때 VPN이 올바른 형태입니다. 어느 쪽도 자신의 먼 끝점에서 도달 가능한 모든 것을 허용하지는 않습니다.