튜토리얼 개요

SSH PortProxy로 안전하게 원격 서비스 접근하기

SSH PortProxy는 방화벽 제약이 있는 환경에서도 안전하게 원격 서비스에 접근할 수 있는 강력한 기술입니다. 기존 SSH 터널링과 유사하지만, 로컬 포트 포워딩을 더욱 직관적으로 구성할 수 있으며, 별도의 터널링 소프트웨어 없이도 작동합니다. 예를 들어 개발 서버가 외부 접속을 차단하고 있더라도, SSH 게이트웨이 서버를 경유하여 로컬 머신에서 localhost:8080으로 접근하면 원격 서버의 웹 서비스에 연결할 수 있습니다. 이는 데이터베이스 접근이나 내부 관리 콘솔 접속 시 특히 유용합니다.

PortProxy의 핵심 장점은 다음과 같습니다:

  1. 방화벽 우회: 원격 서버의 인바운드 허용 없이도 게이트웨이 서버의 SSH 포트(예: 22)만 열려 있으면 접근 가능
  2. 암호화 통신: 모든 트래픽이 SSH 터널 내에서 암호화되므로 중간자 공격 방지
  3. 간단한 설정: 단일 SSH 명령어 또는 설정 파일 수정만으로 구성 완료

💡 기존 SSH 터널링과의 차이점: -L 옵션은 명시적 포트 바인딩이 필요하지만, PortProxy는 동적 포트 할당이 가능해 유연성이 높습니다.

공식 문서: OpenSSH Port Forwarding


사전 준비 사항

1. SSH 서버 환경 확인

PortProxy를 사용하려면 OpenSSH 5.4 이상이 설치되어 있어야 합니다. 다음 명령어로 버전을 확인하세요:

ssh -V
# 출력 예시: OpenSSH_9.2p1, OpenSSL 3.0.2 15 Mar 2023

서버 측 /etc/ssh/sshd_config 파일에서 다음 옵션이 활성화되었는지 확인합니다:

# /etc/ssh/sshd_config
AllowTcpForwarding yes
PermitTTY no  # 필요 시 활성화
X11Forwarding no

변경 후 SSH 서비스 재시작:

sudo systemctl restart sshd

2. 접근 권한 검증

원격 서버의 대상 포트(예: 80, 3306)에 대한 접근 권한이 있는지 확인해야 합니다. 다음 명령어로 테스트:

telnet target-server 80
# 또는
nc -zv target-server 80

접속 거부 시 방화벽 규칙 또는 애플리케이션 설정을 점검해야 합니다.

3. 인증 설정 테스트

비밀번호 또는 SSH 키 기반 인증이 작동하는지 확인합니다:

ssh user@gateway-server -o PreferredAuthentications=password
# 또는 키 인증 테스트
ssh -i ~/.ssh/id_rsa user@gateway-server

인증 실패 시 ~/.ssh/config 파일에 다음과 같이 호스트별 설정을 추가할 수 있습니다:

Host gateway
  HostName 192.168.1.10
  User admin
  IdentityFile ~/.ssh/id_rsa_gateway
  IdentitiesOnly yes

단계별 PortProxy 설정

1. CLI 명령어를 통한 즉시 설정

가장 간단한 방법은 SSH 명령어 인자에 -D 옵션을 사용하는 것입니다. 예를 들어 로컬 포트 8080을 원격 서버의 80포트에 바인딩하려면:

ssh -D 8080 user@gateway-server

이후 로컬 머신에서 브라우저 또는 curl로 localhost:8080에 접근하면 게이트웨이 서버를 경유하여 원격 서버의 웹 페이지에 연결됩니다.

특정 호스트의 특정 포트에 고정하려면 -L 옵션을 사용합니다:

ssh -L 8080:target-db-server:3306 user@gateway-server
# 로컬 8080 → 게이트웨이 경유 → target-db-server:3306

2. 설정 파일을 통한 영구 구성

매번 CLI를 입력하지 않으려면 ~/.ssh/config에 다음과 같이 설정할 수 있습니다:

Host db-proxy
  ProxyCommand ssh -W %h:%p gateway-server
  LocalForward 53306 target-db-server:3306

이후 mysql -h 127.0.0.1 -P 53306 -u user -p로 바로 접근 가능합니다.

3. OS별 설정 차이

  • Windows (OpenSSH): ssh -D 1080 user@gateway 실행 후 PuTTY의 Proxy > SOCKS 설정에서 127.0.0.1:1080 지정
  • macOS: 기본 터미널에서 Linux와 동일한 명령어 사용. GUI 도구인 ShadowsocksX-NG를 활용할 수도 있습니다.
  • Linux: autossh로 백그라운드 실행 가능
    autossh -M 0 -f -N -L 8080:target:80 user@gateway
    

⚠️ Windows에서 WSL(Windows Subsystem for Linux)을 사용할 경우, 호스트 머신의 포트를 WSL에 노출하려면 netsh interface portproxy 설정이 추가로 필요합니다.


트러블슈팅

1. Connection Refused 오류

  • 포트 접근 권한: 원격 서버에서 netstat -tuln 또는 ss -tuln으로 대상 포트가 리슨 중인지 확인
    ss -tuln | grep :3306
    # 출력 예시: tcp  LISTEN 0      128    0.0.0.0:3306   0.0.0.0:*
    
  • 게이트웨이 권한: sshd_config에서 AllowTcpForwardingyes인지 확인

2. SELinux/방화벽 문제

  • SELinux 모드 확인:
    getenforce
    # 출력: Enforcing → 문제 가능성 있음
    
    일시적 해결:
    setenforce 0
    
    영구 적용:
    sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
    
  • 방화벽 허용:
    sudo ufw allow from 192.168.1.0/24 to any port 22
    sudo firewall-cmd --permanent --add-port=22/tcp
    

3. 로컬 포트 충돌

로컬 포트가 이미 사용 중일 경우 netstat 또는 ss로 확인:

ss -tuln | grep :8080
# 프로세스 종료
kill -9 $(ss -tulnpe | grep :8080 | awk '{print $6}' | cut -d',' -f1)

마치며

SSH PortProxy는 방화벽 제약이 있는 환경에서도 안전하게 원격 서비스에 접근할 수 있는 실용적인 기술입니다. 데이터베이스 접근 시 -L 53306:db-server:3306으로 로컬 포트를 바인딩하거나, 관리 콘솔 접근 시 SOCKS 프록시(-D 1080)를 구성하는 등 다양한 시나리오에 적용할 수 있습니다.

핵심 요약

  1. PortProxy는 방화벽 우회와 암호화된 통신을 동시에 제공합니다.
  2. ~/.ssh/config를 활용하면 다중 포트 포워딩을 간편하게 관리할 수 있습니다.
  3. TCP Wrappers(/etc/hosts.allow)와 결합하면 특정 IP만 접근을 허용할 수 있습니다.

참고 링크