최근 수정 시각 : 2024-10-09 13:04:45

Secure Shell

1. 개요2. 기능3. 서버 설치 및 운용
3.1. OpenSSH 설치3.2. 접속 테스트3.3. 공개키/개인키 쌍을 생성하여 비밀번호 입력 없이 접속할 수 있도록 구성하기
3.3.1. PuTTY용 개인키 생성하기
3.4. OpenSSH 호스트 설정3.5. SSH 터널링을 프록시로 사용하기
4. 추천 클라이언트
4.1. SSH 클라이언트4.2. SFTP 클라이언트4.3. SSH 디렉토리를 로컬 드라이브/디렉토리처럼 이용하기
5. 관련 문서

1. 개요

Secure Shell, SSH
원격지의 셸에 접속하기 위해 사용되는 네트워크 프로토콜. 보통 축약해서 SSH라고 부른다. 뜻 그대로 보안 셸이다. 기존의 유닉스 시스템 셸에 원격 접속하기 위해 사용하던 텔넷은 암호화가 이루어지지 않는 텍스트 기반 통신[1]인지라 모든 통신 내용이 탈취될 위험이 높으므로, 여기에 키 교환 알고리즘 기반의 암호화 기능을 추가하여 1995년에 공개된 프로토콜이다. # 기본 포트는 22번.

2. 기능

  • 호스트의 셸 구현.
    • 텔넷과 같이 TTY 기능을 수행한다.
  • 파일 전송 프로토콜(FTP)의 대체(SCP/SFTP)
    • SCP는 단순한 파일 푸쉬 프로토콜로 유닉스 셸의 cp 명령과 동일한 기능을 한다. 단지 원격지 호스트의 파일을 핸들링할 때 SSH 프로토콜을 이용하는지의 여부에서 차이가 있다.
    • SFTP는 FTP와 같은 기능을 한다. FTP에 SSL/TLS 보안인증을 적용한 FTPS와는 작동 메커니즘이 다르다. FTP/ FTPS 프로토콜이 텔넷과 별개의 포트를 사용하는 별개의 서비스인 것과 달리, SFTP는 SSH의 하위 어플리케이션 개념으로 작동하며 SSH 서버의 접속 포트를 함께 사용한다.
  • 호스트와 클라이언트간 터널링 구현
    • 원격지 호스트에 접속하기 위한 특정 포트가 방화벽으로 차단되어 직접적인 연결이 불가능한 경우가 있다. SSH의 터널링 기능을 사용하면 클라이언트의 루프백 IP/포트를 호스트 측의 포트와 연결해주는 우회통로를 형성할 수 있다.[2] 정확히는 원격지 호스트의 네트워크 자원 일부를 로컬 클라이언트의 네트워크 자원 일부와 같은 것으로 취급하는 기능이다.[3]
    • 목적이 유사한 서비스로 VPN[4], 리버스 프록시[5], 공유기의 포트포워딩 등이 있으며, 모두 작동 메커니즘과 작동 성능이 다르므로 필요에 맞게 사용하면 된다.
  • X11 Display 포워딩
    • X11 Display 서버가 설치된 원격 호스트로 접속할 때 ssh 명령어 파라미터에 -X를 주면 호스트에서 구동되는 GUI 프로그램을 클라이언트에서 직접 실행할 수 있다.[6] 이 기능을 사용하려면 리눅스/유닉스 클라이언트도 X11 Display 서버를 실행중이어야 하고, 윈도우에서는 xmanager[7] 같은 전용 프로그램을 사용해야 한다.
    • 윈도우의 원격 데스크톱과 유사하나, 원격 데스크톱이 한 계정에 하나의 세션만 허용하는 것과 달리 여러개의 세션을 동시에 운용할 수 있다.
    • x11 외에 Wayland 등의 window system이 구동중인 시스템에서는 일반적인 사용이 어려울 수 있다.

3. 서버 설치 및 운용

SSH 서버를 구현하는 패키지는 수없이 많은데, 가장 널리 사용되는 무료 패키지는 OpenSSH를 꼽을 수 있다. 역사가 오래 된 만큼 점점 무거워지는 경향이 있어 리눅스에서는 dropbear를 대체제로 이용하는 경우도 있지만, 여기에서는 OpenSSH 서버를 구성하는 방법에 대해 기술한다.

3.1. OpenSSH 설치

  • 윈도우
    • 윈도우 10 1809 이상이나 윈도우 11에서는 선택적 기능에서 OpenSSH 서버를 추가할 수 있다. 선택적 기능 추가를 위해 꼭 윈도우 10 1809 이상을 설치할 필요는 없으며, 그 이하 버전이더라도 Win32 OpenSSH 인스톨러를 사용하여 설치할 수 있다.
    • 설치가 완료되면 서비스에 등록되어 바로 실행되고, 윈도우 방화벽에서 TCP 22번 포트가 개방된다. 접속 시 사용하는 기본 셸은 명령 프롬프트 기반이다. 필요에 따라 파워쉘을 실행할 수도 있다.
  • 리눅스
    • 배포판 마다 구성이 다르다. 어떠한 배포판은 운영체제 설치 시 이미 OpenSSH나 dropbear가 설치되는 경우도 있고, 어떤 배포판은 별도로 패키지 관리자를 통해 설치해줘야 한다. 셸 또한 sh/ash/bash 등 호스트 마다 다르다.
    • 별도로 설치하는 경우는 반드시 서비스가 오류 없이 실행되는지 여부를 확인하고 부팅 시 서비스가 자동실행 되도록 설정해야 한다. 패키지 설치 시 자동으로 서비스를 구성해주는 경우도 있지만 그래도 다시 확인하자.
    • 윈도우와는 달리 호스트의 방화벽 설정을 직접 수정해 SSH 접속을 받아들일 포트를 수동으로 개방해야 한다.

3.2. 접속 테스트

  • 셸에서 ssh 명령을 이용하거나 윈도우의 PuTTY 같은 전용 클라이언트를 이용해 호스트에 접속 가능한지 여부를 확인한다. 이 과정은 SSH 서버가 호스트 컴퓨터에서 정상적으로 실행되는지를 확인하는 것이므로 호스트에서 루프백 접속으로 테스트해도 무방하다. 셸에서 다음의 명령을 실행해 접속이 가능한지 확인한다.{{{#!syntax sh $ ssh <호스트 계정>@<호스트 IP주소 또는 도메인> -p 22 <- 클라이언트에서 원격 접속 테스트
$ ssh <호스트 계정>@localhost -p 22 <- 루프백 접속 테스트}}}
  • 원격 테스트 시, 호스트의 방화벽에서 TCP 22번 포트를 개방한 상태더라도 공유기(라우터) 또는 ISP에서 TCP 22번 포트를 막아버려 접속이 불가한 경우가 있다. 이 경우는 우선 루프백 테스트만을 진행하고 다음과 같이 대응한다.
    • sshd_config 파일을 수정하여 접속 포트를 임의의 다른 포트 번호로 변경한다.
    • 공유기의 포트포워딩 기능을 이용, 공유기의 WAN 측 임의의 포트를 SSH 호스트가 사용하는 IP의 TCP 22번 포트와 연결한다. DMZ 기능이나 Twin-IP 기능은 호스트를 완전히 외부로 개방하게 되므로 사설 네트워크 내부가 아닌 이상 가급적 사용하지 않는다. VPN을 경유하도록 구성할 수도 있겠지만 이중 암호화로 오버헤드만 늘리는 꼴이 되니 차라리 텔넷이 더 낫다.
    • 공유기 관리자나 ISP 관리자 측에 내가 사용할 호스트의 IP에 대한 22번 포트를 개방하도록 요청한다. 다만 이 경우는 심각한 보안문제가 발생할 수 있으므로 대부분의 관리자가 거부할 것이다.

3.3. 공개키/개인키 쌍을 생성하여 비밀번호 입력 없이 접속할 수 있도록 구성하기

개념을 단순화하자면 공개키는 도어락이나 자물쇠, 개인키는 RF태그나 열쇠 정도로 이해하면 된다. 호스트에 특정 계정이 접속을 시도할 때 클라이언트로서의 자격증명을 상호 보유한 키 쌍의 매칭 여부로 판단하고 비밀번호 입력 과정을 생략하는 것이다. 물론 파일이므로 쉽게 복사될 수 있고 내용을 읽을 수 있기 때문에 개인키에 PassPhrase라고 하는 암호 구문을 사용하도록 설정할 수 있다.
윈도우/리눅스 등에 관계 없이 셸에서 다음과 같이 입력해 공개키/개인키 쌍을 생성한다. 호스트의 로컬/원격 셸이든 클라이언트의 셸이든 어디에서 작업을 진행해도 무방하다.[8] 단지 공개키는 호스트, 개인키는 클라이언트가 소유해 반드시 한 쌍이 되어야 하는 점을 기억하면 된다.[9]
#!syntax sh $ ssh-keygen -t <암호화 알고리즘> -b <암호화 비트>
알고리즘은 dsa ecdsa ecdsa-sk ed25519 ed25519-sk rsa 를 이용할 수 있다. 주로 rsa 2048/4096비트나 ed25519가 이용된다.
Generating public/private rsa key pair.
Enter file in which you want to save the key (<계정의 홈 디렉토리>/.ssh/id_rsa):   <- 일반적으로 기본값을 그대로 사용한다
Enter passphrase (empty for no passphrase):   <- 비워도 문제는 없지만, 개인키 파일이 유출될 경우를 대비해 비밀번호를 걸어두도록 하자
Enter same passphrase again:   <- 위의 비밀번호를 재입력한다
Your identification has been saved in <홈 디렉토리>/.ssh/id_rsa.  <- 개인키 파일. 파일 이름에 암호화 알고리즘 이름이 붙고, 확장자가 없다
Your public key has been saved in <홈 디렉토리>/.ssh/id_rsa.pub.  <- 공용키 파일. 마찬가지로 암호화 알고리즘 이름이 붙고, pub 확장자가 있다
The key fingerprint is:
SHA256:<SHA256 해쉬 값> <계정 이름>@<생성작업을 진행한 컴퓨터의 hostname>
The key`s randomart image is:
+---[RSA 2048]----+       <-- 알고리즘 종류
|   .. +o+.       |
|  .  o.o.o.      |
| . ..+..... .    |
| o.=+ .+.  o     |
| o=oo.BooS  .    |       <-- 생성된 키를 표현하는 텍스트 그림
| .ooo.o%+..  E   |
|   .o== o.       |
|    o.+          |
|    +*           |
+----[SHA256]-----+       <-- 해쉬
이렇게 생성된 공개키/개인키는 다음과 같이 처리한다.
  • 공개키 파일 이름을 OpenSSH에서 기본적으로 사용하는 authorized_keys로 변경하고[10] 호스트의 <홈 디렉토리> 하위에 있는 .ssh 디렉토리[11]에 복사한다.
  • 개인키는 클라이언트로 사용할 단말에 복사한다. 사용자가 기억하기 쉽되 타인은 접근하기 어려운 경로가 좋을 것이다.
클라이언트 측에서 다음의 명령을 실행해 비밀번호 없이 키 기반 접속이 가능한지 확인한다.#!syntax sh $ ssh <호스트 계정>@<호스트 IP주소 또는 도메인> -p <접속 포트> -i <개인키 경로>/<개인키 파일 이름>개인키를 이용하여 접속할 때 권한과 관련된 경고[12]가 뜨고 접속이 안되는 경우가 있다. 개인키 파일에 대한 권한이 다중으로 지정되어 있기 때문인데, 소유자의 계정 외에도 개인키를 사용할 수 있다고 판단해 SSH 클라이언트가 자체적으로 연결 시도 자체를 중단하는 것이다. 소유자 계정만 파일을 읽을 수 있도록 권한을 변경해야 한다.
#!syntax sh 리눅스에서는 개인키 파일 권한에 400을 준다.
$ chmod 400 ~/.ssh/id_rsa
#!syntax sh 윈도우에서는 개인키 파일의 속성을 열고 보안 탭에서 고급(V) 버튼을 누르면 고급 보안 설정 창이 뜬다.
상속 사용 안함(I)을 선택한 뒤 팝업창에서 '이 개체에서 상속된 사용 권한을 모두 제거합니다.'를 선택해 모든 권한을 지운다.
추가(D)를 선택하여 현재 접속한 사용자를 추가하고, 오직 한 계정만 읽기 및 실행 권한만 있는지 확인하고, 확인 버튼으로 모든 창을 다 종료한다.

3.3.1. PuTTY용 개인키 생성하기

PuTTY에서 키 기반 접속을 위해서는 셸에서 생성한 개인키가 아니라 PuTTY용으로 변환된 개인키를 이용해야 한다. 변환된 개인키 파일은 PuTTY 뿐 아니라 FileZilla, WinSCP, 안드로이드용 CX파일탐색기 등의 클라이언트에서도 사용 가능하므로, 셸에서 생성한 개인키와 함께 변환된 개인키를 함께 보유하는 것이 권장된다.
  • 다운로드 페이지에서 puttygen.exe 파일을 받는다.
  • puttygen.exe를 실행한다.
  • Load 버튼을 누르고 All files를 선택한 뒤 셸에서 생성한 개인키 파일을 가져온다. 필요 시 passphrase를 입력한다.
  • 필요에 따라 Key comment를 수정하고, Key passphrase를 변경할 수 있다.
  • Save private key를 눌러 ppk 확장자를 가진 PuTTY용 개인키를 저장한다.

3.4. OpenSSH 호스트 설정

  • sshd_config 파일에서 다음의 내용을 수정할 수 있다.
    • SSH 접속 포트 : 기본 포트인 22번이 외부망에 개방되면 무작위 접속 시도가 끊임없이 들어오므로 바꿔주는 것이 권장된다. 공유기 하단에 호스트를 위치시켜 포트포워딩을 사용하는 방법도 있다. 포트를 바꿨다면 호스트의 방화벽 설정 또한 수정해야 한다.
    • 키 인증 접속 허용 여부 : 비밀번호를 입력하는 과정이 물리적으로 노출될 수 있으니 공개키/개인키 쌍을 생성하여 개인키를 가진 단말에서만 접속을 허용하는 것이 권장된다.
    • 비밀번호 사용 접속 허용 여부 : 위와 마찬가지의 이유로, 가급적 키 인증 접속만 허용하고 비밀번호 사용 접속을 차단해두는 것이 좋다.
    • 비밀번호 없이 접속 허용 여부 : 비밀번호가 없으면 보안 셸을 사용할 이유가 없다. 반드시 차단해두자.
    • 루트(관리자) 접속 허용 여부 : 루트를 개방하는 것은 시스템을 완전히 개방하는 것이다. 루트 접속은 차단하고 일반 계정으로 접속해 슈퍼유저 권한을 받아 사용하는 습관을 들이자.
    • 공개키 파일 이름 : 기본적으로 authorized_keys를 사용하도록 되어 있다. 다른 파일 이름을 사용하고 싶을 경우 변경해도 무방하지만, 타인의 계정도 같은 파일 이름을 사용하도록 해야 한다.
    • 계정 별 SFTP의 최상위 디렉토리(/) 설정(chroot) : 보안 문제 등의 사유로 특정 디렉토리만 접속을 허용하고 그 상위 디렉토리는 접근하지 못하게 해야 하는 경우에 사용하는 설정이다. chroot가 적용된 계정은 SFTP만 접속이 가능하고 SSH 접속이 제한되므로 SFTP 전용 계정을 추가로 생성하도록 하고, 최소 하나 이상의 SSH 접속용 계정을 확보하는 것이 권장된다. 자세한 설정법은 링크 참조.
  • 리눅스는 /etc/ssh 디렉토리에 sshd_config 파일이 생성되며, 루트 권한으로만 수정이 가능하다.
  • 윈도우는 C:\\ProgramData\\ssh 폴더에 sshd_config 설정 파일이 생성되어 있다. 해당 폴더는 관리자 계정만 쓰기 권한이 있으며, 일반 사용자 계정으로는 다음과 같이 작업하면 된다.

    • ① 메모장을 관리자 권한으로 실행하여 직접 수정 또는
      ② 바탕화면 등의 임의 폴더에 복사하여 메모장으로 수정한 뒤 파일탐색기로 해당 폴더에 다시 덮어씌우면서 관리자 권한을 승인하기
  • 이미 실행되고 있는 상태에서도 설정 파일의 수정이 가능하지만 수정사항이 바로 반영되지 않는다. 서비스를 재실행하거나 재부팅하여 정상적으로 반영되었는지 확인한다.

3.5. SSH 터널링을 프록시로 사용하기

  • 호스트의 sshd_config에서 "AllowTcpForwarding" 을 yes로 바꿔준다. 주석 처리가 돼있을 경우 주석을 풀어준다
    {{{#!syntax sh 리눅스 : sudo nano /etc/ssh/sshd_config -> AllowTcpForwarding yes
윈도우 : C:\ProgramData\ssh에서 sshd_config를 관리자 권한으로 실행한 메모장 등으로 수정}}}
  • 호스트에서 SSH서비스를 재시작 한다
    #!syntax sh sudo systemctl restart ssh
  • 클라이언트에서 아래 옵션으로 접속한다
    {{{#!syntax sh $ ssh -D 127.0.0.1:5000 -N -v -C <호스트 계정>@<호스트 IP주소 또는 도메인> -p 22

- D 127.0.0.1:5000 : 로컬 SOCKS 프록시 서버를 연다(다른 포트를 사용해도 무방하다)
- N : 원격 명령을 실행하지 않고 포트 포워딩으로만 사용
- v : 디버깅 메시지를 출력 (필수 옵션은 아니다.)
- C : 터널에서 데이터를 압축한다 (대역폭 절약을 위함)

개인키 파일 사용시 아래 옵션을 추가한다
-i <개인키 경로>/<개인키 파일 이름>}}}
  • 개인키 파일을 사용 안할시 비밀번호로 로그인한다
  • 이후 127.0.0.1에 5000번 포트를 리스닝하기 시작하며, 클라이언트에서 프록시로 접속할 수 있다. 브라우저 또는 시스템 프록시설정을 127.0.0.1:5000에 SOCKS로 해두면 VPN처럼 호스트의 IP를 이용해 인터넷에 접속하거나 호스트의 로컬 망에 엑세스할 수 있다.
  • 개인용으로만 사용할 홈서버(NAS 등등)를 외부에서 엑세스할 경우 공유기에서 서비스마다 포트를 죄다 포워딩 시키거나 수틀려서 DMZ로 열어놓는것 보다 SSH포트만 포트 포워딩으로 열어두고 외부에서 접속할 때는 SSH 터널링을 사용하여 로컬 망으로 서비스들에 엑세스 하면 SSH가 뚫리지 않는 이상 안전하게 개인 서버에 엑세스 가능하다.
  • 종료할 때에는 Ctrl + C 등으로 셸을 종료하면 서버도 꺼진다.

4. 추천 클라이언트

4.1. SSH 클라이언트

4.2. SFTP 클라이언트

  • 셸에서 사용하는 sftp 명령 - CLI 기반
  • FileZilla - 리눅스/윈도우용 FTP/FTPS/SFTP/WebDAV 클라이언트로 GUI 기반에서는 가장 널리 사용되고 있다
  • WinSCP - 윈도우용 FTP/FTPS/SFTP/WebDAV 클라이언트로 FileZilla보다 더 직관적인 인터페이스를 가지고 있다

4.3. SSH 디렉토리를 로컬 드라이브/디렉토리처럼 이용하기

  • SSH Filesystem(sshfs)를 이용한 SSH 디렉토리 마운트

    • SSH connection 기반으로 원격 서버를 로컬 파일 시스템으로 마운트할 수 있다. 우분투 20.04 버전에서도 sshfs을 설치 가능하며, /etc/fstab 을 수정하여 부팅단계부터 원격 서버의 디렉토리를 로컬 디렉토리로 마운트할 수 있다.
      윈도우에서는 sshfs 설치는 sshfs-Win WinFsp 설치하면 원격 드라이브 연결이 가능하다. 프로그램 설치 후 Windows 커맨드에서 net use 명령어 실행하고 원격 서버의 패스워드를 입력하면 원격 드라이브가 연결된다. Win10 설치기에 의하면 네트워크 드라이브가 읽기 전용으로 마운트된다고 한다. 이는 네트워크 보안 정책의 문제인지, sshfs-win의 문제인지 확인이 필요하다.
      {{{#!syntax cpp

net use y: \\sshfs\[your id]@192.168.XXX.XXX!22\[your id] /user:[your id]}}}
  • 국산 프로그램인 RAIDRIVE를 이용하면 윈도우 클라이언트에서 GUI 기반의 프론트엔드를 이용해 SSH/SFTP 서버를 로컬 드라이브 처럼 연결할 수 있다.

5. 관련 문서


[1] 1990년대의 PC통신을 생각하면 된다 [2] 일례로 윈도우의 원격 데스크톱(3389) 등은 직접적인 암호화 기능이 없어 보안 문제 발생 가능성이 크기 때문에 인터넷 서비스 업체(ISP)가 아예 포트를 막아버리는데, 터널링을 이용하면 SSH 서버를 경유해 호스트 컴퓨터로의 원격 데스크톱을 이용할 수 있다. [3] 통상적으로 이러한 기능은 호스트가 설정/제어 권한을 갖는데, 특이하게도 SSH 터널링은 클라이언트에게 제어 권한이 있다. [4] 클라이언트가 VPN 서버에 접속 시 VPN 서버 하위의 사설망 내부에서 물리적으로 연결된 단말로 취급되며 별개의 사설망 IP를 부여받는다. [5] HTTP/HTTPS 도메인 바인딩 뿐 아니라 TCP/UDP 포트 스트리밍도 가능하다. 자세한 내용은 구글에서 NGINX streaming을 검색해보자. [6] 리눅스나 유닉스는 화면 출력용 비트맵 데이터 덩어리를 X11 Display 서버를 경유해 모니터로 전달한다. 그 모니터를 원격 호스트의 하드웨어가 아닌 클라이언트의 리모트 세션으로 설정하는 것이다. 리모트 디스플레이에 특화된 터널링이라 할 수 있으며, 그 일련의 과정을 SSH에서 네이티브로 지원한다. [7] 스포티파이 꼼수앱인 xManager와는 다른, 1997년부터 시작된 역사가 깊은 프로그램이다. 이런건 제대로 된 설명이 없고 어째서 꼼수앱이 먼저 등재된걸까… [8] 어느 시스템에서든 SSH 클라이언트로서 키 쌍을 생성할 수 있으므로 작업 위치에 구애받지 않는다는 의미이다. 키 파일의 특성이나 권한 부여 문제 등의 이유로 클라이언트에서 작업하는 것이 권장되긴 한다. [9] 키 쌍을 사용할 수 있는 위치가 특정되지 않기 때문에 한번 생성해놓으면 무한히 복사해서 사용할 수 있다. 개인이 잘 관리하면 유용한 기능이지만 허술하면 해킹으로 이어지기 쉽다. [10] 혼자 사용할 SSH 서버라면 다른 이름을 이용해도 무방하지만, 차후 설정 단계에서 파일 이름을 정확히 지정해야 접속이 가능하다. [11] 리눅스/유닉스 시스템에서는 디렉토리나 파일의 이름이 마침표로 시작하면 숨김 속성이 부여되어 일반적인 파일/디렉토리 탐색 시에는 표시되지 않는다. [12] WARNING: UNPROTECTED PRIVATE KEY FILE! [13] https://www.netsarang.com/ko/xshell-download/ [14] 2024-08-01 기준 KRW 99,000(vat외), USD 99