Step 29. SSH 원격 접속 — 암호화된 대문을 열다

Step 29. SSH 원격 접속 — 암호화된 대문을 열다

Level 0 — 컴퓨터 조작과 구조의 이해 | 난이도 ★★★☆☆ | 예상 소요 시간 4시간

전제: Step 16~17의 가상머신 환경과 Step 21(apt), Step 24(sudo)를 끝냈어야 합니다. 우분투 가상머신과 호스트 PC(윈도우 파워쉘)가 둘 다 필요합니다.

  • 준비물: 우분투 가상머신, 윈도우 파워쉘. 우분투에 openssh-server를 하나 설치합니다.
  • 주의 — 이 책의 절대 규칙: 오늘 실습의 대상은 여러분이 직접 설치한 여러분의 가상머신뿐입니다. 남의 컴퓨터나 서버에 허락 없이 접속을 시도하는 것은 "실험"이라는 이름으로도 정당화되지 않는 범죄입니다 (한국 정보통신망법상 침입 행위). 기술이 커질수록 이 경계는 더 엄격해집니다. 오늘의 모든 명령은 내 랩 안에서만 실행하세요.

여기까지 여러분은 가상머신 창을 띄워 놓고 그 안에서 직접 작업했습니다. 그런데 실제 서버는 대부분 멀리 떨어진 데이터센터나 클라우드에 있고, 화면도 키보드도 없습니다. 그 컴퓨터에 명령을 내리는 사실상 유일한 표준이 SSH(Secure Shell)입니다. 오늘은 호스트 윈도우에서 우분투 가상머신으로 접속을 성공시키고, 비밀번호 대신 열쇠로 로그인하는 공개키 인증까지 완성합니다. "옆방 컴퓨터에 무선으로 명령을 내리는" 첫 경험은 꽤 신기합니다.


1. 학습 목표

이 챕터를 끝내면 다음을 할 수 있습니다:

  • SSH가 무엇이고, 평문 통신의 어떤 문제를 해결하는지 설명한다
  • 우분투에 SSH 서버를 설치하고 systemctl로 켜고 상태를 확인한다
  • 윈도우 파워쉘에서 가상머신으로 ssh 계정@주소 접속에 성공한다
  • 공개키/개인키 쌍을 만들어 비밀번호 없이 접속한다
  • scp로 파일을 원격과 주고받는다

2. 배경 지식 — 오늘의 도구와 개념

오늘의 도구 한눈에 보기

구분 내용
언어·환경 윈도우 파워쉘(클라이언트) + 우분투 터미널(서버)
오늘의 명령어 sudo apt install openssh-server(서버 설치), sudo systemctl start/status ssh(서비스 관리), ip a(주소 확인), ssh 계정@주소(접속), ssh-keygen(열쇠 만들기), scp 파일 계정@주소:~/(파일 전송)
필요한 개념 평문 통신의 위험, 서버와 클라이언트, 포트 22, 공개키 인증(자물쇠와 열쇠), 지문(fingerprint)

2-1. 왜 암호화인가 — 옛날 이야기

인터넷 초기에는 telnet이라는 원격 접속이 있었습니다. 문제는 비밀번호를 포함한 모든 내용이 평문(암호화 없는 날것)으로 전선을 탔다는 것. 같은 네트워크의 누군가가 도청하면 비밀번호가 그대로 보였습니다. 그래서 "전선이 도청당해도 안전한" 통신이 필요했고, 그 답이 SSH입니다.

오늘날의 교훈: "암호화되지 않은 통신은 엽서다." 누구든 읽을 수 있다고 가정하는 것이 보안의 기본 상식이고, SSH는 그 상식이 만든 도구입니다.

2-2. 서버와 클라이언트

SSH에는 두 역할이 있습니다:

  • SSH 서버: 접속을 "받아 주는" 쪽. 오늘 우분투 가상머신에 설치합니다(openssh-server). 포트(port) 번호 22번에서 기다리는 것이 표준입니다.
  • SSH 클라이언트: 접속을 "거는" 쪽. 윈도우 파워쉘에는 이미 ssh 명령이 들어 있습니다.

포트는 "한 컴퓨터 안의 프로그램별 창구 번호"라고 생각하면 됩니다. 같은 주소(IP)라도 22번 창구는 SSH, 80번 창구는 웹이 식으로 나뉩니다.

2-3. 공개키 인증 — 자물쇠와 열쇠

비밀번호 로그인의 약점: 비밀번호는 매번 서버로 보내야 하고, 누군가 알면 끝입니다. SSH의 더 안전한 방식이 공개키 인증(public-key authentication)입니다.

  • 열쇠 한 쌍을 만듭니다: 공개키(public key)개인키(private key).
  • 비유: 공개키는 자물쇠, 개인키는 열쇠입니다.
  • 자물쇠(공개키)는 서버에 달아 둡니다. 누구에게 보여 줘도 상관없습니다.
  • 열쇠(개인키)는 내 컴퓨터에 숨겨 둡니다. 절대 남에게 주지 않습니다.
  • 접속할 때 서버가 "이 자물쇠를 열 수 있는 열쇠 가졌어?"라고 시험하고, 내 개인키가 수학적으로 증명합니다. 열쇠 자체는 전선에 보내지 않습니다.

비밀번호가 "아는 것"이라면 개인키는 "가진 것"입니다. 그리고 이 개인키 파일 하나가 곧 신분증이라, 관리가 곧 보안입니다.


3. 따라 하기

이 챕터의 출력은 환경(주소, 계정명, 지문)마다 전부 다르므로, 아래 출력은 전부 실제 화면과 같은 형식의 출력 예시입니다. 여러분 화면의 값으로 읽어 가세요.

3-1. 우분투에 SSH 서버 설치와 기동

가상머신 터미널에서:

sudo apt update && sudo apt install -y openssh-server

Step 21에서 배운 apt입니다. 서버 프로그램도 결국 패키지입니다. 설치가 끝나면 켜고 상태를 봅니다:

sudo systemctl start ssh
sudo systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
     Active: active (running) ...

(출력 예시.)

읽는 법: systemctl은 서비스(데몬, Step 26)를 관리하는 명령입니다. "active (running)"이 보이면 SSH 서버가 살아서 22번 포트에서 기다리는 중입니다. 상태 화면에서 나올 때는 q입니다.

3-2. 가상머신의 주소 확인

ip a
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
    inet 192.168.39.82/20 brd ... scope global eth0
...

(출력 예시 — 실제로는 이런 형식입니다. lo127.0.0.1은 "자기 자신"이라는 특수 주소라 접속용이 아니고, eth0, ens33 같은 실제 카드의 inet 주소를 찾으세요.)

읽는 법: 이 숫자가 가상머신의 IP 주소 — 네트워크상의 집 주소입니다. 여기서 주소가 안 보이거나 10.0.2.15만 보이면 가상머신의 네트워크 모드 문제일 수 있습니다. 벽 1에서 해결합니다.

3-3. 윈도우에서 첫 접속

호스트 PC의 파워쉘에서 (주소와 계정명은 여러분 것으로):

ssh lee@192.168.x.x
The authenticity of host '192.168.x.x' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxx...
Are you sure you want to continue connecting (yes/no/[fingerprint])?

(출력 예시 — 첫 접속에만 뜨는 확인입니다.)

읽는 법: "이 서버, 처음 보는데 진짜 믿어도 돼?"라는 확인입니다. 지문(fingerprint)은 서버의 신분증 번호로, 진짜 내 가상머신이 맞는지 대조하는 용도입니다 (미션에서 직접 대조해 봅니다). 처음 연결하는 내 가상머신이 맞으니 yes를 치고, 이후 비밀번호를 물으면 우분투 계정의 비밀번호를 입력합니다.

lee@ubuntu:~$

(출력 예시.)

읽는 법: 프롬프트가 바뀌었습니다. 지금 여러분은 윈도우에 앉아 우분투를 조종하고 있습니다. whoami, ls를 쳐 보세요 — 전부 가상머신 안에서 실행됩니다. 나올 때는 exit.

: 이 한 줄이 원격 관리의 전부입니다. 앞으로 여러분이 만질 모든 원격 리눅스는 이 한 줄로 들어갑니다.

3-4. 열쇠 만들기 — ssh-keygen

윈도우 파워쉘에서 (접속한 상태가 아니라 로컬에서):

ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\나/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):

(출력 예시.)

읽는 법: 열쇠 한 쌍을 굽는 중입니다. 저장 위치는 Enter(기본값), passphrase(열쇠의 비밀번호)는 연습용으로 지금은 Enter로 비워 둡니다. 그러면 두 파일이 생깁니다:

  • id_ed25519개인키. 절대 타인에게 주지 않는 파일.
  • id_ed25519.pub공개키. 서버에 달 자물쇠. .pub이 public입니다.

3-5. 자물쇠를 서버에 달기

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh lee@192.168.x.x "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

(출력 예시: 비밀번호를 한 번 묻고, 아무 메시지 없이 끝나면 성공입니다.)

읽는 법: 이 한 줄이 하는 일 — 내 공개키(.pub)를 읽어서(type), SSH로 가상머신에 접속해, 그쪽의 ~/.ssh/authorized_keys("인가된 열쇠 명단") 파일 끝에 추가합니다(>>). "이 열쇠 가진 사람은 들여보내 줘"라고 서버 문 앞에 명단을 올리는 것입니다. 파이프(|)로 윈도우의 출력이 리눅스의 입력으로 흘러가는, 두 세계가 연결되는 순간이기도 합니다.

예측해 보기: 이제 다시 ssh lee@192.168.x.x를 하면 비밀번호를 물을까요, 안 물을까요? 예측하고 접속해 보세요. (정답: 비밀번호 없이 바로 프롬프트가 뜹니다. 서버가 자물쇠를 확인했고 내 개인키가 그 자물쇠를 연 것입니다.)

3-6. 파일 보내기 — scp

echo "원격으로 보내는 첫 파일" > hello-remote.txt
scp hello-remote.txt lee@192.168.x.x:~/
hello-remote.txt                    100%   30     0.0KB/s   00:00

(출력 예시.)

읽는 법: scp는 "SSH로 복사(secure copy)"입니다. 보낼파일 계정@주소:목적지 형식이고, ~/는 저쪽의 내 홈 폴더입니다.

확인: SSH로 접속해서 cat hello-remote.txt를 쳐 보세요. 방금 윈도우에서 만든 파일이 우분투에 있습니다.

: 원격 서버와 파일을 주고받는 것은 실무의 밥입니다. 백업을 가져오고, 스크립트를 올리고, 로그를 내려받는 일 전부가 scp(또는 그 친척들)입니다.


4. 미션과 연습문제

미션 — 지문 대조와 열쇠 관리 완주

  1. 지문 대조: 윈도우에서 첫 접속 때 본 fingerprint를, 가상머신 안에서 sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub로 직접 출력해 같은 지문인지 비교하세요
  2. 상태 이중 확인: 가상머신에서 systemctl status ssh(서비스가 살아 있는가)와 ss -tlnp | grep 22(22번 포트에서 듣고 있는가)를 둘 다 실행해 "서버 생존"을 두 가지 방법으로 확인하세요
  3. 왕복 전송: 윈도우 → 가상머신으로 파일을 보내고(scp), 반대로 가상머신에서 만든 파일을 윈도우로 가져오세요 (scp lee@주소:~/remote.txt .)
  4. 열쇠 폐기와 재등록: 가상머신에서 nano ~/.ssh/authorized_keys로 자기 공개키 줄을 지우고 → 접속 시 비밀번호를 다시 묻는지 확인 → 다시 등록하세요
  5. 전 과정에서 막힌 곳과 해결을 ssh-report.txt에 기록하세요

연습문제

문제 1. telnet 같은 평문 원격 접속의 문제는 무엇이며, SSH는 그 문제를 어떻게 해결하나요?

문제 2. 공개키 인증에서 서버에 올리는 것과 내 컴퓨터에 숨겨 두는 것은 각각 무엇인가요? 개인키를 서버에 올리면 안 되는 이유는?

문제 3. 첫 접속 때 뜨는 fingerprint 확인은 무엇을 위한 장치이며, 이것이 막는 공격(중간자 공격)은 어떤 것인가요?

문제 4. ssh 접속이 "Connection refused"로 즉시 거부될 때와, 한참 기다리다 "타임아웃"될 때는 원인이 다릅니다. 각각 무엇을 의심하고 무엇을 확인해야 하나요?


5. 모범 답안과 완료 기준

미션 모범 답안

# 1. 가상머신 안에서 — 서버의 진짜 지문 출력
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
# 3. 윈도우 → 가상머신, 그리고 반대 방향
scp hello-remote.txt lee@192.168.x.x:~/
scp lee@192.168.x.x:~/remote.txt .

검증하는 법: ① 1번에서 가상머신이 직접 출력한 지문과, 첫 접속 때 파워쉘이 보여 준 지문의 SHA256:... 부분이 같은가 — 같으면 "내가 접속한 상대가 진짜 내 서버"임이 증명된 것입니다. 이것이 중간자 공격(누군가 가짜 서버를 세워 내 접속을 가로채는 공격)을 잡는 실무 습관입니다. ② 2번에서 두 명령 모두 22번과 ssh를 가리켰는가. ③ 4번에서 키를 지운 뒤 비밀번호 질문이 돌아왔는가, 재등록 후 다시 사라졌는가 — 등록과 폐기를 둘 다 해 봐야 진짜 관리입니다.

연습문제 해답

문제 1 해답. 평문 접속은 비밀번호를 포함한 모든 내용이 암호화 없이 전선을 타서, 같은 네트워크의 도청자에게 그대로 노출됩니다. SSH는 오가는 내용 전부를 암호화해서, 중간에서 가로채도 읽을 수 없게 합니다.

문제 2 해답. 서버에 올리는 것은 공개키(자물쇠, authorized_keys에 등록), 내 컴퓨터에 숨겨 두는 것은 개인키(열쇠)입니다. 개인키를 서버에 올리면 그 서버에 들어오는 누구든 내 신분증을 줍는 셈이 됩니다 — 자물쇠는 흩뿌려도 되지만 열쇠는 복제되면 모든 문이 열리기 때문입니다.

문제 3 해답. "지금 접속하는 상대가 내가 아는 그 서버인가"를 확인하는 신분증 대조 장치입니다. 중간자 공격은 공격자가 가짜 서버를 세워 내 접속을 가로채 비밀번호나 세션을 훔치는 공격으로, 가짜 서버는 지문이 다르므로 지문 대조가 이를 잡아 냅니다.

문제 4 해답. 즉시 거부(refused)는 주소까지는 갔는데 그 집의 22번 문이 닫힌 것 — SSH 서버가 안 켜져 있을 가능성이 큽니다. sudo systemctl status ssh로 확인하고 켭니다. 타임아웃은 아예 집에 도착하지 못한 것 — 네트워크 모드(NAT는 들어오는 접속 차단), 주소 오류, 방화벽을 의심합니다. 벽 1의 브리지 또는 포트포워딩 설정을 확인합니다.

완료 기준 체크리스트

  • [ ] SSH가 평문 통신의 어떤 문제를 해결하는지 설명할 수 있다
  • [ ] openssh-server를 설치하고 systemctl로 켜고 상태를 확인할 수 있다
  • [ ] 윈도우에서 우분투로 ssh 접속에 성공했다
  • [ ] 공개키/개인키의 역할과 "개인키는 절대 공유하지 않는다"는 원칙을 설명할 수 있다
  • [ ] authorized_keys가 무엇인지, 권한(700/600)이 왜 중요한지 안다
  • [ ] scp로 파일을 양방향으로 주고받을 수 있다
  • [ ] 미션: 지문 대조, 이중 상태 확인, 왕복 전송, 열쇠 폐기·재등록을 완주했다

6. 흔한 실수와 해결

벽 1. "ip a에 10.0.2.15밖에 없고, 윈도우에서 접속이 안 돼요"

증상: ssh 접속 시 시간이 흐르다 실패(타임아웃)합니다.
원인: VirtualBox의 기본 네트워크 모드(NAT)는 가상머신이 "바깥으로만" 나갈 수 있고, 바깥에서 들어오는 접속은 막힙니다.
해결: 두 갈래 길이 있습니다. ① 가상머신 설정에서 네트워크를 브리지(Bridged)로 바꾸면 집 네트워크의 한 기기처럼 주소를 받습니다. ② NAT를 유지하되 포트포워딩(호스트의 2222번 → 게스트의 22번으로 보내 주는 예외 규칙)을 설정하고 ssh -p 2222 lee@127.0.0.1로 접속합니다. 둘 중 하나가 되면 나머지는 같습니다.

벽 2. "Connection refused가 나와요"

증상: 타임아웃이 아니라 "거부됨"이 즉시 뜹니다.
원인: 주소는 맞게 찾아갔는데, 그 집의 22번 문이 닫혀 있습니다 — SSH 서버가 안 켜져 있습니다.
해결: 가상머신에서 sudo systemctl status ssh로 확인하고, 죽어 있으면 sudo systemctl start ssh. 재부팅 후에도 자동으로 켜지게 하려면 sudo systemctl enable ssh.

벽 3. "키를 등록했는데도 비밀번호를 물어요"

증상: 공개키를 등록했는데 여전히 비밀번호 입력창이 뜹니다.
원인: 대표적으로 셋. ① 저쪽 ~/.ssh 폴더 권한이 느슨함 (SSH는 보안상 권한이 700이 아니면 키를 무시합니다). ② authorized_keys 권한이 600이 아님. ③ 공개키를 잘못 복사(줄바꿈이 끊김).
해결: 가상머신에서 chmod 700 ~/.ssh, chmod 600 ~/.ssh/authorized_keys를 실행하고 다시 시도하세요. SSH의 이 "까다로움"은 버그가 아니라 보안입니다 — 남이 열 수 있는 명단 파일은 신뢰하지 않겠다는 뜻입니다.

벽 4. "지문이 바뀌었다는 무서운 경고가 떠요"

증상: 접속 시 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!가 뜨며 접속이 거부됩니다.
원인: 예전에 접속한 주소의 지문과 다른 서버가 응답합니다. 가상머신을 재설치했거나, IP 주소가 바뀌었거나 — 드물게는 진짜 중간자 공격입니다.
해결: 원인이 "가상머신 재설치"처럼 정상적인 것이 확실하면, 윈도우의 C:\Users\나\.ssh\known_hosts 파일에서 해당 주소의 줄을 지우고 다시 접속합니다. 단, 실제 서버에서 이 경고를 만나면 함부로 지우지 말고 먼저 서버 관리자에게 확인하는 것이 원칙입니다.

벽 5. "scp를 쳤는데 Permission denied가 나와요"

증상: 파일 전송이 거부됩니다.
원인: 접속은 됐지만 저쪽 목적지 폴더에 내 쓰기 권한이 없는 경우가 대부분입니다 (예: /etc 아래로 바로내려 한 경우).
해결: 일단 내 홈(~/)으로 보낸 뒤, 저쪽에서 sudo로 옮기는 것이 안전한 순서입니다. Step 23~24의 권한이 원격에서도 그대로 적용됩니다.


7. 정리

오늘의 개념

개념 한 줄 설명
SSH 암호화된 원격 접속의 표준 — 서버(22번 대기)와 클라이언트
포트 한 컴퓨터 안의 프로그램별 창구 번호 (SSH는 22)
공개키 / 개인키 서버에 다는 자물쇠 / 내 컴퓨터에 숨기는 열쇠
authorized_keys 서버 문 앞의 "인가된 열쇠 명단" (~/.ssh는 700, 이 파일은 600)
fingerprint 서버의 신분증 번호 — 첫 접속 때 대조하는 습관
known_hosts 내가 확인한 서버 지문들의 장부

오늘의 명령어

명령 하는 일
sudo apt install openssh-server SSH 서버 설치
sudo systemctl start/status/enable ssh 서버 켜기 / 상태 보기 / 부팅 시 자동 켜기
ip a 이 컴퓨터의 주소 확인
ssh 계정@주소 원격 접속
ssh-keygen 열쇠 한 쌍 만들기
scp 파일 계정@주소:~/ 파일을 원격으로 안전하게 복사
ss -tlnp | grep 22 22번 포트에서 듣고 있는지 확인

명령어보다 중요한 감각

첫 SSH 접속이 성공한 순간부터, 여러분에게 "컴퓨터"는 더 이상 눈앞의 기계가 아닙니다. 네트워크 너머의 어떤 상자든, 주소와 열쇠만 있으면 여러분의 작업대가 됩니다. 동시에 오늘 실습에는 경계선이 하나 있었습니다 — 여러분이 접속한 것은 여러분이 직접 설치하고 키를 등록한 가상머신이라는 선입니다. 열쇠를 만드는 기술과, 열쇠를 쓸 수 있는 문을 구분하는 판단, 둘 다 배운 것이 오늘입니다.

두 가지를 더 기억해 두세요. 첫째, 서버 쪽 SSH 설정은 /etc/ssh/sshd_config에 있고, 실무 서버의 기본 방어벽은 "비밀번호 로그인 끄기 + 키만 허용"입니다 — 전 세계의 22번 포트는 하루에도 수없이 무차별 로그인 시도를 받기 때문입니다. 오늘 여러분은 그 방어벽의 재료(키)를 직접 만들어 봤습니다. 둘째, SSH는 공격자가 노리는 문이자 관리자의 유일한 출입구입니다. 하나의 기술이 공격과 방어 양쪽의 중심에 서 있는 것 — 이 책 전체가 반복할 그 구조를, 오늘 여러분이 처음으로 손에 쥐었습니다.

허락된 문에만 열쇠를 쓴다는 원칙은 기술이 바뀌어도 바뀌지 않습니다. 그 원칙 위에서, 여러분의 손은 이제 원격을 자유롭게 오갑니다.


전부 체크되면 Step 29 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.