Post

SSH Reverse Tunnel을 통해 명령어 하나로 파일 전송하기

목차


개요

간단한 파일 전송에는 주로 사용하는 도구가 있다. zmodem 이라는 것으로, lrzsz 를 설치하여 이용할 수 있다.
sz를 통해 원격지 파일을 로컬로 복사하거나, rz를 통해 로컬 파일을 원격지로 가져올 수 있다.

macos에서 lrzsz 설치하기 의 포스트를 보듯, sz, rz 명령어는 SSH 접속 이후 기타 서드파티 도구의 도움 없이 (SFTP 등) 터미널 내부에서 sz, rz 명령어를 사용하는 것만으로도 간단하게 파일 전송이 가능하다.

그러나, 이 방법은 매우 치명적인 단점이 있었는데, 터미널이 zmodem 기능을 지원해야만 적용할 수 있다는 것이다. 구현이 어려운 것인지, zmodem을 잘 지원하는 터미널이 많지 않다. iTerm 또한 Trigger 기능으로 확장을 통해 지원하는 형식으로, 정식 지원이 아니다.

단순히 파일 몇 개의 전송을 위해 터미널 창을 벗어나 SFTP 서드파티 도구를 이용하거나, 새로운 터미널을 여는 것은 상당히 번거로운 작업이다. 따라서 서드파티 도구 없이, SSH로 연결된 터미널에서 명령어 하나로, 원격지의 파일을 로컬로 빠르게 복사하는 방법이 있는지 계속 찾아보다가 결국…
SSH Reverse Tunnel을 이용하면 역방향 SSH 연결이 가능하다는 점을 이용해 어느정도 szrz 명령어와 유사한 사용자 경험을 할 수 있는 명령어를 만들 수 있을 것 같다는 생각이 들었다.

최종적으로는

1
2
3
jcp <file1> <file2> <fil3>
또는
jcp <file1> <file2> <fil3> -- <local path>

입력 시 원격지의 파일을 로컬로 복사하는 스크립트를 만들게 되었다.

방법

  • 본 포스트는 MacOS를 기준으로 작성되었으며, Windows 및 Linux에서도 몇 가지의 방법만 다를 뿐(ssh 서버 설정 등), 대부분의 내용은 동일하게 적용될 수 있다.

SSH Server 설치 및 설정

역방향 SSH 터널을 만들기 위해서는 로컬에 SSH 서버가 실행 중이어야 한다.

MacOS의 경우 설정을 수정하여 SSH 서버를 실행시킬 수 있다.
Windows의 경우 Windows용 OpenSSH 서버를 설치하거나, WSL을 이용해 SSH 서버를 실행시킬 수 있다.

서버 실행에 있어 sshd_config 파일을 수정하였다.
외부 접근을 막기 위해, AllowUsers 옵션으로 로컬 호스트 로 접속하는 testuser 만 접속을 허용하도록 설정하였다.

/etc/ssh/sshd_config

1
AllowUsers testuser@localhost testuser@::1 testuser@127.0.0.1

.ssh/config 설정 및 역방향 SSH 터널 설정

이후 ~/.ssh/config 옵션을 수정한다.

Host * 을 대상으로 RemoteForward 옵션을 추가하였다.
여기에서는 포트를 5555 로 설정하였으나, 이는 사용자가 마음대로 변경할 수 있다.
localhost:22 부분은 로컬에서 서비스 중인 SSH 서버의 포트를 적어야 한다.

마지막으로 Host rloc 설정을 추가한다. 이는 원격지에서 접속할 역방향 SSH 정보를 입력한 것이다.
따라서 rloc 설정은 원격지의 .ssh/config 파일을 수정하여 추가해야 한다.

이해를 돕기 위해, 전체 설정인 * 설정, 원격지 서버 별칭인 vm_server 설정과 역방향 SSH 설정인 rloc 설정을 추가하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Host *
    AddKeysToAgent yes
    RemoteForward 5555 localhost:22

Host vm_server
    HostName 10.0.0.68
    User testuser
    Port 22
    IdentityFile ~/.ssh/test_server_private_key

Host rloc
    HostName 127.0.0.1
    User testuser
    Port 5555
    IdentityFile ~/.ssh/ssh_private_key

ssh config 없이 ssh 명령어로 접속 시 역방향 SSH 터널을 추가하고 싶다면 -R 옵션을 사용하면 된다.

1
ssh -R 5555:localhost:22 testuser@test.com

역방향 연결 테스트

1
2
3
4
5
6
7
# 원격지 서버에 접속 (.ssh/config의 server 별칭)
$ ssh vm_server

# 원격지 서버에서 역방향 SSH 연결 테스트
$ ssh rloc

-> 접속 성공

스크린샷

image.png

빨간 사각형에서 보이는 것처럼 최초 MacOS 에서 리눅스 서버로 접속 시도
파란 사각형에서 보이는 것처럼 서버에서 설정했던 rloc 설정을 통해 다시 MacOS로 역방향 SSH 연결 성공

파일 전송 스크립트 작성

역방향 SSH 연결에 성공한 것을 확인하였다면, 이제 파일 전송 스크립트를 작성할 차례다.

필자에게 가장 필요한 것은 remote 에서 local로 파일을 복사하는 것이었다.
(원격지 장비에서 tcpdump 등으로 캡쳐한 패킷 파일을 로컬로 가져와야 하는 경우 등)

따라서 현재는 remote -> local 스크립트만 작성한 상태이다.

https://github.com/iblea/.dotfiles/blob/main/.bin/jcp

위 링크의 내용을 복사하거나, 다운로드하여 (파일 이름 : jcp)
export $PATH 환경변수가 설정되어 있는 경로 중 아무곳이나 넣고, 실행 권한을 부여한다.
(또는 해당 파일이 있는 경로를 $PATH에 추가하면 된다.)

설정에 따라 R_MACRO, R_CONFIG, R_DEFAULT_DOWNLOAD_PATH 변수 값을 수정한다.

특히 리눅스 유저나 윈도우즈 유저의 경우 R_DEFAULT_DOWNLOAD_PATH 값을 수정해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
# .ssh/config의 remote -> local 설정한 별칭
# (위 블로그에 설정한 대로 .ssh/config의 별칭을 rloc으로 설정했다면 변경 불필요 )
R_MACRO="rloc"

# rloc 별칭이 설정된 .ssh/config 파일 경로
R_CONFIG="$HOME/.ssh/config"

# 다운로드될 로컬의 기본 경로를 입력하지 않을 경우 본 설정값의 경로에 저장됨
# <username> 설정 시 config 파일의 rloc username으로 바뀜
# MacOS의 경우 본 설정 그대로 적용 시, 경로를 따로 입력하지 않을 경우 다운로드 디렉토리에 저장됨.
# Windows, Linux의 경우 본 설정값을 수정하여 사용하여야 함.
R_DEFAULT_DOWNLOAD_PATH="/Users/<username>/Downloads"

이제부터, jcp 명령어를 “딸깍” 하는 것으로 파일을 복사할 수 있다.
남들이 sftp, MobaXTerm으로 파일을 복사할 때, 나는 jcp 명령어로 손쉽게 복사할 수 있는 것이다!

jcp 명령은 아래와 같이 사용할 수 있다.

1
2
3
4
5
6
7
8
# 원격지의 파일 1개를 로컬의 $R_DEFAULT_DOWNLOAD_PATH 경로에 저장
jcp <file>

# 원격지의 파일 3개를 로컬의 $R_DEFAULT_DOWNLOAD_PATH 경로에 저장
jcp <file1> <file2> <file3>

# 원격지의 파일 2개를 로컬의 /var/log에 저장
jcp <file1> <file2> -- /var/log

아래 스크린샷은 jcp 명령어를 통해 원격지의 파일을 로컬로 복사한 것이다.

tcpdump로 원격지에서 캡쳐한 패킷 파일을 로컬로 복사하는 과정이다.
jcp server_packet.pcap 명령어를 통해 원격지의 server_packet.pcap 파일을 로컬로 복사하였다.

This post is licensed under CC BY 4.0 by the author.