한 대의 머신에는 이미 승인된 VPN 접근 권한이 있고, 두 번째 머신에는 정확히 하나의 사설 HTTPS 서비스가 필요하며, 로컬 SSH 포워드가 두 번째 머신에 터널을 주지 않고도 그 간극을 메울 수 있습니다. 포워드는 전체 네트워크가 아니라 하나의 TCP 목적지를 전달하며, 바로 그 한계가 핵심입니다. 아래 다섯 단계는 각 단계가 서로 다른 이유로 실패하고 뒤 단계가 앞선 간극을 구제할 수 없으므로 순서대로 진행하세요. 어떤 전제 조건이든 빠져 있다면 이 설계로는 해결되지 않으며 명령을 아무리 조정해도 소용없습니다.

첫 번째 단계: 세 가지 전제 조건 확인

어떤 명령이든 의미를 가지려면 세 가지가 이미 참이어야 합니다. 첫 번째 머신을 포워딩 호스트로 쓸 권한, 그 머신에 대한 동작하는 SSH 접근, 그리고 의도한 목적지를 허용하는 서버 정책입니다. 파일 전송용으로 만든 SSH 계정은 포워딩이 비활성화되어 있을 수 있고, 포워딩을 허용하는 서버도 그 경로로 어떤 목적지에 도달할 수 있는지 제한할 수 있습니다. 합의 없이 동료의 워크스테이션을 점프 지점으로 쓰는 것은 명령이 깔끔하게 동작하더라도 정책 문제이므로 테스트 전에 물어보세요.

두 명령이 그 목록의 기술적인 절반을 해결합니다. 첫 번째는 계정과 키가 대화형 프롬프트 없이 동작함을 증명하고, 두 번째는 구성 파일의 주석 처리된 예시가 아니라 실제 서버 정책을 출력합니다.

ssh -o BatchMode=yes [email protected] 'echo ok'
sudo sshd -T | grep -E 'allowtcpforwarding|permitopen'

두 번째 단계: loopback 포트를 바인딩하고 세션 유지

클라이언트 애플리케이션이 실행되는 머신에서 사설 서비스로 가는 로컬 포워드를 엽니다. 로컬 네트워크에 공개되지 않도록 loopback에 명시적으로 바인딩하고, 어떤 로컬 서비스도 이미 잡고 있지 않은 높은 포트를 고릅니다. 세션을 닫으면 리스너도 닫히므로 작업하는 동안 세션을 계속 실행하세요. ExitOnForwardFailure은 거부된 바인딩이나 점유된 포트를 포워드 없이 남는 세션 대신 즉시 종료로 바꾸며, 바로 이 실패 방식이 가장 많은 시간을 낭비합니다.

사설 연결은 점프 호스트에서 만들어지므로 그 호스트의 DNS, 경로, VPN 정책, 서비스 접근이 모두 동작해야 합니다. SSH 세션은 점프 호스트에 없는 도달성을 만들어 내지 않으며, VPN이 한 번도 밀어 넣지 않은 경로를 고칠 수도 없습니다. 명령의 침묵을 믿는 대신 리스너가 실제로 있는 곳에서 확인하세요.

ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:9443:portal.lab.example:443 [email protected]
ss -ltn '( sport = :9443 )'

세 번째 단계: 소켓이 로컬일 때 HTTPS 이름 유지

https://127.0.0.1:9443/으로 브라우징하면 TLS 서버 이름과 애플리케이션 권한이 바뀝니다. portal.lab.example용으로 발급된 인증서는 loopback 주소에 대해 검증되지 않으며, 그 결과 나타나는 오류는 포워딩 지름길이 아니라 망가진 인증서처럼 보입니다. 명령줄 테스트에서는 실제 URL을 유지하고 소켓 목적지만 바꾸세요. --connect-to가 하는 일이 바로 이것이며, curl 매뉴얼이 아래에서 쓰는 네 필드 형식을 문서화합니다.

curl --noproxy portal.lab.example --connect-to portal.lab.example:443:127.0.0.1:9443 https://portal.lab.example/

이름은 URL, TLS 핸드셰이크, Host 헤더에 남고 TCP 연결만 로컬 리스너로 향합니다. 프록시 없음 옵션은 설정된 HTTP 프록시가 가로채지 않도록 테스트를 이 포워드에 붙잡아 두는 것이고, 인증서 검증을 켜 둔 채로 두는 것이 결과를 의미 있게 만듭니다.

네 번째 단계: 포워드 하나가 커버하지 못하는 범위 알기

TCP 포워드 하나는 목적지 포트 하나를 커버합니다. 두 번째 호스트 이름으로 리디렉션하는 페이지, 사설 네트워크 안의 호스트에서 자산을 불러오는 페이지, 다른 포트로 전송하는 페이지는 각자 포워드가 필요하며, 그 모두가 첫 번째와 같은 정책 확인을 필요로 합니다. 브라우저 작업 흐름은 프록시 구성이나 로컬 매핑을 통해 실제 이름을 로컬 포트로 보내라고 브라우저에 알려야 하므로 자체 요구 사항을 더합니다. 따라서 명령줄 테스트가 성공해도 브라우저에서도 성공한다는 증명은 아니며, 경로가 통한다는 것만 증명합니다.

UDP, SMB 검색, 도메인 로그인은 TCP 포워드를 전혀 지나지 않습니다. 실제 요구 사항이 일반 네트워크 접근이라면 이 설계는 잘못된 도구이고, 지원되는 원격 접근 게이트웨이가 올바른 선택입니다.

다섯 번째 단계: 정리하고 기록하기

테스트가 끝나면 세션을 멈추고 리스너가 사라졌는지 확인하세요. 고른 포트가 이미 점유되어 있었다면 번호를 비우려고 무관한 로컬 서비스를 종료하는 대신 다른 미사용 loopback 포트를 골라 URL, 테스트 명령, 메모를 함께 갱신하세요. 노트북에서 포워드를 열어 둔 채로 두면 진단이 관리되지 않는 서비스로 바뀝니다.

점프 호스트, 포워드한 목적지, 로컬 포트, 그리고 누가 이 배치를 승인했는지 적어 두세요. 누군가의 shell 기록에만 존재하는 포워드는 재부팅 한 번이면 같은 조사를 다시 하게 되며, 다음 사람은 세 가지 전제 조건 중 무엇이 이미 확인되었는지 알지 못합니다.

관련 글