포트포워딩이 불가능한 환경에서 서버 연결하기 (SSH 터널 이용)

Seong-Am Kim
7 min readDec 11, 2023

--

외부 서버를 이용하면 포트포워딩이 불가능한 경우가 거의 없지만 사무실 내에서 개발 서버를 따로 두는 등 온프레미스로 환경이될 경우 공유오피스는 따로 포트포워딩이 불가능한 경우가 많아 서버 접속에 대한 에로사항이 생기는 경우가 있습니다.

Photo by Christina @ wocintechchat.com on Unsplash

예를 들어 외부에서 SSH로 접근한다 했을때 문제가 되는 경우는 아래와 같습니다.

화살표는 연결 방향을 나타냅니다.

위의 사항에서 어떻게 하면 접속이 가능하게 할 수 있을지 공유 해보려고 합니다.

⚠️ 이 글은 접속에 대한 보안과 연결되므로 작성자는 정보만 제공할 뿐, 이와 관련된 어떠한 책임도 지지 않음을 명시합니다. 읽고 사용하는 사람은 자신의 책임하에 판단하여 이 정보를 활용 하셔야 합니다.

개요

결론부터 말씀드리고 그 다음 설정에 대한 세부 사항을 말씀드리겠습니다.

요점은 SSH터널을 이용 합니다. 해당 방법은 SSH 프로토콜을 사용해서 다른 프로토콜이나 포트로 연결을 가능하게 해줍니다.

SSH 터널은 SSH 포트포워딩이라고도 부르며 크게 로컬 포워딩과 원격 포워딩으로 나뉩니다.

저희는 원격포워딩을 사용할건데 원격 포워딩은 SSH서버의 특정 포트를 원격 서버로 포트포워딩을 합니다.

쉽게 이야기 하자면 기존 SSH 연결은 연결하는 측에서 접속의 대상이 되는 서버에 접근을 하는 반면 원격 포워딩은 이와 반대로 연결의 대상이 되는 측에서 연결하려는 서버쪽으로 포트 포워딩을 설정합니다.

해당 부분은 연결 대상이되는 서버의 입장에선 들어오는 요청(인바운드)가 아닌 나가는 요청(아웃바운드) 이기 때문에 포트포워딩이 불가하더라도 연결이 가능하게 합니다.

아래 글에선 연결대상과 연결하려는 쪽 컴퓨터 둘 모두 포트포워딩이 불가능함을 가정을 하며 이를 위해 프록시 서버를 통해 연결을 합니다.

프록시 서버는 연결대상과 연결하려는 쪽 컴퓨터 둘 모두 접근이 가능해야 합니다.

이를 도식화 하면 아래와 같습니다.

화살표는 요청 방향을 나타냅니다.

# 참고 사항

굳이 프록시 서버를 두지 않으셔도 괜찮으며 이 경우 프록시 서버를 연결 하려는 쪽 컴퓨터라고 생각하시면 될듯 합니다.

SSH 연결만 가능한것은 아니며 다른 포트 및 프로토콜도 SSH 터널을 이용해서 연결이 가능합니다. 예로 SSH 접속을 든것이지 데이터베이스 및 웹 서버 등을 연결할 수 있습니다.

접속의 대상이 되는 서버에 대한 설정

기본적으로 SSH는 터널과 관련된 작업들이 보안상 막혀있어 이를 풀어주는 것들이 필요합니다.

아래 경로의 설정 파일을 열어 변경해줍니다.

/etc/ssh/sshd_config

기본적으론 주석이 되어 있을거고 주석 해제 후 no 부분을 yes로 변경해주시면 됩니다.

// SSH 클라이언트에서 원격 서버로 에이전트를 포워딩할 수 있도록 허용
AllowAgentForwarding yes
// TCP 포워딩 허용
AllowTcpForwarding yes
// 로컬에서만 가능한 연결을 외부도 가능하게 변경 해주는 옵션
GatewayPorts yes

설정 변경 후엔 아래 명령어를 통한 ssh 서버의 재시작이 필요합니다.

sudo systemctl restart ssh

(참고) 리눅스가 아닌 맥 환경의 경우 아래 명령어를 통해 ssh 서버를 재시작 할 수 있습니다.

sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load /System/Library/LaunchDaemons/ssh.plist

SSH의 경우 연결이 지속되지 않으면 자동으로 연결을 끊습니다. 따라서 클라이언트 또는 서버의 설정을 변경하여 연결이 정상적이란 신호를 보내줘야 합니다.

이는 클라이언트 또는 서버에서 어느 한곳만 써줘도 됩니다.

SSH 서버에서 변경하실려면 추후 프록시 서버쪽 설정에서 추가적으로 적어 두겠으니 해당 부분 생략하시고 프록시 서버쪽 의설정에서 변경 하시면 됩니다.

클라이언트(접속의 대상이 되는 서버)에서 설정하실려면 아래 경로의 설정을 변경 해줍니다.

~/.ssh/config

Host test-proxy
HostName test-proxy.example.com
// 연결지속을 위한 설정
// ServerAliveInterval는 초단위 아래는 3시간간격으로
ServerAliveInterval 10800
ServerAliveCountMax 3

원격 포트포워딩을 이용해서 프록시 서버로 포트포워딩 합니다.

ssh -R 8080:localhost:22 root@프록시서버IP

위의 명령어는 포그라운드로 실행됩니다. ssh 세션을 바로 시작하기에 마치 ssh로 접속되신것처럼 보이실 겁니다.

해당 ssh 세션을 계속 열어두시고 테스트 해도 괜찮으나 이 경우 ssh 세션이 종료되면 터널도 함께 종료됩니다.

이를 방지하고자 ssh 세션을 열지 않고 백그라운드로 실행 하시려면 위의 명령어 대신 아래 명령어를 입력합니다.
여기서 옵션은 -f 는 백그라운드 실행을 -N은 명령어 실행하지 않고 ssh 세션 유지함을 의미합니다.

ssh -f -N -R 8080:localhost:22 root@프록시서버IP

(옵션) 백그라운드로 잘 실행되고 있는지 아래 명령어를 통해 확인 가능합니다.

ps aux | grep ssh

(옵션) 백그라운드를 종료하고 싶다면 위의 명령어 결과로 나온 두번째 열인 PID 를 확인해서 종료할 수 있습니다.

kill 프로세스아이디

프록시 서버에 필요한 설정

마찬가지로 연결을 중개하는 프록시 서버의 설정을 아래와 같이 변경 해줍니다.

아래 설정이 되어 있지 않은 경우 외부에서 접근이 불가합니다.

/etc/ssh/sshd_config

// 로컬에서만 가능한 연결을 외부도 가능하게 변경 해주는 옵션
GatewayPorts yes
// 앞서 접속의 대상이 되는 서버(SSH 클라이언트)에서 연결 지속을 설정을
// 따로 해주시지 않은 경우 아래 설정을 추가합니다.
ClientAliveInterval 21600
ClientAliveCountMax 3

마찬가지로 설정 변경 적용을 위해 ssh 서버를 재시작 해줍니다.

sudo systemctl restart ssh

(옵션) 아래 명령어를 통해 포트가 리스닝 하고 있는지 확인 가능합니다.

만약 아무것도 출력되지 않으면 포트가 닫혀 있는것으로 접속 대상이 되는 서버쪽에서 SSH 터널을 잘 연결했는지 확인이 필요합니다.

netstat -tuln | grep 8080

접속 하기

이제 필요한 설정은 모두 끝났습니다. 접속을 원하는 컴퓨터에서 아래 명령어를 통해 접속 하시면 됩니다.

ssh -p 8080 user@프록시서버IP

여기서 주의하실게 user가 프록시 서버의 user가 아니라 최종 접속의 대상이 되는 서버의 user의 이름을 입력해주셔야 합니다.

위의 과정을 통해 포트포워딩이 되지 않는 서버에 접속할 수 있습니다.

혹시 잘 안된다면 아래 명령어를 통해서 프록시의 포트가 접근 가능한지 확인해보실 수 있습니다.

telnet 프록시IP 8080

해당 부분에서 Connection refused 가 뜨신다면 접속 가능한 상태가 아니니 접속하시는 컴퓨터에서 프록시 서버에 접근 가능한지 확인해보셔야 합니다.

--

--