infra
Platform

모듈 맵

[Linux] 원격 리눅스 서버 안전 접속과 절대 무너지지 않는 기본 명령어

0 / 37 완료

펼치기
0 / 37 완료0%

리눅스 서버 운영 · 02 / 37

[Linux] 원격 리눅스 서버 안전 접속과 절대 무너지지 않는 기본 명령어

WSL, SSH, VM 세 가지 방법으로 Linux 터미널에 접속하고, 셸의 기본 동작 방식을 익힙니다.

🚨INCIDENT ALERT
HIGH

새벽 2시, Slack 알림이 울렸습니다. 운영 서버 디스크가 90%를 넘었고 누군가 긴급으로 로그 파일을 정리해야 했습니다. 노트북을 열었지만 클릭할 GUI가 없었습니다. 터미널과 SSH 연결만 있었습니다. ls, df, rm 같은 기본 명령어를 몰랐다면 그날 밤을 그냥 넘겼을 겁니다. 터미널은 서버 엔지니어의 두 번째 언어입니다. 손에 익으면 마우스보다 훨씬 빠르고 정확하게 서버를 다룰 수 있습니다.

이번 챕터에서 배울 것
  • 1WSL2를 설치하고 Ubuntu 22.04 터미널을 열 수 있다 (Windows)
  • 2SSH 키를 생성하고 원격 서버에 접속할 수 있다
  • 3프롬프트를 읽어 현재 사용자·서버·디렉토리를 파악할 수 있다
  • 4명령어 + 옵션 + 인수 구조를 이해하고 --help로 모르는 옵션을 찾을 수 있다
  • 5Tab 자동완성과 Ctrl+R 히스토리 검색으로 타이핑을 줄일 수 있다
실습 환경 준비
Windows 사용자
wsl --install -d Ubuntu-22.04

관리자 권한 PowerShell에서 실행. 재부팅 후 Ubuntu 앱에서 username/password 설정

macOS 사용자

기본 Terminal.app 또는 iTerm2 사용. macOS는 zsh 기반이며 Linux와 대부분의 명령어가 동일합니다

클라우드 서버 접속
chmod 600 ~/.ssh/my-key.pem && ssh -i ~/.ssh/my-key.pem ubuntu@<서버_IP>

AWS EC2, GCP, DigitalOcean 모두 SSH 키 기반 접속

WSL2와 SSH — 두 가지 접속 방법

💡개념

WSL2: Windows에서 Linux 환경 구축

WSL2 구조 — Windows 커널 위 Linux VM, 파일 연동확대

예전엔 VirtualBox를 따로 설치하고, 네트워크를 잡고, 공유 폴더도 설정해야 했습니다. 설치하는 데만 한 시간이 걸렸습니다. WSL2는 이 과정을 명령어 한 줄로 줄였습니다. Windows 파일 시스템을 그대로 쓰면서 진짜 Linux 커널이 뜨기 때문에, 이 트랙의 모든 실습을 WSL2 하나로 커버할 수 있습니다.

설치 (Windows 10 2004 이상 / Windows 11)

POWERSHELL
# 관리자 권한 PowerShell: 시작 → PowerShell 우클릭 → 관리자 권한으로 실행
wsl --install -d Ubuntu-22.04

재부팅 후 Ubuntu 앱이 열리면 username과 password를 설정합니다 (비밀번호 입력 시 화면에 표시 안 되는 것이 정상).

WSL과 Windows 파일 연동

로컬 터미널
# Windows C:\Users\my-name\Downloads 를 WSL에서 접근
ls /mnt/c/Users/my-name/Downloads

# WSL 파일을 Windows 탐색기에서 열기
explorer.exe .

파일 성능: /mnt/c/ (Windows 파티션)에서 작업하면 느립니다. 코드는 WSL 홈 디렉토리(~/)에 두는 것이 권장됩니다.

💡개념

SSH: 원격 서버 접속

SSH 연결 흐름 — 로컬 터미널에서 원격 서버 셸까지확대

클라우드 서버는 화면이 없습니다. AWS EC2를 만들어도 모니터가 연결되는 게 아닙니다. 네트워크를 통해 터미널 세션을 여는 게 유일한 접속 방법이 SSH입니다. 서버에 무언가를 설치하거나, 로그를 보거나, 배포 스크립트를 실행할 때 — 전부 SSH로 연결된 터미널에서 이루어집니다.

SSH 키 생성

패스워드 방식 대신 키 쌍(공개키+프라이빗키) 방식이 더 안전하고 실무 표준입니다.

로컬 터미널
# ED25519 알고리즘으로 SSH 키 생성
ssh-keygen -t ed25519 -C "your@email.com"
# 저장 위치: 기본값(~/.ssh/id_ed25519)으로 Enter
# 패스프레이즈: 빈칸도 OK (Enter)

# 결과물 확인
ls -la ~/.ssh/
OUTPUT
id_ed25519       ← 프라이빗 키 (절대 공유 금지, 권한 600 필수)
id_ed25519.pub   ← 퍼블릭 키 (서버에 등록, 공유 가능)

서버 접속

로컬 터미널
# AWS .pem 키로 접속
chmod 600 ~/Downloads/my-ec2-key.pem    # 권한 변경 (필수)
ssh -i ~/Downloads/my-ec2-key.pem ubuntu@54.123.45.67

# ~/.ssh/config로 단축키 설정
# Host prod
#   HostName 54.123.45.67
#   User ubuntu
#   IdentityFile ~/.ssh/my-ec2-key.pem
ssh prod    # 설정 후 이렇게만 입력
💡개념

셸 기본 개념 & 명령어 구조

셸 프롬프트 구조와 명령어 해부 — 사용자·호스트·디렉토리·권한확대

처음 터미널을 열면 ubuntu@ip-172-31-0-1:~$ 같은 문자열이 뜨고 커서가 깜빡입니다. 이 프롬프트가 셸이고, 셸은 사용자가 입력한 명령을 받아 OS에 전달하는 역할을 합니다. 프롬프트 한 줄에는 내가 누구인지, 어느 서버인지, 어느 디렉토리에 있는지가 담겨 있습니다.

로컬 터미널
ubuntu@ip-172-31-0-1:~$
# ubuntu          → 현재 사용자 이름
# ip-172-31-0-1   → 서버 호스트명
# ~               → 현재 디렉토리 (~ = 홈 디렉토리)
# $               → 일반 사용자 (root면 # 표시)

모든 Linux 명령어는 명령어 [옵션] [인수] 구조를 따릅니다.

로컬 터미널
ls -la /etc/nginx
# ls           → 명령어 (프로그램)
# -la          → 옵션 (-l: 자세한 형식, -a: 숨김 파일 포함)
# /etc/nginx   → 인수 (처리할 대상)

필수 단축키:

단축키동작
Tab자동완성 (명령어, 경로, 파일명)
/ 이전/다음 명령어 히스토리
Ctrl+R히스토리 역방향 검색
Ctrl+C현재 실행 중인 명령 중단
Ctrl+L화면 지우기
Ctrl+U현재 줄 전체 삭제
명령 출력에서 무엇을 봐야 하는가 — 초보 판독 기준
명령 실행 후 아무것도 안 나옴정상일 수 있다 — Unix는 '성공하면 조용하다'. echo $?로 종료코드 확인: 0이면 성공, 0이 아니면 실패. 'no news is good news'
ls -l 첫 글자 (- / d / l)파일 종류 신호 — -=일반파일, d=디렉터리, l=심볼릭링크. 그 뒤 9칸은 소유자/그룹/기타 권한(rwx)
command not found오타이거나 미설치 또는 PATH 누락. which <명령>으로 설치 여부, echo $PATH로 경로 확인
Permission denied권한 부족 — 파일 권한(ls -l) 또는 root 필요. 무작정 sudo 붙이기 전에 '정말 권한이 필요한 작업인가' 먼저 판단
pwd / whoami 출력사고 예방의 기본 — '지금 어디서, 누구로' 작업 중인지. rm 같은 위험 명령 전 항상 확인하는 습관
프롬프트가 $ 에서 # 으로 바뀜root로 전환됨 — 모든 명령이 시스템 전체에 영향. #이 보이면 한 번 더 신중하게

실습

1첫 접속 후 서버 환경 파악

터미널을 열거나 SSH로 접속한 직후 반드시 확인하는 명령어들입니다. 어떤 서버인지, 얼마나 운영됐는지, 내가 누구인지를 30초 안에 파악합니다.

로컬 터미널
# 서버 기본 정보 (커널 버전, 호스트명, 아키텍처)
uname -a

# 가동 시간 및 부하 확인
uptime

# 현재 로그인 사용자
whoami

# 배포판 버전 확인
cat /etc/os-release | grep -E "^NAME|^VERSION"
OUTPUT
Linux ip-172-31-0-1 5.15.0-1045-aws #50-Ubuntu SMP x86_64 GNU/Linux
 14:23:01 up 2 days,  3:15,  1 user,  load average: 0.05, 0.03, 0.00
ubuntu
NAME="Ubuntu"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
uname -a && uptime && whoami
🔍실행 후 확인할 것
  • uname -a에서 Linux 커널 버전과 서버 아키텍처(x86_64 등)가 나오는가?
  • uptime에서 서버 가동 시간과 load average 세 숫자가 나오는가?
  • whoami가 예상한 사용자 이름을 출력하는가?
  • ls -la 출력 읽기 순서: 첫 번째 문자(파일 타입) → 권한 9자리 → 링크 수 → 소유자 → 그룹 → 크기 → 수정 시각 → 파일명 순으로 읽는다
  • 파일 타입 첫 글자: -(일반 파일) / d(디렉토리) / l(심볼릭 링크) / s(소켓) / p(파이프) — 대부분의 파일은 - 또는 d
  • 권한 9자리: rwx(소유자) rwx(그룹) rwx(기타) — r=읽기(4) w=쓰기(2) x=실행(1), chmod 적용 전 반드시 현재 권한을 확인한다
  • SSH 키 파일(-rw-------): 600 권한이어야 정상 — rw-r--r--(644)이면 SSH 클라이언트가 키 사용을 거부한다
2Tab 자동완성과 히스토리 검색

실무에서 타이핑을 절반으로 줄이는 두 가지 기능입니다. Tab 자동완성과 Ctrl+R 히스토리 검색을 한 번 써보면 다시는 전체를 타이핑하고 싶지 않아집니다.

로컬 터미널
# Tab 자동완성 연습
cd /et<Tab>        # /etc/로 자동완성
ls /etc/ssh<Tab>   # /etc/ssh/로 자동완성

# 히스토리 검색: Ctrl+R 누른 후 키워드 입력
# (reverse-i-search)`ssh': ssh -i ~/.ssh/key.pem ubuntu@...

# 최근 명령어 목록
history | tail -10

# 특정 번호 재실행 (history 출력의 번호)
!42    # 42번 명령 재실행
!!     # 마지막 명령 재실행
history | tail -10
🔍실행 후 확인할 것
  • cd /et + Tab을 누르면 /etc/로 자동완성되는가?
  • Ctrl+R을 누른 후 ssh를 입력하면 이전 ssh 명령이 나타나는가?
  • history | tail -10이 최근 10개 명령 목록을 출력하는가?
3tmux로 세션 유지

SSH 접속이 끊겨도 작업이 유지되도록 tmux를 사용하는 것이 실무 기본입니다. 장시간 실행되는 스크립트나 빌드 작업은 반드시 tmux 안에서 돌립니다.

로컬 터미널
# tmux 설치 확인 및 설치
which tmux || sudo apt install -y tmux

# 새 세션 시작
tmux new -s mysession

# 세션 내에서 작업 후 나가기 (세션은 유지됨)
# Ctrl+B, D

# 세션 목록 확인
tmux ls

# 세션에 다시 연결
tmux attach -t mysession

tmux 기본 단축키 (Ctrl+B가 prefix):

단축키동작
Ctrl+B, D세션에서 나가기 (세션 유지)
Ctrl+B, "화면 수평 분할
Ctrl+B, %화면 수직 분할
Ctrl+B, ←→↑↓분할된 패널 간 이동
tmux new -s mysession
🔍실행 후 확인할 것
  • tmux new -s mysession 실행 후 하단에 초록색 상태바가 나오는가?
  • Ctrl+B, D로 나간 후 tmux ls에서 세션 목록이 보이는가?
  • tmux attach -t mysession으로 다시 연결되는가?

트러블슈팅

상황: AWS EC2에 처음 접속하려고 ssh -i my-key.pem ubuntu@<IP>를 실행했을 때 키 파일 경고와 함께 접속이 거부됩니다. .pem 파일을 다운로드하면 기본 권한이 0644인 경우가 많아서 자주 발생합니다.

원인: SSH 클라이언트는 보안을 위해 프라이빗 키 파일이 소유자만 읽을 수 있는 권한(0600)인지 확인합니다. 0644처럼 다른 사람도 읽을 수 있는 권한이면 "이 키는 안전하지 않다"고 판단하고 접속을 거부합니다.

진단 — 현재 키 파일 권한 확인:

로컬 터미널
ls -la ~/.ssh/my-key.pem
OUTPUT
-rw-r--r-- 1 ubuntu ubuntu 1674 ...
#  ↑↑↑
#  rw-r--r-- = 0644 → 문제 있음 (다른 사람도 읽기 가능)

해결:

로컬 터미널
# 소유자만 읽기 가능하도록 권한 변경
chmod 600 ~/.ssh/my-key.pem

# 변경 후 확인
ls -la ~/.ssh/my-key.pem
OUTPUT
-rw------- 1 ubuntu ubuntu 1674 ...
#  ↑↑↑
#  rw------- = 0600 → 정상 (소유자만 읽기)

.ssh 디렉토리 자체도 700이어야 합니다: chmod 700 ~/.ssh

상황: ssh ubuntu@54.123.45.67 명령을 입력했는데 수십 초를 기다려도 응답이 없고 타임아웃이 납니다. 서버는 분명 AWS 콘솔에서 "running" 상태인데 접속이 안 됩니다.

원인: 네 가지 가능성이 있습니다. ① 보안 그룹(방화벽)이 22번 포트를 차단 ② 서버의 SSH 서비스가 중지됨 ③ IP 주소가 틀림 ④ 서버가 다른 네트워크에 있음

진단 — 단계적으로 확인:

로컬 터미널
# 1. IP 주소가 맞는지 — AWS 콘솔에서 Public IPv4 확인
# EC2 → Instances → 해당 인스턴스 클릭 → Public IPv4 address

# 2. 네트워크 연결 자체는 되는가?
ping 54.123.45.67

# 3. 22번 포트가 열려 있는가?
nc -zv 54.123.45.67 22
OUTPUT
# nc 결과 (포트 닫힘)
nc: connectx to 54.123.45.67 port 22 (tcp) failed: Connection refused
# nc 결과 (포트 열림)
Connection to 54.123.45.67 22 port [tcp/ssh] succeeded!

해결:

SSH 접속 후
# AWS 경우: 보안 그룹에서 인바운드 규칙 확인
# EC2 → Security Groups → Inbound rules → SSH(22) 허용 여부 확인
# 내 IP만 허용: 현재 클라이언트의 공인 IP/32를 확인해 입력
# 예: curl -4 https://ifconfig.me  → 203.0.113.10 이면 203.0.113.10/32
# 0.0.0.0/0은 인터넷 전체에 SSH를 공개하므로 기본값으로 사용하지 않습니다.

# 포트 번호가 다른 경우 (22 외)
ssh -p 2222 ubuntu@54.123.45.67

심화 — 접속이 '될 때' 실제로 무슨 일이 벌어지나

💡개념

심화: SSH는 사실 '양방향 인증'이다 — 나도, 서버도 서로를 증명한다

본문에서는 내 개인키로 서버에게 '내가 나'임을 증명했습니다. 그런데 SSH 접속에는 반대 방향의 인증이 하나 더 숨어 있습니다. 서버도 자신이 '진짜 그 서버'임을 나에게 증명합니다. 이 두 번째 인증을 알아야 어느 날 갑자기 뜨는 무시무시한 경고 배너를 이해할 수 있습니다.

  • 서버에도 키가 있습니다: 서버는 접속할 때마다 자신의 호스트 키(/etc/ssh/ssh_host_ed25519_key)로 서명해 신원을 증명합니다. 이 키는 내가 만든 로그인용 키와 별개로, 서버가 설치될 때 자동 생성됩니다.
  • 처음 접속 = 신뢰의 첫 등록(TOFU): 처음 보는 서버면 known_hosts에 기록이 없어, SSH가 서버 호스트 키의 지문(fingerprint)을 보여주며 신뢰할지 묻습니다. yes를 누르면 그 지문이 ~/.ssh/known_hosts에 저장됩니다(Trust On First Use).
  • 이후 접속 = 대조: 다음부터는 서버가 보낸 호스트 키를 known_hosts의 기록과 매번 대조합니다. 일치해야 접속이 이어지고, 이 대조가 중간자(MITM) 공격 — 누군가 내 접속을 가로채 가짜 서버로 유도하는 것 — 을 막습니다.
  • 그래서 생기는 한계: 서버를 재생성해 같은 IP를 다시 쓰면 새 서버의 호스트 키가 옛 기록과 어긋나 SSH가 접속을 거부합니다. 이건 내 개인키나 방화벽 문제가 아니라 '서버 신원이 바뀌었다'는 신호입니다.
로컬 터미널
# known_hosts에 저장된 특정 호스트의 기록 조회
ssh-keygen -F 54.123.45.67

정리하면 로그인 성공은 '내 키가 맞다'만이 아니라 '서버도 내가 아는 그 서버가 맞다'까지 통과했다는 뜻입니다.

상황: 어제까지 멀쩡히 접속되던 서버입니다. 비용을 줄이려 EC2 인스턴스를 종료했다가 다시 만들면서 같은 Elastic IP를 새 인스턴스에 붙였습니다. 그런데 ssh prod를 치자 접속되기는커녕 큼지막한 경고 배너가 뜨고 곧바로 거부됩니다. 개인키도 그대로고 방화벽도 안 건드렸습니다.

원인: 새로 만든 인스턴스는 설치 시점에 새 호스트 키를 생성합니다. 하지만 내 ~/.ssh/known_hosts에는 옛 인스턴스의 호스트 키가 그대로 남아 있습니다. SSH 입장에선 'IP는 같은데 서버가 제시하는 신원이 달라졌다 → 누군가 접속을 가로챈 것일 수도 있다'고 판단해 연결을 끊습니다. 로그인용 개인키(내 신원)와는 무관한, 서버 신원 대조 단계에서 막힌 것입니다.

진단:

로컬 터미널
# 경고 메시지가 known_hosts의 몇 번째 줄이 문제인지 알려준다
# Offending key ... in ~/.ssh/known_hosts:12   ← 12번째 줄이 옛 기록

# 저장된 항목을 직접 조회해 옛 지문을 확인
ssh-keygen -F 54.123.45.67

AWS 콘솔에서 그 인스턴스를 최근 재생성했는지 함께 확인합니다. 재생성 사실이 확인되면 호스트 키 변경은 정상적인 결과입니다.

해결:

로컬 터미널
# known_hosts에서 그 호스트의 옛 항목만 삭제
ssh-keygen -R 54.123.45.67

# 재접속하면 다시 '처음 보는 서버'로 취급 → 새 지문을 TOFU로 저장
ssh prod

주의: 재생성한 적이 없는데 이 경고가 뜬다면 진짜 중간자 공격일 수 있습니다. 무작정 -R로 지우지 말고, 클라우드 콘솔의 시스템 로그에 찍힌 실제 호스트 키 지문과 서버가 제시한 지문을 대조한 뒤에 지워야 합니다.

💼
실무 맥락
현업 패턴

새로 프로비저닝된 EC2를 처음 받았을 때 팀에서 표준으로 하는 초기 접속 체크리스트입니다. 단순히 접속하는 게 아니라 서버 상태를 파악하고 팀 기준에 맞게 설정하는 과정입니다.

SSH 접속 후
# 1. 접속
ssh -i ~/.ssh/prod-key.pem ubuntu@<IP>

# 2. 기본 상태 파악
uname -a && uptime && free -h && df -h

# 3. 패키지 업데이트
sudo apt update && sudo apt upgrade -y

# 4. 불필요한 포트 확인
ss -tlnp

# 5. SSH 설정 확인 (패스워드 인증 비활성화 여부)
grep PasswordAuthentication /etc/ssh/sshd_config

# 6. tmux 설치
sudo apt install -y tmux

이 루틴이 익숙해지면 새 서버를 받을 때마다 5분 안에 기본 점검이 끝납니다.


명령어·단축키 빠른 참조

이 모듈에서 다룬 첫 접속·셸 입력 단축키·세션 유지 명령을 모았습니다. "예" 열의 조합을 그대로 써도 됩니다.

명령어/단축키용도자주 쓰는 예
uname -a / uptime / whoami접속 직후 서버 파악uname -a && uptime && whoami
cat /etc/os-release배포판·버전 확인cat /etc/os-release | grep -E "^NAME|^VERSION"
ls -la파일 목록(숨김·상세)ls -la /etc/ssh (권한·소유자 확인)
Tab경로·명령 자동완성cd /et + Tab/etc/
Ctrl+R히스토리 역방향 검색Ctrl+Rssh 입력 → 이전 ssh 명령
history명령 이력 보기·재실행history | tail -10, !123(번호로 재실행)
ssh-keygen -t ed25519SSH 키 생성ssh-keygen -t ed25519 → Enter로 기본 경로
ssh원격 서버 접속ssh -i ~/.ssh/key.pem ubuntu@54.123.45.67
~/.ssh/config접속 별칭 등록Host prod 블록 작성 → ssh prod
tmux new / ls / attachSSH 끊겨도 세션 유지tmux new -s workCtrl+B Dtmux attach -t work
wsl --installWindows에 Linux 설치관리자 PowerShell에서 실행

관련 모듈로 더 깊이:

다음 모듈에서는 Linux 파일시스템 구조와 디렉토리 탐색을 다룹니다. ls, cd, pwd, find 명령어로 서버 내부를 자유롭게 돌아다닐 수 있게 됩니다.

지식 확인

퀴즈 — 10문제

Q1

SSH 접속 시 'Permission denied (publickey)' 오류가 발생했습니다. 원인으로 가장 가능성이 높은 것은?

Q2

터미널에서 명령어를 입력하다 실수했을 때 현재 줄 전체를 지우는 가장 효율적인 방법은?

Q3

WSL2(Windows Subsystem for Linux 2)가 WSL1과 다른 핵심 차이는?

Q4

새 서버 접속용 SSH 키를 만들 때 ssh-keygen -t ed25519를 권장하는 이유는?

Q5

ssh -i ~/.ssh/prod.pem ubuntu@54.123.45.67 를 매번 치기 번거롭다. ~/.ssh/config에 Host prod로 등록하면?

Q6

SSH 개인키로 접속하니 'WARNING: UNPROTECTED PRIVATE KEY FILE'과 함께 접속이 거부된다. 원인과 해결은?

Q7

[심화] SSH로 어떤 서버에 처음 접속하면 호스트 지문(fingerprint)을 보여주며 계속 진행할지 묻고, yes를 누르면 다음부터 묻지 않는다. 이 절차가 실제로 하는 일은?

Q8

[심화] 어제까지 접속되던 EC2를 종료했다가 같은 IP로 새로 만든 뒤 접속하니 REMOTE HOST IDENTIFICATION HAS CHANGED 경고와 함께 거부된다. 올바른 진단과 해결은?

Q9

[1급] bash를 로그인 셸(login shell)로 시작할 때 사용자별로 읽는 초기화 파일의 순서로 옳은 것은?

Q10

[1급] 사용자의 기본 로그인 셸을 chsh -s /bin/zsh로 바꾸려는데 zsh는 설치돼 있는데도 invalid shell 오류가 난다. 원인으로 옳은 것은?

0 / 10 답변

🧪 실습으로 확인하기

새 서버 인수인계 — 처음 30분

초급

낯선 Linux 서버를 인수받았을 때 OS, 서비스, 로그를 빠르게 파악하는 루틴을 직접 수행한다.

30📋 3단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요