coredot.today
SSH 완전 정복: 원격 서버에 '안전하게' 접속하는 기술
블로그로 돌아가기
SSH리눅스서버보안클라우드AWSEC2터미널

SSH 완전 정복: 원격 서버에 '안전하게' 접속하는 기술

10,000km 떨어진 서버를 내 노트북처럼 다루는 기술, SSH. Telnet의 치명적 결함에서 태어난 SSH의 역사부터 키 기반 인증, 터널링, 클라우드 환경 활용, 보안 모범 사례까지 — 클라우드 시대를 여는 가장 기본적인 열쇠를 완전히 이해한다.

코어닷투데이2026-04-0173

들어가며: 10,000km 떨어진 서버를 어떻게 조종할까?

금요일 밤 11시. 서울의 한 스타트업 개발자가 슬랙 알림을 받는다. "프로덕션 서버 응답 없음." 서버는 미국 동부 버지니아(us-east-1)의 AWS 데이터센터에 있다. 직선거리로 약 11,000km. 비행기를 타면 14시간이 걸린다.

하지만 이 개발자는 자리에서 일어나지 않는다. 노트북을 열고 터미널에 한 줄을 친다:

Terminal
$ ssh ubuntu@ec2-54-172-xx-xx.compute-1.amazonaws.com

3초 뒤, 서울의 노트북 화면에 버지니아 서버의 쉘 프롬프트가 뜬다. 마치 그 서버 앞에 직접 앉아 있는 것처럼 명령어를 입력하고, 로그를 확인하고, 프로세스를 재시작한다. 15분 만에 문제를 해결하고 다시 넷플릭스를 켠다.

이 모든 것을 가능하게 하는 기술이 SSH(Secure Shell)다.

클라우드 컴퓨팅 시대에 서버는 더 이상 사무실 전산실에 있지 않다. 전 세계 데이터센터에 흩어져 있다. 이 서버들을 원격으로 관리하려면, 네트워크를 통해 안전하게 접속하는 방법이 필요하다. SSH는 그 방법의 사실상 표준이다.

이 글에서는 SSH가 왜 필요해졌는지(Telnet의 치명적 결함), 어떻게 작동하는지(암호화와 인증), 실무에서 어떻게 쓰는지(키 생성, 터널링, 파일 전송), 그리고 클라우드 환경에서 SSH를 안전하게 운용하는 방법까지 — 완전히 정복한다.


1. SSH 이전의 세계: Telnet과 치명적 결함

1969년, 원격 접속의 시작

인터넷의 전신인 ARPANET 시절부터 사람들은 원격 컴퓨터에 접속할 필요가 있었다. 이를 위해 1969년에 만들어진 프로토콜이 Telnet(Teletype Network)이다. RFC 15로 시작해 1983년 RFC 854로 표준화되었다.

Telnet은 엽서처럼 비밀번호가 보이고 SSH는 잠긴 금고처럼 안전하다

Telnet의 동작은 단순했다. 클라이언트가 서버의 23번 포트에 TCP 연결을 맺고, 사용자가 입력하는 키보드 입력을 그대로 서버에 전송하고, 서버의 출력을 그대로 화면에 표시한다. 마치 아주 긴 케이블로 서버의 모니터와 키보드를 연결한 것과 같다.

1990년대 초반까지 Telnet은 원격 접속의 표준이었다. 대학교 전산실, 기업의 유닉스 서버, 인터넷 초기의 BBS — 모두 Telnet으로 접속했다.

치명적 결함: 모든 것이 평문

문제는 Telnet이 모든 데이터를 암호화 없이 평문(plaintext)으로 전송한다는 것이다.

사용자 입력
비밀번호: MyP@ss123
네트워크 (평문 전송)
MyP@ss123 그대로 노출
서버
인증 처리

사용자 이름, 비밀번호, 입력하는 모든 명령어, 서버가 보내는 모든 출력 — 네트워크를 지나가는 모든 바이트가 누구나 읽을 수 있는 상태로 전송된다.

이것은 마치 엽서에 비밀번호를 적어 보내는 것과 같다. 우체국 직원, 배달부, 옆집 사람 — 엽서를 손에 든 사람은 누구나 내용을 읽을 수 있다.

초기 인터넷에서는 이것이 큰 문제가 아니었다. 네트워크 참여자가 소수의 신뢰할 수 있는 대학과 연구기관이었기 때문이다. 하지만 인터넷이 상용화되고 수백만, 수억 명이 연결되면서 상황이 완전히 바뀌었다.

패킷 스니핑(Packet Sniffing) — 네트워크를 흘러가는 데이터를 중간에서 가로채 읽는 공격 — 이 현실적인 위협이 되었다. 같은 네트워크에 있는 누군가가 Wireshark 같은 도구를 실행하면, Telnet으로 전송되는 비밀번호를 문자 그대로 읽을 수 있었다.

⚠️
Telnet의 보안 취약점 요약: 비밀번호 평문 전송, 명령어 평문 전송, 서버 출력 평문 전송, 데이터 무결성 검증 없음(중간자가 데이터를 변조해도 탐지 불가), 서버 신원 확인 불가(가짜 서버에 접속해도 모름). 오늘날 Telnet을 프로덕션 서버에 사용하는 것은 보안상 금지되어 있다.

Telnet vs SSH: 근본적 차이

항목TelnetSSH
데이터 전송평문 (암호화 없음)전 구간 암호화
비밀번호네트워크에 노출암호화 채널 내 전송
서버 인증없음호스트 키로 검증
데이터 무결성검증 불가MAC으로 변조 탐지
기본 포트2322
파일 전송별도 프로토콜 필요 (FTP)SCP, SFTP 내장
터널링불가포트 포워딩 지원

이 상황에서, 핀란드의 한 대학원생이 결정적인 한 걸음을 내딛는다.


2. SSH의 탄생: 핀란드 대학원생의 분노

서울의 개발자가 SSH로 미국 서버에 접속하는 모습을 텔레포트 포탈로 표현한 일러스트

1995년, 헬싱키 공과대학교

타투 일뢰넨(Tatu Ylönen)은 핀란드 헬싱키 공과대학교(Helsinki University of Technology)의 연구원이었다. 1995년, 그의 대학 네트워크에서 패스워드 스니핑 공격이 발생했다. 수천 개의 사용자 이름과 비밀번호가 유출되었다.

일뢰넨은 분노했다. 그리고 직접 해결책을 만들기로 했다. 그가 3개월 만에 개발한 프로토콜이 SSH-1(Secure Shell version 1)이다. 1995년 7월에 무료로 공개했다.

SSH의 핵심 아이디어는 단순했다:

클라이언트와 서버 사이의 모든 통신을 암호화하자.

공개 직후 폭발적인 반응을 얻었다. 배포 후 몇 달 만에 전 세계 50개국에서 2만 명 이상이 사용했다. "더 이상 Telnet 쓰지 마세요"가 시스템 관리자들 사이에서 상식이 되기 시작했다.

SSH-2: 프로토콜의 진화

SSH-1에는 몇 가지 설계상 취약점이 있었다. 2006년에 SSH-2가 RFC 4251~4256으로 IETF 표준이 되었다. SSH-2는 SSH-1과 호환되지 않는 완전히 새로운 프로토콜로, 더 강력한 암호화, 더 나은 무결성 검증, 그리고 채널 멀티플렉싱을 지원한다.

OpenSSH: 오픈소스의 승리

일뢰넨의 SSH는 점차 상용화되었고, 라이선스 제약이 생겼다. 이에 OpenBSD 팀이 1999년, SSH-1의 초기 자유 라이선스 버전을 기반으로 OpenSSH를 만들었다. 이후 OpenSSH는 세계에서 가장 널리 쓰이는 SSH 구현이 되었다.

1995
SSH-1 공개
타투 일뢰넨, 핀란드 헬싱키 공과대학교에서 개발. 무료 배포.
1999
OpenSSH 탄생
OpenBSD 팀이 자유 라이선스 기반으로 포크. BSD 라이선스로 배포.
2006
SSH-2 IETF 표준화
RFC 4251~4256 발표. 더 강한 암호화, 채널 멀티플렉싱 지원.
현재
사실상 표준
Linux, macOS, Windows 10+ 기본 탑재. 전 세계 서버의 원격 접속 표준.

오늘날 macOS 터미널을 열면 ssh 명령어가 이미 설치되어 있다. Windows 10부터는 OpenSSH 클라이언트가 기본 포함된다. 리눅스는 말할 것도 없다. SSH는 인터넷 인프라의 공기와 같은 존재가 되었다.


3. SSH는 어떻게 작동하는가: 암호화의 3단계

SSH 연결이 맺어질 때, 내부에서는 세 가지 단계가 순서대로 진행된다. 각 단계를 하나씩 살펴보자.

1단계
키 교환
(Key Exchange)
2단계
서버/사용자 인증
(Authentication)
3단계
암호화된 세션
(Encrypted Session)

1단계: 키 교환 (Key Exchange)

클라이언트가 서버에 연결하면, 가장 먼저 대칭 암호화에 사용할 세션 키(session key)를 안전하게 공유해야 한다. 문제는 이 키를 네트워크를 통해 전송하면 도청당할 수 있다는 것이다.

이 문제를 해결하는 것이 Diffie-Hellman 키 교환 알고리즘이다. 1976년에 발명된 이 알고리즘은 "열린 공간에서, 비밀을 전혀 전송하지 않고도, 양쪽이 같은 비밀 값을 공유할 수 있다"는 놀라운 속성을 가진다.

비유하면 이렇다. 두 사람이 각각 비밀 색상을 하나 고른다. 공개된 색상(예: 노란색)을 섞어 자신의 비밀 색상과 혼합한 뒤 상대에게 보낸다. 상대는 받은 혼합 색상에 자기 비밀 색상을 다시 섞는다. 놀랍게도 양쪽이 최종적으로 같은 색상을 얻지만, 중간에 지켜본 사람은 원래의 비밀 색상을 알아낼 수 없다.

실제 SSH에서는 색상 대신 거대한 소수(prime number)와 수학적 연산을 사용하며, 현대 SSH는 주로 Curve25519 기반의 ECDH(Elliptic Curve Diffie-Hellman)를 사용한다.

2단계: 서버 및 사용자 인증

키 교환이 끝나면 암호화된 채널이 열린다. 이제 두 가지 인증이 필요하다:

서버 인증 (Host Key Verification): 내가 접속하려는 서버가 진짜 그 서버인지 확인한다. SSH에 처음 접속하면 이런 메시지를 본 적이 있을 것이다:

Terminal
The authenticity of host 'ec2-54-172-xx-xx (54.172.xx.xx)' can't be established.
ED25519 key fingerprint is SHA256:AbCdEf1234567890...
Are you sure you want to continue connecting (yes/no/[fingerprint])?

yes를 입력하면 이 서버의 공개 키가 ~/.ssh/known_hosts 파일에 저장된다. 다음에 같은 서버에 접속할 때, 서버의 키가 바뀌어 있으면 SSH는 경고를 띄운다. 누군가가 가짜 서버로 바꿔치기한 것일 수 있기 때문이다. 이것이 중간자 공격(Man-in-the-Middle Attack) 방어의 핵심이다.

사용자 인증: 서버가 진짜임을 확인한 후, 이번에는 사용자가 자신의 신원을 증명한다. 방법은 두 가지다:

  1. 비밀번호 인증 — 사용자가 비밀번호를 입력
  2. 공개 키 인증 — 사용자의 키 쌍으로 인증 (다음 섹션에서 자세히)

3단계: 암호화된 세션

인증이 완료되면, 이후의 모든 데이터는 1단계에서 합의한 세션 키로 대칭 암호화(AES-256-GCM 등)되어 전송된다. 명령어 입력, 서버 출력, 파일 전송 — 모든 것이 암호화된다. 중간에 누가 패킷을 가로채도 의미 없는 바이트 덩어리만 보인다.

💡
왜 비대칭 + 대칭 두 가지를 쓸까? 비대칭 암호화(공개 키/개인 키)는 안전하지만 느리다. 대칭 암호화(AES)는 빠르지만 키를 안전하게 교환하는 방법이 필요하다. SSH는 Diffie-Hellman(비대칭)으로 세션 키를 교환한 뒤, AES(대칭)로 실제 데이터를 암호화한다. 두 방식의 장점만 취하는 하이브리드 전략이다.

4. 비밀번호 인증 vs 키 기반 인증

SSH로 서버에 접속할 때, 사용자 인증 방식은 크게 두 가지다. 비밀번호와 키 기반 인증. 둘의 차이를 이해하는 것은 SSH 보안의 핵심이다.

비밀번호 인증: 익숙하지만 위험한

가장 직관적인 방식이다. ssh user@server를 입력하면 비밀번호를 묻고, 맞으면 접속된다.

Terminal — 비밀번호 인증
$ ssh ubuntu@54.172.xx.xx
ubuntu@54.172.xx.xx's password: ********
Welcome to Ubuntu 24.04 LTS
ubuntu@ip-172-31-xx-xx:~$

비밀번호 자체는 SSH의 암호화된 채널을 통해 전송되므로 Telnet처럼 평문으로 노출되지는 않는다. 하지만 근본적인 문제가 있다:

  • 브루트포스 공격: 자동화된 봇이 수천 가지 비밀번호를 계속 시도할 수 있다
  • 비밀번호 재사용: 사람들은 여러 서비스에 같은 비밀번호를 쓴다. 하나가 유출되면 전부 위험하다
  • 숄더 서핑: 누군가 옆에서 비밀번호 입력을 지켜볼 수 있다
  • 관리 부담: 서버가 100대면 비밀번호 100개를 관리해야 한다

키 기반 인증: 비밀번호 없이, 더 안전하게

키 기반 인증은 수학적으로 연결된 한 쌍의 키를 사용한다:

공개키는 누구나 볼 수 있는 자물쇠, 개인키는 금고 속 황금 열쇠

  • 개인 키(Private Key): 내 컴퓨터에만 존재. 절대 외부에 공개하지 않는다. 나의 도장
  • 공개 키(Public Key): 서버에 등록. 누구에게 공개해도 상관없다. 나의 인감증명서
내 노트북
개인 키 보관
(~/.ssh/id_ed25519)
→ 서명 전송 →
서버
공개 키로 서명 검증
(~/.ssh/authorized_keys)

인증 과정을 간략히 설명하면:

  1. 서버가 랜덤한 "챌린지(challenge)" 데이터를 보낸다
  2. 클라이언트는 개인 키로 이 데이터에 서명(sign)한다
  3. 서버는 등록된 공개 키로 서명을 검증한다
  4. 서명이 유효하면 인증 성공

이 과정에서 개인 키 자체는 네트워크를 통해 전송되지 않는다. 서명만 전송된다. 공개 키로 서명을 검증할 수는 있지만, 공개 키로부터 개인 키를 역산하는 것은 수학적으로 불가능하다.

비밀번호 vs 키: 비교

항목비밀번호 인증키 기반 인증
브루트포스 저항취약 (추측 가능)사실상 불가능 (256비트 엔트로피)
비밀 전송 여부비밀번호가 채널을 통과개인 키는 절대 전송 안 됨
자동화 적합성불편 (매번 입력)CI/CD, 스크립트에 최적
다중 서버 관리서버마다 비밀번호 기억하나의 키 쌍으로 여러 서버
분실 시 위험유출 시 즉시 악용 가능패스프레이즈로 이중 보호 가능
실무 권장개발/테스트 환경에서만프로덕션 필수
🔑
AWS EC2의 선택: AWS EC2는 인스턴스 생성 시 키 페어를 만들고, 비밀번호 인증은 기본적으로 비활성화한다. 이것은 AWS가 "키 기반 인증이 더 안전하다"는 것을 정책으로 강제하는 것이다.

5. 실전: SSH 키 생성부터 접속까지

SSH 키 기반 인증을 아파트 카드키 시스템에 비유한 일러스트 — 비밀번호는 구식 열쇠, 키 인증은 카드키

이론은 충분하다. 이제 실제로 SSH 키를 만들고, 서버에 등록하고, 접속해 보자.

5-1. ssh-keygen: 키 쌍 만들기

Terminal — 키 생성
$ ssh-keygen -t ed25519 -C "myname@company.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519): [Enter]
Enter passphrase (empty for no passphrase): ********
Enter same passphrase again: ********
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub

각 옵션을 설명하면:

  • -t ed25519: 키 알고리즘 지정. Ed25519는 현재 가장 권장되는 알고리즘이다. RSA보다 짧은 키 길이에 동등 이상의 보안을 제공하고 서명/검증 속도도 빠르다
  • -C "email": 코멘트. 키를 식별하기 위한 라벨. 관리 편의를 위해 이메일을 넣는다
  • 패스프레이즈(passphrase): 개인 키를 암호화하는 비밀번호. 개인 키 파일이 유출되어도 패스프레이즈 없이는 사용 불가. 반드시 설정하는 것을 권장한다

생성 결과 두 개의 파일이 만들어진다:

~/.ssh/id_ed25519 개인 키 (Private Key) 절대 공유 금지. 권한 600
~/.ssh/id_ed25519.pub 공개 키 (Public Key) 서버에 등록. 공유 가능

5-2. ssh-copy-id: 서버에 공개 키 등록

키를 만들었으면, 접속하려는 서버에 공개 키를 등록해야 한다. 가장 편리한 방법은 ssh-copy-id다:

Terminal — 공개 키 등록
$ ssh-copy-id -i ~/.ssh/id_ed25519.pub ubuntu@54.172.xx.xx
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub"
Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'ubuntu@54.172.xx.xx'"

이 명령은 내부적으로 서버의 ~/.ssh/authorized_keys 파일에 공개 키를 추가한다. 이후부터는 비밀번호 없이 키로 접속할 수 있다.

Terminal — 키 기반 접속
$ ssh ubuntu@54.172.xx.xx
Welcome to Ubuntu 24.04 LTS
ubuntu@ip-172-31-xx-xx:~$

비밀번호를 묻지 않는다. 키 교환 → 서명 검증이 자동으로 진행되었기 때문이다.

5-3. ~/.ssh/config: SSH를 편하게 쓰는 비결

서버가 여러 대라면 매번 ssh ubuntu@54.172.xx.xx -i ~/.ssh/my-key -p 2222를 입력하는 것은 고통이다. ~/.ssh/config 파일을 설정하면 별칭(alias)으로 간단히 접속할 수 있다:

SSH config로 긴 명령어 대신 짧은 별명을 쓰는 개발자

~/.ssh/config
# 프로덕션 웹 서버
Host prod-web
    HostName 54.172.xx.xx
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519
    Port 22

# 스테이징 서버
Host staging
    HostName 10.0.1.50
    User deploy
    IdentityFile ~/.ssh/id_ed25519
    ProxyJump bastion

# 배스천 호스트 (점프 서버)
Host bastion
    HostName 54.172.yy.yy
    User ec2-user
    IdentityFile ~/.ssh/bastion-key.pem

이제 이렇게만 입력하면 된다:

Terminal
$ ssh prod-web
$ ssh staging

~/.ssh/config에서 자주 쓰는 설정들:

설정설명
Host별칭. ssh 별칭으로 접속
HostName실제 IP 또는 도메인
User접속할 사용자 이름
IdentityFile사용할 개인 키 파일 경로
PortSSH 포트 (기본값 22)
ProxyJump경유할 점프 서버 (배스천 호스트)
ServerAliveInterval연결 유지를 위한 heartbeat 주기 (초)
ServerAliveCountMaxheartbeat 실패 허용 횟수
💡
ssh-agent 활용 팁: 패스프레이즈를 매번 입력하기 귀찮다면, ssh-agent를 사용하자. ssh-add ~/.ssh/id_ed25519를 한 번 실행하면, 세션이 유지되는 동안 패스프레이즈 입력 없이 자동 인증된다. macOS는 키체인과 연동되어 재부팅 후에도 기억한다.

6. SSH 터널링: 암호화된 비밀 통로

SSH의 진정한 힘은 단순한 원격 접속을 넘어선다. SSH는 암호화된 터널을 만들어, 일반적으로는 접근할 수 없는 네트워크 리소스에 안전하게 도달하는 통로 역할을 한다. 이것이 SSH 포트 포워딩(Port Forwarding), 흔히 SSH 터널링이라 불리는 기능이다.

SSH 터널을 두 성 사이의 암호화된 비밀 지하 통로로 표현한 일러스트 — 보초가 지키는 성문과 안전한 터널

SSH 터널은 두 성을 잇는 안전한 지하 통로

로컬 포트 포워딩 (Local Port Forwarding)

"내 컴퓨터의 포트를 통해 원격 서버 뒤에 있는 서비스에 접근한다."

가장 흔한 시나리오: 프로덕션 데이터베이스(RDS)가 프라이빗 서브넷에 있어서 직접 접근할 수 없다. 하지만 같은 VPC의 EC2 인스턴스는 접근 가능하다.

내 노트북
localhost:3306
→ SSH 터널 →
EC2 (점프 서버)
SSH 포트 22
→ 내부 접근 →
RDS (DB)
db.internal:3306
Terminal — 로컬 포트 포워딩
$ ssh -L 3306:db.internal:3306 ubuntu@ec2-bastion

# 이제 다른 터미널에서:
$ mysql -h 127.0.0.1 -P 3306 -u admin -p
# → 실제로는 프라이빗 서브넷의 RDS에 접속됨!

-L 로컬포트:원격호스트:원격포트 형식이다. 내 컴퓨터의 3306 포트에 접속하면, SSH 터널을 타고 EC2를 경유해서 db.internal:3306(RDS)에 도달한다.

리모트 포트 포워딩 (Remote Port Forwarding)

"원격 서버의 포트를 통해 내 컴퓨터의 서비스를 노출한다."

예를 들어, 내 노트북에서 개발 중인 웹 앱(localhost:3000)을 동료에게 보여주고 싶은데, 내 노트북은 NAT 뒤에 있어서 직접 접근이 안 된다.

Terminal — 리모트 포트 포워딩
$ ssh -R 8080:localhost:3000 ubuntu@public-server

# 이제 누구든 public-server:8080에 접속하면
# 내 노트북의 localhost:3000으로 연결됨

-R 원격포트:로컬호스트:로컬포트 형식이다. 방향이 반대임에 주의하라.

동적 포트 포워딩 (Dynamic Port Forwarding)

"SSH 서버를 SOCKS 프록시로 사용한다."

특정 포트 하나가 아니라, 모든 트래픽을 SSH 터널로 보낸다. 사실상 간이 VPN이다.

Terminal — 동적 포트 포워딩
$ ssh -D 1080 ubuntu@ec2-us-east-1

# 브라우저 프록시 설정에서 SOCKS5 → 127.0.0.1:1080
# 이제 브라우저의 모든 트래픽이 미국 서버를 경유

세 가지 터널링 비교

유형플래그방향대표 사용 사례
로컬 포워딩-L내 PC → 원격 서버 뒤의 리소스프라이빗 DB 접근, 내부 웹 대시보드
리모트 포워딩-R원격 서버 → 내 PC의 리소스로컬 개발 서버 외부 노출, 웹훅 테스트
동적 포워딩-D모든 트래픽을 SSH로 프록시전체 트래픽 암호화, 지역 제한 우회
💡
실무 팁 — 백그라운드 터널: ssh -fN -L 3306:db.internal:3306 bastion 에서 -f는 백그라운드 실행, -N은 원격 명령어 실행 없이 터널만 유지를 의미한다. 터미널을 점유하지 않으면서 터널을 유지할 때 유용하다.

7. SCP와 SFTP: SSH로 파일 전송하기

서버에 접속하는 것만큼 자주 하는 일이 파일 전송이다. SSH 위에 구축된 두 가지 파일 전송 도구가 있다.

SCP (Secure Copy Protocol)

cp 명령어의 네트워크 버전이다. 파일을 SSH 채널을 통해 암호화 전송한다.

Terminal — SCP 사용법
# 로컬 → 서버로 파일 복사
$ scp ./deploy.tar.gz ubuntu@prod-web:/home/ubuntu/

# 서버 → 로컬로 파일 복사
$ scp ubuntu@prod-web:/var/log/app.log ./logs/

# 디렉토리 전체 복사 (-r 옵션)
$ scp -r ./dist/ ubuntu@prod-web:/var/www/html/

SCP는 단순하고 빠르다. 하지만 파일 목록 조회, 이어받기, 디렉토리 탐색 등 고급 기능은 없다.

SFTP (SSH File Transfer Protocol)

FTP와 비슷한 인터페이스를 제공하지만, SSH 위에서 동작해 모든 데이터가 암호화된다. 기존의 FTP(평문 전송)를 완전히 대체한다.

Terminal — SFTP 사용법
$ sftp ubuntu@prod-web
sftp> ls
app/ config/ logs/
sftp> cd logs
sftp> get app-2026-04-01.log
Fetching /home/ubuntu/logs/app-2026-04-01.log
sftp> put ./hotfix.py /home/ubuntu/app/
Uploading ./hotfix.py
sftp> exit

SCP vs SFTP 비교

항목SCPSFTP
인터페이스단일 명령어대화형 셸
디렉토리 탐색불가ls, cd, pwd 지원
전송 재개불가이어받기 가능 (reget)
속도약간 빠름표준
스크립트 호환셸 스크립트에 간단히 삽입배치 모드 지원 (-b)
추천 상황단발성 파일 복사반복적 파일 관리, GUI 클라이언트
💡
rsync도 SSH 위에서 동작한다: 대량의 파일을 동기화할 때는 rsync -avz -e ssh가 SCP/SFTP보다 효율적이다. rsync는 변경된 부분만 전송하는 델타 전송(delta transfer)을 지원하기 때문이다. 배포 자동화에 자주 쓰인다.

8. 클라우드 환경에서의 SSH

클라우드, 특히 AWS에서는 SSH가 어떻게 쓰이는지 살펴보자. 온프레미스와는 다른 패턴들이 있다.

EC2 키 페어

AWS EC2 인스턴스를 생성할 때, AWS 콘솔에서 키 페어(Key Pair)를 만들거나 기존 키를 지정한다. AWS가 하는 일은:

  1. RSA 또는 ED25519 키 쌍을 생성한다
  2. 공개 키를 EC2 인스턴스의 ~/.ssh/authorized_keys에 자동 등록한다
  3. 개인 키(.pem 파일)를 다운로드하게 한다 (이 기회가 처음이자 마지막이다!)
Terminal — EC2 접속
# .pem 파일 권한 설정 (필수!)
$ chmod 400 my-ec2-key.pem

# EC2 접속
$ ssh -i my-ec2-key.pem ec2-user@ec2-54-172-xx-xx.compute-1.amazonaws.com
⚠️
chmod 400은 왜 필수인가? SSH는 개인 키 파일의 권한이 너무 느슨하면(다른 사용자가 읽을 수 있으면) 접속을 거부한다. WARNING: UNPROTECTED PRIVATE KEY FILE! 에러가 나온다. 이것은 보안을 위한 의도적 설계다. 개인 키는 오직 소유자만 읽을 수 있어야 한다.

배스천 호스트 (Bastion Host / Jump Box)

프로덕션 환경에서는 EC2 인스턴스를 퍼블릭 서브넷에 직접 노출하지 않는다. 프라이빗 서브넷에 배치하고, SSH 접속은 배스천 호스트라는 단일 진입점을 통해서만 허용한다.

배스천 호스트는 성의 정문 초소 — 모든 방문자가 거쳐야 한다

인터넷
개발자 노트북
배스천 호스트
퍼블릭 서브넷
SSH 포트 22만 허용
웹 서버
프라이빗 서브넷
API 서버
프라이빗 서브넷
DB 서버
프라이빗 서브넷

SSH의 ProxyJump 기능을 사용하면 배스천을 경유하는 것이 한 줄로 가능하다:

Terminal
# 배스천을 경유해서 프라이빗 서버에 접속
$ ssh -J bastion-user@bastion-host private-user@10.0.1.50

# 또는 ~/.ssh/config에 ProxyJump 설정 (위의 config 예시 참고)
$ ssh staging

AWS Systems Manager Session Manager: SSH를 넘어서

최근 AWS는 SSH의 대안으로 Session Manager를 제공한다. SSH 포트(22)를 열지 않아도 EC2에 접속할 수 있다.

항목전통적 SSHSession Manager
포트 오픈22번 포트 필수인바운드 포트 불필요
키 관리키 쌍 직접 관리IAM 기반 인증
배스천 호스트필요불필요
감사 로그별도 설정 필요CloudTrail 자동 기록
파일 전송SCP/SFTP 지원제한적 (S3 경유)
포트 포워딩완전 지원지원 (SSM 터널링)
오프라인 접근네트워크만 있으면 가능AWS API 엔드포인트 필요

Session Manager는 "SSH 포트를 아예 닫을 수 있다"는 점에서 보안 관점의 큰 진보다. 하지만 SSH를 완전히 대체하지는 못한다. SCP/SFTP 같은 파일 전송, 복잡한 터널링, AWS 외부 서버 접속 — 이런 경우에는 여전히 SSH가 필요하다.

💡
실무 권장 패턴: 일상적인 EC2 접속은 Session Manager를 사용하고, 파일 전송이나 터널링이 필요한 경우에만 SSH를 쓰는 하이브리드 운영이 현재의 베스트 프랙티스다. 이렇게 하면 SSH 포트를 상시 열어둘 필요가 줄어든다.

9. SSH 보안 모범 사례: 현실적인 10가지

SSH 자체는 안전한 프로토콜이다. 하지만 설정을 잘못하면 아무리 좋은 자물쇠도 무용지물이 된다. 프로덕션 환경에서 반드시 적용해야 할 보안 설정을 정리한다.

서버의 SSH 설정 파일은 /etc/ssh/sshd_config다. 아래 설정들을 적용한 후 sudo systemctl restart sshd로 SSH 데몬을 재시작한다.

9-1. root 직접 로그인 비활성화

/etc/ssh/sshd_config
PermitRootLogin no

root는 시스템의 최고 권한 계정이다. root로 직접 SSH 접속을 허용하면, 공격자가 root 비밀번호만 뚫으면 시스템 전체를 장악한다. 일반 계정으로 접속한 뒤 sudo를 사용하는 것이 안전하다.

9-2. 비밀번호 인증 비활성화

/etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no

키 기반 인증만 허용한다. 비밀번호 인증을 끄면 브루트포스 공격이 원천적으로 불가능하다.

9-3. SSH 포트 변경

/etc/ssh/sshd_config
Port 2222

기본 22번 포트를 변경하면 자동화된 봇의 스캔을 상당수 회피할 수 있다. 보안의 근본적 해결책은 아니지만(security through obscurity), 불필요한 공격 시도를 줄여 로그를 깨끗하게 유지하는 데 도움이 된다.

9-4. fail2ban 설치

Terminal
$ sudo apt install fail2ban
$ sudo systemctl enable fail2ban

fail2ban은 반복적으로 로그인을 실패하는 IP를 자동으로 차단(ban)한다. 기본 설정으로 5회 실패 시 10분간 차단. 설정에 따라 영구 차단도 가능하다.

9-5. 접속 허용 사용자 제한

/etc/ssh/sshd_config
AllowUsers ubuntu deploy
# 또는 그룹 단위로
AllowGroups ssh-users

시스템에 계정이 많더라도, SSH 접속이 가능한 사용자를 명시적으로 제한한다.

나머지 핵심 설정들

SSH 보안 설정 — 영향도 순위
키 기반 인증 전환
필수
root 로그인 차단
필수
비밀번호 인증 비활성화
필수
fail2ban 적용
강력 권장
접속 사용자 제한
권장
SSH 포트 변경
권장
유휴 세션 타임아웃
권장
SSH 프로토콜 v2 강제
참고
배너 메시지 설정
선택

추가로 꼭 알아야 할 설정들:

설정sshd_config 값설명
유휴 타임아웃ClientAliveInterval 300 + ClientAliveCountMax 2접속 후 방치 시 10분 뒤 자동 종료
최대 인증 시도MaxAuthTries 33회 실패 시 연결 종료
빈 비밀번호 차단PermitEmptyPasswords no비밀번호 없는 계정 로그인 방지
X11 포워딩 비활성화X11Forwarding no불필요한 GUI 포워딩 차단

키 교체 (Key Rotation)

키도 비밀번호처럼 주기적으로 교체해야 한다. 특히:

  • 퇴사자 발생 시: 해당 공개 키를 모든 서버의 authorized_keys에서 즉시 제거
  • 키 유출 의심 시: 즉시 새 키 쌍 생성, 구 키 폐기, 모든 서버 업데이트
  • 정기 교체: 6개월~1년 주기 권장
⚠️
실수하면 서버에 접속 불가! sshd_config를 잘못 수정하면 SSH 접속이 끊길 수 있다. 설정 변경 전에 반드시: (1) 현재 세션을 유지한 채로 (2) 새 터미널에서 설정 변경 후 재시작하고 (3) 또 다른 새 터미널에서 접속 테스트. 성공을 확인한 후에만 기존 세션을 종료한다. AWS EC2의 경우 실수 시 Session Manager를 백도어로 쓸 수 있으니, 미리 설정해 두는 것이 안전하다.

10. SSH 문제 해결 가이드

SSH 접속이 안 될 때, 당황하지 말고 아래 순서대로 점검하자.

가장 흔한 에러와 해결법

Permission denied (publickey)
키 파일 경로가 잘못되었거나, 서버에 공개 키가 등록되지 않았거나, 키 파일 권한이 잘못된 경우.
🔧
점검 사항
1. ls -la ~/.ssh/로 키 파일 존재 확인
2. chmod 600 ~/.ssh/id_ed25519로 권한 수정
3. chmod 700 ~/.ssh/ 디렉토리 권한 확인
4. 서버의 ~/.ssh/authorized_keys에 공개 키가 있는지 확인
디버깅 명령어
ssh -vvv user@server — verbose 모드로 인증 과정의 모든 단계를 출력. 어디서 실패하는지 정확히 파악 가능.
Connection timed out
서버에 도달할 수 없는 경우. 네트워크 문제 또는 방화벽 차단.
🔧
점검 사항
1. 서버 IP/도메인이 정확한지 확인
2. AWS Security Group에서 SSH 포트(22) 인바운드 허용 확인
3. telnet server-ip 22로 포트 열려 있는지 테스트
4. VPN 연결이 필요한 네트워크인지 확인
AWS에서 자주 놓치는 것
Security Group의 SSH 인바운드 규칙에서 소스 IP를 0.0.0.0/0(전체 허용)이 아닌 내 IP/32로 제한했는데, IP가 바뀐 경우. 카페나 재택근무 시 IP가 달라지면 접속 불가.

디버깅 체크리스트

1단계
네트워크 확인
ping server-ip — 서버에 도달 가능한가?
2단계
포트 확인
nc -zv server-ip 22 — SSH 포트가 열려 있는가?
3단계
인증 확인
ssh -vvv user@server — 어느 단계에서 실패하는가?
4단계
권한 확인
~/.ssh/ (700), 개인 키 (600), authorized_keys (644)
5단계
서버 로그 확인
sudo tail -f /var/log/auth.log — 서버 측 에러 메시지 확인

마치며: SSH는 클라우드로 가는 다리다

이 글에서 우리는 먼 여정을 했다. Telnet의 평문 전송이라는 치명적 결함에서 출발해, 분노한 핀란드 대학원생이 SSH를 만들고, 그것이 OpenSSH로 발전해 오늘날 인터넷 인프라의 기반이 된 이야기. 키 교환과 암호화의 원리, 비밀번호 대신 키를 써야 하는 이유, 터널링으로 안전한 통로를 만드는 방법, 그리고 클라우드 환경에서의 실전 운용까지.

SSH는 30년이 넘은 기술이다. 하지만 클라우드 시대에 그 중요성은 오히려 커졌다. 서버가 더 이상 건물 안 전산실에 있지 않기 때문이다. 전 세계에 분산된 수십, 수백 대의 서버를 관리하려면, 안전한 원격 접속 기술이 반드시 필요하다. SSH가 바로 그 기술이다.

1995 SSH 탄생 핀란드 헬싱키 공과대학교
30+ 역사 (년) 여전히 사실상 표준
3 핵심 기능 원격 접속, 파일 전송, 터널링

DX 전문가를 꿈꾸는 여러분에게 SSH는 가장 먼저 익혀야 할 기술 중 하나다. 서버에 접속할 수 없으면 아무것도 할 수 없기 때문이다. 오늘 바로 터미널을 열고 ssh-keygen을 실행해 보자. 첫 번째 키 쌍을 만드는 순간, 클라우드로 가는 다리를 건너기 시작한 것이다.

🚀
다음 단계: SSH로 서버에 접속할 수 있게 되었다면, 다음은 서버 위에서 무엇을 할 것인가의 문제다. Docker로 애플리케이션을 컨테이너화하고, CI/CD 파이프라인을 구축하고, 모니터링을 설정하는 것 — 이 모든 것의 첫 걸음이 ssh user@server다.